요약
LLM 서빙에서 긴 컨텍스트를 다루는 방식이 바뀌고 있다. 지금까지 텐서 병렬성(TP)은 모델 가중치와 KV 캐시를 여러 GPU에 분산하는 표준 수단이었지만, GQA(Grouped Query Attention)와 MLA(Multi-Head Latent Attention)가 주류 아키텍처가 되면서 TP만으로는 해결할 수 없는 메모리 병목이 드러났다.
Decode Context Parallelism(DCP) 은 2026년 8월 7일 vLLM 블로그에 공개된 기법으로, KV 캐시를 어텐션 헤드 수(H) 대신 시퀀스 길이(T) 차원으로 샤딩한다. 각 GPU는 전체 요청의 KV 데이터 중 1/N만 저장하고, 디코드 스텝에서 AllGather Q → 로컬 어텐션 → AllGather+ReduceScatter 리듬으로 분산 계산을 수행한다.
결과는 명확하다. 8×B200 노드에서 Kimi K2.6(MLA 모델)으로 측정했을 때, TP 단독 기준선이 동시성 64에서 메모리 상한에 막혀 ~1,863 tok/s/GPU 에 머무는 반면, DCP 적용 후 동시성 512, KV 사용률 82%에서 6,091 tok/s/GPU — 약 3.3배 향상을 달성한다.
- vLLM 블로그 포스트: 2026-08-07
- CLI 사용:
vllm serve <model> --tensor-parallel-size N --dcp <dcp_size> - 지원 모델: GQA(LLaMA 등), MLA(DeepSeek-V2/V3, Kimi K2.6 등)
배경: 텐서 병렬성의 KV 캐시 한계
TP가 KV 캐시를 분산하는 방식
Tensor Parallelism은 어텐션 레이어에서 Q/K/V 헤드를 GPU 수(tp_size)로 나눠 배분한다. 헤드 수가 H이고 tp_size가 8이라면, 각 GPU는 H/8개의 KV 헤드를 담당한다.
전통적인 MHA(Multi-Head Attention)에서는 이 방식이 잘 작동했다. GPT-3 기준 96개 헤드를 8 GPU에 나누면 GPU당 12개 헤드를 책임지고, KV 캐시도 1/8로 줄어든다.
GQA와 MLA에서 무슨 일이 생기는가
문제는 최신 아키텍처가 KV 헤드를 극단적으로 줄이면서 시작된다.
- GQA(Grouped Query Attention): LLaMA 3 70B는 Q 헤드가 64개지만 KV 헤드는 8개다. TP=8이면 GPU당 KV 헤드가 1개다. TP=16을 적용하면 헤드가 8개밖에 없으니
KV 헤드 < GPU 수조건이 발생해 KV 캐시를 각 GPU에 복제해야만 한다.
- MLA(Multi-Head Latent Attention): DeepSeek, Kimi K2.6이 사용하는 방식이다. 전체 KV를 단일 지연 벡터(latent vector)로 압축한다. 실질적으로 KV 헤드가 1개다. TP가 몇 개든 KV 캐시는 복제될 뿐이다.
[TP=8, GQA KV heads=8]
GPU 0: KV[head 0] (각 GPU가 서로 다른 헤드 담당 → 정상)
[TP=16, GQA KV heads=8]
GPU 0~1: KV[head 0] 복제 (16 > 8 이므로 복제 발생 → 메모리 낭비)
[TP=8, MLA KV heads=1]
GPU 0~7: KV[latent] 복제 (8 > 1 이므로 전부 복제 → 심각한 낭비)MLA 모델에서 TP=8을 쓰면 같은 KV 데이터가 8개 GPU에 모두 올라가 있다. 이 낭비된 메모리만큼 배치 사이즈를 늘릴 수 없고, 동시 처리 요청 수의 상한이 낮아진다.
DCP 아키텍처: 시퀀스 차원 샤딩
핵심 아이디어
DCP는 KV 캐시를 시퀀스 길이(T) 차원으로 나눈다. dcp_size=N이면 토큰 i의 KV 항목은 dcp_rank = i % N인 GPU에 저장된다. 인터리브 방식이다.
요청 A: 컨텍스트 길이 4096 토큰, dcp_size=4
GPU 0: token[0], token[4], token[8], ... (1/4 of KV)
GPU 1: token[1], token[5], token[9], ... (1/4 of KV)
GPU 2: token[2], token[6], token[10], ... (1/4 of KV)
GPU 3: token[3], token[7], token[11], ... (1/4 of KV)각 GPU는 1/N만큼의 KV만 저장하므로, 같은 GPU 메모리로 N배 더 많은 요청을 동시에 처리할 수 있다.
디코드 계산 흐름
디코드 스텝에서 DCP 그룹의 GPU들이 협력해 어텐션을 계산하는 방식은 다음과 같다.
단계별 통신 패턴
- AllGather Q: 새로 생성한 토큰 하나의 Query 벡터를 DCP 그룹 내 모든 GPU에 공유한다. 디코드에서 새 토큰은 항상 하나이므로 이 통신 비용은 작다. (MLA 모델에서는 모델 로드 시 Q 프로젝션을 각 GPU에 복제해 두면 이 AllGather를 건너뛸 수 있다.)
- 로컬 어텐션 계산: 각 GPU는 자신이 보유한 KV 슬라이스에 대해서만 어텐션을 계산한다. 로컬 KV만 읽으므로 메모리 대역폭 부하가 1/N으로 줄어든다.
- AllGather + ReduceScatter: 각 GPU에서 나온 부분 어텐션 출력을 모아 최종 결과를 얻는다. Flash Attention 구현에서는 LSE(Log-Sum-Exp) 값을 함께 전달해 수치 안정성을 유지한다.
왜 디코드에 집중하는가
길고 짧은 출력이 섞이는 에이전틱 워크로드에서 실측한 분포는 흥미롭다. 입력 컨텍스트는 이봉분포(bimodal)를 보인다: 요청의 약 53%는 64K 토큰 이상(최대 1M까지)이고, 나머지 47%는 64K 미만이다. 반면 출력 토큰은 중앙값 400개 수준으로 매우 짧다.
이 패턴에서 병목은 명확하다. 긴 컨텍스트를 KV 캐시로 유지한 채 짧은 출력만 생성하는 상황이 반복된다. 계산 집약도가 낮고 메모리 대역폭 집약도가 높은 전형적인 메모리 바운드 워크로드다. KV 캐시를 줄이는 것이 처리량 향상으로 직결된다.
실제 워크로드 벤치마크
실험 환경
- 하드웨어: 8×NVIDIA B200 (NVLink 연결)
- 모델: Kimi K2.6 (MLA 아키텍처)
- 설정: TP=8 기준선 vs TP=8 + DCP=2
처리량 결과
| 설정 | 최대 동시성 | tok/s/GPU | KV 사용률 | 상한 이유 |
|---|---|---|---|---|
| TP=8 (기준선) | ~64 | ~1,863 | ~100% → OOM | 메모리 부족 |
| TP=8 + DCP=2 | 512 | 6,091 | 82% | 처리 포화 |
동시성 64에서 기준선은 KV 메모리가 가득 차 OOM 상황에 가깝다. DCP를 적용하면 같은 메모리로 약 8배 더 많은 동시 요청을 수용하고, GPU당 처리량은 3.3배 증가한다.
MLA와 GQA에서의 효과 차이
DCP는 MLA 모델에서 특히 극적인 효과를 낸다. MLA는 KV 헤드가 사실상 1개이므로 TP 단독으로는 KV 복제를 피할 방법이 없다. DCP는 이 제약을 우회하는 유일한 방법이다.
GQA 모델에서도 TP가 KV 헤드 수를 초과하는 상황, 또는 컨텍스트가 매우 길어 KV 사용률이 포화되는 상황에서 유효하다.
운영 가이드
언제 DCP를 쓸 것인가
DCP가 효과적인 경우:
- 컨텍스트가 32K 토큰 이상인 요청이 주를 이룰 때
- MLA 모델(DeepSeek-V2/V3/R1, Kimi K2.x)을 서빙할 때
- GPU 수가 GQA 모델의 KV 헤드 수를 초과할 때
- KV 메모리가 병목(KV 사용률이 90%+)이어서 배치 사이즈를 늘리지 못할 때
DCP를 피해야 하는 경우:
- 컨텍스트가 8K 이하인 단문 요청이 대부분일 때 (AllGather 오버헤드가 이득보다 클 수 있음)
- GPU가 NVLink로 연결되지 않아 AllGather 대역폭이 낮을 때
설정 예시
# TP=8 + DCP=2: 총 16 GPU (TP 8개 × DCP 2그룹)
vllm serve moonshotai/Kimi-K2.6 \
--tensor-parallel-size 8 \
--dcp 2
# DCP 그룹 내 KV 캐시 인터리브 크기 조정 (기본값=1 토큰)
# 더 큰 청크로 인터리빙하면 CPU 정렬 오버헤드 감소 대신 언밸런스 위험
export VLLM_DCP_KV_INTERLEAVE_SIZE=16메모리 오버헤드
DCP는 KV를 샤딩하지만 AllGather 시 임시 버퍼가 필요하다. 실용적인 규칙으로, DCP 그룹 크기를 2~4로 유지하면 통신 오버헤드가 GPU 메모리 절약 대비 작다. 8 이상으로 늘리면 AllGather 비용이 증가해 실효 처리량이 오히려 낮아질 수 있다.
연관 기법
DCP는 독립적이지만 다른 최적화와 병행 가능하다.
- 투기적 디코딩(Speculative Decoding): DCP와 독립적으로 결합 가능. EAGLE-3 같은 드래프터가 KV 샤딩 위에서 동작한다.
- Prefill-Decode 분리(PD Disaggregation): vLLM 0.25에서 안정화된 PD 분리와 DCP는 별도 차원의 최적화다. 긴 컨텍스트 서빙에서는 두 기법을 함께 쓸 수 있다.
요점 정리
GQA와 MLA가 대세가 된 2026년, TP 단독으로 KV 캐시를 효율적으로 분산하는 것은 구조적으로 불가능해졌다. KV 헤드가 1~8개에 불과한 아키텍처에서 TP=8~16을 쓰면 같은 데이터가 GPU 수만큼 복제될 뿐이다.
DCP는 이 문제를 근본적으로 다르게 접근한다: 헤드 수와 무관하게 시퀀스 차원으로 나누면 복제가 없다. 단일 B200 노드에서 3.3배 처리량 향상은 인프라 비용 대비 명확한 이점이다.
실용적인 권장사항은 단순하다: MLA 모델을 멀티-GPU로 서빙하거나, 에이전틱 장문 컨텍스트 요청이 많다면 --dcp 2 또는 --dcp 4를 기본 설정에 추가하라. 통신 비용은 NVLink 환경에서 무시할 수준이고, KV 메모리 절약 효과는 즉각적이다.
References
- vLLM Blog — "Efficient Decode Context Parallelism with vLLM for Long Context Workloads" (2026-08-07): https://vllm.ai/blog/2026-08-07-decode-context-parallelism
- vLLM GitHub RFC — Decode Context Parallel for GQA: https://github.com/vllm-project/vllm/issues/24685
- vLLM GitHub PR — Support Decode Context Parallel (DCP) for MLA: https://github.com/vllm-project/vllm/pull/23734
- vLLM Documentation — Context Parallel Deployment: https://docs.vllm.ai/en/latest/serving/context_parallel_deployment/
- Kimi K2.6 vLLM Recipe: https://recipes.vllm.ai/moonshotai/Kimi-K2.6
- Helix Parallelism RFC (combining TP + CP): https://github.com/vllm-project/vllm/issues/34018