07. Prefill-decode disaggregation — phase를 떼면 무엇이 줄고 무엇이 새로 생기는가
이 장의 핵심 질문
- prefill과 decode는 왜 "같은 GPU에서 서로 방해"하는가? 그 방해의 정체는 무엇인가?
- 두 phase를 물리적으로 떼면(disaggregation) 무엇이 줄고, 그 대가로 무엇이 새로 생기는가?
- "PD 분리가 goodput을 높인다"는 주장을 조건과 함께 어떻게 읽는가?
앞 장과의 연결 — 첫 묶음(①)에서 배포 D1은 "병렬화된 다중 device 엔진"이 됐다. 이제 그 엔진이 요청을 받는 서비스가 될 때 생기는 문제를 다룬다. 01장의 latency 한계(②)에서 예고한 "긴 프롬프트가 짧은 요청을 느리게 한다"는 간섭이 이 장의 출발점이다. 선수 과정 ②의 prefill/decode·KV 캐시 개념을 전제한다.
먼저: prefill과 decode는 자원 성격이 정반대다
선수 과정 ②에서 배웠듯, LLM 추론은 두 단계로 나뉜다. 이 장의 핵심은 두 단계가 소비하는 자원의 성격이 반대라는 점이다.
- prefill(프리필) — 입력 프롬프트 전체를 한 번에 처리해 각 토큰의 KV 캐시를 만든다. compute-bound(연산 집약): 한 번에 많은 토큰을 병렬 처리하므로 연산 유닛을 강하게 쓴다.
- decode(디코드) — 토큰을 하나씩 자기회귀적으로 생성한다. 매 스텝 전체 KV 캐시를 읽어야 해 memory-bound(메모리 대역폭 집약): 연산은 적지만 메모리 이동이 병목이다.
일상 비유: prefill은 "긴 서류 뭉치를 한 번에 스캔"(장비를 풀가동), decode는 "스캔한 내용을 참고하며 한 줄씩 받아쓰기"(장비는 놀고 참조만 반복). 둘의 병목 자원이 다르다.
📌 핵심 — prefill은 연산이, decode는 메모리 대역폭이 병목이다. 이 자원 성격의 비대칭이 다음 절의 간섭과, 그것을 푸는 PD 분리의 근거 전부다.
왜 같은 GPU에서 서로 방해하는가 — 간섭(interference)
두 phase를 같은 GPU에서 섞어 돌리면(aggregated, 결합 방식), 서로를 방해한다.
- 긴 prefill이 decode를 멈춘다 — 누군가 아주 긴 프롬프트를 보내면, 그 prefill이 GPU를 오래 점유해, 이미 토큰을 생성 중이던 다른 요청들의 decode 스텝이 밀린다. 사용자 입장에선 "받아쓰기가 갑자기 뚝뚝 끊긴다"(토큰 간 간격 TBT/TPOT 악화 — 선수 과정 ②).
- 자원 낭비 — prefill은 연산을, decode는 메모리를 원하는데 한 GPU에 섞으면 어느 한쪽 자원이 남거나 모자란다. 둘의 요구가 어긋난다.
이것이 01장에서 배포 D0가 겪은 "긴 프롬프트가 짧은 요청을 느리게 하는" latency 간섭의 정체다.
sequenceDiagram
participant U1 as 짧은 요청(decode 중)
participant GPU as 결합형 GPU
participant U2 as 긴 요청(prefill 도착)
Note over GPU: aggregated 모드 — 한 GPU가 둘 다 처리
U1->>GPU: decode 스텝 (토큰 생성 중)
U2->>GPU: 긴 prefill 도착 (GPU 장기 점유)
Note over GPU: prefill이 연산 유닛 독점
GPU-->>U1: decode 스텝 지연 ⚠️ (TBT 악화)
Note over U1: 사용자: 생성이 뚝뚝 끊김
PD 분리 — phase를 물리적으로 떼기
PD 분리(prefill-decode disaggregation) 는 prefill과 decode를 서로 다른 GPU 풀(pool) 에서 처리하는 구조다. prefill 노드(P) 가 프롬프트를 처리해 KV 캐시를 만들고, 그 KV를 decode 노드(D) 로 네트워크로 전송하면, D가 중단 없이 토큰을 생성한다.
이 구조가 주는 것:
- 간섭 제거 — P와 D가 물리적으로 분리돼, 긴 prefill이 진행 중인 decode를 방해하지 않는다.
- 독립 스케일링 — P 풀과 D 풀을 따로 늘리고 줄일 수 있다. prefill 부하와 decode 부하가 다르게 움직이므로 유용하다.
- 하드웨어 이질성 허용 — compute-bound인 P와 memory-bound인 D에 서로 다른 종류의 하드웨어를 배치할 수 있다(예: P엔 연산 강한 장치, D엔 메모리 대역폭 좋은 장치).
flowchart LR
REQ["요청 도착"] --> P["Prefill 풀(P)<br/>compute-bound<br/>KV 생산(producer)"]
P -->|"KV 전송<br/>(네트워크 페이로드)"| D["Decode 풀(D)<br/>memory-bound<br/>KV 소비(consumer)"]
D --> OUT["토큰 스트림 출력"]
classDef req fill:#fff3c4,stroke:#d4a017,color:#000
classDef comp fill:#cfe2ff,stroke:#2563eb,color:#000
classDef mem fill:#e9d8fd,stroke:#7c3aed,color:#000
classDef comm fill:#ffe0b2,stroke:#e07b00,color:#000
class REQ req
class P comp
class D mem
class OUT req
🔬 증거 읽기 — PD 분리의 위상 (확인일 2026-07-20) — PD 분리는 최근 사실상 업계 표준이 됐다. 주요 서빙 프레임워크(vLLM·SGLang·TensorRT-LLM·NVIDIA Dynamo 등)가 지원하고, 대규모 사업자 배포에서 쓰인다고 여러 학술 자료가 보고한다.
- 출처 등급 · 주장 유형: PRIMARY(원 논문 DistServe·Splitwise·Mooncake 등) + SECONDARY(정리) · measured/vendor-reported 혼재
- canonical URL: DistServe(OSDI'24, arxiv.org/abs/2401.09670 계열), 및 다수 후속 논문(2025–2026), 확인일 2026-07-20
- conditions: "표준"이라는 서술은 프레임워크 지원 수준의 진술이다. does-not-support: 특정 배포에서 PD 분리가 항상 이득이라거나, 특정 사업자의 정확한 P:D 비율·토폴로지를 지지하지 않는다(그건 그 배포의 unknown). 프레임워크 명칭·지원 범위는 버전 의존이므로 11·12장에서 다시 확인한다.
새로 생기는 비용 — KV가 "네트워크 페이로드"가 된다
PD 분리의 핵심 대가는 이것이다: KV 캐시가 네트워크로 전송해야 할 데이터가 된다. 결합 방식에선 KV가 같은 GPU 메모리에 있어 이동이 없었지만, 분리하면 P가 만든 KV를 D로 옮겨야 한다.
이 전송은 여러 새 비용을 만든다.
- KV 전송이 임계 경로에 얹힌다 — 사용자가 첫 토큰을 받기까지의 시간(TTFT)에 이제 prefill 시간 + KV 전송 시간 + D의 첫 토큰 생성이 모두 포함된다. 전송이 느리면 TTFT가 나빠진다.
- decode 노드 유휴 위험 — KV가 충분히 빨리 도착하지 않으면 D가 놀며 기다린다. 전송 대역폭이 부족하면 분리의 이득이 상쇄된다.
- 큐·실패 경로 증가 — P→D 사이에 큐가 생기고, 전송 실패·노드 장애 같은 새 실패 지점이 생긴다.
- 모델 가중치·KV 풀 중복 — P와 D가 각각 모델 가중치를 갖고 KV 풀을 따로 관리해, 자원이 일부 중복된다.
⚖️ 절충 — 격리 이득 vs 전송·중복 비용 — PD 분리는 간섭 제거·독립 스케일링·하드웨어 이질성을 얻는 대신, KV 전송(임계 경로)·큐·실패 경로·자원 중복이라는 비용을 만든다. "분리하면 항상 낫다"는 거짓이다. 부하가 낮거나 프롬프트가 짧아 간섭이 작으면, 전송 비용이 이득을 넘어설 수 있다. 실제로 최근 연구들은 SLO 조건에 따라 분리/결합의 최적이 갈린다고 보고하며, 둘을 동적으로 오가는 방식(단일 GPU 내 격리, 상황별 전환 등)도 등장했다.
일방향 프로토콜 — P는 producer, D는 consumer
PD 분리의 구조적 성질 하나: KV 전송은 일방향이다. P가 KV를 생산(producer), D가 소비(consumer) 하며, D에서 P로 되돌리는 채널이 없는 것이 일반적 설계다. 이 producer/consumer 계약이 주요 엔진에 공통으로 유지된다.
이 성질의 실무적 결과: 멀티턴 대화에서 D가 생성한 응답의 KV는 P에서 접근할 수 없어, 새 턴마다 P→D 파이프라인을 다시 거친다. 이 한계를 완화하려고 별도의 외부 KV 계층을 두는 접근이 08장의 주제로 이어진다.
⚠️ 경계 혼동 주의 — "간섭 제거"와 "빨라짐"은 다르다 — PD 분리가 없애는 것은 phase 간 간섭이지, 절대적 latency가 늘 줄어드는 것이 아니다. 오히려 단일 요청 TTFT는 KV 전송 때문에 늘어날 수도 있다. 분리의 이득은 주로 여러 요청이 섞일 때 decode 안정성(TBT/TPOT)과 goodput에서 온다. "분리 = 항상 더 빠름"으로 읽으면 틀린다.
goodput — 이 묶음의 핵심 지표 예고
PD 분리 논문들이 최적화 대상으로 삼는 것은 단순 throughput이 아니라 goodput(굿풋) 이다. goodput은 대략 "SLO를 만족하면서 처리한 유효 처리량"을 뜻한다(정확한 정의는 10장). 즉 "빠르게 많이"가 아니라 "약속한 품질(SLO)을 지키며 많이"다.
왜 이 구분이 중요한가: SLO를 어기면서 낸 처리량은 사용자에게 쓸모없는(late) 응답일 수 있다. PD 분리는 decode 간섭을 없애 SLO 위반을 줄임으로써 goodput을 높인다. 이 "SLO를 붙인 처리량"이라는 관점이 10장 capacity 계약의 토대다.
🔬 증거 읽기 — PD 분리 성능 주장 검증 — "PD 분리로 goodput을 X배" 또는 "비용을 Y% 절감"이라는 주장을 만나면 확인하라:
- (a) 어떤 SLO 기준(TTFT·TPOT 목표)에서 측정했나 — SLO가 느슨하면 이득이 크게 보인다.
- (b) KV 전송 비용을 포함했나 — 전송 시간을 TTFT에 넣었는가, 아니면 뺐는가.
- (c) 어떤 워크로드(프롬프트/생성 길이 분포, 부하율)인가 — 긴 프롬프트·높은 부하일수록 분리가 유리.
- (d) P:D 비율·하드웨어 구성은 무엇인가.
이 조건이 다르면 다른 배포의 "X배"와 직접 비교 불가다(15장). 특히 KV 전송 비용을 분모에서 뺀 주장은 과장되기 쉽다.
배포 D3 — 척추에 PD 분리를 얹다
배포 D3 — 배포 D1(병렬화된 엔진)의 팀이 "긴 프롬프트가 짧은 요청의 생성을 끊는" 간섭(01장의 latency 문제)을 겪는다. 이들은 prefill 풀과 decode 풀을 분리해 간섭을 없앤다. 그 대가로 KV를 P→D로 전송해야 하고, 전송 대역폭·큐·실패가 새 관심사가 된다. 이제 "KV를 어떻게, 어디로 옮기고 어디에 둘 것인가"가 다음 장(08)의 주제다.
이 장에서 배운 것
- prefill은 compute-bound, decode는 memory-bound로 자원 성격이 반대다. 같은 GPU에 섞으면 긴 prefill이 decode를 방해하는 간섭이 생긴다.
- PD 분리는 두 phase를 다른 GPU 풀로 떼어 간섭 제거·독립 스케일링·하드웨어 이질성을 얻는다.
- 대가로 KV가 네트워크 페이로드가 된다: KV 전송이 TTFT 임계 경로에 얹히고, decode 유휴·큐·실패·자원 중복이 새로 생긴다.
- KV 전송은 일방향(P=producer, D=consumer) 이라, 멀티턴에서 D의 KV를 재사용하기 어렵다 → 외부 KV 계층(08장)의 동기.
- PD 분리는 "항상 빨라짐"이 아니라 간섭 제거를 통한 goodput(SLO를 붙인 처리량) 개선이다. 이득은 SLO·워크로드·전송 비용 조건에 달렸다.
🔎 이 장의 '지지하지 않는 결론' + 'unknown으로 남겨야 할 것'
- 지지하지 않는 결론 — "PD 분리는 언제나 latency를 줄이고 항상 이득이다"는 지지되지 않는다. 단일 요청 TTFT는 KV 전송 때문에 늘 수도 있고, 이득/손실은 SLO·부하·전송 비용에 달렸다.
- unknown으로 남길 것 — 특정 사업자 배포의 정확한 P:D 비율·토폴로지·KV 전송 대역폭·실제 goodput 이득은 그 배포가 공개하지 않는 한
unknown. 정리 문헌의 예시 수치(예: "KV 전송이 prefill 시간의 N배")는 특정 논문의 특정 조건이며 일반값이 아니다.
✍️ 확인 문제
- prefill과 decode의 병목 자원(연산 vs 메모리 대역폭)이 반대라는 사실이, 왜 "같은 GPU에 섞으면 자원이 낭비된다"와 "PD 분리 시 하드웨어 이질성을 쓸 수 있다"를 동시에 설명하는지 말하라.
- (조건/분모 유형) 어떤 논문이 "PD 분리로 goodput 3배"라고 주장한다. 이 "3배"를 다른 논문의 "2배"와 나란히 순위 매기기 전에 반드시 맞춰 확인해야 할 조건을 셋 이상 들어라. 특히 KV 전송 비용을 어디에 넣었는지가 왜 결정적인가?
- (경계 혼동 유형) 동료가 "PD 분리하면 단일 요청도 무조건 빨라진다"고 한다. 무엇이 틀렸는지, PD 분리가 실제로 개선하는 것(간섭·TBT·goodput)과 개선하지 않을 수 있는 것(단일 TTFT)을 구분해 바로잡아라.
다음 장에서는 PD 분리가 만든 "KV 전송" 문제를 정면으로 다룬다. KV의 ownership·lifetime·계층(tier), backpressure, 그리고 "전송할 것인가 재계산할 것인가"의 절충이 초점이다.
다음 → 08. KV 전송과 계층화 — KV는 누구 것이고 어디에 얼마나 머무는가