한 줄 요약 — LLM이 토큰을 1개 생성할 때마다 모델 weights 전체 + 지금까지 쌓인 KV cache 전체를 GPU 메모리에서 읽어와야 하는데, 문맥이 128K처럼 길어지면 KV cache가 모델보다 커져서(78GB > 14GB) 생성이 극도로 느려진다. 기존 해법인 KV cache 압축(eviction)은 속도를 얻는 대신 생성 품질을 잃는다.
"key-value (KV) cache … has emerged as a critical bottleneck" — Abstract
"they suffer from degradation in generation quality" — Abstract (기존 KV cache 압축 기법에 대해)
구체적 수치 Fig. 1 : Llama2-7B-128K 기준, full KV cache는 78GB / 순전파 56ms, 4K만 골라낸 partial cache는 16GB / 14ms, 초소형 draft 모델(Llama-68M)은 150MB / 0.45ms. 즉 "매번 78GB를 읽는 것"이 문제의 정체다.
| 접근법 | 무엇을 줄였나 / 해결했나 | 대가는 무엇인가 |
|---|---|---|
| KV cache eviction StreamingLLM, H2O §2.2 | 오래된/덜 중요한 KV를 버려서 cache 크기를 고정 | 버린 토큰은 영구 삭제 → 정보 손실. needle retrieval 과제에서 acceptance rate가 0.05 수준으로 붕괴 Table 1 |
| KV cache quantization §2.3 | KV를 저비트로 압축해 메모리 절감 | 정밀도 손실 위험. 본 논문과는 orthogonal(독립적으로 병행 가능) |
| 일반 speculative decoding draft 모델 + verify §2.1 | 작은 모델이 미리 예측 → 큰 모델이 병렬 검증, 출력 분포는 무손실 유지 | 128K급 긴 문맥용 draft 모델을 따로 훈련해야 하고, 훈련 없이 쓰면 문맥이 길수록 draft-target 간 divergence(불일치)가 계속 증가 Fig. 2a |
| ZeRO-Inference DeepSpeed, offloading | 모델 weights를 CPU/NVMe에 두고 layer 단위로 GPU에 흘려보내 GPU 1장으로 초거대 모델 추론 가능 (아래 배경 카드 참고) | throughput(대량 배치) 지향 설계라 토큰 1개당 latency는 매우 느림. TriForce가 비교 baseline으로 사용 §1, Table 3 |
| REST §5.2 | 외부 datastore에서 초안 검색 | 미리 만든 고정 저장소라 현재 문맥에 동적으로 적응 못함 (1.47×) |
| Skipping Layers §5.2 | layer 일부를 건너뛰며 self-draft | KV cache의 68%를 여전히 사용 → 긴 문맥 병목 해결 못함 (1.36×) |
| TriForce (본 논문) | 훈련 없이, 같은 모델 + KV cache 3%(4K)를 중간 draft로 쓰고, 그 아래에 초소형 모델을 한 단 더 쌓는 2단 계층 speculation | full KV cache를 (GPU든 CPU든) 계속 보관해야 함 — 메모리 절약 기법이 아니라 latency 가속 기법 |
GPU 메모리가 모자라 거대 모델을 못 돌리는 사람들을 위한 기술이다. 아이디어는 단순하다: 모델 weights를 GPU에 하나도(zero) 두지 않고 CPU DRAM이나 NVMe SSD에 통째로 넣어둔 뒤, 계산할 때 layer 하나씩만 PCIe로 GPU에 흘려보내 계산하고 버린다. 이렇게 하면 V100-32GB 한 장으로도 (NVMe 기준) 최대 15조 파라미터급 모델을 돌릴 수 있다.
"hosting the model weights in CPU or NVMe memory" — DeepSpeed 블로그 §How ZeRO-Inference works
블로그의 핵심 결론: (1) 모델이 GPU에 안 들어가면 일부만 GPU에 올리는 것보다 전부 offload하고 남는 GPU 메모리를 batch 키우는 데 쓰는 게 빠르다 (full offload가 partial 대비 1.3~2.4×) — §Full Offload vs. Partial Offload. (2) prefetching(다음 layer 미리 가져오기)으로 NVMe에서 1.13~1.21× 개선 — §Prefetching. (3) 명시적으로 "throughput-oriented" 워크로드용이며 latency 민감 응용에는 부적합 — §When to use. 바로 이 "latency가 느린 offloading"이 TriForce가 4.86× 격파하는 baseline이다 Table 3.
핵심 아이디어 한 줄 — 병목이 2개(① 모델 weights, ② KV cache)이므로, draft도 2단으로 쌓는다. 초소형 모델(150MB)이 먼저 초안을 쓰고 → 같은 target 모델이 KV cache의 3%(4K)만 검색해 붙인 상태로 1차 검증하고 → 마지막에 full cache로 최종 검증한다. 최종 검증이 표준 speculative decoding과 동일하므로 출력 분포는 수학적으로 무손실이다 §4.2 Correctness.
LLM은 다음 단어를 예측할 때 앞에 나온 모든 단어를 매번 다시 참조한다(attention). 매번 처음부터 다시 계산하면 낭비니까, 각 단어에 대해 한 번 계산한 중간 결과물인 Key(K)와 Value(V) 벡터를 저장해 두고 재사용하는데, 이 저장소가 KV cache다. 문제는 단어(토큰) 수에 비례해 커진다는 것 — 128K 토큰이면 Llama2-7B 기준 78GB Fig. 1. 그리고 토큰을 1개 생성할 때마다 이걸 전부 GPU 연산기 앞까지 읽어와야 한다.
비유: 교수(큰 모델)가 문장을 직접 쓰면 한 단어에 1분씩 걸린다. 그런데 교수는 "이미 쓰인 10단어를 한꺼번에 채점"하는 것도 1분이면 된다(GPU는 병렬 처리가 공짜에 가까움). 그래서 조교(작은 draft 모델)가 빠르게 10단어를 미리 써오면, 교수는 1분에 한 번씩 채점만 한다. 틀린 단어부터는 버리고 교수가 정답을 하나 적어준다. 채점 규칙 덕분에 최종 출력은 교수가 혼자 쓴 것과 확률적으로 완전히 동일하다(무손실). 단, 조교가 자주 틀리면(acceptance rate ↓) 이득이 사라진다.
KV cache를 통째로 저장하는 대신, 맨 앞의 몇 토큰(attention sink: 모델이 이유 없이 강하게 주목하는 앵커)과 최근 토큰들만 남기고 나머지는 버리는 방식. 무한히 긴 텍스트도 고정 메모리로 처리할 수 있지만, 버린 중간 내용은 영원히 복구 불가하다. TriForce는 이걸 target에는 절대 안 쓰고, 가장 작은 1차 draft 모델(Llama-68M)에만 붙여 쓴다.
관찰 ① 병목이 문맥 길이에 따라 바뀐다 Fig. 2b, 2c — 짧은 문맥에선 모델 weights가, 긴 문맥에선 KV cache가 지배적 병목. 그래서 각 병목마다 다른 draft를 배정하는 계층 구조가 필요하다.
관찰 ② Attention은 매우 희소(sparse)하다 §3.1, Fig. 3a — 120K 문맥에서 단 4K 토큰으로 attention 점수의 96.8%를 복원 가능. 즉 cache의 3%만 있어도 "거의 같은 모델"처럼 행동한다 → 자기 자신을 draft로 쓰는 self-speculation의 근거.
관찰 ③ 문맥 참조에는 지역성(contextual locality)이 있다 §3.2, Fig. 3c — 지금 토큰이 참조하는 옛 문맥과, 바로 다음 토큰들이 참조하는 옛 문맥이 거의 같다. 따라서 한 번 골라둔 4K 캐시를 여러 디코딩 스텝에 재사용할 수 있어 캐시 구축 비용이 분할상환(amortize)된다.
full cache를 어차피 (최종 검증용으로) 보관하므로, draft cache는 버리는(eviction) 방식이 아니라 "골라오는(retrieval)" 방식으로 만들 수 있다. KV cache를 chunk(작은 덩어리)로 쪼개고, 현재 query와 각 chunk의 평균 key 사이 attention 점수를 계산해 점수 높은 chunk들만 4K 예산에 채운다. 시간(recency)이 아니라 관련성(relevance) 기준 선택이다.
"evicted tokens are permanently discarded" — §4.1 (StreamingLLM/H2O가 needle retrieval에 부적합한 이유)
retrieval cache로 KV 병목은 풀었지만, draft가 7B weights 전체를 여전히 로드하므로(14ms) 이번엔 weights가 병목이 된다. 그래서 그 아래에 Llama-68M + StreamingLLM cache(0.45ms)를 한 단 더 깐다.
prefix의 마지막 토큰으로 중요도 순 캐시를 최초 구축 → 이후에는 새 토큰의 KV가 중요도 최하위 항목을 덮어쓰며(overwrite) 유지 → 수락률의 이동평균이 임계값 아래로 떨어지거나 정해진 stride마다 전체 재구축(rebuild). 관찰 ③(지역성)이 있기에 재구축을 드물게 해도 된다.
γ₁=2, γ₂=6, Fig. 1의 계층별 비용(0.45 / 14 / 56ms)을 그대로 사용한 1 iteration:
| step | 이벤트 | 비용 | 1차 확정 n | 최종 확정 N |
|---|---|---|---|---|
| 1 | 68M이 2토큰 초안 | 2×0.45ms | 0 | 0 |
| 2 | 7B+retrieval 검증: 2수락 + 보너스 1샘플 | 14ms | 3 | 0 |
| 3 | 68M이 2토큰 초안 | 0.9ms | 3 | 0 |
| 4 | 검증: 1수락, 1거절→교정 1개 | 14ms | 5 | 0 |
| 5 | 68M이 2토큰 초안 | 0.9ms | 5 | 0 |
| 6 | 검증: 2수락 + 보너스 1 → n=8 ≥ 6, 루프 종료 | 14ms | 8 | 0 |
| 7 | full cache 최종 검증: 후보 8개 중 7수락 + 교정 1 | 56ms | — | 8 |
합계 ≈ 100.7ms에 토큰 8개 = ~12.6ms/token. vanilla는 56ms/token이므로 산술상 ~4.4×. 실제 측정치 2.31× Table 2는 여기에 retrieval 계산·캐시 갱신·커널 오버헤드가 더해진 값이다. (거절이 잦아질수록 이 수치는 빠르게 나빠진다 — s₈의 붕괴 케이스 참고)
| Figure | 설득하려는 주장 | 근거로 쓰는 것 |
|---|---|---|
| Fig. 1 | 병목 2개 → 계층 3개(모델 2 + 캐시 3)로 풀 수 있다 | 계층별 메모리/지연 수치(150MB·0.45ms / 16GB·14ms / 78GB·56ms) + needle 과제에서 eviction의 정확도-지연 trade-off 대비 |
| Fig. 2a | 기존 소형 draft(훈련 없이)는 긴 문맥에서 못 쓴다 | 문맥 128→32K로 갈수록 draft-target divergence가 단조 증가, 온도에도 민감 |
| Fig. 2b | 긴 문맥에선 KV cache가 weights를 넘어서는 새 병목 | 4K→128K에서 GPU HBM 구성비 분해(weights 고정 vs KV 선형 증가) |
| Fig. 2c | 문맥이 길수록 메모리 대부분이 KV cache | Llama2-7B/13B, batch 1/4에서 KV 점유율 곡선 |
| Fig. 3a | attention은 희소 → cache 3%로 충분 | 120K 문맥, top-4096 복원율 96.8% heatmap (첫 2 layer 제외 거의 1.0) |
| Fig. 3b | partial cache self-speculation의 acceptance는 이미 높다 | Top-K 1K 예산으로 이론상 97.6%, StreamingLLM/H2O도 90.5%+ |
| Fig. 3c | 골라둔 캐시를 여러 step 재사용 가능(지역성) | top-4K 인덱스 고정 후 256토큰 동안 복원율 0.8+ 유지 |
| Fig. 4 + Table 1 | eviction 말고 retrieval이어야 한다 | needle retrieval acceptance: Stream 0.05 / H2O 0.07 vs Retrieval 0.99 |
| Table 2 | on-chip에서 빠르고 온도에 강건 | T=0~1.2에서 2.02~2.31×, acceptance 0.89+ 유지 (naive는 0.27까지 추락) |
| Table 3 | 소비자 GPU offloading에서 진짜 위력 | 2×4090에서 7.78~7.94×, 단일 4090에서 ZeRO-Inference 대비 4.86× |
| Table 4 | batch 상황에서도 유효 | batch 6×19K에서 1.90× |
| Fig. 5 | 문맥이 길수록 더 유리(scalability) | 이론 상한 13.1× vs naive 상한 1.87×, 측정치도 우상향 |
| Table 5 | 동종 training-free 기법 대비 최고 | TriForce 2.31× vs REST 1.47× vs Skipping Layers 1.36× |
| Fig. 6a/b/c | 4K 예산이 최적 / chunk 크기는 중간이 최적 / tree 계열과 호환 | budget-acceptance 곡선 plateau, chunk 크기 U자형, Sequoia 결합 시 이론 토큰수 증가 |
| T (temperature) | TriForce speedup (acceptance) | Naive Policy: 68M+Stream 단독 draft |
|---|---|---|
| 0.0 | 2.31× (0.9234) | 1.56× (0.4649) |
| 0.6 | 2.19× (0.9137) | 1.42× (0.4036) |
| 1.0 | 2.08× (0.9004) | 1.29× (0.2872) |
| 1.2 | 2.02× (0.8902) | 1.27× (0.2664) |
| ablation: Retrieval만(계층 없이) 1.80× · StreamingLLM cache로 계층만 1.90× → 둘을 합쳐야 2.31× | ||
| GPU | Target | TriForce | AR baseline | Speedup |
|---|---|---|---|---|
| 2× RTX 4090 | Llama2-7B-128K | 108ms/tok | 840ms | 7.78× |
| 2× RTX 4090 | Llama2-13B-128K | 226ms/tok | 1794ms | 7.94× |
| 1× RTX 4090 | Llama2-7B-128K | 312ms/tok | 1516ms (ZeRO-Inference) | 4.86× |
| (batch, 문맥) | budget | T=0 | T=0.6 |
|---|---|---|---|
| (2, 56K) | (2, 1024) | 1.89× | 1.75× |
| (6, 19K) | (6, 768) | 1.90× | 1.76× |
| (10, 12K) | (10, 768) | 1.72× | 1.61× |
Fig. 5: 문맥 32K→128K로 갈수록 TriForce의 speedup은 우상향하고(이론 상한 13.1×), naive policy는 상한이 1.87×에 묶인다. 이유는 두 가지 — 문맥이 길수록 ① draft(4K 고정)와 target(선형 증가)의 지연 격차가 벌어지고 ② acceptance는 유지되기 때문 §5.1 Analysis.
Fig. 6a: 예산 4K에서 acceptance-오버헤드 균형이 최적(그 이상은 drafting 지연만 증가). Fig. 6b: chunk가 너무 작으면 개별 토큰에 과적합, 너무 크면 고득점 토큰이 저득점에 희석 → 중간이 최적. Fig. 6c: Sequoia 같은 tree 기반 speculation과 결합하면 이론 생성 토큰 수가 추가 상승 — TriForce는 그들과 직교(orthogonal)함을 어필.
§6 논문 명시 결론: attention sparsity와 contextual locality라는 두 관찰로부터, KV cache와 model weights라는 이중 병목을 계층적 speculation으로 완화했다. A100에서 최대 2.31×, 2×RTX4090 offloading에서 7.78×(0.108s/token)를 달성했고, 이는 장문맥 모델 serving의 실용화 가능성을 보여준다. 별도의 future work 절은 없으며, tree-based speculation과의 결합(Fig. 6c)이 사실상의 확장 방향으로 제시된다.
| Problem | 128K 문맥에서 토큰 1개 생성마다 78GB KV cache 전체 로드 → memory-bound로 추론이 느림. 압축하면 품질 손실. |
|---|---|
| Idea | 훈련 없이, target 자신 + 검색된 3% cache를 중간 draft로 세우고, 그 밑에 68M 초소형 draft를 한 단 더 — 병목(weights/KV) 하나당 draft 하나. 최종 검증은 full cache라 무손실. |
| Cost | full KV cache는 여전히 어딘가(GPU/CPU) 보관 필수. retrieval 계산·캐시 재구축 오버헤드. batch 커지면 이득 감소. |
| 전제조건 | attention sparsity(3%로 96.8% 복원)와 contextual locality(고른 캐시가 수백 step 유효)가 해당 워크로드에서 성립해야 함. |
| 가장 강한 근거 | Table 1의 needle retrieval: eviction 0.05 vs retrieval 0.99 — 그리고 Table 3의 offloading 7.78×. |
구현 디테일 Appendix A — 캐시 예산이 고정이라 CUDA graphs로 커널 런칭 오버헤드를 제거할 수 있었고(speculation처럼 작은 실행이 많은 구조에서 중요), FlashAttention 사용. 특히 §3에서는 설명 편의상 첫 2개 layer를 full cache로 뒀지만, 실제 시스템은 모든 layer를 sparse로 유지한다 — acceptance가 약간 떨어지는 대신 drafting 비용이 상수로 고정되는 쪽을 택했다.
더 긴 입력 Appendix B.1 — L40 1장 + offloading으로 LWM-Text-256K에서 11.81×, 512K에서 12.10×. Fig. 5의 "길수록 유리" 주장을 실측으로 연장.
더 긴 출력 Appendix B.2 — 출력 256~2048 토큰에서 speedup이 2.28~2.34×로 안정. 캐시가 주기적으로 재구축되며 문맥 진화를 따라가기 때문.
γ 최적값 Appendix B.3 — γ₁=2, γ₂=6이 최적. 68M draft와 7B+retrieval 사이의 격차 때문에 1단계 speculation의 acceptance가 낮아 γ₁을 길게 못 가져간다는 고백이 여기 숨어 있다.
| # | 한계 | 출처 |
|---|---|---|
| 1 | 메모리를 줄여주지 않는다 — full cache 보관 전제. 78GB를 감당할 저장 공간(HBM 또는 CPU RAM)은 필요 | §4.1 설계 전제에서 도출 [논문에 없음: 명시적 한계 절 없음] |
| 2 | 1단계(68M) speculation의 acceptance가 낮음 → γ₁=2로 제한 | Appendix B.3 |
| 3 | batch 증가 시 speedup 감소 (10에서 1.61×) | Table 4 |
| 4 | 전 layer sparse 유지로 인한 acceptance 소폭 손해 | Appendix A |
| 5 | 지역성/희소성이 약한 워크로드에서의 거동은 미평가 (평가는 PG-19·NarrativeQA·needle 중심) | [논문에 없음: 직접 정리] |
TriForce의 모든 이득은 하나의 가정 위에 서 있다: "다음 수백 토큰이 참조할 옛 문맥 ≈ 방금 참조한 옛 문맥"(contextual locality). 이 가정이 깨지는 순간, 계층 전체가 연쇄적으로 비효율이 된다.
| step | 이벤트 | acceptance | n | 비고 |
|---|---|---|---|---|
| 1~2 | draft ×2 → 1차 검증: 첫 토큰부터 거절→교정 | 0.3 | 1 | 14ms에 1토큰 |
| 3~4 | draft ×2 → 1차 검증: 또 즉시 거절 | 0.3 | 2 | 14ms에 1토큰 |
| 5~12 | 같은 패턴 4회 반복해야 n=6 도달 | 0.3 | 6 | 1차 검증만 6회=84ms |
| 13 | full 검증(56ms): 후보 6개 중 3개에서 거절 → 3토큰만 확정 | 0.5 | — | 이후 수락률 이동평균 임계 미달 → rebuild 발동(추가 비용) |
합계 ≈ 145ms + rebuild 비용에 3토큰 → ~50ms+/token으로 vanilla(56ms)와 사실상 동급. 정상 케이스(12.6ms)와 4배 차이. 수락률이 시스템의 손익분기점을 직접 결정함을 보여준다.
① 대규모 serving 층위 — 평가는 batch ≤ 10, 그마저 speedup이 단조 감소(Table 4). vLLM류 continuous batching과의 결합, 요청 간 캐시 관리 등은 미답. ② 메모리 층위 — "무손실"의 대가로 78GB full cache 보관이 전제라, 애초에 그 메모리가 없는 환경(순수 메모리 부족 문제)은 이 논문의 해법 범위 밖이며 그때 필요한 것이 오히려 ZeRO-Inference류다. ③ 워크로드 층위 — needle retrieval은 "retrieval cache에 유리한" 과제이기도 하다. 지역성과 희소성이 동시에 약한 과제(예: 문서 전체를 골고루 훑는 요약)의 acceptance는 보고되지 않았다. ④ 비교 공정성 — ZeRO-Inference 대비 4.86×는 상대 시스템이 CPU-attention 구현이라는 조건이 붙는다(각주 1).
| 상황 | TriForce 적합성 | 이유 |
|---|---|---|
| 장문맥(32K~512K) · 소규모 batch · 소비자 GPU + offloading | ◎ 최적 | full-cache 실행이 비쌀수록 이득 극대화 (7.78~12.1×) |
| 장문맥 · A100급 on-chip · latency 민감 서비스 | ○ 유효 | 2.0~2.3×, 온도 강건. 훈련 기반 기법과 결합 여지 |
| 짧은 문맥(<8K) | △ 부적합 | KV 병목 자체가 없어 계층이 오버헤드 Fig. 2b |
| 대규모 batch serving | △ 미검증 | batch 10에서 이미 1.6×로 감소 Table 4 |
| GPU+CPU 합쳐도 full cache를 못 담는 환경 | ✕ 범위 밖 | full cache 보관이 설계 전제 — 이 경우는 eviction/quantization/ZeRO의 영역 |
| 참조 패턴이 step마다 급변하는 워크로드 | ✕ 위험 | 지역성 가정 붕괴 → rebuild 빈발 (위 사고실험) |