vLLM 분산 서빙 가이드

vLLM은 LLM 추론의 세 가지 주요 작업인 프롬프트 처리(prefill), 토큰 생성(decode), 그리고 CPU 바운드 프론트엔드 작업(토큰화 및 파싱)을 분리하는 분산 서빙(disaggregated serving)을 도입했습니다. 이러한 단계를 분리함으로써 vLLM은 긴 프롬프트가 활성 생성 스트림을 지연시키는 것을 방지하며, 운영자가 TTFT(Time To First Token)와 ITL(Inter-Token Latency)을 독립적으로 튜닝할 수 있도록 합니다.

분산 서빙의 기술적 아키텍처

vLLM의 분산 서빙은 추론 파이프라인을 독립적으로 확장하고 튜닝할 수 있는 별도의 계층으로 나눕니다:

Prefill과 Decode의 분리

Prefill과 Decode는 별도의 인스턴스로 실행됩니다. Prefill 인스턴스는 초기 프롬프트를 처리하여 KV 캐시(어텐션 키 및 값)를 생성하며, 이는 KV 커넥터를 통해 Decode 인스턴스로 전송됩니다.

  • KV 캐시 전송: 전송 크기는 모델과 프롬프트 길이에 따라 다릅니다. 예를 들어, BF16의 Llama-3.1-70B는 토큰당 320 KiB를 저장하므로, 10k 토큰 프롬프트는 약 3 GB의 데이터를 전송해야 합니다.
  • 커넥터: vLLM은 NIXL, LMCache, Mooncake, FlexKV, AMD의 MoRI-IO를 포함한 이 전송을 위한 여러 커넥터를 지원하며, 종종 고속 이동을 위해 RDMA를 활용합니다.

프론트엔드 분산 (Render/Derender)

CPU 집약적인 작업은 GPU가 없는 프론트엔드 계층으로 이동합니다:

  • /render: OpenAI 스타일의 요청을 토큰 ID로 변환합니다.
  • /derender: 출력 토큰 ID를 콘텐츠, 추론, 도구 호출의 분리를 포함한 구조화된 OpenAI 응답으로 다시 변환합니다.

기타 분산 차원

  • 인코더 분산: 멀티모달 모델에서 인코더를 파이프라인의 나머지 부분과 분리하는 데 사용됩니다.
  • AFD 플러그인: MoE(Mixture-of-Experts) 모델에서 어텐션과 FFN(Feed-Forward Networks)을 분리합니다.
  • 하이브리드 SSM: 하이브리드 SSM 모델을 위한 Mamba 상태 전송을 지원합니다.

성능 영향: Goodput 및 지연 시간

분산 서빙은 최대 원시 처리량보다는 TTFT 및 ITL 목표를 모두 충족하면서 지속 가능한 요청 속도인 goodput을 개선하는 데 중점을 둡니다.

꼬리 지연 시간(Tail Latency) 감소

통합 서빙에서는 긴 Prefill 요청이 동일한 GPU의 모든 동시 Decode 스트림을 지연시켜 p99 ITL의 급증을 유발할 수 있습니다. 분산 설정에서는 Decode 인스턴스가 Decode 배치만 실행하므로 Prefill로 인한 지연이 제거됩니다.

8k 토큰 프롬프트를 사용하여 NVIDIA L40S GPU 2대에서 Qwen2.5-7B-Instruct를 테스트한 결과, 통합 설정의 p99 ITL은 0.4 req/s에서 23 ms에서 169 ms로 급증한 반면, 분산(P/D) 설정의 p99 ITL은 25 ms에서 52 ms 사이를 유지했습니다.

Goodput 증가

이러한 이득을 위해서는 빠른 KV 전송이 중요합니다. Qwen3-235B-A22B-FP8을 사용한 AMD의 MoRI-IO 벤치마크에 따르면, 분산 모드에서는 요청의 73%가 TTFT(<1s) 및 ITL(<50ms) 목표를 충족한 반면, 통합 모드에서는 30%에 그쳐 goodput이 2.4배 증가했습니다.

전송 비용

모든 첫 번째 토큰은 KV 캐시 전송에 대한 지연 시간 페널티를 지불합니다. 전송이 느리면(예: P2P 지원 또는 RDMA 부족) TTFT가 증가합니다. P2P 지원이 없는 하드웨어에서는 8k 토큰 프롬프트를 전송하는 데 약 1.3초가 소요되어, ITL은 안정적임에도 불구하고 시스템이 TTFT 목표를 달성하지 못하게 되었습니다.

운영 구현

Prefill/Decode 실행

vLLM v0.30.0부터 분산 설정에는 Prefiller, Decoder, 그리고 핸드오프를 조정할 프록시라는 세 가지 구성 요소가 필요합니다.

  1. Prefiller: 특정 kv_connector(예: NIXL)를 사용하는 kv_producer로 구성됩니다.
  2. Decoder: kv_consumer로 구성됩니다.
  3. Proxy: max_tokens=1 및 do_remote_decode: true로 Prefiller를 호출한 다음, 결과로 생성된 kv_transfer_params를 Decoder로 전달합니다.

다중 턴 대화

채팅에서 이전 턴의 KV 캐시를 재계산하지 않기 위해 vLLM은 bidirectional_kv_xfer를 지원합니다. 이를 통해 Prefiller는 Decoder로부터 기존 블록을 다시 가져와 프롬프트의 새로운 토큰만 계산할 수 있습니다.

Render 계층 배포

Render 계층은 상태 비저장(stateless)이며 표준 CPU 웹 서비스로 확장됩니다. 출력 불일치를 방지하기 위해 Render, Derender 및 엔진 계층 전반에서 모델, 토크나이저 및 파서 구성을 동기화하는 것이 중요합니다.

현재 제한 사항 및 향후 과제

  • 스트리밍 파서 오버헤드: 파서를 사용한 스트리밍 Derender는 현재 파서를 재구축하고 모든 청크에 대해 토큰 기록을 재생하기 때문에 계산 비용이 많이 들며, 긴 생성 과정에서 $O(n^3)$의 문자 작업이 발생합니다. 이를 해결하기 위해 캐싱 계층이 계획되어 있습니다.
  • 와이어 오버헤드: 스트리밍 Derender 중에 모든 청크와 함께 prompt_token_ids가 다시 전송되기 때문에 긴 프롬프트가 요청 본문을 지배합니다.
  • 정확성 격차: 배치 Derender에서의 finish_reason: "tool_calls" 문제와 logprobs에 대해 정수 토큰 ID 대신 자리 표시자 문자열이 반환되는 문제 등이 해결되고 있습니다.

요약 권장 표

상황 권장 사항
부하 시 ITL p99가 SLO를 충족하지 못함 분산
높은 동시성에서 긴 프롬프트 분산 (KV 전송이 빠른 경우)
컨텍스트가 증가하는 채팅/에이전트 루프 양방향 전송을 통한 분산
GPU CPU 프로필에서 높은 토큰화/파싱 부하 확인 Render 계층 분리
TTFT가 제약 조건인 경우 통합 유지 또는 사전 측정
느린 KV 전송 전송 개선 또는 통합 유지
낮고, 간헐적이거나 지연 시간에 민감하지 않은 트래픽 통합 유지

Sources