KV Cache
기초
K
k_new
V
v_new
LLM 추론 기초 세미나
어떻게 계산되고,
추론 엔진은 그것을 어떻게 관리하는가
오늘 다룰 다섯 가지
AGENDA
01
왜 KV Cache인가
토큰을 하나씩 생성하는 LLM과 그 안에 숨은 중복 계산
02
Attention과 Q·K·V
Q·K·V 투영, causal mask, 그리고 변하지 않는 과거
03
계산과 메모리
decode 한 스텝, prefill과 decode, 계산량과 메모리 크기 공식
04
추론 엔진에서
PagedAttention, continuous batching, prefix caching
05
확장과 다음 흐름
심화: disaggregated serving, diffusion LLM
LLM은 토큰을 한 번에 하나씩 생성한다
01 · 왜 KV CACHE인가
step 1
오늘
날씨가
LLM
정말
step 2
오늘
날씨가
정말
LLM
맑고
step 3
오늘
날씨가
정말
맑고
LLM
따뜻하다
자기회귀(autoregressive): 방금 만든 토큰이 다시 입력 끝에 붙는다. 스텝마다 입력이 1씩 길어진다.
프롬프트
이전 출력
이번 출력
캐시가 없으면 매 스텝 과거 전체를 다시 계산한다
01 · 왜 KV CACHE인가
step 1
step 2
step 3
step 4
step 5
step 6
새로 필요한 K·V 계산
중복 재계산
77%
프롬프트 4토큰 · 6스텝 기준, 토큰별 K·V 계산 39회 중 30회가 이미 했던 계산
길이 n까지 생성하면
1 + 2 + … + n ≈ n² / 2
생성이 길어질수록 낭비는 제곱으로 커진다.
각 토큰은 세 개의 벡터 Q · K · V로 투영된다
02 · ATTENTION과 Q·K·V
x_t
토큰의 hidden state
(d_model 차원)
× W_Q
q
Query · 질문
지금 토큰이 문맥에서 어떤 정보를 찾는가
× W_K
k
Key · 색인
이 토큰이 무엇을 갖고 있는가 — 다른 토큰의 Q와 비교된다
× W_V
v
Value · 내용
선택되었을 때 실제로 전달되는 정보
W_Q · W_K · W_V는 학습된 가중치 행렬. 이 투영은 레이어마다, 헤드마다 따로 일어난다 (MHA 기준 · GQA/MQA는 KV 헤드를 공유).
Attention은 행렬 곱 두 번과 softmax 한 번
02 · ATTENTION과 Q·K·V
Attention(Q,K,V) = softmax(Q·Kᵀ / √d) · V
Q
n × d
×
Kᵀ
d × n
=
점수 S
n × n
softmax
×
V
n × d
=
출력
n × d
Q·Kᵀ — 각 쿼리와 모든 키의 유사도
softmax — 행마다 합이 1인 가중치로
× V — 가중치만큼 Value를 섞는다
Causal mask: 각 토큰은 자신과 과거만 본다
02 · ATTENTION과 Q·K·V
Q ↓ / K →
오늘
날씨가
정말
맑고
따뜻
오늘
−∞
−∞
−∞
−∞
날씨가
−∞
−∞
−∞
정말
−∞
−∞
맑고
−∞
따뜻
i번째 행 = i번째 토큰의 쿼리
볼 수 있는 키는 1번부터 i번까지 (자기 자신 포함)
미래 칸은 −∞로 가린다
softmax를 거치면 가중치 0 — 미래 토큰은 결과에 영향이 없다
그래서 토큰 i의 hidden state와 K·V는 뒤에 어떤 토큰이 오든 바뀌지 않는다
다음 스텝에서 새로 필요한 건 마지막 한 행뿐이다
핵심 관찰
step t
step t+1
step t와 완전히 같은 값 → 다시 계산할 필요 없음
새 행: q_t+1 · [k_1 … k_t+1]ᵀ
새 행을 계산하려면 과거 모든 토큰의 K와 V가 필요하다
→ 매번 다시 만들지 말고 저장해 두자 = KV Cache
Q는 저장하지 않는다. 과거 토큰의 쿼리는 다시 쓰이지 않기 때문
KV Cache를 쓰는 decode 한 스텝
03 · KV CACHE 계산
x_t
새 토큰 1개
① 투영 (1개분)
q_t
k_t
v_t
② KV Cache에 append
k_1
k_2
k_3
⋮
k_t
v_1
v_2
v_3
⋮
v_t
③ attention (q_t 1개 × 캐시 전체)
s = q_t · Kᵀ / √d
1 × t
o_t = softmax(s) · V
④ o_t → 다음 레이어 → … → 다음 토큰
새로 계산하는 K·V는 토큰 1개분. 대신 attention은 매 스텝 캐시 전체(t개)를 읽는다. (한 레이어·한 헤드 기준, norm·RoPE·잔차 생략)
코드로 보면 (한 레이어·한 헤드, 단순화)
03 · KV CACHE 계산
## Prefill: 프롬프트 X 전체를 한 번에
K_cache = X @ W_K
# [n, d] n개 토큰의 K
V_cache = X @ W_V
# [n, d] (attention도 함께 계산)
## Decode: 토큰 하나씩 반복
q, k, v = x_t @ W_Q, x_t @ W_K, x_t @ W_V
# [1, d] 새 토큰 1개만 투영
K_cache = cat([K_cache, k])
# [t, d] append
V_cache = cat([V_cache, v])
# [t, d] append
s = q @ K_cache.T / sqrt(d)
# [1, t] 캐시 전체를 읽음
o = softmax(s) @ V_cache
# [1, d] 다음 레이어로
실제 엔진에서는 이 캐시가 레이어 수 × KV 헤드 수만큼 존재하고, cat 대신 미리 잡아 둔 메모리 블록에 써 넣는다.
추론은 두 단계: prefill이 채우고, decode가 늘린다
03 · KV CACHE 계산
Prefill
프롬프트 처리
행렬 × 행렬
n개 동시에
KV Cache
한 번에 채움
일반적으로 연산 집약적 (compute-bound)
GPU 연산 유닛을 꽉 채워 병렬 처리
TTFT = 요청 도착 → 첫 토큰 (주로 대기 + prefill)
Decode
토큰 생성 루프
벡터 × 행렬
1개씩
캐시 전체 읽고
한 줄 추가
일반적으로 메모리 대역폭 집약적 (memory-bound)
계산은 적고, 가중치와 캐시를 읽는 시간이 대부분
TPOT · ITL = 토큰과 토큰 사이 시간 (decode 한 스텝)
Prefill: 프롬프트 전체로 KV를 채운다
03 · PREFILL 자세히
토큰 n개 (병렬)
레이어 연산
KV Cache
임베딩
레이어 1
QKV → attn → MLP
쓰기 →
레이어 2
QKV → attn → MLP
쓰기 →
⋮
레이어 L
QKV → attn → MLP
쓰기 →
출력
마지막 위치만 lm_head
첫 토큰 “정말”
① 레이어마다 같은 일
n개 토큰의 q·k·v를 행렬 곱 한 번에 계산 → k·v를 캐시 블록에 기록 → n×n causal attention → MLP
② K·V만 따로 못 구한다
레이어 l+1의 K·V는 레이어 l의 attention·MLP 출력에서 나온다 → 모델 전체를 끝까지 돌려야 한다
③ 끝난 시점의 캐시
프롬프트 n개분만 있다. 첫 토큰 “정말”의 K·V는 다음 decode 스텝에서 추가된다
prefix cache hit면 miss 구간만 prefill, chunked prefill이면 조각별로 나눠 같은 일을 한다 — 앞 조각이 채운 캐시를 읽으며 이어 쓴다
Decode: 캐시를 읽고 한 줄씩 쓴다
03 · DECODE 자세히
1개
레이어 연산
KV Cache (n + t)
입력
정말
직전에 생성된 토큰
레이어 1
QKV → attn → MLP
읽기 ⇄ 쓰기
레이어 2
QKV → attn → MLP
읽기 ⇄ 쓰기
⋮
레이어 L
QKV → attn → MLP
읽기 ⇄ 쓰기
출력
lm_head → 샘플링
“맑고”
↺ 다음 스텝 입력
① 입력은 직전 토큰 1개
첫 스텝의 입력은 prefill이 낸 첫 토큰. 그래서 그 K·V가 지금 캐시에 추가된다
② 레이어마다 읽고 쓰기
k·v를 append(진한 칸) → q 하나로 캐시 전체(n + t개)와 attention
③ EOS나 최대 길이까지 반복
한 스텝 = 토큰 1개. 스텝의 실행·스케줄링 시간이 ITL의 주요 부분
계산은 적지만 매 스텝 가중치 전체 + KV Cache 전체를 메모리에서 읽는다 → 대개 memory-bound (배치·문맥 길이에 따라 달라짐). 여러 요청을 한 배치로 묶어 가중치 읽기를 나눠 쓴다
Prefill과 Decode 한눈에
03 · KV CACHE 계산
항목 | Prefill | Decode |
입력 | 프롬프트 토큰 n개를 한꺼번에 | 직전에 생성된 토큰 1개 |
연산 형태 | 행렬 × 행렬 (큰 GEMM) | 요청당 벡터 × 행렬, 배치 시 GEMM |
Attention | n × n causal | 1 × (n + t), 캐시 전체를 읽음 |
KV Cache | n개분을 새로 기록 | 1개분 append, 전체 읽기 |
병목 | 대개 연산 (compute-bound) | 대개 메모리 대역폭 (memory-bound) |
배치 효과 | 긴 프롬프트는 단일 요청도 연산 활용도가 높음 (짧으면 배치 효과 큼) | 가중치 읽기를 나눠 써 이득이 크다 |
지표 | TTFT | TPOT · ITL |
주요 최적화 | prefix caching, chunked prefill | 큰 배치, GQA · FP8 KV, speculative decoding |
지연 지표 세 가지: TTFT · TPOT · ITL
03 · KV CACHE 계산
TTFT
요청 도착 · 대기 + Prefill
t1
t2
t3
t4
t5
ITL
ITL
ITL
ITL
TPOT = 이 구간 ÷ (출력 토큰 수 − 1) = ITL의 평균
전체 지연 (E2E) = TTFT + TPOT × (N − 1)
TTFT · Time To First Token
요청 도착부터 첫 토큰까지. 주로 큐 대기 + prefill (+ 첫 토큰 샘플링·전송). 긴 프롬프트·prefix 캐시 miss면 커진다
TPOT · Time Per Output Token
첫 토큰 이후 토큰당 평균 시간. 가중치·KV 읽기, 배치 크기, 스케줄링에 영향을 받는다. “글이 얼마나 빨리 써지나”
ITL · Inter-Token Latency
연속된 두 토큰 사이의 실제 간격 하나하나. 평균보다 P99 같은 분포로 본다. 긴 prefill이 끼어들면 튄다
K·V 계산량: n²에서 n으로
03 · KV CACHE 계산
↑ 누적 K·V 투영 횟수
캐시 없음 · Σt ≈ n²/2
KV Cache · n
생성 스텝 t →
캐시 없음
스텝 t마다 t개 토큰의 K·V를 다시 투영
KV Cache
스텝마다 새 토큰 1개만 투영, 나머지는 메모리에서 읽기
단, 새 q와 누적 K·V의 attention은 스텝마다 t에 비례 → attention 누적 비용은 여전히 n²
연산을 메모리로 바꾼 거래. 이제 병목은 메모리 용량과 대역폭
KV Cache 크기는 이렇게 계산한다
03 · 메모리
2 K·V
×
L
×
H_kv
×
d_h
×
bytes
=
토큰당 크기
K와 V 두 벡터
레이어 수
KV 헤드 수
헤드 차원
dtype 바이트
2 (K·V)
×
32
×
8
×
128
×
2 B (FP16)
=
128 KiB
예시: Llama 3 8B · FP16 (레이어 32, KV 헤드 8, 헤드 차원 128)
× 시퀀스 길이 8,192 토큰
1 GiB / 요청
× 동시 요청(배치) 32
32 GiB
비교: Llama 2 7B (KV 헤드 32)
512 KiB / 토큰
배치가 커지면 KV Cache가 모델 가중치보다 커진다
03 · 메모리
Llama 3 8B · FP16 · 요청당 8,192 토큰 기준 GPU 메모리 사용량
모델 가중치
≈ 15 GiB
KV · 배치 1
1 GiB
KV · 배치 8
8 GiB
KV · 배치 32
32 GiB · 가중치의 2배
KV · 배치 64
64 GiB
GPU 메모리 = 가중치 + KV Cache + 활성값. 남은 메모리를 KV Cache에 얼마나 잘 쓰느냐가 동시 처리량을 결정한다.
KV 헤드를 공유해 캐시를 줄인다: MHA → GQA → MQA
03 · 메모리
MHA
Q 헤드마다 자기 K·V를 가진다 (Q 8 : KV 8)
1×
예: Llama 2 7B
GQA
Q 헤드 여러 개가 한 KV 그룹을 공유 (Q 8 : KV 2)
1/4
예: Llama 3, Mistral, Qwen
MQA
모든 Q 헤드가 K·V 하나를 공유 (Q 8 : KV 1)
1/8
예: PaLM, Falcon
그 밖의 방법
KV 양자화 (FP8 · INT4)
MLA: 잠재 벡터로 압축 (DeepSeek)
Sliding window
토큰 축출 (StreamingLLM, H2O)
Q 헤드
K·V 헤드 (캐시 대상)
최대 길이만큼 연속 예약하면 단편화로 메모리를 낭비한다
04 · 추론 엔진에서의 KV CACHE
GPU의 KV Cache 영역
A 실제 토큰
A 예약만 됨
틈
B 실제
B 예약만 됨
틈
C 실제
새 요청 D: 빈 공간을 다 합치면 충분하지만 연속된 공간이 없어 대기
① 내부 단편화
출력 길이를 미리 모르니 최대 길이만큼 예약
② 외부 단편화
요청마다 크기가 달라 사이사이 쓸 수 없는 틈
③ 공유 불가
같은 프롬프트라도 요청마다 따로 복사
기존 시스템은 KV Cache 메모리의 20.4 ~ 38.2%만 실제 토큰 저장에 썼다 — Kwon et al., vLLM 논문 (SOSP 2023)
PagedAttention: KV Cache를 고정 크기 블록으로 나눈다
04 · 추론 엔진에서의 KV CACHE
요청 A · 논리 블록
블록 0
오늘
날씨가
정말
맑고
블록 1
따뜻
하다
.
산책
블록 2
가자
!
빈칸
빈칸
블록 크기 = 4 토큰 (vLLM 기본값은 16)
Block table
논리 | 물리 | 채움 |
0 | #7 | 4/4 |
1 | #1 | 4/4 |
2 | #3 | 2/4 |
GPU 물리 블록
#0
B·0
#1
A·1
#2
빈 블록
#3
A·2
#4
B·1
#5
빈 블록
#6
빈 블록
#7
A·0
OS 가상 메모리와 같은 발상 — 논리적으로는 연속, 물리적으로는 흩어져 있어도 된다
낭비는 마지막 블록의 빈칸뿐 — 필요할 때 블록을 하나씩 추가 할당
Continuous batching: 스텝마다 요청이 들어오고 나간다
04 · 추론 엔진에서의 KV CACHE
step
1
2
3
4
5
6
7
8
9
10
11
12
요청 1
요청 2
요청 3
요청 4
요청 5
Prefill
Decode
블록 대기
KV 블록이 요청 2개분만 있다고 가정
핵심: 스텝마다 교체
끝난 요청은 바로 빠지고 블록은 free list로 → 대기 요청이 다음 스텝에 합류
섞기는 정책 선택
prefill과 decode를 한 배치에 섞는 건 별도 스케줄링 정책 (예: chunked prefill)
Preemption
블록이 모자라면 일부 요청의 블록을 회수 → 나중에 재계산 또는 CPU에서 swap-in
Prefix caching: 같은 앞부분은 한 번만 계산한다
04 · 추론 엔진에서의 KV CACHE
공유 prefix · 시스템 프롬프트
#5
#2
#9
ref_count = 3
요청 A
#4
#11
“환불 규정 알려줘”
요청 B
#0
“배송은 언제 와?”
요청 C
#6
#8
“주문 취소하고 싶어”
효과
공유 부분 prefill 생략 → TTFT 감소, 메모리도 한 벌만
잘 맞는 곳
멀티턴 대화, 긴 시스템 프롬프트, few-shot, 에이전트
구현
vLLM: 블록 해시 (APC) · SGLang: RadixAttention
KV Cache는 어떻게 찾나?
04 · 추론 엔진에서의 KV CACHE
① 요청 안에서: 주소 계산
토큰 위치 p = 9 (“!”)
p // 4 = 2 (블록) · p % 4 = 1 (오프셋)
block_table[2] = #3
물리 블록 #3, 슬롯 1 → k · v
검색이 아니라 O(1) 인덱싱. attention 커널이 block table을 받아 흩어진 블록에서 K·V를 직접 모아 읽는다.
② 요청 사이에서: prefix 해시 조회
h0 = hash(∅, 블록0 토큰)
hit · #5 공유
h1 = hash(h0, 블록1 토큰)
hit · #2 공유
h2 = hash(h1, 블록2 토큰)
miss · 새로 계산
• 해시에 이전 블록 해시가 들어가므로 앞부분 전체가 같아야 hit
• 꽉 찬 블록만 등록, 참조 중이지 않은 블록만 메모리가 필요할 때 LRU로 축출
• SGLang은 radix tree에서 가장 긴 공통 prefix를 매칭
한 요청의 여정: KV 블록을 빌리고 돌려준다
04 · 추론 엔진에서의 KV CACHE
요청 도착
대기 큐에 들어감
스케줄링
빈 블록이 충분한지 확인
블록 할당
prefix hit 블록은 공유, 나머지는 새로
Prefill
miss 구간의 KV를 블록에 채움 → 첫 토큰
Decode 루프
스텝마다 KV append, 블록이 차면 하나 더
완료
블록 반환 (prefix 캐시로 남길 수 있음)
Scheduler
이번 스텝에 누구를 돌릴지
할당 · 해제
KV Cache Manager
블록 풀 · free list · 해시 테이블 · block table
block table
Model Runner
attention 커널이 블록을 읽고 쓴다
더 나아가기: 요즘 엔진이 KV Cache로 하는 일
04 · 추론 엔진에서의 KV CACHE
Chunked prefill
긴 프롬프트를 조각내 decode와 섞어 처리 → 긴 prefill로 인한 decode 지연 증가를 줄인다 (청크 크기로 TTFT·ITL 절충)
P 조각
D
P 조각
D
P 조각
D
Prefill / Decode 분리
성격이 다른 두 단계를 다른 GPU에서. 만든 KV Cache를 네트워크로 넘긴다
Prefill 노드
KV 전송
Decode 노드
KV offload · 계층형 캐시
GPU에서 밀려난 블록을 CPU·SSD·원격 저장소에 보관했다가 hit 시 다시 로드
GPU HBM
CPU DRAM
SSD · 원격
KV 양자화 · 압축
FP8 KV Cache로 용량 절반 → 같은 GPU에 더 많은 요청과 긴 문맥
FP16
FP8
Disaggregated serving: prefill과 decode를 다른 GPU로
05 · 심화 · 확장과 다음 흐름
KV-aware 라우터
prefix가 많이 겹치는 노드로 요청을 보냄
Prefill 풀 · 연산 집약
GPU P1
GPU P2
프롬프트 → KV 생성 → 첫 토큰
KV 블록 전송
RDMA · NVLink
Decode 풀 · 대역폭 집약
D1
D2
D3
받은 KV로 큰 배치 decode
전역 KV 풀 · CPU DRAM / SSD / 원격 저장소
GPU에서 밀려난 블록을 보관하고 어느 노드든 다시 로드 (Mooncake Store, LMCache 등)
같은 모델·같은 입력 조건이면 블록 해시 = hash(이전 해시, 블록 토큰)를 클러스터 공통 키로 쓸 수 있다. 전송하려면 dtype·메모리 레이아웃도 맞아야 한다.
전송할까, 다시 계산할까: KV 크기가 곧 네트워크 비용
05 · 심화 · 확장과 다음 흐름
예: Llama 3 8B · FP16 · 프롬프트 8,192 토큰
128 KiB × 8,192 = 1 GiB
÷ 50 GB/s (400 Gb/s 링크)
≈ 21 ms / 요청 (이론치)
레이어 단위로 계산과 겹치면 체감 지연은 더 줄어든다
토큰당 전송할 KV 크기
Llama 2 7B · MHA · FP16
512 KiB
Llama 3 8B · GQA · FP16
128 KiB
Llama 3 8B · GQA · FP8 KV
64 KiB
GQA · MLA · FP8처럼 KV를 줄이는 기법이 그대로 전송량 절감
분리가 유리할 때
긴 프롬프트, 엄격한 TTFT·TPOT 목표, 큰 클러스터
불리할 때
짧은 프롬프트, 작은 규모, 노드 비율·레이아웃 변환 등 운영 복잡도
Diffusion LLM: causal mask가 사라지면 K·V가 매 스텝 바뀐다
05 · 심화 · 확장과 다음 흐름
AR · causal
과거만 본다
→ K·V 고정
Diffusion · 양방향
모두가 모두를 본다
→ K·V 계속 변함
MASK를 여러 개씩 동시에 채운다
step 0
MASK
MASK
MASK
MASK
MASK
step 1
MASK
날씨가
MASK
MASK
따뜻하다
step 2
오늘
날씨가
MASK
맑고
따뜻하다
step 3
오늘
날씨가
정말
맑고
따뜻하다
한 칸이 채워질 때마다, 그 칸을 보는 모든 토큰의 hidden state와 K·V가 달라진다
문맥이 매 스텝 바뀌므로 AR처럼 과거 KV 전체를 정확히 재사용하기 어렵다
순수 방식은 매 스텝 전체 재계산 → 병목이 대체로 연산 쪽으로
그래도 KV Cache는 다시 돌아온다: 근사 캐시와 블록 diffusion
05 · 심화 · 확장과 다음 흐름
순수 diffusion
프롬프트까지 포함해 매 스텝 전체를 다시 계산
캐시 없음 · 전체 재계산 비용이 큼
근사 KV Cache
프롬프트·확정 토큰의 K·V는 스텝 사이에 거의 안 변한다 → 캐시하고 가끔만 갱신
Fast-dLLM, dKV-Cache, dLLM-Cache 등 · 근사
블록 diffusion
블록 사이는 causal, 블록 안은 diffusion → 끝난 블록의 K·V는 고정
BD3-LM 등 · 블록 단위로 정확한 캐시
캐시 재사용
이번 스텝 계산
아직 MASK
서빙 관점: 기존 AR 엔진의 페이징·배칭 원리는 활용할 수 있지만, diffusion의 반복 갱신과 병렬 토큰 생성에 맞는 스케줄링·캐시 관리가 필요하다.
KV Cache, 다섯 문장으로
정리
01
causal mask 덕분에 과거 토큰의 K·V는 변하지 않는다 → 저장해서 재사용 (Q는 저장하지 않음)
02
Prefill이 캐시를 채우고, decode는 캐시 전체를 읽으며 한 줄씩 늘린다
03
크기 = 2 × 레이어 × KV 헤드 × 헤드 차원 × 바이트 × 토큰 수 — 금세 가중치보다 커진다
04
추론 엔진의 핵심은 KV 메모리 관리: 페이징 · continuous batching · prefix 캐싱
05
Disaggregated serving은 KV를 클러스터 자원으로 옮기고, diffusion LLM은 근사 재사용 또는 블록 구조를 통한 정확한 재사용을 활용한다
Attention과 KV Cache 크기 줄이기
참고 논문 1/3
Transformer · Attention
Attention Is All You Need
Q·K·V와 attention의 출발점 · Vaswani et al., NeurIPS 2017 · arxiv.org/abs/1706.03762
MQA
Fast Transformer Decoding: One Write-Head is All You Need
K·V 헤드를 하나로 공유 · Shazeer, 2019 · arxiv.org/abs/1911.02150
GQA
GQA: Training Generalized Multi-Query Transformer Models from Multi-Head Checkpoints
Q 헤드 그룹이 KV 헤드를 공유 · Ainslie et al., EMNLP 2023 · arxiv.org/abs/2305.13245
MLA
DeepSeek-V2: A Strong, Economical, and Efficient Mixture-of-Experts Language Model
K·V를 저차원 잠재 벡터로 압축 · DeepSeek-AI, 2024 · arxiv.org/abs/2405.04434
토큰 축출
Efficient Streaming Language Models with Attention Sinks
StreamingLLM: 앞 토큰 몇 개와 최근 창만 유지 · Xiao et al., ICLR 2024 · arxiv.org/abs/2309.17453
토큰 축출
H2O: Heavy-Hitter Oracle for Efficient Generative Inference of Large Language Models
attention을 많이 받는 토큰만 캐시에 남김 · Zhang et al., NeurIPS 2023 · arxiv.org/abs/2306.14048
추론 엔진과 disaggregated serving
참고 논문 2/3
Continuous batching
Orca: A Distributed Serving System for Transformer-Based Generative Models
스텝 단위 스케줄링 · Yu et al., OSDI 2022 · usenix.org/conference/osdi22/presentation/yu
PagedAttention · vLLM
Efficient Memory Management for Large Language Model Serving with PagedAttention
블록 단위 KV 관리로 단편화 제거 · Kwon et al., SOSP 2023 · arxiv.org/abs/2309.06180
RadixAttention · SGLang
SGLang: Efficient Execution of Structured Language Model Programs
radix tree로 요청 간 prefix 재사용 · Zheng et al., NeurIPS 2024 · arxiv.org/abs/2312.07104
Chunked prefill
Taming Throughput-Latency Tradeoff in LLM Inference with Sarathi-Serve
prefill을 쪼개 decode와 섞기 · Agrawal et al., OSDI 2024 · arxiv.org/abs/2403.02310
PD 분리
DistServe: Disaggregating Prefill and Decoding for Goodput-optimized LLM Serving
prefill·decode를 다른 GPU로 · Zhong et al., OSDI 2024 · arxiv.org/abs/2401.09670
PD 분리
Splitwise: Efficient Generative LLM Inference Using Phase Splitting
단계별로 다른 하드웨어에 배치 · Patel et al., ISCA 2024 · arxiv.org/abs/2311.18677
KV 중심 아키텍처와 diffusion LLM
참고 논문 3/3
전역 KV 풀
Mooncake: A KVCache-centric Disaggregated Architecture for LLM Serving
Kimi의 PD 분리 + CPU·SSD KV 풀 · Qin et al., 2024 · arxiv.org/abs/2407.00079
Diffusion LLM
Large Language Diffusion Models
LLaDA: 8B masked diffusion LLM · Nie et al., 2025 · arxiv.org/abs/2502.09992
블록 diffusion
Block Diffusion: Interpolating Between Autoregressive and Diffusion Language Models
BD3-LM: 블록 사이 AR, 블록 안 diffusion · Arriola et al., ICLR 2025 · arxiv.org/abs/2503.09573
dLLM 근사 캐시
Fast-dLLM: Training-free Acceleration of Diffusion LLM by Enabling KV Cache and Parallel Decoding
블록 단위 근사 KV Cache + 병렬 디코딩 · Wu et al., 2025 · arxiv.org/abs/2505.22618
dLLM 근사 캐시
dKV-Cache: The Cache for Diffusion Language Models
확정된 토큰을 한 스텝 늦게 캐시 · Ma et al., 2025 · arxiv.org/abs/2505.15781
dLLM 근사 캐시
dLLM-Cache: Accelerating Diffusion Large Language Models with Adaptive Caching
프롬프트·응답을 다른 주기로 갱신 · 2025 · arxiv.org/abs/2506.06295