vLLM 푸시 기반 NIXL KV 커넥터: 분리 추론에서 TTFT 최대 3배 개선
vLLM은 프리필-디코드(P-D) 분리 추론을 위한 푸시 기반 NIXL KV 커넥터를 추가하여 전송 조정 및 설정을 첫 토큰까지의 중요 경로에서 제외했습니다. AWS EFA로 연결된 Amazon EC2 P5en 인스턴스의 1P1D 배포에서 Qwen3-32B 벤치마크를 실행한 결과, 푸시 모드는 기본 풀 모드에 비해 TTFT(첫 토큰까지의 시간)가 최대 3배, TPOT(출력 토큰당 시간)가 최대 30% 개선되었습니다.
푸시 커넥터가 해결하는 문제
프리필-디코드 분리는 프리필과 디코드를 별도의 엔진 인스턴스에서 실행하여 각 단계를 독립적으로 확장하고 최적화할 수 있게 하여, 부하 상태에서 리소스 활용률, 처리량 및 지연 시간을 개선합니다. 대가로 KV 캐시는 토큰 생성이 시작되기 전에 프리필 인스턴스에서 디코드 인스턴스로 전송되어야 하므로 KV 전송이 TTFT 중요 경로에 직접 놓이게 됩니다.
vLLM은 이 전송을 NVIDIA Inference Xfer Library(NIXL) 커넥터를 통해 수행하며, 이 커넥터는 AWS Elastic Fabric Adapter(EFA)와 같은 RDMA 지원 상호 연결을 통해 KV 블록을 이동합니다. 지원되는 인스턴스 유형에서 EFA는 GPUDirect RDMA 및 Neuron Direct RDMA를 지원하므로 NIXL은 호스트 메모리를 경유하지 않고 GPU 또는 Trainium 디바이스 메모리 간에 KV 블록을 직접 전송할 수 있습니다.
기본 NIXL 커넥터 모드는 풀 기반입니다. 프리필 인스턴스가 프롬프트 KV 캐시 계산을 완료한 후, 라우터는 프리필 블록 ID를 포함한 소스 메타데이터를 디코드 인스턴스에 중계합니다. 그런 다음 디코드 인스턴스는 대상 블록을 할당하고, NIXL 전송을 준비하며, NIXL READ를 시작하여 프리필 인스턴스에서 KV 블록을 가져옵니다. 이러한 조정 및 설정 단계는 프리필 이후 디코딩이 시작되기 전에 순차적으로 실행되므로 TTFT 중요 경로를 늘립니다.
푸시 기반 KV 전송 작동 방식
푸시 기반 전송은 vLLM 게시물에 명시된 두 가지 이유로 TTFT와 디코드 처리량을 개선합니다.
- 풀 모델의 직렬화를 제거하여 생산자와 소비자 작업을 중첩합니다. 디코드 인스턴스는 생산자가 여전히 KV를 계산하는 동안 대상 블록을 미리 등록합니다. 전송은 소비자 측 식별자 발견 왕복 이후가 아니라 생산자의 블록이 준비되는 즉시 시작되므로, 해당 왕복이 첫 토큰까지의 경로에서 제거됩니다.
- 전송 설정 시간을 디코드 인스턴스에서 분리합니다. NIXL 디스크립터 준비 및 전송 제출은 프리필 측과 백그라운드 스레드에서 실행되므로 디코드 인스턴스는 대기 시간에 중요한 토큰 생성 단계에서 이러한 주기를 소비하지 않습니다.
최종 효과는 디코드 인스턴스에서 더 낮은 TTFT와 더 높은 출력 토큰 처리량입니다.
푸시 커넥터는 세 가지 행위자를 조정합니다: 대상 블록을 미리 등록하는 디코드 인스턴스, 각 요청을 매칭하고 전송을 발행하는 프리필 인스턴스, 그리고 엔진의 포워드 패스 루프에서 KV 쓰기를 분리하는 전용 백그라운드 스레드입니다.
3단계 프로토콜
1. 등록(디코드 측). 디코드 인스턴스가 원격 프리필이 필요한 요청에 대해 로컬 블록을 할당할 때, 프리필 인스턴스가 KV를 써야 할 위치를 설명하는 등록 정보를 준비합니다: 자신의 ID와 방금 예약한 블록 위치. 동일한 엔진 단계 내에서 작업자는 이 등록을 NIXL 알림으로 프리필 인스턴스에 전송합니다. 등록이 할당 시점에 이루어지므로 커넥터는 프리필 인스턴스가 프리필을 완료하기 전에 대상 블록을 알 수 있습니다.
2. 랑데부(프리필 측). 디코더의 등록과 생산자의 프리필 완료는 어떤 순서로든 도착할 수 있으며 커넥터는 둘 다 처리합니다. 등록이 먼저 도착하면 생산자는 자체 프리필이 끝날 때까지 보유합니다. 프리필이 먼저 끝나면 생산자는 등록이 도착할 때까지 요청의 블록을 보유합니다. 두 번째로 발생하는 이벤트가 전송을 트리거합니다. 커넥터는 식별자로 요청을 짝지으며, 매칭은 재발행된 요청을 고려하여 선점되거나 재시도된 요청을 올바르게 연관시킵니다.
3. 전송(프리필 측). 요청이 매칭되면 생산자는 디코드 인스턴스에 대한 연결을 설정하고(이미 없을 경우) NIXL WRITE를 발행하여 KV 블록을 디코더의 등록된 메모리에 직접 복사하며 각 대상 텐서 병렬 순위를 처리합니다. 생산자와 소비자는 서로 다른 내부 블록 레이아웃을 사용할 수 있습니다. 각 측은 전송 시 블록 위치를 자체 물리적 레이아웃에 매핑하므로 각 측에서 서로 다른 블록 크기를 허용합니다. 각 WRITE에는 데이터가 도착하면 NIXL이 디코드 인스턴스에 전달하는 완료 알림이 포함됩니다. 디코더는 자신에게 쓰는 각 생산자 순위당 하나씩 이러한 알림을 계산하며, 모든 예상 알림이 도착한 후에만 KV가 수신된 것으로 간주하고 요청은 디코딩을 진행합니다.
스레딩 모델
푸시 커넥터는 각 프리필 작업자에서 전용 백그라운드 전송 스레드를 사용하여 모델 실행과 KV 전송 준비를 분리합니다. 요청 시작 시 디코드 메인 루프는 대상 KV 블록을 할당하고 프리필 인스턴스에 등록하는 반면, 프리필 메인 루프는 프롬프트 KV 캐시를 계산합니다. 대상 등록과 프롬프트 KV가 모두 준비된 후 프리필 메인 루프는 KV 블록을 백그라운드 스레드에 넘겨주고 빠르게 모델 실행으로 돌아갑니다.
백그라운드 스레드는 NIXL 연결을 설정하거나 재사용하고, 요청의 KV 블록 ID를 메모리 디스크립터에 매핑하고, 연속 블록을 더 큰 전송 영역으로 병합하고, NIXL WRITE를 디코드 인스턴스에 제출합니다. NIXL이 전송을 완료하면 디코드 인스턴스에 완료 알림을 보내며, 디코드 인스턴스는 토큰 생성을 시작합니다. 디스크립터 준비 및 전송 제출을 대기 시간에 중요한 메인 루프에서 분리하면 요청별 작업이 모델 실행을 지연시키지 않습니다.
풀 vs 푸시: 라우팅 트레이드오프
두 모드는 동일한 NIXL 및 EFA/RDMA 데이터 경로를 사용합니다. 풀은 프리필 후 메타데이터 중계 및 디코드 측 설정을 수행하는 반면, 푸시는 디코드 측 설정을 프리필과 중첩하여 이러한 작업을 프리필 후 중요 경로에서 제거하므로 디코딩이 더 빨리 시작될 수 있습니다.
두 모드는 또한 라우팅 트레이드오프를 포함합니다. 풀 모드는 라우터가 프리필 완료 후 디코드 인스턴스를 선택할 수 있게 하여 부하 인식 라우팅 및 QoS 관리에 더 큰 유연성을 제공합니다. 푸시 모드는 대상 설정이 프리필과 중첩될 수 있도록 디코드 인스턴스를 더 일찍 선택합니다. 그 대가로 유사한 부하에서 프리필 인스턴스는 프롬프트 KV와 대상 등록이 모두 준비되는 즉시 전송이 시작되므로 KV 블록을 더 빨리 해제할 수 있습니다.
성능 데이터
평가는 EFA로 연결된 Amazon EC2 P5en 인스턴스의 1P1D 배포에서 Qwen3-32B 모델을 사용했습니다. P→D 전송 성능을 분리하기 위해 벤치마크는 --no-enable-prefix-caching으로 프리픽스 캐싱을 비활성화하여 디코드 노드가 모든 요청에 대해 프리필 노드에서 전체 KV 캐시를 가져오도록 강제했습니다. 이 설정 없이는 중첩 프롬프트가 디코드 노드의 로컬 캐시를 재사용하고 전송을 우회하여 비교 결과를 왜곡할 수 있습니다.
TTFT. 벤치마크는 입력 길이 1k–16k 및 요청 속도 1–8 QPS를 스윕했습니다. 낮은 부하와 짧은 프롬프트에서는 두 모드가 거의 동일하게 수행됩니다. QPS와 입력 길이가 증가함에 따라 풀 모드는 급격히 저하되어 8 QPS 및 16k 입력에서 약 1,744ms에 도달합니다. 푸시 모드는 약 540ms로 훨씬 낮아 약 3배 개선됩니다. 이러한 차이는 풀 모드가 NIXL 디스크립터를 디코드 작업자의 엔진 루프 내에서 동기적으로 인라인으로 게시하여 해당 작업이 토큰 생성을 지연시키기 때문에 발생합니다. 푸시 모드는 이를 백그라운드 스레드로 이동시켜 중요 경로에서 제외합니다.
TPOT. 동일한 조건에서 패턴은 TTFT와 유사합니다. 가벼운 부하에서는 푸시와 풀이 약 5.6–5.8ms로 비슷합니다. 부하와 입력 길이가 증가함에 따라 풀은 4–8 QPS 및 16k 입력에서 약 10.4ms로 상승하는 반면, 푸시는 약 7ms를 유지합니다. 푸시는 디코드 작업자에서 디스크립터 준비 및 전송 제출을 오프로드하므로 토큰 생성이 부족해지지 않아 높은 동시성과 긴 컨텍스트에서도 토큰당 지연 시간이 일정하게 유지됩니다.
푸시 모드 활성화 방법
푸시 모드를 사용하려면 프리필 및 디코드 서버 모두에서 NixlConnector 대신 NixlPushConnector를 구성하십시오. vLLM 게시물에 따르면 이 기능은 EFA로 연결된 AWS Trainium 인스턴스 클러스터에서 구축 및 검증된 후 가속기 비종속 기능으로 vLLM에 기여되었습니다. 게시된 결과는 EFA가 있는 AWS p5en(GPU) 클러스터에서 나온 것으로, GPU에서도 개선 효과가 유지됨을 보여줍니다.
푸시 vs 풀 선택 시점
조기 디코드 노드 선택이 허용되고 낮은 TTFT가 우선일 때 푸시 기반 커넥터를 선택하십시오. 풀 기반 커넥터는 양방향 KV 전송이 필요하거나 부하 인식 라우팅을 위해 프리필 후까지 디코드 인스턴스 선택을 지연해야 하는 워크로드에 더 적합합니다. vLLM은 푸시 및 풀 기반 KV 커넥터를 모두 지원하므로 사용자는 배포에 가장 적합한 방식을 선택할 수 있습니다.
벤치마크 재현
참조 토폴로지는 EFA가 활성화된 두 개의 p5en GPU 노드(프리필 :8100, 디코드 :8200)와 프록시 및 벤치마크 클라이언트를 실행하는 세 번째 더 작은 노드입니다. 두 GPU 노드는 p5en.48xlarge(8x NVIDIA H200), Ubuntu 24.04.4 LTS(커널 6.14.0-1018-aws), NVIDIA 드라이버 580.126.16(CUDA 13.0 드라이버 API), CUDA 툴킷 13.0, EFA 설치 프로그램 1.50.0(EFA 커널 모듈 3.3.0g, libfabric 2.6.0amzn1.0, rdma-core 64.0amzn0)을 사용했습니다. 각 인스턴스는 200Gb/s의 EFA 인터페이스 16개를 노출하여 총 3.2Tb/s를 제공합니다.
재현 가이드의 소프트웨어 버전은 vllm==0.29.0 및 nixl==1.4.1입니다. 모드 차이는 단일 구성 필드입니다: 풀은 NixlConnector, 푸시는 NixlPushConnector입니다. 디코드 서버는 --no-enable-prefix-caching을 추가하여 프리필에서 전체 KV 가져오기를 강제합니다. 벤치마크 스크립트는 vLLM 풀 리퀘스트 #57567에 있으며, 게시물에는 serve_pd.sh, run_sweep.sh, cleanup.sh, plot_push_vs_pull.py가 포함되어 실행, 스윕, 정리 및 그림 재생성을 지원합니다.
EFA 디바이스 선택에 대해 LIBFABRIC 백엔드는 efa 공급자로 16개 EFA 디바이스를 레일로 연 다음 각 GPU의 KV 캐시를 해당 GPU의 PCIe 스위치를 공유하는 2개 레일에만 등록하므로 모든 전송이 PCIe 로컬로 유지됩니다. NIXL 또는 libfabric 디바이스 오버라이드는 설정되지 않았습니다. 이는 기본 선택입니다.
향후 작업
vLLM은 백그라운드 NIXL 스레딩 모델을 풀 모드 커넥터에 도입하여 NIXL 설정을 중요 경로에서 분리함으로써 풀 모드 워크로드도 동일한 최적화의 혜택을 받을 수 있도록 하는 방안을 모색하고 있습니다. 이를 탐구하기 위한 풀 리퀘스트(#45211)가 열려 있습니다.