데이터 병렬 배포

데이터 병렬 배포 (Data Parallel Deployment)

vLLM은 모델 가중치를 여러 인스턴스/GPU에 복제해 각자 독립적인 요청 배치를 처리하는 데이터 병렬 배포를 지원합니다. 밀집(Dense) 모델과 MoE 모델 모두에서 동작하며, 특히 DeepSeek처럼 MLA(Multi-head Latent Attention)를 쓰는 MoE 모델에서는 어텐션 레이어는 데이터 병렬로, 전문가 레이어는 EP/TP로 나누는 게 유리할 수 있습니다.

출처: 문서

본문

데이터 병렬 배포에서는 모델 가중치가 별도 인스턴스/GPU에 복제되어 서로 다른 독립적인 요청 배치를 처리합니다. 밀집 모델과 MoE 모델 양쪽 모두에서 동작합니다.

MoE 모델, 특히 DeepSeek처럼 MLA를 사용하는 모델에서는 어텐션 레이어에 데이터 병렬을, 전문가 레이어에 expert parallel 또는 tensor parallel(EP 또는 TP)을 사용하는 것이 유리할 수 있습니다.

이 경우 데이터 병렬 랭크는 완전히 독립적이지 않습니다. 포워드 패스가 정렬되어야 하며, 처리할 요청이 DP 랭크 수보다 적을 때에도 모든 전방 패스에서 모든 랭크의 전문가 레이어가 동기화되어야 합니다.

기본적으로 전문가 레이어는 크기 DP × TP의 tensor parallel 그룹을 형성합니다. 대신 expert parallelism을 사용하려면 --enable-expert-parallel CLI 인자를 포함하세요(멀티 노드의 경우 모든 노드에). EP를 켰을 때 어텐션과 전문가 레이어가 어떻게 다르게 동작하는지는 Expert Parallel Deployment를 참고하세요.

vLLM에서 각 DP 랭크는 별도의 "core engine" 프로세스로 배포되며, ZMQ 소켓을 통해 프론트엔드 프로세스와 통신합니다. DP attention은 TP attention과 결합될 수 있으며, 이 경우 각 DP 엔진은 설정된 TP 크기만큼의 per-GPU 워커 프로세스를 소유합니다.

MoE 모델에서 어떤 랭크든 요청이 진행 중이면, 현재 요청이 예약되지 않은 모든 랭크에서도 빈 "dummy" 포워드 패스가 수행되도록 해야 합니다. 이는 모든 랭크와 통신하는 별도의 DP Coordinator 프로세스와, 모든 랭크가 유휴해져 일시정지될 수 있는 시점을 판정하기 위해 매 N 스텝마다 수행되는 collective 연산으로 처리됩니다. TP를 DP와 함께 사용하면 전문가 레이어는 크기 DP × TP의 그룹을 형성합니다(기본적으로 tensor parallelism, --enable-expert-parallel 설정 시 expert parallelism).

모든 경우에 DP 랭크 간 요청을 로드밸런싱하는 것이 유리합니다. 온라인 배포에서 이 밸런싱은 각 DP 엔진의 상태 — 특히 현재 예약된 요청과 대기(큐) 중인 요청, 그리고 KV cache 상태 — 를 고려해 최적화할 수 있습니다. 각 DP 엔진은 독립적인 KV cache를 가지며, 프롬프트를 지능적으로 라우팅하면 prefix caching의 이점을 극대화할 수 있습니다.

이 문서는 온라인 배포(API 서버 포함)에 초점을 맞춥니다. DP + EP는 오프라인 사용(LLM 클래스)에서도 지원됩니다. 예시는 examples/features/data_parallel/data_parallel_offline.py를 참고하세요.

온라인 배포에는 두 가지 별개의 모드가 있습니다 — 내부 로드밸런싱을 갖춘 자립형(self-contained) 방식, 또는 외부의 per-rank 프로세스 배포 및 로드밸런싱 방식입니다.

내부 로드밸런싱 (Internal Load Balancing)

vLLM은 단일 API 엔드포인트를 노출하는 "자립형" 데이터 병렬 배포를 지원합니다.

vllm serve 명령줄 인자에 예를 들어 --data-parallel-size=4를 포함하기만 하면 구성됩니다. 이는 4개의 GPU를 요구합니다. tensor parallel과 결합할 수도 있습니다. 예를 들어 --data-parallel-size=4 --tensor-parallel-size=2는 8개의 GPU를 요구합니다. DP 배포의 크기를 잡을 때 --max-num-seqsDP 랭크당 적용된다는 점을 기억하세요.

반대로 admission control 제한인 --max-num-queued-reqs--max-num-queued-tokens는 전체 서버에 적용되지, DP 랭크별이 아닙니다. 각 API 서버 프로세스는 라우팅하는 모든 DP 랭크에 걸친 in-flight 요청과 prefill 백로그를 셉니다. 예를 들어 --data-parallel-size=4 --max-num-seqs=256 --max-num-queued-reqs=256 설정에서 총 256개가 in-flight가 되면 새 요청을 거부하는데, 실제로는 랭크들이 1024개를 함께 처리할 수 있음에도 그렇습니다. 랭크를 포화시키려면 상한을 대략 data-parallel-size * max-num-seqs에 원하는 큐 깊이를 더한 값으로 잡으세요.

단일 데이터 병렬 배포를 여러 노드에 걸쳐 실행하려면 각 노드에서 서로 다른 vllm serve를 실행해 해당 노드에서 실행할 DP 랭크를 지정해야 합니다. 이 경우에도 여전히 단일 HTTP 엔트포인트가 있습니다 — API 서버는 한 노드에서만 실행되지만, 반드시 DP 랭크와 같은 노드에 있을 필요는 없습니다.

단일 8-GPU 노드에서 DP=4, TP=2를 실행하려면:

vllm serve $MODEL --data-parallel-size 4 --tensor-parallel-size 2

DP=4를 실행하되 DP 랭크 0·1은 헤드 노드, 랭크 2·3은 두 번째 노드에 두려면:

# Node 0  (with ip address 10.99.48.128)
vllm serve $MODEL --data-parallel-size 4 --data-parallel-size-local 2 \
                  --data-parallel-address 10.99.48.128 --data-parallel-rpc-port 13345
# Node 1
vllm serve $MODEL --headless --data-parallel-size 4 --data-parallel-size-local 2 \
                  --data-parallel-start-rank 2 \
                  --data-parallel-address 10.99.48.128 --data-parallel-rpc-port 13345

API 서버만 첫 번째 노드에 두고 모든 엔진을 두 번째 노드에 두는 DP=4 실행:

# Node 0  (with ip address 10.99.48.128)
vllm serve $MODEL --data-parallel-size 4 --data-parallel-size-local 0 \
                  --data-parallel-address 10.99.48.128 --data-parallel-rpc-port 13345
# Node 1
vllm serve $MODEL --headless --data-parallel-size 4 --data-parallel-size-local 4 \
                  --data-parallel-address 10.99.48.128 --data-parallel-rpc-port 13345

이 DP 모드는 --data-parallel-backend=ray를 지정해 Ray와 함께 쓸 수도 있습니다:

vllm serve $MODEL --data-parallel-size 4 --data-parallel-size-local 2 \
                  --data-parallel-backend=ray

Ray 사용 시 몇 가지 주목할 차이점이 있습니다:

  • 모든 로컬/리모트 DP 랭크를 시작하기 위해 (어느 노드에서든) 단일 실행 명령 하나만 필요하므로, 각 노드에서 실행하는 방식보다 편리합니다
  • --data-parallel-address를 지정할 필요가 없으며, 명령을 실행한 노드가 --data-parallel-address로 사용됩니다
  • --data-parallel-rpc-port를 지정할 필요가 없습니다
  • 단일 DP 그룹이 여러 노드를 요구할 때(예: 단일 모델 복제본이 최소 두 노드에서 실행돼야 하는 경우) VLLM_RAY_DP_PACK_STRATEGY="span"을 설정하세요. 이 경우 --data-parallel-size-local은 무시되고 자동으로 결정됩니다
  • 리모트 DP 랭크는 Ray 클러스터의 노드 리소스에 따라 할당됩니다

현재 내부 DP 로드밸런싱은 API 서버 프로세스 안에서 수행되며, 각 엔진의 실행/대기 큐를 기반으로 합니다. 향후 KV cache 인지 로직을 통합해 더 정교하게 만들 수 있습니다.

이 방법으로 큰 DP 크기를 배포하면 API 서버 프로세스가 병목이 될 수 있습니다. 이 경우 직교하는 --api-server-count 명령줄 옵션으로 확장할 수 있습니다(예: --api-server-count=4). 이는 사용자에게 투명합니다 — 여전히 단일 HTTP 엔드포인트/포트가 노출됩니다. 이 API 서버 스케일아웃은 "내부적"이며 여전히 "헤드" 노드로 한정됩니다.

하이브리드 로드밸런싱 (Hybrid Load Balancing)

하이브리드 로드밸런싱은 내부 방식과 외부 방식의 중간에 있습니다. 각 노드는 자체 API 서버를 실행하며, 해당 노드에 함께 위치한 데이터 병렬 엔진에만 요청을 큐잉합니다. 업스트림 로드밸런서(예: ingress controller 또는 traffic router)가 사용자 요청을 각 노드의 엔드포인트로 분산합니다.

--data-parallel-hybrid-lb로 이 모드를 활성화하되, 여전히 전역 데이터 병렬 크기로 모든 노드를 실행합니다. 내부 로드밸런싱과의 주요 차이점:

  • 각 노드가 어떤 랭크를 소유하는지 알도록 --data-parallel-size-local--data-parallel-start-rank를 반드시 제공해야 합니다
  • 모든 노드가 API 엔드포인트를 노출하므로 --headless와 호환되지 않습니다
  • 로컬 랭크 수에 따라 노드별 --api-server-count를 조정하세요

이 구성에서 각 노드는 스케줄링 결정을 로컬로 유지해 노드 간 트래픽을 줄이고, 큰 DP 크기에서 단일 노드 병목을 피합니다.

외부 로드밸런싱 (External Load Balancing)

특히 더 큰 규모의 배포에서 데이터 병렬 랭크의 오케스트레이션과 로드밸런싱을 외부에서 처리하는 것이 합리적일 수 있습니다.

이 경우 각 DP 랭크를 각자 엔드포인트를 가진 별도 vLLM 배포처럼 취급하고, 외부 라우터가 각 서버의 실시간 텔레메트리를 바탕으로 HTTP 요청을 그들 사이에 밸런싱하는 것이 더 편리합니다.

비-MoE 모델에서는 각 배포 서버가 완전히 독립적이므로 이미 손쉽게 가능합니다. 이 경우 --data-parallel-* 인자 없이 독립 vLLM 인스턴스를 실행하세요. 외부 DP CLI 옵션은 MoE 배포에서만 지원됩니다.

MoE DP+EP에 대해 다음 CLI 인자로 구성할 수 있는 동등한 토폴로지를 지원합니다.

DP 랭크가 같은 위치(동일 노드/ip 주소)에 있으면 기본 RPC 포트가 사용되지만, 각 랭크마다 다른 HTTP 서버 포트를 지정해야 합니다:

# Rank 0
CUDA_VISIBLE_DEVICES=0 vllm serve $MODEL --data-parallel-size 2 --data-parallel-rank 0 \
                                         --port 8000
# Rank 1
CUDA_VISIBLE_DEVICES=1 vllm serve $MODEL --data-parallel-size 2 --data-parallel-rank 1 \
                                         --port 8001

멀티 노드의 경우 랭크 0의 주소/포트도 지정해야 합니다:

# Rank 0  (with ip address 10.99.48.128)
vllm serve $MODEL --data-parallel-size 2 --data-parallel-rank 0 \
                  --data-parallel-address 10.99.48.128 --data-parallel-rpc-port 13345
# Rank 1
vllm serve $MODEL --data-parallel-size 2 --data-parallel-rank 1 \
                  --data-parallel-address 10.99.48.128 --data-parallel-rpc-port 13345

--data-parallel-external-lb--nnodes와 함께 사용할 때, 데이터 병렬 랭크는 --nnodes--data-parallel-size로 나누어떨어질 때만 --node-rank에서 추론할 수 있습니다. 나누어떨어지지 않으면 자동 랭크 추론이 거부되고 --data-parallel-rank를 명시적으로 설정해야 합니다. 외부-LB 랭크 여러 개가 한 노드에 함께 있을 때는 CUDA_VISIBLE_DEVICES 또는 --device-ids로 각 프로세스에 서로 겹치지 않는 디바이스 세트를 할당하세요. 디바이스는 프로세스 간에 자동 분할되지 않습니다.

이 시나리오에서도 DP 랭크 0 엔진과 같은 위치에 coordinator 프로세스가 실행됩니다.

위 다이어그램에서 각 점선 상자는 별도의 vllm serve 실행에 해당합니다 — 예를 들어 별도의 Kubernetes 파드일 수 있습니다.

더 알아보기 (Learn more)