본문으로 건너뛰기
5분 AI.
GITHUB TRENDING PYTHON WEEKLY #14 딥다이브 · 2026-10-23 분석

vllm 딥다이브
— GPU의 빈자리를 줄이는 LLM 서빙의 설계

추론·서빙 엔진

빠른 판단

무엇
연속 배치와 블록 단위 KV 캐시로 모델 요청을 처리하는 LLM 추론 라이브러리·API 서버
이럴 때
오픈 모델을 자체 운영하며 동시 요청·컨텍스트 길이·GPU 메모리의 균형을 조정할 때
입력
모델 가중치와 배치 입력 또는 API 생성 요청
결과
스케줄링·캐시 관리를 거친 생성 결과·응답 스트림
vLLM은 이미 학습된 대규모 언어 모델을 여러 사용자가 효율적으로 쓰도록 만드는 추론·서빙 엔진입니다. 질문을 GPU에 보내는 것에서 멈추지 않고, 실행 순서·중간 계산 메모리·응답 스트리밍·분산 실행까지 관리합니다. 이 글은 Python API에서 시작해 스케줄러와 KV 캐시 블록을 거쳐 GPU 실행 계층까지 내려갑니다. 저장소는 vllm-project/vllm, 주 언어는 Python, 라이선스는 Apache-2.0입니다. 2026-10-23 GitHub 기준 스타 95,202개·포크 23,834개이며, 코드 설명은 커밋 f4edf9f 기준입니다.
목차
  1. 프로젝트 한줄 요약
  2. 왜 주목받는가
  3. 기술 스택 전체 지도
  4. 아키텍처 심화 분석
  5. 디렉토리 구조 해부
  6. 학습 포인트 (기술별)
  7. 하드웨어 / 시스템 요구사항
  8. 직접 해볼 수 있는 실습 과제
  9. 관련 기술 심화 학습 로드맵
  10. 핵심 키워드 사전
  11. 참고 링크

1프로젝트 한줄 요약

여러 언어 모델 요청에 계산 자원을 배분하는 실행 관리자

vLLM은 학습된 모델의 가중치를 불러와 텍스트 등을 생성하고, 그 계산을 서버 자원에 맞춰 배분하는 시스템입니다. Python에서 LLM.generate()를 부르는 라이브러리로도, vllm serve로 실행하는 API 서버로도 쓸 수 있습니다. 이 저장소에서 배울 핵심은 모델의 정답을 바꾸는 법보다, 같은 모델로 더 많은 요청을 효율적으로 처리하는 법입니다.

용어부터
추론과 서빙
추론은 학습된 모델로 결과를 계산하는 일입니다. 서빙은 그 계산을 사용자의 요청에 맞춰 제공하는 운영 체계입니다. 요청 검증·대기열·취소·응답 전송도 서빙에 포함됩니다. 모델 파일만 있어서는 이 체계가 저절로 생기지 않습니다.
한 문장 비유

모델이 요리사라면, vLLM은 주문표와 조리대를 관리하는 주방장입니다

주문 하나를 끝낸 뒤 다음 주문을 받으면 조리대가 자주 빕니다. 여러 주문을 함께 처리하되, 먼저 끝난 주문의 자리에 새 주문을 넣으면 같은 주방으로 더 많은 손님을 받을 수 있습니다.

GPU는 조리대, 요청은 주문표, KV 캐시는 조리 중인 재료를 놓는 공간에 비유할 수 있습니다. vLLM은 이번 차례에 무엇을 얼마나 계산하고, 그 중간 상태를 어디에 보관할지 결정합니다.

1-1. 입력부터 출력까지 여섯 단계

  1. 사용자가 문자열이나 대화 메시지를 보냅니다.
  2. 렌더러와 토크나이저가 모델이 이해하는 토큰 ID로 바꿉니다.
  3. 스케줄러가 이번 반복에서 계산할 요청과 토큰 수를 고릅니다.
  4. KV 캐시 관리자가 필요한 블록을 확보합니다.
  5. 실행기가 모델을 계산하고, 샘플러가 다음 토큰을 선택합니다.
  6. 출력 처리기가 토큰을 문자열로 복원하고 호출자에게 전달합니다.

첫 진입점은 vllm/entrypoints/llm.py의 LLM.generate()입니다. 공식 예제 examples/basic/offline_inference/basic.py도 LLM과 SamplingParams를 사용합니다. 아래는 같은 API를 작은 모델에 적용한 학습용 예시입니다.

from vllm import LLM, SamplingParams

llm = LLM(model="Qwen/Qwen3-0.6B", max_model_len=2048)
params = SamplingParams(temperature=0.0, max_tokens=64)
outputs = llm.generate(["KV 캐시를 쉬운 비유로 설명해 줘."], params)

for output in outputs:
    print(output.outputs[0].text)

SamplingParams는 출력 길이와 토큰 선택 규칙을 담습니다. 위 코드는 준비된 추론 환경에서 사용하는 예시이며, 생성 문장과 실행 속도는 모델·장치·설정에 따라 달라집니다. 오프라인 추론은 HTTP 서버 없이 함수로 결과를 받는 방식입니다.

읽는 목표
함수 호출 뒤에 숨어 있는 자원 관리 이해하기

입문 단계에서는 모델 수식 전체보다 요청 → 스케줄링 → 메모리 확보 → 실행 → 정리의 경계를 잡으세요. 이 흐름은 데이터 처리 서버, 작업 큐, 게임 서버의 자원 관리에도 이어지는 시스템 설계 지식입니다.

2왜 주목받는가

처리량과 메모리라는 실제 운영 문제를 함께 다루기 때문

2-1. 주간 트렌딩 순위와 기술적 배경을 구분하기

vLLM은 2026-10-23 분석 기준 GitHub Trending Python Weekly #14로 선정된 저장소입니다. 스타 95,202개와 포크 23,834개는 넓은 관심과 활용의 신호입니다. 다만 그 숫자만으로 이번 주의 유입 원인을 특정할 수는 없습니다. 다음 세 가지는 현재 기능과 소스 구조에서 읽을 수 있는 주목할 만한 기술적 이유입니다.

큰 모델의 서빙에서는 계산을 빠르게 하는 일과, 계산할 요청을 잘 모으고 메모리를 덜 낭비하는 일이 함께 중요합니다. 커밋 f4edf9f의 제목은 Intel XPU의 커널·샘플러 단위 테스트 활성화입니다. 이는 장치별 실행 경로를 검증하는 개발이 진행 중이라는 사례이며, 주간 트렌딩의 직접 원인이라는 뜻은 아닙니다.

성능을 읽는 두 축
처리량과 지연시간
처리량은 초당 처리한 요청이나 토큰의 양이고, 지연시간은 한 사용자가 기다리는 시간입니다. 배치를 키우면 처리량이 좋아질 수 있지만 대기시간이나 첫 토큰 시간은 늘어날 수 있습니다.

2-2. 비교할 때는 공통 기능보다 선택의 초점을 보기

접근 / 도구강점과 초점vLLM에서 주목할 점
직접 만든 생성 루프한 요청의 모델 호출과 샘플링을 이해하기 쉽습니다.대기열·취소·배칭·캐시 관리를 직접 조합하는 부담을 줄입니다.
llama.cppREADME 기준 C/C++ 추론, 여러 장치와 CPU·GPU 혼합 실행을 지원합니다.Python 모델 실행 계층부터 분산 서빙 제어까지 연결해 공부할 수 있습니다.
TensorRT LLMNVIDIA GPU에 맞춘 커널·추론 런타임 최적화가 중심입니다.여러 하드웨어 백엔드와 PyTorch 기반 실행 구조를 함께 살펴볼 수 있습니다.
vLLMKV 캐시·스케줄링·모델 실행·API 서빙의 통합이 중심입니다.모델·커널·장치의 조합에 따라 지원 범위와 실제 성능을 확인해야 합니다.

비교 근거는 llama.cpp 공식 저장소와 NVIDIA의 TensorRT LLM 소개입니다. TensorRT LLM도 in-flight batching과 paged KV cache를 지원합니다. 따라서 이 개념들을 vLLM만의 독점 기능으로 외우면 안 됩니다.

2-3. 초기 성능 수치를 현재의 보장으로 읽지 않기

2023년 공식 소개 글은 특정 GPU·모델·데이터 조건에서 Hugging Face Transformers와 TGI 대비 높은 처리량을 보고했습니다. 그 결과는 PagedAttention의 배경을 이해하는 자료입니다. 2026년의 모든 모델에서 같은 배수가 나온다는 근거로 사용할 수는 없습니다.

비교의 기준

버스의 좌석 수, 운행 횟수, 승객 대기시간을 함께 봐야 하듯, 추론 엔진도 같은 모델·정밀도·입출력 길이·동시 요청 수를 맞춰 비교해야 합니다. 혼자 쓰는 작은 모델과 수백 요청을 받는 서버는 최적의 선택이 다를 수 있습니다.

3기술 스택 전체 지도

Python 제어 계층, 네이티브 계산 계층, 두 가지 서버 프런트엔드

pyproject.toml은 Python 배포와 빌드의 출발점입니다. dependencies가 dynamic으로 선언되어 있어 의존성 전체가 이 파일 안에 나열되지는 않습니다. setup.py의 get_requirements()가 대상 장치에 맞는 requirements/cuda.txt·requirements/cpu.txt·requirements/xpu.txt 등을 읽습니다.

3-1. 백엔드와 모델 실행 계층

기술실제 선언값역할 / 근거 파일
Python>=3.11,<3.15API·설정·스케줄러. pyproject.toml
PyTorchtorch==2.14.0텐서·모델 실행. requirements/cuda.txt와 빌드 의존성
Transformers>=5.16.1,<5.21.0모델 설정·생태계 연동. requirements/common.txt
tokenizers>=0.23.2토큰화와 문자열 복원 관련 의존성. requirements/common.txt
safetensors>=0.6.2모델 가중치 형식 지원. requirements/common.txt
FlashInferflashinfer-python==0.7.2GPU 커널 경로. requirements/cuda.txt
양자화compressed-tensors==0.17.0압축·양자화된 모델 표현 연동. requirements/common.txt
구조화 출력xgrammar==0.2.8문법 제약을 이용한 출력 생성. 아키텍처 조건부 의존성
프로세스 통신pyzmq>=25.0.0, msgspec엔진 경계의 메시지 통신과 직렬화. requirements/common.txt

vLLM은 Python으로 계산 순서를 정하지만, 실제 텐서 연산은 PyTorch와 장치별 커널에 맡기는 여러 계층의 시스템입니다. vllm/model_executor/models/llama.py의 LlamaAttention.forward()를 보면 Q·K·V 투영, 회전 위치 임베딩, Attention 호출이 연결됩니다. Hugging Face 가중치와 호환되는 자체 추론용 모델 구현이므로, 단순히 외부 모델의 생성 함수를 감싼 구조보다 깊습니다.

버전 표 읽기
고정 버전과 허용 범위
==는 특정 버전을 요구하고, >=와 <는 설치 가능한 범위를 정합니다. 범위 선언은 실제 설치 버전을 뜻하지 않습니다. 표는 커밋 f4edf9f의 의존성 선언값입니다.

3-2. 프런트엔드: 여기서는 HTTP 요청을 받는 계층

이 저장소에서 프런트엔드라는 말은 주로 추론 엔진 앞의 API 처리 계층을 가리킵니다. 루트에는 package.json이 없으며 React나 Vue 기반의 일반 사용자용 웹 화면을 주 구성요소로 두지 않습니다. 따라서 웹 UI를 찾기보다 라우터·렌더러·토크나이저·스트리밍 처리를 읽는 편이 목적에 맞습니다.

계층실제 선언값읽을 코드
Python HTTPfastapi[standard]>=0.133.0,<0.137.0vllm/entrypoints/launchers/app.py
검증 / ASGIpydantic>=2.12.0, starlette>=1.0.1requirements/common.txt와 각 API의 요청 자료형
스트리밍SSE, StreamingResponsevllm/entrypoints/openai/chat_completion/api_router.py
Rust HTTPaxum="0.8.8", tokio="1.47.1"rust/Cargo.toml, rust/src/server/
Rust 직렬화serde="1.0.228", rmp-serde="1.3.1"Rust API 계층과 Python 엔진 사이의 메시지 표현

rust/README.md는 Rust 프런트엔드를 실험적이며 기능이 완전하지 않은 대안으로 명시합니다. VLLM_USE_RUST_FRONTEND=1로 선택하는 경로도 Python 엔진과 ZMQ 경계를 통해 통신합니다. Rust가 존재한다고 Python 추론 엔진 전체가 Rust로 교체되었다고 해석하면 안 됩니다.

3-3. 인프라와 빌드: Python 패키지 안에 네이티브 산출물 넣기

부품실제 설정배울 점
패키지 빌드setuptools.build_meta, setuptools>=77.0.3,<81.0.0pyproject.toml의 Python 배포 경계
네이티브 빌드cmake>=3.26.1, NinjaPython 설치와 C++·CUDA 빌드 연결
C++ / CUDA / HIP언어 표준 모두 20, GCC >=11.3 검사CMakeLists.txt의 컴파일러 호환성 관리
Rust 빌드edition 2024, workspace 버전 0.1.0rust/Cargo.toml의 여러 크레이트 구성
DockerCUDA_VERSION=13.0.3, PYTHON_VERSION=3.12docker/Dockerfile의 여러 빌드 단계와 실행 이미지
관측prometheus_client>=0.18.0, OpenTelemetry >=1.27.0지표 수집과 요청 추적. requirements/common.txt

docker/Dockerfile은 rust-build, csrc-build, extensions-build, build 등을 나눕니다. 서버 이미지인 vllm-openai 단계의 진입점은 ["vllm", "serve"]입니다. 컴파일 도구가 필요한 단계와 실제 서버 실행 단계를 나누는 컨테이너 설계를 배울 수 있습니다.

3-4. CI도 장치별로 설계되어 있다

.github/workflows/pre-commit.yml은 Python 3.12에서 저장소 전체 정적 검사를 수행하도록 구성합니다. 하드웨어 테스트는 .buildkite/ci_config.yaml의 .buildkite/image_build/·.buildkite/test_areas/·.buildkite/hardware_tests/ 경로로 나뉩니다. 공통 의존성이나 csrc/ 변경은 넓은 테스트를 실행하는 패턴에 포함됩니다.

.buildkite/intel_jobs/samplers_intel.yaml에는 VLLM_TEST_DEVICE=xpu와 VLLM_XPU_USE_SAMPLER_KERNEL=1이 등장합니다. 같은 샘플링 동작도 장치 경로를 실제로 선택해야 검증된다는 의미입니다. 테스트 명령이 있다는 사실과 특정 실행에서 테스트가 통과했다는 사실은 구분해야 합니다.

기술 스택을 읽는 순서

pyproject.toml → setup.py → requirements/ → CMakeLists.txt → docker/ → CI 설정 순으로 읽어 보세요. 필요한 라이브러리 목록이 어떻게 설치 가능한 패키지와 실행 이미지로 바뀌는지 연결됩니다.

4아키텍처 심화 분석

한 번의 HTTP 요청이 반복되는 GPU 작업으로 바뀌는 과정

4-1. 전체 시스템 구조도

아래는 일반적인 Python 온라인 서빙 경로를 단순화한 그림입니다. 실제 프로세스 수와 실행기는 병렬화·장치·실행 설정에 따라 달라집니다. Rust 프런트엔드를 선택하는 경우에는 그림 맨 위의 API 처리 계층이 달라집니다.

사용자 / API 클라이언트 | | POST /v1/chat/completions v +----------------------------------------------------+ | API 서버 프로세스 | | FastAPI 라우터 -> OpenAIServingChat | | 대화 렌더링 / 토큰화 / SamplingParams 구성 | | AsyncLLM -> EngineCoreClient | +----------------------------------------------------+ | 엔진 요청 ^ 토큰 결과 | ZMQ / 직렬화 메시지 | v | +----------------------------------------------------+ | EngineCore 프로세스 | | Scheduler.schedule() | | | | | +-- KVCacheManager -> BlockPool | | | 재사용 조회 / 블록 확보 / 참조 수 관리 | | v | | SchedulerOutput -> Executor.execute_model() | +----------------------------------------------------+ | 한 장치 또는 여러 worker v +----------------------------------------------------+ | Worker -> GPUModelRunner -> 모델 계층 | | PyTorch / 선택된 attention 백엔드 / 장치별 커널 | | 모델 출력 -> 다음 토큰 선택 -> 엔진으로 반환 | +----------------------------------------------------+ | +-- 결과는 위 경로를 거슬러 출력 처리기로 토큰 ID -> 문자열 -> JSON 또는 SSE

vllm/entrypoints/openai/chat_completion/api_router.py의 create_chat_completion()은 처리 결과의 종류에 따라 JSON 응답이나 text/event-stream 응답을 반환합니다. OpenAIServingChat._create_chat_completion()은 render_chat_request()로 입력을 준비한 뒤 engine_client.generate()를 호출합니다.

소스 탐색의 함정
예전 API 서버 파일에 모든 로직이 있지 않습니다

vllm/entrypoints/openai/api_server.py는 현재 여러 함수를 다시 내보내며 폐기 예정 경고를 냅니다. 서버 조립은 vllm/entrypoints/launchers/api_server/entry.py와 vllm/entrypoints/launchers/app.py부터 따라가세요. 파일 이름만 보고 오래된 구조를 현재 구조로 설명하기 쉬운 지점입니다.

4-2. 반복의 중심: EngineCore.step()

vllm/v1/engine/core.py의 EngineCore.step()은 스케줄링·실행·결과 반영을 한 반복으로 묶습니다. 아래는 핵심 호출 순서를 보존하고 계측·문법 처리 등을 생략한 학습용 축약입니다.

# vllm/v1/engine/core.py: EngineCore.step()의 흐름
scheduler_output = self.scheduler.schedule(self._should_throttle_prefills())
future = self.model_executor.execute_model(scheduler_output, non_block=True)
grammar_output = self.scheduler.get_grammar_bitmask(scheduler_output)
model_output = future.result()

# 실행 경로에 따라 샘플링이 별도 호출일 수 있음
if model_output is None:
    model_output = self.model_executor.sample_tokens(grammar_output)

self._process_aborts_queue()
outputs = self.scheduler.update_from_output(scheduler_output, model_output)

non_block=True라고 지정해도 곧바로 모든 결과가 준비되는 것은 아닙니다. 이 경로에서는 future.result()로 결과를 기다립니다. 별도의 step_with_batch_queue()도 있으므로 이 축약을 모든 실행 모드의 유일한 시간표로 이해하면 안 됩니다.

4-3. 설계 패턴 ① 비동기 스트림과 프로세스 경계

vllm/v1/engine/async_llm.py의 AsyncLLM.generate()는 add_request()로 요청을 등록하고 요청별 수집기에서 결과를 꺼내 yield합니다. 별도의 출력 처리 루프가 엔진 결과를 요청별 수집기에 전달합니다. API 요청을 받는 속도와 GPU가 토큰을 만드는 속도를 연결하는 구조입니다.

# AsyncLLM.generate()의 핵심 구조를 줄인 예시
q = await self.add_request(request_id, prompt, sampling_params)
finished = False
while not finished:
    out = q.get_nowait() or await q.get()
    finished = out.finished
    yield out

# 원본은 취소·오류 분기와 종료 표지도 별도로 처리함

이 함수의 asyncio.CancelledError·GeneratorExit 처리에서는 등록된 요청을 abort()합니다. 연결이 끊어진 사용자를 위해 계속 GPU를 쓰지 않도록, 전송 계층의 취소를 엔진의 작업 정리와 연결합니다. 다른 비동기 서버에서도 유용한 자원 수명 관리 패턴입니다.

용어 연결
비동기와 병렬 실행은 다른 축
await는 기다리는 동안 다른 일을 진행할 수 있게 합니다. 여러 GPU나 프로세스가 동시에 계산하는 것은 병렬 실행입니다. vLLM은 두 방식 모두 사용하지만, async def 하나가 GPU 계산을 병렬화하는 것은 아닙니다.

4-4. 설계 패턴 ② 토큰 예산으로 통합한 스케줄링

vllm/v1/core/sched/scheduler.py의 Scheduler.schedule()은 각 요청의 num_computed_tokens를 필요한 토큰 수에 가까워지도록 진행시킵니다. 함수 주석도 스케줄러 내부에서 prefill과 decode를 별개 단계로 고정하지 않는다고 설명합니다. 이 관점으로 긴 입력의 분할 처리와 추측 토큰 검증을 같은 예산 체계에 담습니다.

# 실행 중인 요청을 배분하는 부분의 축약
num_new_tokens = (
    request.num_tokens_with_spec
    + request.num_output_placeholders
    - request.num_computed_tokens
)
num_new_tokens = min(num_new_tokens, token_budget, input_budget - draft_slots)
# 원본에는 긴 입력 제한, 모델 길이 제한, 인코더 예산 등이 추가됨
new_blocks = self.kv_cache_manager.allocate_slots(request, num_new_tokens)
# 성공한 요청의 배분을 반영하는 단계
token_budget -= num_new_tokens

작은 예: 한 반복의 예산을 8토큰이라고 가정해 봅시다. 실행 중인 A와 B가 각각 다음 1토큰을 계산한다면 6토큰이 남습니다. 긴 입력을 가진 C는 그 6토큰만 먼저 계산하고 나머지를 뒤로 넘길 수 있습니다. 이는 개념 예시이며 실제 배분에는 캐시, 인코더, 우선순위와 장치 제약이 함께 작용합니다.

스케줄러의 비유

엘리베이터에 사람 수 제한과 무게 제한이 따로 있듯, max_num_seqs와 토큰 예산은 서로 다른 제약입니다. 짧은 요청 10개와 긴 요청 10개를 같은 비용으로 계산할 수 없습니다.

블록 확보에 실패하면 실행 중인 요청을 선점하는 분기가 있습니다. Scheduler._preempt_request()는 블록을 정리하고 상태를 PREEMPTED로 바꾼 뒤 num_computed_tokens=0으로 되돌려 대기열에 넣습니다. 다시 계산할 비용이 생길 수 있으므로 선점을 많이 한다고 효율적인 것은 아닙니다.

4-5. 설계 패턴 ③ 블록 풀과 내용 기반 캐시 재사용

vllm/v1/core/kv_cache_manager.py의 KVCacheManager는 요청별 캐시 배치와 슬롯 확보를 조율하고, vllm/v1/core/block_pool.py의 BlockPool은 실제 블록 메타데이터의 할당·반납·캐시 퇴거를 관리합니다. 큰 메모리 문제를 여러 작은 블록의 수명 관리로 바꾸는 설계입니다.

논리적 토큰 순서 물리적 KV 블록 요청 A: [0..15] [16..31] [32..47] 블록 2: A와 B의 공통 앞부분 | | | 블록 9: A의 뒷부분 v v v 블록 4: A의 다른 뒷부분 [2] [9] [4] 블록 7: B의 뒷부분 요청 B: [0..15] [16..31] | | v v [2] [7] 블록 2의 참조 수 = 2 토큰 수 16과 블록 번호는 이해를 위한 예시

vllm/v1/core/kv_cache_utils.py의 KVCacheBlock에는 block_id, ref_cnt, block_hash, 자유 블록 연결 정보가 있습니다. BlockPool.get_new_blocks()는 자유 큐에서 블록을 꺼내 참조 수를 늘리고, free_blocks()는 참조 수를 줄여 0이 된 블록을 재사용 대상으로 돌립니다. 반납된 캐시 블록이 곧바로 지워지는 것은 아닙니다.

접두사 캐시는 단순히 문자열 몇 글자가 같은지 비교하지 않습니다. hash_block_tokens()는 이전 블록의 해시, 현재 토큰 ID 묶음, 추가 키를 함께 해시합니다. 앞 문맥이 달라지면 같은 토큰 묶음이라도 다른 계산 상태가 되기 때문입니다.

# vllm/v1/core/kv_cache_utils.py: hash_block_tokens()
curr_block_token_ids_tuple = tuple(curr_block_token_ids)
return BlockHash(
    hash_function((parent_block_hash, curr_block_token_ids_tuple, extra_keys))
)

KVCacheManager.get_computed_blocks()는 가장 긴 캐시 적중 구간을 찾습니다. 이 함수는 다음 토큰의 점수를 얻기 위해 마지막 토큰을 다시 계산하도록 최대 적중 길이를 request.num_tokens - 1로 제한합니다. 블록 정렬 제약 때문에 한 토큰보다 많은 부분을 다시 계산할 수도 있다는 주석도 있습니다.

해시 기본값은 CacheConfig.prefix_caching_hash_algo="sha256"입니다. generate_block_hash_extra_keys()에서는 LoRA·멀티모달 입력 등 추가 문맥을 고려합니다. 따라서 같은 화면상의 문장이라고 언제나 캐시가 공유된다고 단정하면 안 됩니다.

현재 구현의 세부사항

BlockHashToBlockMap의 주석은 동일한 해시의 블록을 항상 하나로 합치지는 않는다고 밝힙니다. 블록 테이블이 뒤에 덧붙는 성질을 유지하려는 선택입니다. 또한 자유 블록 큐는 캐시 없는 블록의 LIFO 재사용과 캐시 블록의 FIFO 재사용을 구분합니다. 단순한 “해시 딕셔너리 하나”보다 많은 수명 정책이 들어 있습니다.

KV 캐시 최적화의 핵심은 기억할 내용을 바꾸는 것이 아니라, 같은 중간 상태를 안전하게 공유하고 필요한 공간만 확보하는 것입니다. 고전적인 PagedAttention의 블록 관리 아이디어와, 현재 선택 가능한 FlashAttention·FlashInfer 등의 실제 계산 백엔드는 구분해서 이해하세요. 모든 모델이 같은 캐시 형식이나 같은 커널을 쓰는 것은 아닙니다.

4-6. 설계 패턴 ④ 인터페이스로 분리한 실행 전략

vllm/v1/executor/abstract.py의 Executor.get_class()는 distributed_executor_backend 값에 따라 실행기를 고릅니다. uni는 UniProcExecutor, mp는 MultiprocExecutor, ray는 RayExecutorV2로 이어집니다. 스케줄러가 직접 모든 장치 실행 방식을 구현하지 않게 만드는 전략 선택 구조입니다.

선택하는 대상파일 / 함수분리의 효과
실행기vllm/v1/executor/abstract.py
Executor.get_class()
단일 프로세스와 분산 작업 지시 방식을 분리합니다.
Attention 백엔드vllm/v1/attention/selector.py
get_attn_backend()
자료형·헤드 크기·장치 등의 조건에 맞는 구현을 선택합니다.
모델 클래스vllm/model_executor/models/registry.py
_ModelRegistry.resolve_model_cls()
설정의 모델 아키텍처와 실행 클래스를 연결합니다.

GPU 쪽에서는 vllm/v1/worker/gpu_worker.py의 Worker.execute_model()과 vllm/v1/worker/gpu/model_runner.py의 GPUModelRunner.execute_model()을 따라가면 됩니다. 별도 지정이 없고 Triton·기능 지원 조건을 만족하면 V2 실행기가 선택되며, 조건에 따라 vllm/v1/worker/gpu_model_runner.py의 V1 구현으로 전환됩니다. 처음부터 커널 전체를 읽기보다 입력으로 받은 스케줄 결과가 어떤 텐서와 블록 테이블로 바뀌는지 추적하세요. 제어 정책과 계산 구현을 분리하는 이유가 드러납니다.

5디렉토리 구조 해부

200만 줄을 처음부터 읽지 않고, 질문에 맞는 경로 찾기
vllm/ ├── pyproject.toml Python 패키지·빌드 선언 ├── setup.py 장치별 의존성·네이티브 빌드 연결 ├── vllm/ │ ├── entrypoints/ CLI·HTTP API·서버 시작점 │ ├── config/ 모델·캐시·스케줄러 등의 설정 │ ├── engine/ 엔진 인자와 설정 조립 │ ├── v1/ │ │ ├── engine/ 요청·출력 처리와 EngineCore │ │ ├── core/ 스케줄러와 KV 캐시 관리 │ │ ├── executor/ 단일·분산 실행기 │ │ ├── worker/ 장치 작업과 모델 실행 │ │ ├── attention/ Attention 인터페이스·백엔드 │ │ └── metrics/ 성능·대기열 지표 │ ├── model_executor/ 모델·계층·양자화 구현 │ ├── distributed/ 통신·병렬화·KV 전송 │ ├── compilation/ 컴파일·그래프 변환 │ └── platforms/ 장치별 선택과 설정 ├── csrc/ C++·CUDA 등 네이티브 구현 ├── rust/ 대안 API 계층과 관련 크레이트 ├── requirements/ 공통·장치·개발 의존성 ├── tests/ 정확성·경계 조건·통합 테스트 ├── benchmarks/ 성능 측정·커널 실험 자료 ├── examples/ 추론·서빙·관측 예제 ├── docs/ 사용자·개발 문서 ├── docker/ 하드웨어별 컨테이너 구성 ├── cmake/ 네이티브 빌드 보조 설정 ├── .github/ 정적 검사·협업 자동화 └── .buildkite/ 장치별 빌드·테스트 파이프라인

트리 맨 위의 vllm/은 저장소를 나타내는 표기이고, 그 안의 vllm/이 Python 패키지입니다. 실제 파일 경로는 vllm/v1/engine/core.py처럼 저장소 루트 기준으로 읽으면 됩니다. v1은 엔진 계층의 이름이며 설치 패키지의 릴리스 번호와는 별개입니다.

궁금한 질문먼저 열 파일다음으로 이어질 곳
CLI는 어디서 시작하나?vllm/entrypoints/cli/main.pyvllm/entrypoints/cli/serve.py와 서버 launcher
누가 다음 요청을 고르나?vllm/v1/core/sched/scheduler.pyvllm/v1/core/kv_cache_manager.py와 vllm/v1/core/sched/output.py
모델 종류는 어떻게 찾나?vllm/model_executor/models/registry.py해당 모델 파일과 공통 계층
GPU 없이 읽을 단서는?tests/v1/core/test_scheduler.py가짜 요청·블록 수·예산을 만드는 보조 함수
대기시간은 어디서 재나?vllm/v1/metrics/loggers.pyexamples/observability/의 대시보드 자료

tests/는 Python 2,227개 파일·779,412줄, vllm/ 패키지는 Python 2,929개 파일·1,136,955줄입니다. 주석·빈줄을 포함한 물리적 줄 수이므로 이를 테스트 커버리지나 품질 점수로 환산하면 안 됩니다. 처음 읽을 때는 구현 하나와 그 구현의 테스트를 짝지어 선택하는 편이 효과적입니다.

6학습 포인트 (기술별)

파일을 읽고 끝내지 않고, 다른 시스템에도 옮길 수 있는 지식으로 만들기

6-1. Python 타입과 데이터 계약

Scheduler.schedule()의 반환형은 SchedulerOutput입니다. 스케줄러가 텐서를 직접 계산하지 않고 “어떤 요청의 몇 토큰을 계산할지”를 자료 구조로 전달한다는 점에 주목하세요. vllm/v1/core/sched/output.py와 vllm/v1/outputs.py를 나란히 읽으면 실행 전 계획과 실행 후 결과가 서로 다른 계약이라는 사실이 보입니다.

실습 아이디어: 두 자료형에서 요청 ID·토큰 수·새 블록 정보를 찾아 표로 옮기세요. 그다음 필드 하나가 빠지면 어느 계층이 다음 작업을 할 수 없게 되는지 설명해 보세요.

6-2. 비동기 Python과 요청 수명

AsyncLLM.generate()는 비동기 생성기로 결과를 여러 번 반환합니다. 등록 → 대기 → 여러 번 출력 → 종료와, 등록 → 취소 → 정리의 두 경로를 구분해 읽으세요. 정상 경로만 빠른 서버보다 실패한 요청의 자원까지 회수하는 서버가 운영에서 더 예측 가능합니다.

실습 아이디어: 요청 하나의 상태를 종이에 그린 뒤 CancelledError가 어느 위치에서 발생해도 정리할 수집기와 엔진 요청이 무엇인지 표시하세요.

6-3. 자료 구조와 메모리 관리

KVCacheBlock의 참조 수와 자유 큐는 객체 풀의 구체적인 사례입니다. 블록이 “요청에 사용 중”인지, “재사용 가능한 캐시”인지, “새 내용으로 덮어써도 되는 공간”인지 구분하는 기준을 찾아보세요. 해시 인덱스에 남아 있다는 사실과 사용 중이라는 사실은 같지 않습니다.

실습 아이디어: 블록 세 개를 두 요청이 나누어 쓰는 상황을 만들고, 할당·공유·반납할 때마다 ref_cnt와 자유 큐를 손으로 갱신하세요.

6-4. PyTorch와 병렬화된 모델 계층

vllm/model_executor/models/llama.py에는 QKVParallelLinear, RowParallelLinear, RMSNorm 등이 나타납니다. 일반적인 신경망 레이어에 장치 분할과 추론 최적화가 어떻게 결합되는지 볼 수 있습니다. LlamaAttention.forward()의 Q·K·V 분리부터 읽으면 수식과 코드의 대응이 비교적 분명합니다.

실습 아이디어: 헤드 수를 8개, tensor parallel 크기를 2라고 가정해 각 장치가 담당하는 query 헤드를 그려 보세요. KV 헤드는 개수가 작을 때 복제될 수 있으므로 모든 텐서가 동일하게 반으로 나뉜다고 가정하지 마세요.

6-5. 시스템 관측과 실험 설계

지표물어볼 질문실제 지표 이름
TTFT첫 결과를 보기까지 오래 기다리는가?vllm:time_to_first_token_seconds
ITL생성이 시작된 뒤 토큰 사이가 느린가?vllm:inter_token_latency_seconds
전체 지연요청 완료까지 얼마나 걸리는가?vllm:e2e_request_latency_seconds
대기 요청실행보다 유입이 빠른가?vllm:num_requests_waiting

이 이름들은 vllm/v1/metrics/loggers.py에서 확인할 수 있습니다. 평균만 보지 말고 p50·p95 같은 백분위수를 함께 비교하세요. 첫 실행의 모델 로딩·컴파일·그래프 준비 시간과 준비가 끝난 뒤의 요청 지연도 구분해야 합니다.

6-6. 테스트에서 설계 의도를 역으로 읽기

tests/v1/core/test_scheduler.py의 test_preempt_during_execution()은 블록 크기 16, 블록 수 11, 토큰 예산 100 같은 작은 조건으로 선점 상황을 구성합니다. 블록 0이 null 블록으로 예약되어 실제 가용 블록은 10개라는 주석까지 읽어야 계산이 맞습니다. 거대한 모델 없이도 스케줄러의 경계 조건을 설명하는 좋은 독서 자료입니다.

tests/v1/core/test_prefix_caching.py에는 pytest.mark.cpu_test가 있고, .buildkite/test_areas/misc.yaml도 CPU 테스트와 그 외 테스트를 나눕니다. 다만 CPU 표시가 있다고 의존성 설치 없이 모든 테스트가 독립 실행된다는 뜻은 아닙니다.

좋은 소스 독서는 함수 이름을 외우는 일이 아니라, 입력·출력·자원 소유자·실패 시 정리 규칙을 설명할 수 있게 되는 일입니다. 이 네 가지를 한 장에 정리하면 처음 보는 분산 시스템도 훨씬 덜 막막해집니다.

7하드웨어 / 시스템 요구사항

설치 가능한 환경과 원하는 모델이 실제로 들어가는 환경은 다릅니다

7-1. 코드 읽기와 모델 실행에 필요한 것을 구분하기

목적 / 경로확인할 요구사항근거
소스 공부텍스트 편집기와 Git만으로 핵심 흐름을 읽을 수 있습니다.스케줄러·캐시·테스트 자료 구조 추적
일반 실행 환경빠른 시작 문서 기준 Linux, Python 3.11~3.14docs/getting_started/quickstart.md
NVIDIA GPU문서 기준 compute capability 7.5 이상. 선택 커널은 추가 조건이 있을 수 있습니다.docs/getting_started/installation/gpu.cuda.inc.md
AMD GPU지원 GPU와 ROCm 조합 확인. 현재 문서는 기본 ROCm 10.0·별도 7.2 계열 wheel을 설명합니다.docs/getting_started/installation/gpu.rocm.inc.md
Intel GPUData Center GPU·ARC 계열 안내. XPU wheel 문서는 Python 3.12를 요구합니다.docs/getting_started/installation/gpu.xpu.inc.md
x86 CPULinux, AVX512 권장·AVX2 기능 제한. GPU와 다른 패키지 경로입니다.docs/getting_started/installation/cpu.x86.inc.md
Apple SiliconGPU 사용은 별도 vLLM-Metal 플러그인·MLX 경로. 문서는 macOS Sonoma 이상을 안내합니다.docs/getting_started/installation/gpu.apple.inc.md

Python 패키지가 지원하는 전체 버전 범위와 특정 장치 wheel이 제공되는 범위는 같지 않습니다. 장치 이름 하나만 확인하지 말고 OS·Python·PyTorch·드라이버·커널의 조합을 확인하세요. 기본 CUDA 패키지 하나가 모든 GPU와 CPU 환경을 동시에 해결하지는 않습니다.

7-2. 메모리는 가중치와 KV 캐시를 더해 생각하기

가중치 메모리의 거친 하한은 파라미터 수 × 파라미터당 바이트입니다. 예를 들어 70억 파라미터를 2바이트로 저장하면 약 14GB, 즉 약 13.0GiB입니다. 이는 가중치만의 계산입니다. 실행 중간 텐서, 그래프, 통신 버퍼, KV 캐시와 할당 여유가 추가됩니다.

# 일반적인 decoder의 full attention, 단일 요청에 대한 근사식
KV 바이트 ≈ 2 × 레이어 수 × KV 헤드 수 × 헤드 차원
             × 저장 토큰 수 × 원소당 바이트

# 예시: 32층, KV 헤드 8개, 차원 128, 4096토큰, 2바이트
2 × 32 × 8 × 128 × 4096 × 2 = 536,870,912바이트
                           = 512MiB

이 예시에서 서로 캐시를 공유하지 않는 요청 8개라면 KV 데이터만 약 4GiB입니다. 실제 사용량은 블록 단위 반올림, 병렬화, 자료형과 모델 구조에 따라 달라집니다. sliding window, MLA, Mamba 같은 구조에는 위 공식을 그대로 적용할 수 없습니다.

용량 계산의 함정
GB와 GiB
1GB는 10억 바이트이고, 1GiB는 1,073,741,824바이트입니다. 모델 크기와 장치 메모리 표시의 단위가 다르면 여유 공간을 잘못 계산할 수 있습니다. 또한 가중치 양자화와 KV 캐시 자료형은 따로 선택되는 항목입니다.

7-3. 현재 기본값을 그대로 운영 정답으로 외우지 않기

vllm/config/cache.py의 gpu_memory_utilization 기본값은 0.92입니다. 이는 모델 실행기에 사용할 장치 메모리 비율이며 KV 캐시만의 비율이나 GPU 연산 사용률이 아닙니다. Worker.determine_available_memory()는 프로파일링으로 캐시에 쓸 수 있는 메모리를 계산합니다. kv_cache_memory_bytes를 직접 지정하는 경로는 이 비율 설정을 따르지 않는다고 명시합니다.

CacheConfig.DEFAULT_BLOCK_SIZE=16은 출발점이며 최종 블록 크기는 백엔드 제약의 영향을 받습니다. SchedulerConfig의 2,048토큰·128시퀀스 기본값도 테스트 편의를 위한 값이라는 주석이 있습니다. 실제 실행 기본값은 vllm/engine/arg_utils.py에서 사용 맥락·장치·모델에 맞춰 조정됩니다.

문서와 설정을 대조해야 하는 이유
같은 커밋 안에서도 설치 안내와 빌드 기본값이 다릅니다

CUDA 설치 문서는 기본 바이너리를 CUDA 12.9로 설명하지만, docker/Dockerfile의 기본 인자는 CUDA 13.0.3입니다. 배포 wheel과 컨테이너 빌드는 다른 경로이므로 하나를 모든 배포물의 버전으로 일반화하면 안 됩니다.

XPU 문서에는 triton==3.7.2+xpu가 남아 있지만 requirements/xpu.txt는 triton==3.8.0+xpu를 선언합니다. 이 부분은 실제 불일치입니다. 장치별 공식 설치 안내와 선택한 릴리스의 의존성을 함께 확인해야 합니다.

어떤 모델이 실행되는지는 파라미터 수 하나가 아니라 정밀도·문맥 길이·동시 요청 수·커널·장치 메모리의 조합으로 결정됩니다. 디스크에는 가중치와 다운로드 캐시가, 시스템 RAM에는 로딩·전처리·CPU 경로용 공간이 필요합니다. 모든 모델에 통하는 단일 최소 VRAM·RAM 수치를 제시하기 어려운 이유입니다.

8직접 해볼 수 있는 실습 과제

읽기 과제부터 통제된 성능 실험까지, 다섯 단계

과제 1은 GPU와 설치 없이 할 수 있습니다. 과제 2~5는 7절의 장치별 설치 조건을 만족하는 별도 학습 환경을 전제로 합니다. 실행 예시는 기본 Python 프런트엔드와 작은 생성 모델을 기준으로 하며, 학습 결과에는 패키지 버전·모델 revision·장치·정밀도·길이 설정을 함께 기록하세요.

과제 1 · 입문 · GPU 불필요

요청 하나의 여행 지도를 그리기

create_chat_completion()에서 AsyncLLM.generate(), EngineCore.step(), Scheduler.schedule()까지 호출 순서를 찾아보세요. 각 화살표에 전달하는 자료형과 실행 프로세스를 적습니다.

완료 기준: “HTTP 요청 하나가 모델 실행 한 번과 같지 않은 이유”를 설명하고, 정상 종료·사용자 취소 시 정리할 자원을 각각 표시한 그림 한 장을 만듭니다.

과제 2 · 입문 · 준비된 추론 환경

오프라인 API와 생성 파라미터 익히기

1절의 예제에 프롬프트를 세 개 넣고 max_tokens를 16과 64로 바꿉니다. RequestOutput의 입력·출력 토큰 ID와 종료 사유를 살펴보세요. 토큰 수 제한은 한국어 글자 수 제한과 다릅니다.

완료 기준: 입력 토큰 수·생성 토큰 수·종료 사유를 표로 남깁니다. 모델 로딩 시간은 요청 처리 시간과 구분하고, 출력 문장이 매번 같다는 보장은 하지 않습니다.

과제 3 · 중급 · HTTP와 스트리밍

API 서버를 띄우고 전송과 계산의 경계 관찰하기

호환 환경에서 아래처럼 서버를 시작한 뒤 다른 터미널에서 스트리밍 요청을 보냅니다. 이 설정값들은 작은 실습을 위한 명시적 예시이며 모든 GPU에서의 실행을 보장하지 않습니다.

vllm serve Qwen/Qwen3-0.6B \
  --host 127.0.0.1 --port 8000 \
  --served-model-name study-model \
  --max-model-len 2048 \
  --max-num-seqs 8 --max-num-batched-tokens 2048 \
  --gpu-memory-utilization 0.80
curl -N http://127.0.0.1:8000/v1/chat/completions \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "study-model",
    "messages": [{"role": "user", "content": "캐시의 역할을 설명해 줘."}],
    "max_tokens": 128,
    "stream": true
  }'

완료 기준: SSE의 data: 이벤트와 종료 표지를 찾습니다. 이어 응답 도중 요청을 취소하고, 서버 지표에서 실행 요청이 정리되는지 확인합니다. 네트워크 청크 하나가 항상 토큰 하나와 일치한다고 가정하지 마세요.

과제 4 · 중급 · 측정 조건 통제

요청 유입량을 바꾸며 병목 찾기

과제 3의 서버에서 동일한 입력·출력 길이 조건으로 요청률을 바꿉니다. 아래 옵션은 vllm/benchmarks/serve.py와 vllm/benchmarks/datasets/datasets.py의 인자 처리를 따라 읽을 수 있습니다.

vllm bench serve \
  --backend openai --endpoint /v1/completions \
  --model study-model --tokenizer Qwen/Qwen3-0.6B \
  --dataset-name random \
  --random-input-len 128 --random-output-len 64 \
  --num-prompts 40 --request-rate 4 \
  --metric-percentiles 50,95 --ignore-eos

요청률을 1·4·8로 바꾸되 모델과 서버 설정은 유지합니다. --request-rate는 요청의 유입 속도이고 동시 실행 개수와 동일하지 않습니다. 기본값 inf는 모든 요청을 처음에 보내는 조건이므로 별도의 부하 형태로 다루세요.

완료 기준: 성공·실패 요청 수, 초당 출력 토큰, TTFT p50·p95, ITL p95를 표로 비교합니다. 워밍업 조건을 맞추고 대기 요청 수가 늘어나는 구간을 찾아 원인을 설명합니다.

과제 5 · 고급 · 접두사 캐시 실험

같은 앞부분이 재사용되는 조건 검증하기

긴 공통 시스템 메시지와 서로 다른 짧은 질문을 준비합니다. 첫 요청과 후속 요청을 순차 전송해 접두사 재사용을 관찰하고, 시스템 메시지 앞부분을 바꿨을 때의 결과와 비교하세요. 모델·chat template·토큰화 결과·출력 길이 조건을 고정합니다.

KVCacheManager.get_computed_blocks()와 hash_block_tokens()를 함께 읽고, 마지막 토큰 재계산과 블록 경계가 왜 남는지 설명하세요. 반복마다 캐시를 초기화하는 조건과 누적하는 조건을 구분해야 합니다.

완료 기준: 적중 토큰 관련 정보와 TTFT를 함께 기록하고, 짧은 공통 입력에서는 차이가 작을 수 있는 이유를 씁니다. 캐시를 끄는 비교는 해당 모델이 이를 지원하는지 먼저 확인하세요.

성능 실습의 결과물은 빠르다는 감상이 아니라, 조건을 고정한 표와 그 차이를 설명하는 가설이어야 합니다. 캐시·배치·유입률을 한꺼번에 바꾸면 어떤 설정이 영향을 주었는지 알기 어렵습니다. 한 번에 한 축을 바꾸고 예외와 실패도 기록하세요.

9관련 기술 심화 학습 로드맵

주당 3~5시간을 가정한 8주 학습 순서

첫 목표는 거대한 엔진을 다시 만드는 것이 아니라, 각 계층의 책임을 설명하고 작은 실험으로 설계 이유를 확인하는 것입니다. GPU가 없다면 1~4주와 7~8주의 설계·소스 과제부터 진행할 수 있습니다.

주차공부할 개념소스와 결과물
1주Python 타입·자료 클래스·반복자, 추론과 서빙의 구분vllm/entrypoints/llm.py, vllm/sampling_params.py를 읽고 입력·출력 계약 표 작성
2주토큰화·chat template·자기회귀 생성·prefill / decodeLlamaAttention.forward()의 Q·K·V 흐름과 토큰 증가 그림 작성
3주비동기 생성기·수집기·취소·프로세스 통신AsyncLLM.generate()의 정상·취소 시퀀스 작성, 실습 1 완료
4주대기열·예산·선점·자원 풀·참조 수Scheduler.schedule()과 BlockPool을 손으로 시뮬레이션
5주가중치 메모리·KV 캐시·캐시 키·블록 경계소형 모델의 입력 길이별 메모리 추정과 접두사 실험 설계
6주지표·부하 생성·워밍업·백분위수vllm/benchmarks/serve.py와 지표 정의를 읽고 실습 4의 비교 표 작성
7주tensor / pipeline / data parallel, 장치 간 통신Executor.get_class()와 vllm/distributed/의 역할 지도 작성
8주컴파일·장치별 백엔드·패키징·API 계약vllm/compilation/, docker/Dockerfile, rust/README.md 비교 노트 작성

9-1. 그다음에는 관심에 따라 가지를 고르기

마지막 주의 발표 질문

“긴 입력의 요청이 몰릴 때 첫 토큰 시간이 늘어나는 이유는 무엇인가?” “모든 요청이 다른 접두사를 쓰면 어떤 최적화의 효과가 작아지는가?” 두 질문에 스케줄러·캐시·지표를 연결해 답할 수 있다면 주요 구조를 이해한 것입니다.

10핵심 키워드 사전

코드와 문서를 읽다가 되돌아올 수 있는 짧은 설명
용어쉬운 설명
가중치모델이 학습으로 얻은 숫자 묶음. 추론을 시작할 때 불러오는 주요 데이터입니다.
토큰모델이 처리하는 텍스트 등의 단위. 한국어 한 글자나 한 단어와 항상 일치하지 않습니다.
토큰화텍스트를 토큰 ID 목록으로 바꾸는 과정입니다.
chat template사용자·시스템·도우미 메시지를 모델이 학습한 대화 형식으로 배열하는 규칙입니다.
자기회귀 생성앞의 입력과 지금까지 생성한 토큰을 바탕으로 다음 토큰을 이어 만드는 방식입니다.
prefill입력 문맥을 처리해 생성에 필요한 중간 상태를 준비하는 계산입니다.
decode준비된 문맥과 이전 결과를 사용해 다음 토큰을 이어 가는 계산입니다.
KV 캐시Attention에서 재사용하는 Key·Value 중간 상태. 전체 대화 원문이나 완성 답변의 저장소와는 구별됩니다.
PagedAttentionKV 상태를 블록으로 나누고 블록 테이블을 통해 접근하는 Attention 설계입니다.
블록 테이블요청의 논리적 토큰 구간과 실제 캐시 블록 번호를 연결하는 표입니다.
참조 수블록을 현재 몇 군데에서 사용하는지 나타내는 수. 안전한 재사용 판단에 필요합니다.
접두사 캐싱토큰화된 공통 앞 문맥의 계산 상태를 재사용해 입력 계산을 줄이는 방법입니다.
캐시 퇴거새 데이터를 담기 위해 재사용 가능한 옛 캐시 항목을 내보내는 일입니다.
연속 배칭반복 사이에 완료 요청을 빼고 새 요청을 넣으며 처리 묶음을 갱신하는 방식입니다.
chunked prefill긴 입력 계산을 토큰 예산에 맞춰 여러 번으로 나누는 방법입니다.
선점실행 중인 요청을 일시적으로 밀어내고 자원을 회수하는 처리. 이후 재계산 비용이 생길 수 있습니다.
샘플링모델이 낸 점수에서 다음 출력 토큰을 고르는 과정입니다.
추측 디코딩초안 토큰을 미리 제안하고 목표 모델로 검증하는 방법. 효율은 수용률과 추가 비용에 좌우됩니다.
양자화숫자를 적은 비트로 표현해 메모리와 연산 비용을 줄이는 기술. 정확도와 커널 지원을 확인해야 합니다.
tensor parallel한 모델 연산의 텐서를 여러 장치에 나누어 계산하는 병렬화입니다.
pipeline parallel모델의 층들을 여러 장치의 단계로 나누는 병렬화입니다.
data parallel모델 실행 복제본들에 서로 다른 요청을 배분하는 방식입니다.
expert parallelMoE 모델의 전문가 네트워크를 장치들에 나누어 배치하는 방식입니다.
SSEHTTP 연결로 서버 이벤트를 순차 전달하는 형식. 생성 결과의 스트리밍에 쓰입니다.
TTFT / ITL첫 토큰까지의 시간 / 생성 토큰 사이의 시간. 사용자가 느끼는 대기의 서로 다른 부분입니다.
ZMQ프로세스 사이에서 메시지를 주고받는 통신 라이브러리 계열입니다.
커널여기서는 GPU 등에서 특정 연산을 수행하는 낮은 수준의 계산 함수입니다.
CUDA GraphGPU 작업 흐름을 기록해 반복 실행의 호출 부담을 줄이는 기능입니다.
ABI컴파일된 프로그램끼리 호출·자료 표현을 맞추는 규약. PyTorch·CUDA 조합이 중요한 이유 중 하나입니다.

이 단어들은 서로 연결됩니다. 연속 배칭을 많이 활용하려면 충분한 KV 공간이 필요하고, 캐시와 양자화로 공간을 아껴도 장치 간 통신이나 긴 대기열이 새 병목이 될 수 있습니다. 한 기능 이름보다 전체 실행 흐름을 기준으로 이해하세요.

11참고 링크

개념 자료와, 같은 커밋의 소스 링크를 함께 두기

11-1. 공식 자료와 관련 기술

11-2. 커밋 f4edf9f에서 바로 읽을 파일

현재 상태 (2026-10-23 확인)

항목상태
선정GitHub Trending Python Weekly #14
스타 / 포크95,202 / 23,834 — 2026-10-23 GitHub 기준
생성일2023-02-09
주 언어Python
최신 릴리스v0.32.0 — 2026-10-18
최근 push2026-10-23
최근 커밋f4edf9f — 2026-10-23
[XPU] Enable kernel/sampler unit tests on Intel XPU (#62419)
추적 파일 규모일반 파일 8,407개. 하위 모듈 내부·Git 메타데이터·심볼릭 링크 제외
Python 규모5,514개 파일 / 2,014,179줄. 패키지·테스트·예제·도구 등 전체 포함
Rust 규모375개 파일 / 152,025줄
CUDA 규모.cu 113개 / 56,745줄 + .cuh 74개 / 23,618줄
C++ / 공통 헤더.cpp·.cc 54개 / 29,923줄 + .h·.hpp 86개 / 33,170줄
기타 언어Shell 147개 / 23,753줄, JavaScript 7개 / 166줄
라이선스Apache-2.0 — 모델 가중치의 이용 조건은 각 모델에서 별도 확인

코드 규모는 커밋 f4edf9f의 Git 추적 파일을 확장자별로 나누고 각 파일의 줄바꿈 문자 수를 합산한 물리적 줄 수입니다. 주석·빈줄·테스트 fixture·추적된 외부 코드가 포함되며, 순수 구현량이나 실행 성능을 뜻하지 않습니다. 전체 커밋 수·기여자별 비중은 이 규모 표의 집계 대상에 포함하지 않습니다.

사용하기 전에 알아둘 한계
API 호환성·하드웨어·릴리스 경계를 함께 확인하세요

소스 설명은 개발 커밋 f4edf9f 기준입니다. 최신 안정 릴리스 v0.32.0과 기능·의존성·기본값이 같다고 보장할 수 없습니다. README의 여러 하드웨어·모델 지원 목록도 모든 모델·양자화·커널 조합의 지원을 의미하지 않습니다.

OpenAI 호환 API의 기능 범위와 모델별 대화 템플릿·도구 호출 지원을 확인해야 합니다. Rust 프런트엔드는 자체 안내에서 실험적이며 기능이 완전하지 않다고 밝힙니다. 실습의 관찰 항목은 검증할 과제이며, 특정 장치의 성능이나 실행 성공을 보장하는 결과가 아닙니다.

보안 문서는 노드 간 통신이 기본적으로 안전하지 않으며 격리된 네트워크로 보호해야 한다고 설명합니다. 로컬 학습용 HTTP 실행 예시를 그대로 외부 공개 서비스 설정으로 사용하지 마세요.