한 줄 요약 — SOTA 모델(예: Megatron-Turing-530B)은 fp16 추론만 해도 A100-40GB가 최소 40장 필요해서, 학생·연구자·소기업은 공개된 모델조차 돌려볼 수 없다. 4년도 안 되어 SOTA가 0.3B(BERT-Large) → 530B로 커지면서, 모델 크기의 성장이 곧 접근성의 붕괴가 됐다 §Introduction.
핵심 관찰: 정작 보통 컴퓨터에도 CPU DRAM + NVMe SSD를 합치면 수 TB의 메모리가 이미 있다. 비싼 건 GPU HBM뿐이다. 그렇다면 모델을 꼭 GPU에 담아야 하나? §Introduction
"hosting no (zero) weights in GPU" — §Introduction (기술명 ZeRO의 유래)
| 접근법 | 무엇을 해결했나 | 대가는 무엇인가 |
|---|---|---|
| 전부 GPU에 적재 DeepSpeed-Inference, Accelerate, MII §When to use | 가장 빠른 latency. 다중 GPU로 분산(tensor parallel) | 530B급이면 GPU 수십 장이 필요 — 비용이 대부분의 사용자를 배제 |
| Partial offload (들어가는 만큼만 GPU에 고정, 나머지는 필요할 때 가져오기) §Alternative approach | GPU에 있는 부분은 전송 생략 | ① 175B급에선 GPU에 넣을 수 있는 비율이 미미해 절감 효과가 무의미. ② 남는 GPU 메모리가 없어 batch를 못 키움 → throughput 하락 (아래 Table 2에서 실증) |
| ZeRO-Inference (본 블로그) full offload + layer streaming | weights 전체를 CPU/NVMe에 두고 layer 단위 스트리밍 → GPU 메모리는 전부 batch에 투자. V100 1장으로 NVMe 기준 15T 파라미터까지 | 토큰당 latency는 태생적으로 느림 — 대량 batch·throughput 워크로드 전용 |
컴퓨터 메모리는 "빠를수록 작고 비싼" 피라미드다. GPU HBM(수십 GB, 초당 ~TB급으로 GPU 코어와 직결) > CPU DRAM(수백 GB~TB) > NVMe SSD(수십 TB). 그런데 CPU/NVMe에서 GPU로 데이터를 옮기는 통로가 PCIe인데, 이게 초당 겨우 수십 GB로 HBM보다 수십 배 느린 병목이다. ZeRO-Inference의 모든 설계는 결국 "느린 PCIe 전송을 어떻게 숨기느냐"의 싸움이다.
모델 전체(수백 GB)를 CPU DRAM 또는 NVMe에 고정(pin)해 두고, 추론 시 layer 1개씩만 PCIe로 GPU에 가져와 계산한다. 계산이 끝나면 그 layer의 weights는 즉시 버리고(메모리 해제) 다음 layer를 받는다. layer의 출력(activation)만 GPU에 남아 다음 layer의 입력이 된다. GPT3-175B는 96 layer이므로, GPU에는 항상 전체의 ~1%만 존재 — 530B 모델의 GPU 메모리 요구가 1TB → 10GB로 두 자릿수 감소한다.
모델을 안 올렸으니 GPU 메모리 대부분이 빈다. 이걸 긴 시퀀스·큰 batch의 입력 토큰으로 채운다. layer 1개의 계산량은 처리하는 토큰 수에 비례해 커지므로(예: GPT3-175B layer 1개, batch 1 · 2048 토큰에 약 7 TFlops), 토큰을 많이 실을수록 계산 시간이 길어져 전송 시간을 완전히 덮는다. 즉 이 시스템에서 큰 batch는 사치가 아니라 PCIe를 숨기기 위한 필수 연료다.
GPT3-175B → layer당 weights ≈ 175B/96 ≈ 1.8B 파라미터 ≈ fp16 3.6GB. PCIe 3.0 x16 ≈ 16GB/s 가정 → layer 전송 ≈ 0.23초. V100 fp16 실효 ~60 TFLOPS 가정:
| batch (각 2048 토큰) | layer당 계산량 | 계산 시간 | 전송 시간 | 지배 요인 | layer당 실효 시간 |
|---|---|---|---|---|---|
| 1 | 7 TFlops | 0.12s | 0.23s | 전송 (PCIe 병목) | 0.23s — GPU가 절반 놀고 있음 |
| 2 | 14 TFlops | 0.23s | 0.23s | 균형점 | 0.23s |
| 8 | 56 TFlops | 0.93s | 0.23s | 계산 — 전송 완전히 숨겨짐 | 0.93s에 8개 시퀀스 처리 → 시퀀스당 비용 ½로 |
batch 1과 batch 8의 총 소요는 4배 차이지만 처리량은 8배 차이 — batch를 키울수록 "전송비는 고정, 일은 늘어나는" 구조라 throughput이 계속 좋아진다. 반대로 batch를 못 키우면(붕괴 케이스, s₈) GPU는 PCIe를 기다리며 논다.
(a) Prefetching — 위 timeline처럼 다음 layer를 미리 당겨온다. 특이점: CPU offload에서는 효과가 없었고(짧은 생성 시퀀스라 계산 시간이 너무 짧아 숨길 틈이 없음), NVMe offload에서만 1.13~1.21× 개선 — NVMe→CPU 전송과 CPU→GPU 전송이 2단 파이프라인을 이루기 때문 §Prefetching layer weights.
(b) 다중 GPU 병렬 fetch — GPU가 여러 장이면 각 GPU가 layer의 서로 다른 조각을 자기 PCIe로 동시에 받고(1단계), 그 뒤 GPU끼리 NVLink(PCIe보다 수십 배 빠름)로 all-gather 해 전체 layer를 조립한다(2단계). PCIe 대역폭이 GPU 수만큼 합산되는 효과 → GPU당 throughput이 오히려 증가하는 super-linear scaling §Parallelizing layer fetching.
DeepSpeed 설정에서 ZeRO stage 3 + 파라미터 offload 대상만 지정하면 Hugging Face generate 파이프라인에 그대로 얹힌다:
"zero_optimization": {
"stage": 3,
"offload_param": { "device": "cpu" } // 또는
"offload_param": { "device": "nvme", "nvme_path": "/local_nvme" }
}
※ 블로그 원문 figure는 이미지 형태의 표/차트이며, 본 문서에서는 본문 수치를 기반으로 s₅에 재구성했다.
| Figure | 설득하려는 주장 | 근거로 쓰는 것 |
|---|---|---|
| Fig. 1 (Model Scaling) | V100 1장의 한계는 GPU가 아니라 "모델을 어디에 두느냐"가 결정한다 | HBM 기준 최대 <16B vs NVMe 기준 15T — 약 1000배 차이 |
| Table 1 (Models) | 실험 대상이 실제 공개 초거대 모델임 | OPT-30B / OPT-175B / BLOOM-176B, 전부 V100 32GB 초과 |
| Table 2 (Full vs Partial) | 어중간하게 GPU에 넣지 말고 전부 offload하라 — 이 블로그의 대표 주장 | OPT-30B: full offload가 partial 대비 CPU 1.3×·NVMe 2.4× 빠름 (43 / 30 tok/s) |
| Table 3 (Prefetching) | prefetch는 NVMe에서만 유효 | NVMe 1.13~1.21× vs CPU 개선 없음 |
| Table 4 (Multi-GPU) | GPU를 늘리면 GPU당 성능도 올라간다 (super-linear) | 2·4 GPU에서 per-GPU throughput 증가 — PCIe 합산 효과 |
| Table 5~7 (출력 길이) | 큰 batch가 성능의 생명줄임을 역으로 증명 | 출력 토큰 10→50에서 KV cache 증가로 batch가 ½로 줄자 throughput도 비례 하락 |
| 전략 | CPU offload | NVMe offload |
|---|---|---|
| Full offload (전부 CPU/NVMe, GPU는 batch 전용) | 43 tokens/s | 30 tokens/s |
| Partial offload (10~12B를 GPU에 고정) | full 대비 1.3× 이상 느림 | full 대비 2.4× 이상 느림 |
| 최적화 | CPU offload | NVMe offload |
|---|---|---|
| Prefetching | 개선 없음 (계산 시간이 짧아 숨길 여지 없음) | OPT-30B 1.13× · OPT-175B 1.14× · BLOOM-176B 1.21× |
| 2~4 GPU 병렬 fetch | GPU당 throughput 자체가 상승 → super-linear scaling (prefetch 켠 상태 측정) | |
| 출력 토큰 수 | batch 크기 | throughput |
|---|---|---|
| 10 (기준) | 기준 | 기준 |
| 50 (5×) | ½로 감소 (KV cache가 GPU 메모리를 잠식) | batch 감소에 비례해 하락 |
§Conclusion 블로그 명시 결론: 모델 초대형화가 AI 접근성을 위협하는 상황에서, ZeRO-Inference는 모델을 CPU/NVMe에 두고 layer를 스트리밍함으로써 GPU 1장 수준의 예산으로 SOTA 모델 추론을 가능하게 하며, 공개 모델 배포(BigScience, Meta 등)와 함께 AI 민주화를 완성하는 조각이 되고자 한다. 별도의 future work 절은 없고, 다중 GPU 결과에서 "미래 PCIe 세대의 대역폭 향상이 성능을 더 끌어올릴 것"이라는 전망만 덧붙인다 §Parallelizing.
| Problem | SOTA 모델 추론에 GPU 수십 장 필요 → 대다수 사용자 배제. |
|---|---|
| Idea | weights를 GPU에 0개 두고 CPU/NVMe에서 layer 단위 스트리밍. 비운 GPU 메모리는 전부 대량 batch에 투자해 계산 시간으로 전송 시간을 덮는다. |
| Cost | 토큰당 latency 태생적 열세. 큰 batch가 확보되는 워크로드에서만 효율적. |
| 전제조건 | throughput 지향 + 대량 batch/긴 시퀀스 + CPU/NVMe 용량 충분. |
| 가장 강한 근거 | full offload가 partial 대비 1.3~2.4× 빠름(Table 2) — "batch가 왕"이라는 설계 철학의 실증. |
각주 1 — baseline이 16B에서 끊기는 이유: 16B 모델(fp16 32GB)은 V100-32GB에 "들어가긴" 하지만 입력·중간 결과를 둘 공간이 없어 실질 추론 불가.
각주 2 — partial offload에서 GPU 고정량을 더 늘리면 작은 batch에서도 OOM. "GPU에 더 넣기"의 한계를 실험적으로 확인.
각주 3 — 다중 GPU 실험은 독립 PCIe 링크를 가진 GPU만 골라 수행 — PCIe를 공유하는 슬롯 구성이면 병렬 fetch 이득이 줄어든다는 뜻이다.
실험 조건의 소박함 §Token Generation Performance — 성능 수치는 입력 4토큰 / 출력 10토큰, greedy search, HF pipeline + KV cache 기준. 오늘날의 장문맥·장출력 워크로드와는 거리가 있다.
| # | 한계 | 근거 |
|---|---|---|
| 1 | latency 민감 응용에는 부적합 — 자체적으로 대안(DeepSpeed-Inference/MII) 사용을 권고 | §When to use |
| 2 | 출력이 길어지면 KV cache가 batch를 잠식해 throughput 하락 | §Impact of output length |
| 3 | 성능이 PCIe 세대·슬롯 구성에 강하게 종속 | §Parallelizing, 각주 3 |
| 4 | weights offload 중심 설계 — KV cache offload 시 attention을 CPU에서 계산하는 등 긴 문맥 대응은 미성숙 | TriForce 논문 각주 1의 지적 [블로그에 없음] |
ZeRO-Inference의 모든 효율은 "계산 시간 ≥ 전송 시간"이라는 한 가지 부등식 위에 서 있고, 그 부등식을 성립시키는 유일한 수단이 대량 batch다. batch를 못 키우는 상황 — 대화형 서비스(batch 1), 긴 출력으로 KV cache가 커진 상황 — 에서는 부등식이 깨지고 GPU는 PCIe를 기다리는 기계가 된다.
① 알고리즘 층위 — ZeRO-Inference는 "무엇을 어디에 두고 어떻게 나르나"만 다루고, 비싼 실행의 횟수 자체를 줄이는 발상(speculative decoding)은 범위 밖이다. 2년 뒤 TriForce가 정확히 이 직교 축을 공략해 같은 offloading 환경에서 4.86×를 얻는다. ② KV cache 층위 — 2022년 시점이라 KV cache는 "batch를 줄이는 성가신 존재"로만 등장하고, KV cache 자체의 offload·압축·선택적 로드는 다루지 않는다. ③ 정밀도 층위 — fp16 고정. 이후 표준이 된 4/8bit quantization과 결합하면 전송량이 2~4배 줄어 손익분기 batch가 낮아질 텐데, 미평가다 [블로그에 없음: 해석].
| 상황 | 적합성 | 이유 |
|---|---|---|
| 오프라인 대량 배치 처리 (요약·라벨링·평가) + GPU 예산 극소 | ◎ 최적 | 큰 batch 확보 → 전송 완전 은닉, 1000배 큰 모델 접근 |
| NVMe만 큰 워크스테이션 | ○ 유효 | prefetch 1.13~1.21× — 단 CPU 경유 2단 전송 감수 |
| GPU 2~4장 (독립 PCIe 슬롯) | ○ 유효 | 병렬 fetch로 super-linear — 슬롯 공유 구성이면 감소 |
| 대화형 챗봇, latency SLA 있는 서비스 | ✕ 부적합 | 블로그 스스로 DeepSpeed-Inference/MII 권고 §When to use |
| 장문맥(수만 토큰 이상) 생성 | ✕ 취약 | KV cache가 batch를 잠식 → 효율의 전제 붕괴. 이 지점의 후속 해법이 TriForce류 |