RAM이 LLM과 연결되는 방식은 어느 정도 이해했다고 생각했다. 모델이 크면 메모리가 많이 필요하고, 메모리가 부족하면 실행할 수 없다는 설명까지는 자연스러웠다.
그런데 HBM이라는 단어가 나오자 다시 애매해졌다.
처음에는 HBM을 RAM보다 한 단계 위에 있는 별도의 장치처럼 생각했다. 또 이름에 High Bandwidth가 들어가니 단일 메모리 접근도 무조건 훨씬 빠를 것이라고 받아들였다. 둘 다 정확하지 않았다.
이번에는 HBM을 제품 이름으로 외우지 않고 다음 질문을 순서대로 따라갔다.
- HBM은 RAM 분류 안에서 어디에 있는가
- 여러 DRAM die를 왜 쌓는가
- 대역폭은 실제로 어떤 식으로 커지는가
- LLM은 HBM에 무엇을 저장하는가
- 학습과 prefill과 decode는 왜 서로 다른 병목을 갖는가
- FlashAttention과 PagedAttention은 HBM의 어떤 문제를 해결하는가
- 여러 GPU를 연결하면 HBM 대역폭을 단순히 더할 수 있는가
한 줄 요약
HBM은 LLM이 생각하는 장치가 아니다. LLM 계산에 필요한 가중치와 상태를 GPU에 매우 넓은 통로로 공급하는 DRAM 계열의 작업 메모리다.
LLM 시스템의 자원을 네 문장으로 나누면 이해하기 쉽다.
- GPU 연산 성능은 행렬곱을 얼마나 빨리 계산하는지 결정한다.
- HBM 용량은 가중치와 KV cache와 작업 공간을 얼마나 담는지 결정한다.
- HBM 대역폭은 계산할 데이터를 GPU 코어에 얼마나 빨리 공급하는지 결정한다.
- GPU interconnect는 여러 GPU에 나뉜 tensor를 얼마나 빨리 교환하는지 결정한다.
어느 하나만 높다고 전체 LLM이 같은 비율로 빨라지지는 않는다.
먼저 바로잡은 분류
HBM은 RAM과 별개의 저장장치가 아니다. RAM이라는 큰 분류 안에 있는 DRAM 계열 메모리다.
RAM
├─ SRAM
│ ├─ CPU와 GPU cache
│ ├─ GPU shared memory
│ └─ 작은 on-chip 저장 공간
│
└─ DRAM
├─ DDR
├─ LPDDR
├─ GDDR
└─ HBM
따라서 RAM과 HBM을 서로 반대되는 개념처럼 비교하면 안 된다. 실제 비교는 보통 DDR RAM과 HBM RAM, 또는 GDDR VRAM과 HBM VRAM 사이에서 이뤄진다.
HBM도 DRAM이므로 다음 성질을 그대로 가진다.
- 전원이 끊기면 데이터가 사라진다.
- 데이터를 유지하려면 refresh가 필요하다.
- LLM의 지식을 영구 보관하는 저장장치가 아니다.
- 모델 checkpoint는 SSD 같은 비휘발성 저장장치에 있고 실행할 때 HBM으로 적재한다.
HBM을 장착한 GPU에서 80GB HBM이라는 표시는 일반적으로 80GB GPU device memory, 즉 80GB VRAM을 의미한다.
DDR과 LPDDR과 GDDR과 HBM
네 메모리는 같은 DRAM 계열이지만 최적화 목표와 물리 배치가 다르다.
| 구분 | 대표 사용처 | 물리 배치 | 우선하는 목표 |
|---|---|---|---|
| DDR | 서버와 PC CPU | 메인보드 DIMM 슬롯 | 큰 용량과 범용성 및 교체 가능성 |
| LPDDR | 모바일과 노트북 및 통합 SoC | 보드 또는 package 가까이 | 낮은 전력과 통합성 |
| GDDR | 소비자와 그래픽 GPU | GPU 주변 PCB | 높은 핀당 속도와 합리적인 비용 |
| HBM | 데이터센터 AI와 HPC 가속기 | 가속기와 같은 package | 매우 높은 총대역폭과 비트당 효율 |
HBM이 모든 면에서 우월한 것은 아니다.
CPU 서버에서 수 TB의 확장 가능한 메모리가 필요하면 DDR DIMM이 자연스럽다. 소비자 GPU에서는 HBM의 고급 packaging 비용보다 GDDR의 비용과 제조 편의성이 중요할 수 있다. HBM은 높은 비용을 감수하더라도 GPU 코어에 수 TB/s급 데이터를 공급해야 하는 영역에 적합하다.
HBM stack 안에서는 무슨 일이 일어나는가
HBM의 물리 구조를 이해하는 핵심은 적층, TSV, base die, interposer 네 가지였다.[1][2]
DRAM die를 수직으로 쌓는다
HBM은 여러 개의 얇은 DRAM die를 수직으로 적층한다.
┌─────────────────┐
│ DRAM Die 12 │
├─────────────────┤
│ ... │
├─────────────────┤
│ DRAM Die 2 │
├─────────────────┤
│ DRAM Die 1 │
├─────────────────┤
│ Base Interface │
└─────────────────┘
제품 설명의 4-High, 8-High, 12-High는 적층된 DRAM die 수를 나타낸다.
여기서 처음 했던 오해가 하나 있었다. 8단을 12단으로 늘리면 대역폭도 1.5배가 될 것이라고 생각했다. 외부 인터페이스가 같다면 적층 수 증가는 기본적으로 용량 증가다. 대역폭은 별도의 조건으로 결정된다.
- 핀당 전송률
- 외부 데이터 인터페이스 폭
- 독립 channel과 pseudo-channel 수
- 가속기 package에 연결한 HBM stack 수
TSV가 위아래 die를 연결한다
TSV는 Through-Silicon Via의 약자다. 실리콘을 수직으로 관통하는 미세 전극으로 적층된 die를 연결한다.[1]
DRAM
│ TSV
DRAM
│ TSV
DRAM
│ TSV
Base Die
칩 가장자리와 메인보드 배선을 길게 우회하는 대신 실리콘을 수직으로 통과한다. 이 방식은 짧은 거리 안에 많은 연결을 만들 수 있게 한다.
그 결과 다음 이점이 생긴다.
- 매우 많은 데이터 신호선을 package 안에 배치할 수 있다.
- GPU와 메모리 사이의 배선이 짧아진다.
- 여러 channel과 bank를 동시에 사용하기 쉬워진다.
- 짧고 넓은 링크를 사용해 비트당 전송 에너지를 낮추기 유리하다.
Base die가 외부 연결을 담당한다
stack 아래에는 GPU 쪽 인터페이스를 담당하는 base 또는 interface 영역이 있다. 세대와 제조사 구현에 따라 PHY와 제어 기능의 배치는 달라진다.
HBM4로 갈수록 base die에 더 많은 logic 기능을 넣는 방향이 뚜렷해졌다. 따라서 HBM을 단순히 DRAM die를 쌓은 탑으로만 보면 부족하다. 아래쪽 인터페이스가 GPU와 어떤 계약으로 데이터를 주고받는지도 중요하다.[1][11]
GPU와 HBM은 interposer 위에 나란히 놓인다
일반적인 HBM 가속기에서 GPU와 HBM은 하나의 거대한 silicon die로 합쳐진 것이 아니다. 같은 package 안에서 GPU die와 여러 HBM stack이 나란히 놓이고, 아래 silicon interposer가 많은 신호선을 연결한다.[2]
┌────────┐ ┌───────────────────┐ ┌────────┐
│ HBM 0 │ │ │ │ HBM 2 │
├────────┤ │ GPU Accelerator │ ├────────┤
│ HBM 1 │ │ │ │ HBM 3 │
└────────┘ └───────────────────┘ └────────┘
Silicon Interposer
──────────────── Package Substrate ───────────────
HBM stack 내부는 die를 위로 쌓았으므로 3D 구조다. GPU와 HBM stack은 interposer 위에 나란히 있으므로 package 전체는 흔히 2.5D packaging이라고 부른다.
HBM은 왜 대역폭이 높은가
메모리 대역폭의 첫 번째 근사는 단순하다.
Bandwidth
= per-pin data rate x number of data pins / 8
8로 나누는 이유는 bit를 byte로 바꾸기 위해서다.
DDR 예시
DDR5-6400의 64bit 데이터 경로 하나를 단순 계산하면 다음과 같다.
6.4 Gbps x 64 / 8
= 51.2 GB/s
CPU는 여러 memory channel을 사용해 총대역폭을 늘릴 수 있다. 그래도 DIMM socket과 메인보드 배선과 package pin 수의 제약을 받는다.
HBM 예시
HBM 구성 예시에서는 한 stack의 1,024bit 데이터 경로를 여러 channel과 pseudo-channel로 나눈다.[3]
1,024bit 인터페이스가 핀당 6.4Gbps로 동작한다고 가정했다.
6.4 x 1024 / 8
= 819.2 GB/s per stack
같은 stack 네 개를 독립적으로 연결한다고 가정했다.
819.2 x 4
= 3276.8 GB/s
≈ 3.28 TB/s
NVIDIA는 H100 SXM 계열의 HBM3 메모리 대역폭을 3TB/s 이상으로 명시한다.[4]
DDR과 HBM의 차이를 도로로 비유하면 다음과 같다.
- DDR은 상대적으로 적은 차선을 빠르게 운행하는 쪽에 가깝다.
- HBM은 GPU 바로 옆에 매우 많은 차선을 놓는 쪽에 가깝다.
HBM의 핵심은 작은 메모리 요청 하나가 마법처럼 빨라지는 것이 아니다. 같은 시간에 운반할 수 있는 전체 데이터량이 매우 커지는 것이다.
HBM 세대가 바꾸는 것
HBM 세대가 발전해도 적층 DRAM, TSV, 넓은 가속기 인터페이스라는 중심 원리는 유지된다.
세대 발전은 주로 다음 방향으로 진행된다.
- 핀당 전송률 증가
- channel과 병렬 처리 구조 개선
- stack당 DRAM 용량 증가
- 더 높은 적층 수 지원
- base die의 logic 기능 강화
- 전력 전달과 신호 무결성 개선
- 열 방출 개선
- 외부 데이터 I/O 폭 확대
HBM2E와 HBM3E의 E 표기는 기본 세대보다 속도와 용량을 확장한 제품군을 가리키는 데 사용된다. 세부 수치는 JEDEC 표준과 제조사 제품 구현을 나눠 확인해야 한다.
2026년 Samsung HBM4 제품 자료는 2,048개의 외부 I/O와 12단 36GB 구성, 최대 13Gbps 핀 속도, stack당 최대 3.3TB/s를 제시한다.[11] 이 값은 해당 제조사의 제품 사양이지 모든 HBM4 구현의 고정값은 아니다.
세대 이름만으로 LLM 성능을 결정할 수 없는 이유도 여기에 있다. 같은 HBM 세대라도 stack 수, 활성 memory controller, 총용량, 실제 clock과 software가 다르면 결과가 달라진다.
대역폭과 지연시간과 용량
이 세 지표를 섞으면 HBM과 LLM을 거의 항상 잘못 설명하게 된다.
대역폭
1초 동안 전체적으로 이동할 수 있는 데이터량이다.
예시
3 TB/s
지연시간
메모리 요청을 보낸 뒤 첫 데이터가 도착하기까지의 시간이다.
HBM의 이름은 High Bandwidth Memory다. Ultra Low Latency Memory가 아니다. 높은 TB/s를 보고 개별 random read의 지연시간도 같은 비율로 줄었다고 판단하면 안 된다.
HBM은 많은 channel과 bank에 다수 요청을 동시에 흘려 aggregate bandwidth를 만든다. 따라서 다음 접근 특성이 중요하다.[5]
- 연속적이고 병합 가능한 global memory 접근
- 많은 동시 요청
- channel과 bank 병렬성
- bank conflict 최소화
- cache와 shared memory를 사용한 재사용
- 불필요한 HBM 왕복 제거
용량
동시에 상주시킬 수 있는 데이터량이다.
LLM에서는 질문을 세 개로 분리해야 한다.
- 모델과 KV cache가 들어가는가
- 들어간 데이터를 얼마나 빨리 읽을 수 있는가
- 각 접근의 첫 응답은 얼마나 오래 걸리는가
용량이 충분해도 대역폭이 낮으면 decode가 느릴 수 있다. 대역폭이 높아도 working set이 HBM을 넘어서 CPU RAM을 계속 왕복하면 느릴 수 있다.
GPU 메모리 계층에서 HBM의 위치
LLM 데이터는 다음 계층을 거친다.
크고 멀다
SSD or Object Storage
↓
CPU DDR RAM
↓ PCIe or package fabric
GPU HBM
↓
GPU L2 Cache
↓
L1 and Shared Memory
↓
Registers
↓
Tensor Core and CUDA Core
작고 가깝다
모델 실행 과정을 단순화하면 다음과 같다.
- SSD에 모델 checkpoint를 보관한다.
- 런타임이 checkpoint를 CPU RAM에 읽거나 memory-map한다.
- GPU별로 weight를 복사하고 분할하거나 양자화해 HBM에 올린다.
- GPU kernel이 HBM의 큰 tensor를 tile로 나눠 L2와 on-chip SRAM으로 가져온다.
- register operand를 Tensor Core 또는 일반 arithmetic lane이 계산한다.
- 필요한 결과를 cache 또는 HBM에 기록한다.
Unified Memory에서는 CPU와 GPU가 하나의 논리 주소 공간을 공유할 수 있다. 그렇다고 모든 물리 메모리가 같은 속도가 되는 것은 아니다. page가 CPU RAM과 HBM 중 어디에 상주하는지, fault와 migration이 발생하는지가 여전히 중요하다.[6]
LLM 추론이 HBM에 저장하는 것
모델 weight만 세면 실제 HBM 요구량을 과소평가한다.
추론 중 HBM에는 다음 데이터가 들어간다.
- 모델 weight
- 과거 token의 KV cache
- 현재 layer와 token의 activation
- attention과 GEMM workspace
- logits와 sampling buffer
- quantization scale과 zero-point와 packing metadata
- GPU runtime context와 allocator memory pool
- multi-GPU collective communication buffer
추론 peak memory를 다음처럼 생각할 수 있다.
Inference peak memory
≈ Weights
+ KV cache
+ Activations and kernel workspace
+ Runtime reservation and fragmentation
+ Temporary loading copies
모델 파일이 70GB이고 GPU HBM이 80GB라고 해서 바로 실행 가능한 것은 아니다. 파일 크기와 runtime resident tensor의 크기가 다를 수 있고, KV cache와 workspace가 들어갈 여유가 필요하다.
파라미터 수로 weight 크기 계산하기
이상적인 weight 크기는 다음 식으로 계산한다.
Weight bytes
= parameter count x bytes per parameter
70B 모델을 예로 들었다.
| 정밀도 | 파라미터당 크기 | 70B weight의 이상적 크기 |
|---|---|---|
| FP32 | 4 byte | 약 280GB |
| BF16 또는 FP16 | 2 byte | 약 140GB |
| INT8 | 1 byte | 약 70GB |
| INT4 | 0.5 byte | 약 35GB |
실제 quantized model은 scale, zero-point, group metadata, tensor padding과 file format 때문에 표보다 커질 수 있다.
HBM이 부족하면 선택지는 다음과 같다.
- 여러 GPU에 weight를 분할한다.
- INT8이나 INT4로 양자화한다.
- 일부 layer를 CPU RAM으로 offload한다.
- KV cache precision이나 context를 줄인다.
- batch와 동시 sequence 수를 줄인다.
모든 선택에는 비용이 있다. 양자화는 품질과 kernel 지원, 분산은 통신, offload는 host-device 전송 비용을 만든다.
HBM capacity cliff
모델과 KV cache와 workspace가 HBM에 들어갈 때는 주요 kernel이 HBM 대역폭으로 데이터를 공급받는다.
그런데 HBM을 조금 초과해 매 layer나 page를 CPU RAM에서 가져오기 시작하면 PCIe나 별도 fabric 전송이 token 생성의 critical path에 들어온다.
Working set fits in HBM
→ HBM path
→ fast
Working set spills to host RAM
→ page migration or layer transfer
→ host-device link enters critical path
→ performance can drop sharply
용량을 1GB 초과했다고 성능도 몇 퍼센트만 줄어드는 것이 아니다. 실행 경로 자체가 달라지므로 불연속적으로 느려질 수 있다. 이를 여기서는 capacity cliff라고 부른다.
CPU offload는 큰 모델을 실행 가능하게 만드는 capacity 기법이다. HBM과 같은 속도를 제공하는 기법은 아니다.
Roofline으로 보는 LLM decode
Transformer의 선형 계층을 단순화하면 다음과 같다.
y = W x
W가 m x n 행렬이고 weight 원소 하나가 s byte라고 가정했다.
Operations ≈ 2mn FLOPs
Weight traffic ≈ mn x s bytes
Arithmetic intensity
≈ 2mn / mn x s
≈ 2 / s FLOPs per byte
BF16과 FP16의 s는 2이므로 batch 1 matrix-vector 연산은 대략 1 FLOP/byte다.
Roofline 모델은 달성 가능한 성능의 상한을 다음처럼 설명한다.[7]
Attainable performance
≤ min
Peak compute
Memory bandwidth x arithmetic intensity
가상의 가속기를 두었다.
Peak compute = 1 PFLOP/s
HBM bandwidth = 3 TB/s
Arithmetic intensity = 1 FLOP/byte
메모리가 공급할 수 있는 계산 속도는 다음 수준이다.
3 TB/s x 1 FLOP/byte
= 3 TFLOP/s
연산기는 1PFLOP/s를 지원해도 데이터가 도착하지 않으면 그 능력을 사용하지 못한다. 이것이 memory wall이다.
batch 1 decode는 token 하나를 위해 거대한 weight를 읽고 각 weight를 거의 한 번만 사용하는 matrix-vector 성격이 강하다. 모델 전체가 GPU cache에 들어가지 않으므로 HBM traffic이 계속 발생한다.
HBM 대역폭으로 token 속도 상한 계산하기
작은 batch의 autoregressive decode에서 token 하나를 만들 때 모델 weight 대부분을 한 번 읽는다고 근사했다.
Ideal tokens per second
≤ effective HBM bandwidth / weight bytes read per token
충분한 HBM capacity를 가진 3TB/s급 시스템과 70B 모델을 가정했다.
INT8
Weight size ≈ 70GB
3000 / 70 ≈ 42.9 tokens/s
BF16
Weight size ≈ 140GB
3000 / 140 ≈ 21.4 tokens/s
INT4
Weight size ≈ 35GB
3000 / 35 ≈ 85.7 tokens/s
이 값은 weight traffic만 고려한 이론적 상한이다.
실제 속도는 다음 이유로 더 낮다.
- peak보다 낮은 유효 HBM 대역폭
- KV cache와 activation traffic
- attention과 normalization과 logits 계산
- kernel launch와 scheduling overhead
- dequantization과 scale 처리
- tensor layout과 memory access 효율
- multi-GPU collective communication
- sampling과 CPU 측 처리
양자화가 decode를 빠르게 만들 수 있는 중요한 이유는 HBM에서 읽을 byte를 줄이기 때문이다. 하지만 GPU와 kernel이 해당 format을 효율적으로 처리하지 못하면 이상적인 속도 향상은 나오지 않는다.
Prefill과 Decode를 분리해서 봐야 하는 이유
LLM inference는 같은 모델을 실행해도 두 단계의 성격이 다르다.
Prefill
Prefill은 prompt의 여러 token을 한 번에 처리하고 KV cache를 생성한다.
W x [x1, x2, x3, ... xT]
같은 weight를 여러 token 계산에 재사용한다. matrix-matrix 형태가 되면서 arithmetic intensity가 높아진다. 긴 prompt에서는 대형 GEMM과 attention 계산이 커져 decode보다 compute-bound 성향이 강해질 수 있다.
Prefill은 주로 TTFT에 영향을 준다.
TTFT
= Time To First Token
다만 짧은 prompt, 작은 batch, 비효율적인 kernel에서는 prefill도 memory-bound가 될 수 있다. Prefill은 언제나 compute-bound라는 말도 지나친 일반화다.
Decode
Decode는 이미 생성한 token에 의존해 다음 token을 하나씩 만든다.
token 1 result
↓
token 2 compute
↓
token 2 result
↓
token 3 compute
단일 sequence에서는 미래 token을 정확히 미리 계산할 수 없다. token 사이의 직렬 의존성이 있다.
batch가 작으면 weight를 읽고 token 하나만 계산하므로 데이터 재사용률이 낮다. 이때 HBM bandwidth-bound가 되기 쉽다.
Decode는 주로 TPOT 또는 ITL에 영향을 준다.
TPOT = Time Per Output Token
ITL = Inter Token Latency
Batch가 커지면 바뀌는 것
batch B개의 hidden state를 함께 계산하면 다음 연산이 된다.
Y = W X
같은 weight W를 B개 sequence 계산에 재사용할 수 있다.
Operations ≈ 2mnB
Weight traffic ≈ mn x s
Arithmetic intensity
≈ 2B / s
BF16과 FP16에서는 s가 2이므로 단순 근사는 다음과 같다.
Arithmetic intensity ≈ B FLOPs per byte
| Batch | 단순 근사 연산 밀도 |
|---|---|
| 1 | 약 1 FLOP/byte |
| 16 | 약 16 FLOPs/byte |
| 128 | 약 128 FLOPs/byte |
batch가 커질수록 weight reuse와 GPU utilization이 좋아지고 전체 throughput이 증가한다.
하지만 비용도 커진다.
- sequence별 KV cache가 필요하다.
- HBM capacity 사용량이 증가한다.
- 요청을 모으는 queueing delay가 발생할 수 있다.
- 사용자별 latency와 서버 전체 throughput 사이의 trade-off가 생긴다.
HBM capacity가 큰 가속기는 큰 모델만 실행하는 것이 아니다. 더 많은 sequence를 동시에 수용해 serving throughput을 높이는 데도 유리하다.
KV cache가 HBM을 사용하는 방식
Transformer attention은 새 token을 처리할 때 과거 token의 Key와 Value를 다시 사용한다. 이를 매번 재계산하지 않고 저장한 것이 KV cache다.
일반적인 dense KV cache 크기는 다음과 같이 근사할 수 있다.
KV bytes
= B x T x L x 2 x H_kv x D_head x S
B = batch or concurrent sequences
T = cached tokens per sequence
L = transformer layers
2 = Key and Value
H_kv = KV heads
D_head = dimension per head
S = bytes per element
80 layer GQA 모델 예시
다음 조건을 가정했다.
B = 1
L = 80
H_kv = 8
D_head = 128
S = 2 bytes for BF16
token 하나당 KV cache는 다음과 같다.
80 x 2 x 8 x 128 x 2
= 327680 bytes
≈ 0.328MB per token
128,000 token은 다음과 같다.
327680 x 128000
= 41943040000 bytes
≈ 41.94GB
같은 길이의 sequence가 batch 8이면 단순 합계는 약 335.5GB다.
이 계산에는 block padding, allocator metadata와 추가 workspace가 포함되지 않았다. Prefix sharing, sliding-window attention과 KV quantization을 사용하면 줄어들 수 있다.
MHA와 GQA와 MQA
KV cache 식에서 H_kv가 중요한 이유다.
- MHA는 query head마다 독립적인 K와 V head를 사용한다.
- GQA는 여러 query head가 더 적은 수의 K와 V head를 공유한다.
- MQA는 대부분 또는 전체 query head가 하나의 K와 V head 집합을 공유한다.
H_kv가 줄면 KV cache capacity와 decode 중 읽어야 하는 K와 V traffic도 줄어든다.
GQA와 MQA는 단순한 model architecture 차이가 아니다. HBM capacity와 bandwidth에 직접 영향을 주는 설계 선택이다.
긴 context에서 바뀌는 병목
일반적인 exact autoregressive attention에서 새 query token은 기존 K와 V를 읽어 attention을 계산한다.
context가 길어질수록 다음 현상이 생긴다.
- KV cache 총용량이 token 수에 비례해 증가한다.
- 새 token마다 읽어야 할 기존 K와 V가 증가한다.
- decode attention 시간이 커진다.
- 동시 사용자 수만큼 KV cache가 증가한다.
짧은 context에서는 weight read가 주요 병목일 수 있다. 매우 긴 context에서는 KV cache read가 점점 중요한 bandwidth 병목이 된다.
이때 HBM의 두 조건이 동시에 필요하다.
- 긴 context를 담을 capacity
- 기존 K와 V를 빠르게 읽을 bandwidth
FlashAttention이 해결한 HBM I/O
일반적인 attention 구현은 score matrix와 softmax 중간 결과를 HBM에 기록하고 다음 kernel에서 다시 읽을 수 있다.
HBM → compute → intermediate result → HBM
HBM → next compute → result → HBM
GPU의 on-chip SRAM은 HBM보다 작지만 계산 코어에 가깝다.
FlashAttention은 Q와 K와 V를 작은 tile로 나눠 SRAM에서 처리하고 online softmax로 부분 결과를 결합한다.[8]
핵심은 다음과 같다.
- 표준 exact attention과 같은 결과를 계산한다.
- 계산 순서와 tiling을 바꾼다.
- 큰 attention matrix를 HBM에 완전히 만들지 않는다.
- HBM과 SRAM 사이의 read와 write 횟수를 줄인다.
FlashAttention은 단순히 FLOPs를 줄인 기법이 아니다. 메모리 계층 사이의 I/O를 직접 최적화한 알고리즘이다. 일부 계산이 늘어도 HBM 왕복이 크게 줄면 전체 시간이 짧아질 수 있다.
PagedAttention이 해결한 HBM capacity
서빙 환경의 KV cache는 크기가 고정되어 있지 않다.
- 요청마다 sequence 길이가 다르다.
- 생성 중 cache가 계속 자란다.
- 완료된 요청은 메모리를 반납한다.
- shared prefix와 beam은 일부 cache를 공유할 수 있다.
요청마다 최대 길이의 큰 연속 영역을 미리 예약하면 fragmentation과 과도한 예약이 발생한다.
PagedAttention은 운영체제의 paging에서 영감을 받아 KV cache를 고정 크기 block으로 관리한다.[9]
- 필요한 만큼 block을 점진적으로 할당한다.
- 논리 block과 물리 block을 block table로 연결한다.
- prefix와 beam의 KV block을 공유할 수 있다.
- fragmentation을 줄인다.
- 같은 HBM에서 더 많은 요청과 큰 batch를 수용한다.
PagedAttention은 HBM 칩의 raw bandwidth를 높이지 않는다. 주어진 HBM capacity를 덜 낭비하도록 만드는 memory management 기법이다.
학습은 왜 더 많은 HBM을 요구하는가
학습에서는 weight만 저장하지 않는다.
- gradient
- optimizer state
- master weight
- backward에 필요한 activation
- gradient bucket
- communication buffer
- checkpoint 임시 데이터
설명을 위해 전통적인 mixed-precision Adam 구성을 가정했다.[10]
| 항목 | 파라미터당 크기 |
|---|---|
| FP16 weight | 2 byte |
| FP16 gradient | 2 byte |
| FP32 master weight | 4 byte |
| FP32 first moment | 4 byte |
| FP32 second moment | 4 byte |
| 합계 | 약 16 byte |
70B model state만 계산하면 다음과 같다.
70 billion x 16 bytes
= 1.12TB
Activation과 workspace는 포함하지 않은 값이다.
16byte per parameter는 모든 학습의 고정 법칙이 아니다. BF16 master weight 사용 여부, gradient precision, optimizer 종류, quantized optimizer와 sharding 방식에 따라 달라진다.
학습 메모리를 줄이는 대표적인 방법은 다음과 같다.
- FSDP와 ZeRO로 weight와 gradient와 optimizer state를 분산한다.
- Activation checkpointing으로 저장을 줄이고 backward에서 다시 계산한다.
- Gradient accumulation으로 micro-batch를 나눠 처리한다.
- Optimizer state를 낮은 precision으로 저장한다.
- CPU 또는 NVMe offload를 사용한다.
각 방법은 HBM capacity를 computation, communication 또는 느린 memory tier와 교환한다.
학습도 항상 compute-bound인 것은 아니다
대형 GEMM은 높은 weight reuse 덕분에 compute-bound가 될 수 있다.
하지만 학습 전체에는 다음 작업도 포함된다.
- optimizer update
- normalization
- element-wise operation
- activation read와 write
- embedding lookup
- attention I/O
- gradient reduction 전후의 tensor movement
이 작업들은 HBM bandwidth에 민감할 수 있다. 학습 GPU 선택에서도 peak Tensor FLOPS만 보면 안 되는 이유다.
여러 GPU의 HBM을 더하면 생기는 문제
70B BF16 weight가 약 140GB라면 작은 HBM 하나에 들어가지 않는다. 여러 GPU에 model을 나누게 된다.
Tensor parallelism
행렬을 여러 GPU가 나눠 계산하고 partial result를 All-Reduce 또는 All-Gather한다.
GPU 0 HBM → partial compute ┐
GPU 1 HBM → partial compute ├→ collective → next layer
GPU 2 HBM → partial compute ┤
GPU 3 HBM → partial compute ┘
Pipeline parallelism
Layer를 stage로 나누고 stage 사이 activation을 전송한다. Stage가 놀지 않도록 micro-batch와 pipeline schedule을 설계해야 한다.
Expert parallelism
MoE expert를 GPU별로 나누고 router가 token을 해당 GPU로 보낸다. All-to-all 성격의 token exchange가 새로운 병목이 될 수 있다.
전체 성능은 다음 요소의 결합으로 결정된다.
- 각 GPU의 HBM capacity
- 각 GPU의 HBM bandwidth
- 각 GPU의 compute
- GPU interconnect bandwidth와 latency
- topology와 collective algorithm
- communication과 compute overlap
HBM은 각 GPU 내부의 고속도로다. NVLink와 Infinity Fabric과 PCIe는 GPU 사이의 고속도로다. 내부 도로가 넓어도 GPU 사이의 도로가 막히면 전체 실행은 통신을 기다린다.
여러 GPU의 HBM capacity와 bandwidth를 단순 합산한 값은 유용한 첫 근사다. 하지만 하나의 자유로운 공유 HBM처럼 동작한다는 뜻은 아니다.
HBM과 연결된 LLM 최적화
| 최적화 | 줄이려는 HBM 비용 | 주요 대가 |
|---|---|---|
| INT8과 INT4 weight quantization | weight capacity와 read traffic | 품질과 dequantization과 kernel 지원 |
| KV cache quantization | 긴 context의 cache와 read traffic | 정확도와 scale 처리 |
| GQA와 MQA | KV head와 cache 크기 | 모델 구조와 품질 |
| FlashAttention | Attention의 HBM 왕복 | 지원 shape와 kernel 제약 |
| PagedAttention | KV fragmentation | block table 관리 |
| Kernel fusion | 중간 tensor materialization | compiler와 kernel 복잡도 |
| Continuous batching | weight reuse와 utilization | queueing latency와 KV capacity |
| Speculative decoding | 순차 decode 횟수 | draft 비용과 acceptance rate |
| Tensor parallelism | 여러 GPU HBM 사용 | collective communication |
| Activation checkpointing | 학습 activation capacity | recomputation |
| Sliding window attention | 오래된 KV 범위 | 사용할 수 있는 문맥 구조 |
| CPU offload | GPU HBM 요구량 | host-device transfer |
Sparsity가 자동으로 HBM을 줄이지 않는 이유
Weight가 논리적으로 sparse해도 dense format으로 저장하고 dense kernel이 읽으면 HBM traffic은 줄지 않는다.
실제 절감을 얻으려면 다음 조건이 필요하다.
- 압축된 sparse format
- index metadata보다 큰 데이터 절감
- 해당 format을 직접 처리하는 hardware와 kernel
- 불규칙 접근으로 인한 bandwidth 손실 최소화
Compute가 줄었다는 사실과 memory traffic이 줄었다는 사실을 분리해야 한다.
MoE가 HBM 문제를 모두 해결하지 않는 이유
MoE는 token마다 일부 expert만 활성화해 compute를 줄일 수 있다.
하지만 모든 expert weight를 보유해야 한다면 전체 HBM capacity 요구는 여전히 크다. Expert가 여러 GPU에 분산되면 routing과 token exchange가 interconnect를 압박한다.
MoE의 세 비용을 따로 봐야 한다.
- token당 활성 compute
- 전체 expert weight capacity
- expert routing communication
HBM의 단점
가격과 packaging
HBM에는 다음 공정이 필요하다.
- DRAM die 박막화와 적층
- TSV 가공
- 미세 접합
- base die
- silicon interposer 또는 고급 package
- 복잡한 전력과 신호 설계
- package-level 검사
DDR DIMM이나 일반 GDDR board보다 제조와 packaging 비용이 높다.
수율
GPU, interposer, HBM stack, 접합 중 하나의 문제가 고가 package 전체 가치에 영향을 줄 수 있다. Known-good-die 선별과 package test가 중요하다.
열과 전력
짧고 넓은 링크는 비트당 에너지 효율에 유리하다. 하지만 수 TB/s로 계속 데이터를 이동하는 전체 package 전력은 여전히 크다.
비트당 효율이 좋다는 말과 package 전체 전력이 작다는 말은 같지 않다.
적층 내부의 열을 빼내기도 어렵고 GPU 가까이에 배치되므로 package 냉각과 power delivery가 중요하다.
확장성
DDR DIMM처럼 사용자가 나중에 stack을 추가하기 어렵다.
제품 package를 만들 때 다음 요소가 사실상 고정된다.
- HBM stack 수
- stack당 capacity
- memory interface
- memory controller
- package power와 thermal design
Peak와 effective bandwidth
표기의 TB/s는 peak theoretical bandwidth다.
실제 값은 다음 요인에 따라 낮아진다.
- memory access pattern
- request 크기와 정렬
- channel imbalance
- bank conflict
- cache hit와 miss
- ECC와 refresh
- thermal throttling
- tensor layout
- kernel implementation
- read와 write 혼합 비율
GPU를 고를 때 스펙 표만 보지 않고 실제 model과 precision과 batch와 context 조건의 benchmark를 봐야 한다.
다시 확인한 오해
HBM은 RAM과 다른 저장장치다
아니다. HBM은 DRAM 계열의 휘발성 RAM이다.
HBM capacity와 VRAM capacity는 별개다
HBM GPU에서 표시되는 HBM capacity가 그 GPU의 device memory다.
HBM은 개별 접근도 무조건 압도적으로 빠르다
HBM의 핵심 강점은 aggregate bandwidth다. 개별 latency와 total bandwidth는 다른 지표다.
적층 수를 늘리면 bandwidth도 같은 비율로 늘어난다
적층 수 증가는 주로 capacity 증가다. 외부 bus width와 pin rate와 channel과 stack 수가 bandwidth를 결정한다.
GPU FLOPS가 높으면 LLM token 속도도 같은 비율로 높다
작은 batch decode는 HBM bandwidth-bound가 되기 쉬워 peak FLOPS를 다 사용하지 못할 수 있다.
Weight만 HBM에 들어가면 된다
KV cache와 activation과 workspace와 runtime과 communication buffer를 위한 공간도 필요하다.
HBM이 많으면 LLM이 더 똑똑해진다
같은 weight와 같은 연산이면 HBM 자체는 답변 품질을 바꾸지 않는다.
다만 더 큰 model, 긴 context, 높은 precision, 큰 training batch를 가능하게 해 간접적으로 품질과 서비스 목표에 영향을 줄 수 있다.
Unified Memory면 DDR과 HBM 차이가 사라진다
논리 주소 공간의 통합과 물리 bandwidth의 통합은 다르다. 실제 page residency와 migration 비용은 남는다.
여러 GPU의 HBM을 더하면 하나의 거대한 HBM이 된다
Model을 분산할 수는 있지만 GPU 사이의 collective communication 비용이 생긴다.
시스템을 평가할 때 확인할 것
적재 가능성
- 파라미터 수와 weight precision은 무엇인가
- Quantization metadata를 포함한 실제 weight 크기는 얼마인가
- Runtime과 workspace를 제외한 usable HBM은 얼마인가
- 목표 context와 batch의 KV cache는 얼마인가
- 단일 GPU에 들어가는가
- 여러 GPU에 shard해야 하는가
추론 성능
- TTFT와 TPOT를 나눠 측정했는가
- Prefill과 decode throughput을 나눴는가
- Batch 1 latency와 다중 사용자 throughput을 구분했는가
- Peak가 아닌 effective HBM bandwidth를 측정했는가
- 긴 context에서 KV cache read가 병목인지 확인했는가
- Quantization kernel이 해당 GPU에서 실제로 빠른가
분산 실행
- Tensor와 pipeline과 expert parallelism 중 무엇을 쓰는가
- GPU topology와 interconnect는 무엇인가
- Collective communication이 critical path에 들어오는가
- Compute와 communication을 overlap할 수 있는가
학습
- Weight와 gradient와 optimizer state precision은 무엇인가
- Activation memory를 따로 계산했는가
- Checkpointing과 recomputation을 사용하는가
- FSDP와 ZeRO sharding 단계와 communication cost는 무엇인가
- CPU와 NVMe offload가 transfer bottleneck을 만들지 않는가
최종 정신 모델
LLM 시스템을 공장으로 비유하면 다음과 같다.
| LLM 구성요소 | 공장 비유 |
|---|---|
| Model weight | 원재료 |
| HBM capacity | 작업장 바로 옆 창고 크기 |
| HBM bandwidth | 창고에서 작업대로 이어지는 컨베이어 처리량 |
| Tensor Core FLOPS | 작업 기계의 계산 능력 |
| GPU interconnect | 여러 공장 사이의 물류망 |
| KV cache | 이전 작업 결과를 보관하는 기록 창고 |
| FlashAttention | 중간 재료를 큰 창고에 반납하지 않고 작은 작업대에서 재사용하는 공정 |
| Quantization | 원재료를 더 작게 압축해 저장하고 운반하는 방식 |
| PagedAttention | 창고를 고정 크기 구획으로 효율적으로 배치하는 방식 |
계산기가 아무리 빨라도 HBM에서 데이터가 도착하지 않으면 기다린다. HBM이 아무리 빨라도 compute, interconnect, kernel 또는 capacity가 부족하면 전체 LLM은 빨라지지 않는다.
LLM performance
= f
compute
HBM capacity
HBM bandwidth
interconnect
software
workload
특히 workload를 빼고 hardware만 비교하면 잘못된 결론을 내리기 쉽다.
- 긴 prompt의 prefill인지
- batch 1 decode인지
- 다중 사용자 serving인지
- 긴 context인지
- 학습인지
- 단일 GPU인지 분산 GPU인지
이 조건에 따라 실제 병목이 달라진다.
지금 내가 HBM을 가장 짧게 설명한다면 이렇게 말할 수 있다.
HBM은 LLM의 지식을 담는 영구 저장소가 아니라, GPU가 다음 계산을 시작하기 전에 필요한 숫자를 제때 공급하기 위한 매우 넓고 가까운 DRAM이다.
출처
모든 링크는 2026-07-21에 다시 확인했다.
- SK hynix의 HBM 적층과 TSV 및 base die 설명
- AMD의 SSI High-Bandwidth Memory Package Concept
- AMD의 HBM Topology
- NVIDIA의 H100 Tensor Core GPU와 Hopper Architecture In-Depth
- NVIDIA의 Hopper Tuning Guide
- NVIDIA의 CUDA Programming Guide Unified Memory
- Samuel Williams와 Andrew Waterman과 David Patterson의 Roofline 성능 모델 원문
- Tri Dao 등의 FlashAttention 원 논문
- Woosuk Kwon 등의 PagedAttention 원 논문
- Samyam Rajbhandari 등의 ZeRO 원 논문
- Samsung Semiconductor의 HBM 제품 자료와 HBM4 제품 발표
- AMD의 CDNA 3 Architecture Whitepaper
- SK hynix의 TSV 기반 3D DRAM과 HBM 설명
댓글