처음에는 “LLM은 행렬 곱이 많아서 GPU가 빠르다”라는 한 문장으로 이해했다. 방향은 맞지만 70B 모델의 메모리, prefill과 decode의 속도 차이, KV cache, multi-GPU 확장을 한꺼번에 설명하려고 하니 이 문장만으로는 부족했다.
그래서 이번에는 GPU와 LLM의 관계를 다음 네 자원으로 나눠 다시 추적했다.
- 연산량(compute): Tensor Core가 얼마나 많은 행렬 연산을 처리하는가
- 용량(capacity): weight, activation, gradient, optimizer state, KV cache가 VRAM에 들어가는가
- 대역폭(bandwidth): HBM과 on-chip memory 사이에서 필요한 데이터를 충분히 빨리 옮기는가
- 연결(interconnect): 여러 GPU가 collective communication을 감당하는가
확인 기준은 CUDA Programming Guide 13.3, Transformer·FlashAttention·ZeRO·PagedAttention·Megatron-LM 원 논문과 NVIDIA 성능 문서다. 아래 계산은 병목을 이해하기 위한 근사다. 실제 값은 모델 구조, precision, kernel, batch, context 길이, GPU 세대에 따라 달라진다.
먼저 내린 결론
LLM은 본질적으로 거대한 텐서 연산 그래프다. 그중 대부분의 계산량은 행렬 곱셈이 차지하고, 대부분의 데이터는 GPU 메모리와 연산 장치 사이를 계속 이동한다. GPU는 동일한 형태의 연산을 수천 개 스레드에서 병렬 실행하고 높은 메모리 대역폭을 제공하므로 이 작업에 적합하다.
다만 “GPU가 빠르면 LLM이 무조건 빠르다”는 설명은 불완전하다. 실제 병목은 작업 단계에 따라 달라진다.
- 학습: 대형 행렬 곱, activation, gradient, optimizer state, GPU 간 동기화가 중요하다.
- Prefill: 긴 입력을 한꺼번에 처리하므로 Tensor Core 연산 성능과 Attention 구현이 중요하다.
- Decode: 토큰을 하나씩 생성하므로 작은 batch에서는 연산량보다 weight와 KV cache를 읽는 메모리 대역폭이 중요해지기 쉽다.
- 분산 실행: GPU 수보다 VRAM 분할 방식, 통신 토폴로지, collective 연산, pipeline bubble이 중요하다.
- 서비스: 모델 자체뿐 아니라 batching, KV cache 관리, kernel fusion, quantization, scheduling이 처리량과 지연시간을 결정한다.
가장 유용한 한 문장은 다음과 같다.
LLM은 수학적 계산 그래프이고 GPU는 그 그래프를 대량 병렬로 실행하는 엔진이다. 학습에서는 계산량과 상태 저장이, 추론에서는 weight·KV cache 이동과 토큰의 순차 생성이 핵심 문제다.
1. GPU가 LLM에 적합한 근본 이유
1.1 CPU와 GPU는 최적화 목표가 다르다
| 구분 | CPU | GPU |
|---|---|---|
| 주된 목표 | 한 스레드의 빠른 실행과 낮은 지연시간 | 많은 작업의 높은 총처리량 |
| 코어 구성 | 적지만 복잡하고 강력한 코어 | 많고 상대적으로 단순한 연산 코어 |
| 강점 | 분기, 운영체제, 복잡한 제어 흐름 | 동일한 형태의 대량 데이터 병렬 계산 |
| 메모리 특성 | 큰 캐시와 낮은 단일 접근 지연 | 높은 device memory 대역폭 |
| LLM의 대표 역할 | 토크나이징, 요청 관리, 스케줄링 | 행렬 곱, Attention, 역전파 |
CPU는 복잡한 명령 흐름을 빠르게 진행하도록 설계된다. 반면 GPU는 단일 스레드 지연시간 일부를 포기하고 수많은 스레드를 동시에 실행해 전체 처리량을 높인다. LLM은 같은 수학식을 수많은 tensor 원소에 반복 적용하므로 GPU의 처리량 중심 구조와 잘 맞는다. [1][2]
1.2 LLM은 언어가 아니라 숫자로 실행된다
텍스트는 tokenizer를 거쳐 token ID가 된다.
"GPU는 빠르다"
→ tokenizer
→ [token_id_1, token_id_2, ...]
→ embedding vector
→ Transformer 연산
→ 다음 token 확률
GPU는 단어의 의미를 직접 다루지 않는다. GPU가 보는 것은 다음과 같은 숫자 배열이다.
- token ID
- embedding vector
- weight matrix
- activation tensor
- gradient tensor
- probability vector
따라서 GPU의 역할은 “언어 이해 장치”가 아니라 “LLM의 수학을 실행하는 장치”에 가깝다.
2. GPU 내부에서 LLM이 실행되는 방식
2.1 SM, thread, warp
GPU는 여러 Streaming Multiprocessor(SM)로 구성된다. GPU kernel이 실행되면 작업은 많은 thread block으로 나뉘고, 각 block은 사용 가능한 SM에 스케줄링된다. CUDA thread는 보통 warp 단위로 함께 실행된다. [1][2]
LLM의 큰 tensor를 작은 tile로 나눈 뒤 각 SM이 tile 일부를 계산한다고 생각하면 된다.
큰 행렬
├─ tile 1 → SM 1
├─ tile 2 → SM 2
├─ tile 3 → SM 3
└─ ...
2.2 CUDA Core와 Tensor Core
- CUDA Core: 일반적인 부동소수점·정수 연산 등을 수행한다.
- Tensor Core: 작은 행렬 블록의 multiply-accumulate를 높은 처리량으로 수행하도록 특화되어 있다.
LLM의 Linear, Q/K/V projection, MLP는 대부분 행렬 곱으로 표현되므로 Tensor Core 활용 여부가 매우 중요하다. 다만 모든 LLM 연산이 Tensor Core에 적합한 것은 아니다.
- LayerNorm/RMSNorm
- softmax
- masking
- sampling
- tensor reshape
- element-wise activation
같은 연산은 행렬 곱보다 메모리 접근이나 일반 연산 비중이 클 수 있다.
2.3 GPU 메모리 계층
GPU 내부 메모리는 대략 다음처럼 이해할 수 있다.
빠름·작음
register
shared memory / on-chip SRAM
L1 / L2 cache
HBM 또는 device DRAM
CPU host memory
storage
느림·큼
효율적인 GPU kernel은 데이터를 HBM에서 읽은 뒤 on-chip memory에서 최대한 재사용하고 최종 결과만 다시 HBM에 쓴다. HBM이 매우 빠르더라도 연산 장치 내부 데이터 재사용보다 느리기 때문이다.
2.4 GPU는 CPU와 함께 동작한다
일반적인 실행 흐름은 다음과 같다.
CPU
├─ 요청 수신
├─ tokenizer 실행
├─ batch 구성
├─ GPU kernel 실행 요청
└─ 결과 후처리
GPU
├─ weight/activation 로딩
├─ Transformer forward
├─ logits 계산
└─ 필요 시 sampling
CPU와 GPU가 분리된 시스템에서는 host memory와 device memory도 분리되어 있다. 따라서 CPU↔GPU 복사가 빈번하거나 CPU가 GPU에 충분히 빠르게 작업을 공급하지 못하면 GPU가 놀 수 있다. [1][2]
3. Transformer 한 레이어가 GPU 연산으로 바뀌는 과정
Decoder-only Transformer 한 레이어의 입력을 다음과 같이 두자.
X \in \mathbb{R}^{B \times S \times H}
B: batch sizeS: sequence lengthH: hidden dimension
3.1 Embedding
token ID는 embedding table의 행을 조회해 vector로 변환된다.
E \in \mathbb{R}^{V \times H}
V: vocabulary sizeH: hidden dimension
Embedding lookup 자체는 대형 행렬 곱보다는 메모리 조회에 가깝다. 반면 마지막 logits 계산은 hidden state와 vocabulary projection matrix를 곱하므로 vocabulary가 크면 비용이 커질 수 있다.
3.2 Q, K, V projection
Self-Attention에 필요한 Query, Key, Value를 만든다.
Q=XW_Q, \qquad K=XW_K, \qquad V=XW_V
각 연산은 대형 GEMM으로 실행된다. GPU 관점에서는 다음 작업이다.
[batch × tokens, hidden]
× [hidden, projection dimension]
→ [batch × tokens, projection dimension]
3.3 Attention score와 output
Scaled dot-product attention은 다음과 같다.
A = \frac{QK^T}{\sqrt{d}}
P = \operatorname{softmax}(A + \text{causal mask})
O = PV
핵심 행렬 곱은 다음 두 개다.
QK^TPV
일반적인 full attention의 시간 복잡도는 sequence length에 대해 제곱으로 증가한다.
O(BS^2H)
따라서 다른 조건이 같다면 S를 두 배로 늘릴 때 Attention 연산량은 대략 네 배가 된다. Causal Attention은 유효 영역이 삼각형이므로 이론상 불필요한 영역을 줄일 수 있지만, 실제 비용은 kernel 구현, padding, sequence 길이 분포에 따라 달라진다. [3]
3.4 Output projection
Attention head 결과를 합친 뒤 다시 hidden dimension으로 projection한다.
Y = OW_O
이 역시 대형 GEMM이다.
3.5 MLP/FFN
표준 FFN은 단순화하면 다음과 같다.
Y = \sigma(XW_1)W_2
SwiGLU 계열은 대략 다음 형태다.
Y = \left(\operatorname{SiLU}(XW_g) \odot XW_u\right)W_d
MLP는 큰 weight matrix를 사용하므로 Transformer의 파라미터와 연산량에서 큰 비중을 차지한다.
3.6 한 레이어의 대략적인 연산량
표준 Multi-Head Attention과 hidden size의 4배인 FFN을 가정하면 대략 다음과 같다.
- Attention projection 파라미터: 약
4H^2 - FFN 파라미터: 약
8H^2 - 합계: 레이어당 약
12H^2
Linear 계열 forward FLOPs는 대략:
24BSH^2
Attention의 token-token 상호작용은 대략:
4BS^2H
따라서 다음 관계가 생긴다.
- hidden dimension
H가 커지면 projection과 MLP 비용이 크게 증가한다. - sequence length
S가 매우 길어지면 Attention 비용이 크게 증가한다. - 정확한 FLOP는 MHA/GQA/MQA, SwiGLU intermediate size, causal kernel, vocabulary 크기에 따라 달라진다.
4. 행렬 곱과 GPU 성능
4.1 GEMM 연산량
다음 행렬 곱을 생각하자.
C_{M \times N}=A_{M \times K}B_{K \times N}
Multiply-add를 두 FLOP으로 계산하면 연산량은 대략:
2MNK
이다.
행렬의 각 출력 tile은 상당 부분 독립적으로 계산할 수 있어 GPU가 여러 SM에 작업을 분배하기 좋다.
4.2 Arithmetic intensity
GPU 연산이 계산 병목인지 메모리 병목인지 판단하는 핵심 개념이다.
I = \frac{\text{FLOPs}}{\text{이동한 byte 수}}
대략적인 성능 상한은 Roofline 관점에서 다음처럼 쓸 수 있다.
\text{Performance}
\le
\min(\text{Peak FLOPS},\ \text{Memory Bandwidth} \times I)
실행시간 관점에서는:
T \gtrsim
\max\left(
\frac{\text{FLOPs}}{\text{Peak FLOPS}},
\frac{\text{Bytes moved}}{\text{Memory Bandwidth}}
\right)
로 이해할 수 있다. 실제 실행에는 kernel launch, synchronization, communication, 주소 계산 등의 추가 비용이 있다. [4]
4.3 Compute-bound와 memory-bound
Compute-bound
연산 장치가 바빠서 느린 상태다.
- 큰 training batch
- 긴 prompt의 prefill
- 큰 GEMM
- weight tile을 여러 token이 재사용하는 상황
에서는 arithmetic intensity가 올라가 Tensor Core throughput이 중요해질 수 있다.
Memory-bound
연산 장치가 데이터를 기다려서 느린 상태다.
- batch 1 decode
- matrix-vector에 가까운 연산
- LayerNorm, activation 같은 낮은 arithmetic intensity 연산
- weight와 KV cache를 반복해서 읽는 상황
에서 나타나기 쉽다.
중요한 결론은 다음과 같다.
GPU의 최대 FLOPS가 두 배라도 현재 작업이 HBM 대역폭 병목이면 실제 속도는 두 배가 되지 않는다.
5. 학습에서 GPU가 하는 일
학습 한 step은 크게 다음 순서다.
Forward
→ Loss 계산
→ Backward
→ Gradient 동기화
→ Optimizer update
5.1 Forward
입력 token을 모든 Transformer layer에 통과시켜 logits와 loss를 계산한다. 학습에서는 전체 sequence가 이미 주어져 있으므로 causal mask를 적용하면서도 여러 token 위치를 병렬 계산할 수 있다.
5.2 Backward
Forward에서 다음을 계산했다고 하자.
Y=XW
Backward에서는 대략 다음 행렬 곱이 필요하다.
\frac{\partial L}{\partial X}
=
\frac{\partial L}{\partial Y}W^T
\frac{\partial L}{\partial W}
=
X^T\frac{\partial L}{\partial Y}
즉 forward 행렬 곱뿐 아니라 input gradient와 weight gradient를 위한 추가 행렬 곱이 수행된다.
5.3 학습 FLOP 근사
Dense Transformer 학습 비용의 흔한 근사치는 다음과 같다.
C \approx 6ND
N: 파라미터 수D: 학습 token 수C: 학습 FLOPs
직관적으로는 token당 forward 약 2N, backward 약 4N FLOP으로 본 것이다. Embedding, logits, Attention 세부 비용을 생략한 근사이므로 정확한 예산 산정에는 모델별 계산이 필요하다. [5]
계산 예시
7B 모델을 1조 token으로 학습한다고 하면:
6 \times 7 \times 10^9 \times 10^{12}
=
4.2 \times 10^{22}\text{ FLOPs}
가 된다. 대규모 학습에 GPU cluster가 필요한 이유다.
5.4 학습 메모리 구성
학습에서는 weight만 저장하지 않는다.
- model parameter
- gradient
- optimizer state
- activation
- master weight
- 통신 buffer
- temporary workspace
- allocator 여유 공간
전형적인 mixed-precision Adam 구성을 단순화하면 파라미터당 다음 메모리를 사용할 수 있다.
| 구성 | 파라미터당 크기 예시 |
|---|---|
| BF16/FP16 weight | 2 bytes |
| BF16/FP16 gradient | 2 bytes |
| FP32 master weight | 4 bytes |
| Adam first moment | 4 bytes |
| Adam second moment | 4 bytes |
| 합계 | 약 16 bytes |
구현에 따라 master weight가 없거나 gradient·optimizer state 정밀도가 다를 수 있다. 위 값은 activation을 제외한 거친 예시다.
계산 예시
- 7B:
7\text{B} \times 16bytes ≈ 112GB - 70B:
70\text{B} \times 16bytes ≈ 1.12TB
여기에 activation이 추가되므로 full-parameter 학습의 메모리 요구량은 같은 모델의 추론보다 훨씬 크다.
5.5 Activation memory
Backward에서 gradient를 계산하려면 forward 중간값이 필요하다. batch, sequence length, hidden dimension, layer 수가 커지면 activation 메모리도 커진다.
Activation checkpointing은:
- activation 일부만 저장하고
- backward 때 필요한 값을 다시 계산해
- 메모리를 절약한다.
즉 다음 교환이다.
적은 GPU 메모리 사용
↔
추가 GPU 계산
Selective activation recomputation과 sequence parallelism은 저장할 activation과 재계산 범위를 더 세밀하게 조절한다. [8]
5.6 Mixed precision training
학습에서는 보통 모든 값을 동일한 정밀도로 계산하지 않는다.
- matrix multiplication input: BF16, FP16, FP8 등
- accumulation: 더 높은 정밀도
- 일부 optimizer state: FP32
- numerically sensitive operation: 높은 정밀도 유지 가능
정밀도를 낮추면:
- weight·activation 메모리 감소
- HBM traffic 감소
- Tensor Core throughput 증가 가능
이라는 이점이 있다. 반면 표현 범위와 정밀도 부족으로 overflow, underflow, gradient 손실, 학습 불안정이 생길 수 있어 scaling과 정밀도 관리가 필요하다. [11]
6. 학습의 병렬성과 생성의 병렬성은 다르다
6.1 학습
학습 데이터는 정답 token까지 이미 존재한다.
나는 / 오늘 / 학교에 / 갔다
Causal mask를 적용하면 각 위치는 미래 token을 볼 수 없지만, 각 위치의 forward 계산 자체는 동시에 수행할 수 있다.
병렬화 가능한 차원은 다음과 같다.
- batch
- sequence/token
- attention head
- hidden dimension
- matrix tile
- microbatch
레이어 의존성은 남는다.
Layer 1 output
→ Layer 2 input
→ Layer 3 input
따라서 한 sample의 모든 layer를 완전히 동시에 실행할 수 있는 것은 아니다.
6.2 Autoregressive generation
생성은 다음 token이 이전 token에 의존한다.
token 1 생성
→ token 2 생성
→ token 3 생성
미래 token을 미리 정확히 계산할 수 없으므로 token 간에는 직렬 의존성이 있다. 그러나 한 token을 생성하기 위한 내부 행렬 곱, attention head, batch 요청은 병렬 처리된다.
학습은 sequence 위치까지 넓게 병렬화할 수 있지만, 일반적인 autoregressive decode는 token 사이가 순차적이다.
7. LLM 추론: Prefill과 Decode
LLM 추론은 같은 forward 연산이라도 Prefill과 Decode에서 GPU 특성이 크게 다르다.
7.1 Prefill
사용자 prompt 전체를 한꺼번에 처리하는 단계다.
8,000-token prompt
→ 모든 token의 Q/K/V 계산
→ Attention 수행
→ 각 layer의 KV cache 생성
→ 첫 token logits 계산
특징:
- 한 번에 많은 token을 처리한다.
- 큰 GEMM이 만들어진다.
- 같은 weight tile을 여러 token이 재사용한다.
- Tensor Core 활용도가 높아지기 쉽다.
- 긴 sequence에서는 Attention 비용과 HBM IO가 커진다.
- 첫 token 지연시간(TTFT)에 큰 영향을 준다.
7.2 Decode
Prefill 이후 새 token을 하나씩 생성하는 단계다.
token S+1
→ token S+2
→ token S+3
특징:
- 한 step에서 요청당 새 token 하나를 처리한다.
- 작은 batch에서는 GEMM이 matrix-vector 연산에 가까워진다.
- token마다 weight 대부분을 다시 읽어야 한다.
- 이전 token의 KV cache를 읽어야 한다.
- memory-bound가 되기 쉽다.
- token 간 시간(TPOT)에 큰 영향을 준다.
7.3 Decode 속도의 직관적 하한
작은 batch에서 모델 weight가 cache에 전부 들어가지 않는다고 단순화하면:
\text{token latency}
\gtrsim
\frac{\text{한 step에서 읽는 weight bytes}}
{\text{aggregate memory bandwidth}}
이다.
실제 실행에는 다음 비용이 더해진다.
- KV cache read/write
- kernel launch
- GPU 간 collective
- normalization과 activation
- sampling
- scheduler
- memory fragmentation
따라서 이 식은 이상적인 하한에 가깝고 실제 token latency는 더 크다.
7.4 Batch가 throughput을 높이는 이유
batch 1에서는 읽어 온 weight tile을 한 요청에만 사용한다. batch가 커지면 같은 weight tile을 여러 요청의 token 계산에 재사용할 수 있다.
weight tile 1회 로딩
├─ request A 계산
├─ request B 계산
├─ request C 계산
└─ request D 계산
결과적으로:
- arithmetic intensity 증가
- GPU utilization 증가
- 전체 tokens/s 증가
- 요청별 대기시간 증가 가능
이라는 trade-off가 생긴다.
7.5 주요 serving 지표
| 지표 | 의미 | 주요 영향 요소 |
|---|---|---|
| TTFT | 요청부터 첫 token까지 시간 | queue, tokenizer, prefill, prompt 길이 |
| TPOT | 생성 token 사이 시간 | decode, HBM bandwidth, batch, TP 통신 |
| ITL | inter-token latency | TPOT와 유사한 사용자 체감 지표 |
| Throughput | 초당 전체 생성 token 수 | batch, scheduler, GPU 수, quantization |
| Goodput | SLO를 만족한 유효 처리량 | tail latency, queue, 실패·재시도 |
서비스에서는 낮은 latency와 높은 throughput을 동시에 최대화하기 어렵다.
8. VRAM과 모델 크기
8.1 추론 weight 메모리
파라미터 수를 P, 파라미터당 byte를 q라고 하면:
M_{weights} \approx Pq
7B 모델의 순수 weight 크기
| 저장 정밀도 | 이론적 크기 |
|---|---|
| FP32, 4 bytes | 약 28GB |
| BF16/FP16, 2 bytes | 약 14GB |
| INT8, 1 byte | 약 7GB |
| INT4, 0.5 byte | 약 3.5GB |
70B 모델의 순수 weight 크기
| 저장 정밀도 | 이론적 크기 |
|---|---|
| FP32 | 약 280GB |
| BF16/FP16 | 약 140GB |
| INT8 | 약 70GB |
| INT4 | 약 35GB |
실제 VRAM 요구량은 다음 이유로 더 크다.
- quantization scale과 metadata
- KV cache
- activation
- CUDA context
- temporary workspace
- communication buffer
- sampling buffer
- memory allocator 단편화와 여유 공간
8.2 여러 GPU의 VRAM은 자동으로 합쳐지지 않는다
Data Parallelism만 사용하면 각 GPU가 모델 전체 복사본을 가진다.
GPU 1: 전체 모델
GPU 2: 전체 모델
이 경우 GPU 두 장을 사용해도 하나의 더 큰 모델을 자동으로 올릴 수 없다. Tensor Parallelism, Pipeline Parallelism, FSDP/ZeRO 등의 sharding이 적용되어야 여러 GPU 메모리를 하나의 모델에 활용할 수 있다.
9. KV cache
9.1 왜 필요한가
새 token을 생성할 때 과거 token의 K와 V를 매번 다시 계산하면 큰 낭비다. 각 layer에서 이미 계산한 K/V를 저장해 다음 decode step에서 재사용하는 것이 KV cache다.
KV cache는 과거 token의 네트워크 계산을 피하지만, 새 token이 과거 문맥을 attend할 때 해당 cache를 읽는 비용까지 없애지는 않는다.
9.2 크기 공식
일반적인 KV cache 크기 근사는 다음과 같다.
M_{KV}
=
B \times S \times L
\times 2
\times N_{KVHeads}
\times d_{head}
\times q
B: batch 또는 동시 sequence 수S: 저장된 token 수L: layer 수2: K와 VN_{KVHeads}: KV head 수d_{head}: head dimensionq: 원소당 bytes
9.3 계산 예시
다음 가상 모델을 가정한다.
- 80 layers
- 8 KV heads
- head dimension 128
- BF16, 2 bytes
한 sequence의 token 하나당 KV cache:
80 \times 2 \times 8 \times 128 \times 2
=327{,}680\text{ bytes}
약 320KiB/token이다.
| Context length | 요청 하나의 대략적 KV cache |
|---|---|
| 8K | 약 2.5GiB |
| 32K | 약 10GiB |
| 128K | 약 40GiB |
동시 요청이 10개라면 KV cache도 거의 10배가 필요하다. 실제 크기는 padding, block allocation, cache dtype, sharding 방식에 따라 달라진다.
9.4 MHA, GQA, MQA
MHA
각 Query head가 독립적인 K/V head를 가진다. 표현력은 높지만 KV cache가 크다.
GQA
여러 Query head가 K/V head를 공유한다. KV head 수가 줄어 KV cache 용량과 decode memory traffic이 감소한다.
MQA
모든 Query head가 하나의 K head와 하나의 V head를 공유한다. KV cache를 더 크게 줄일 수 있지만 모델 품질과 구조적 trade-off가 있다.
GQA와 MQA는 단순한 모델 구조 선택을 넘어 GPU serving 비용에 직접 영향을 주는 hardware-aware 설계다. [13][14]
9.5 PagedAttention
사용자마다 sequence 길이가 달라 KV cache가 동적으로 커지고 줄어든다. 연속 메모리를 요청별 최대 길이로 미리 잡으면 내부 단편화와 낭비가 커진다.
PagedAttention은 운영체제의 paging과 비슷하게 KV cache를 block 단위로 관리한다.
- 필요한 만큼 block 할당
- 비연속 physical block 사용 가능
- sequence 간 cache block 공유 가능
- 단편화 감소
- 더 큰 batch 가능
PagedAttention의 목적은 Attention 계산량 자체를 없애는 것이 아니라 serving memory 관리 효율을 높이는 것이다. [9]
10. FlashAttention
10.1 일반 Attention의 IO 문제
일반적인 구현은 S \times S score 또는 probability matrix를 HBM에 기록하고 다시 읽는다.
QKᵀ 계산
→ score matrix를 HBM에 저장
→ 다시 읽어 softmax
→ probability matrix 저장
→ 다시 읽어 V와 곱함
sequence가 길면 이 중간 행렬이 매우 커지고 HBM traffic이 증가한다.
10.2 FlashAttention의 핵심
FlashAttention은 Attention을 작은 tile로 나눈다.
- Q/K/V block을 on-chip SRAM에 올린다.
- block 단위로 score와 softmax 통계를 계산한다.
- 전체
S \times S중간 행렬을 HBM에 materialize하지 않는다. - backward에서 일부 값을 저장하는 대신 다시 계산한다.
10.3 복잡도
FlashAttention은 exact attention의 수학적 결과를 유지하면서 HBM 접근과 추가 메모리를 줄인다.
- FLOPs: 여전히
O(S^2d) - 입력·출력 외 추가 메모리: 선형 수준
- 핵심 개선: HBM read/write 감소
즉 FlashAttention은 일반적으로 Attention을 근사해 빨라지는 방법이 아니다. 같은 계산을 GPU 메모리 계층에 맞게 재구성한다. [6]
10.4 중요한 시스템 원리
GPU에서는 FLOP를 조금 더 수행하더라도 HBM 접근을 크게 줄이면 전체 실행이 더 빨라질 수 있다.
이 원리는 FlashAttention뿐 아니라 activation recomputation, kernel fusion, quantization kernel에도 적용된다.
11. 추론 최적화 기법
11.1 Continuous batching
고정 batch는 가장 늦게 끝나는 요청 때문에 나머지 slot이 놀 수 있다. Continuous batching은 decode step 사이에 완료 요청을 제거하고 새 요청을 넣는다.
효과:
- GPU 유휴 slot 감소
- throughput 증가
- queue와 scheduling 정책에 따라 tail latency 변화
11.2 Prefix caching
여러 요청이 동일한 system prompt나 긴 prefix를 공유하면 해당 prefix의 KV cache를 재사용할 수 있다.
공통 system prompt
→ KV cache 1회 계산
→ 여러 요청이 공유
반복 prefix가 길수록 TTFT와 prefill 비용을 줄일 수 있다. cache hit rate가 낮으면 이점도 작다. [20]
11.3 Kernel fusion
작은 연산을 별도 kernel로 실행하면 각 단계에서 HBM read/write와 kernel launch가 발생한다.
RMSNorm
→ HBM write/read
→ Linear
→ HBM write/read
→ Activation
Fusion kernel은 여러 연산을 한 kernel 또는 더 적은 kernel로 묶어 중간값을 register/shared memory에 유지한다.
효과:
- HBM traffic 감소
- kernel launch overhead 감소
- 중간 tensor allocation 감소
11.4 CUDA Graph
반복되는 GPU 작업 그래프를 미리 capture한 뒤 재실행하면 CPU의 반복 kernel launch overhead를 줄일 수 있다. 다만 동적 shape와 batch 변화가 크면 graph 관리가 복잡해질 수 있다. [16]
11.5 Speculative decoding
작은 draft model이 여러 token 후보를 먼저 만들고 큰 target model이 후보들을 한 번에 검증한다.
draft: token A, B, C, D 제안
target: A~D 병렬 검증
→ 허용된 prefix 채택
적절한 알고리즘은 target model의 출력 분포를 유지하면서 target model의 순차 실행 횟수를 줄일 수 있다. [15]
Trade-off:
- draft model 계산과 메모리 추가
- acceptance rate가 낮으면 이점 감소
- target 검증 batch의 GPU 활용도 향상 가능
11.6 Offloading
일부 weight, optimizer state, KV cache를 CPU memory나 storage로 내릴 수 있다.
장점:
- GPU VRAM보다 큰 모델 실행 가능
단점:
- PCIe 또는 네트워크 전송 병목
- latency 증가
- prefetch와 overlap 설계 필요
Offloading은 메모리 용량 문제를 완화하지만 대역폭 문제를 다른 계층으로 이동시키는 방식이다.
12. Quantization과 GPU
12.1 정밀도를 낮추는 이유
정밀도가 낮아지면 보통 다음 효과가 있다.
- weight와 activation 메모리 감소
- HBM traffic 감소
- 지원되는 GPU에서는 행렬 처리량 증가
- 동일 VRAM에서 batch 또는 KV cache 여유 증가
12.2 Training과 inference quantization은 다르다
학습에서는 gradient 안정성과 dynamic range 때문에 mixed precision 관리가 중요하다. 추론에서는 weight-only INT8/INT4, weight-activation quantization, KV cache quantization 등 다양한 선택이 가능하다.
12.3 4bit가 항상 8bit보다 두 배 빠르지 않은 이유
- dequantization 비용
- packing/unpacking
- scale과 zero-point load
- GPU의 native instruction 지원 차이
- kernel 품질
- 비행렬 연산 비중
- batch와 shape
- KV cache 정밀도가 별도일 수 있음
- communication과 scheduler 비용
때문이다.
Quantization은 순수 weight 용량 감소 효과는 계산하기 쉽지만 실제 end-to-end 속도는 반드시 benchmark해야 한다.
12.4 품질 손실
낮은 bit 수는 weight 표현 오차를 만든다. 모델별 sensitivity, calibration data, quantization 방식, outlier 처리에 따라 품질 손실이 달라진다.
따라서 운영 판단은 최소 다음을 함께 비교해야 한다.
- 정확도/평가 점수
- TTFT
- TPOT
- throughput
- 최대 동시 요청 수
- VRAM
- 전력과 비용
13. 여러 GPU에 LLM을 분산하는 방법
13.1 Data Parallelism(DP)
각 GPU가 모델 전체 복사본을 가지고 서로 다른 batch를 처리한다.
GPU 1: model replica + batch A
GPU 2: model replica + batch B
GPU 3: model replica + batch C
GPU 4: model replica + batch D
각 GPU가 gradient를 계산한 뒤 AllReduce 등으로 동기화한다.
장점:
- 개념이 단순하다.
- 큰 global batch 처리에 적합하다.
단점:
- model과 optimizer state가 GPU마다 중복된다.
- gradient 동기화 비용이 발생한다.
- 기본 DP만으로는 한 GPU보다 큰 모델을 담지 못한다.
13.2 ZeRO와 FSDP
Data Parallelism의 중복 상태를 shard한다.
- ZeRO Stage 1: optimizer state 분할
- ZeRO Stage 2: optimizer state와 gradient 분할
- ZeRO Stage 3: optimizer state, gradient, parameter 분할
필요한 layer의 parameter를 계산 시점에 모으고 사용 후 다시 분산할 수 있다. 메모리는 절약되지만 AllGather, ReduceScatter와 같은 통신이 추가된다. [7][18]
13.3 Tensor Parallelism(TP)
한 layer의 weight matrix를 여러 GPU로 분할한다.
W = [W1 | W2 | W3 | W4]
GPU 1 → W1
GPU 2 → W2
GPU 3 → W3
GPU 4 → W4
각 GPU가 부분 결과를 계산한 뒤 AllReduce, AllGather, ReduceScatter 등으로 합친다.
장점:
- 한 layer를 여러 GPU 메모리에 분산할 수 있다.
- 단일 모델의 연산을 동시에 수행한다.
단점:
- 거의 매 layer 통신이 발생할 수 있다.
- 작은 tensor나 느린 interconnect에서는 통신 지연이 커진다.
- TP degree를 과도하게 높이면 GPU당 GEMM이 작아져 효율이 떨어질 수 있다.
Megatron-LM은 Transformer 내부 행렬을 나누는 tensor model parallel 방식을 제시했다. [10]
13.4 Pipeline Parallelism(PP)
layer 범위를 GPU별로 나눈다.
GPU 1: Layer 1~20
GPU 2: Layer 21~40
GPU 3: Layer 41~60
GPU 4: Layer 61~80
여러 microbatch를 파이프라인으로 흘려 GPU 유휴 시간을 줄인다.
문제는 pipeline bubble이다.
- 뒤 stage는 첫 activation이 도착할 때까지 기다린다.
- 앞 stage는 마지막 microbatch를 보낸 뒤 먼저 빈다.
- stage별 계산량이 불균형하면 가장 느린 stage에 맞춰진다.
13.5 Sequence Parallelism(SP)
sequence dimension의 activation 연산을 GPU 사이에 나눈다. Tensor Parallelism과 함께 사용해 activation 중복을 줄일 수 있다. 긴 sequence 학습에서 activation 메모리를 줄이는 데 유용하다. [8]
13.6 Context Parallelism(CP)
긴 context 자체를 여러 GPU에 분산한다. Attention 계산에 필요한 K/V나 부분 통계를 GPU 사이에 교환해야 하므로 context 길이, network topology, attention algorithm에 따라 효율이 달라진다. [19]
13.7 Expert Parallelism(EP)
Mixture-of-Experts 모델의 expert를 GPU별로 나눈다.
token
→ router
→ 선택된 expert가 있는 GPU로 이동
→ expert 계산
→ 원래 흐름으로 복귀
All-to-All 통신이 중요하다.
MoE의 특징:
- 전체 parameter 수는 매우 클 수 있다.
- token당 일부 expert만 활성화되어 계산량은 제한할 수 있다.
- 전체 expert weight 저장 공간은 여전히 필요하다.
- routing imbalance와 network all-to-all이 병목이 될 수 있다.
13.8 실제 대규모 구성
실제 학습은 한 종류만 사용하지 않고 여러 차원을 결합한다.
Data Parallel
× Tensor Parallel
× Pipeline Parallel
× Sequence/Context Parallel
× Expert Parallel
어떤 조합이 최적인지는 다음에 달려 있다.
- 모델 크기와 layer 수
- hidden dimension
- sequence length
- GPU VRAM
- 노드당 GPU 수
- NVLink/NVSwitch 구성
- 노드 간 network
- microbatch와 global batch
- MoE 여부
14. GPU 간 통신
14.1 주요 collective
| 연산 | 의미 | 대표 사용처 |
|---|---|---|
| AllReduce | 모든 GPU 값을 합쳐 모든 GPU에 제공 | DP gradient 동기화 |
| AllGather | 각 GPU 조각을 모아 전체 tensor 구성 | parameter/activation gathering |
| ReduceScatter | 합산 후 결과 조각을 GPU별 분배 | FSDP/ZeRO, TP/SP |
| All-to-All | GPU별 데이터를 서로 재분배 | Expert Parallelism |
| Send/Recv | stage 사이 point-to-point 전송 | Pipeline Parallelism |
NCCL은 AllReduce, AllGather, ReduceScatter, All-to-All 등 다중 GPU collective의 동작과 호출 규칙을 공식 문서로 제공한다. [17]
14.2 연결 계층
일반적으로 통신 경로는 다음 계층을 가진다.
같은 GPU 내부
→ 같은 노드 NVLink/NVSwitch
→ 같은 노드 PCIe
→ 노드 간 InfiniBand/RoCE/Ethernet
대역폭과 지연시간이 다르므로 통신이 잦은 Tensor Parallel group은 보통 빠른 scale-up domain 안에 배치하는 것이 유리하다. Data Parallel group은 상대적으로 큰 계산 사이에 통신하므로 노드 간 확장에 배치할 여지가 있다. 실제 배치는 모델 shape와 network topology를 측정해 결정해야 한다.
14.3 계산과 통신 overlap
이상적인 분산 시스템은 일부 tensor를 계산하는 동안 이전 tensor의 통신을 진행한다.
compute layer N+1
동시에
communicate layer N result
통신을 숨길 수 없다면 GPU 수가 늘어도 속도가 선형으로 증가하지 않는다.
15. GPU를 두 배 늘려도 두 배 빨라지지 않는 이유
이상적인 실행시간은 다음과 같다.
T_{ideal}
=
\frac{\text{Total FLOPs}}
{\text{GPU count} \times \text{Sustained FLOPS per GPU}}
실제 실행시간은 다음에 더 가깝다.
T
=
T_{compute}
+T_{memory}
+T_{communication}
+T_{pipeline\ bubble}
+T_{launch}
+T_{idle}
+T_{checkpoint}
GPU 수가 증가할수록 다음 문제가 나타난다.
- collective 참여 GPU 증가
- 네트워크 hop과 혼잡
- 작은 per-GPU matrix로 인한 Tensor Core 효율 저하
- pipeline bubble
- stage imbalance
- straggler
- 동기화 지연
- 장애 확률 증가
- checkpoint 규모 증가
따라서 “GPU 개수”보다 sustained utilization과 scaling efficiency가 중요하다.
16. Peak FLOPS와 실제 성능이 다른 이유
GPU 사양표의 peak FLOPS는 특정 조건에서의 이론값이다.
- 특정 dtype
- 특정 Tensor Core instruction
- 충분히 큰 matrix
- 올바른 shape/alignment
- 데이터 준비 완료
- sparsity 적용 여부
실제 LLM에는 다음이 섞여 있다.
- GEMM
- Attention
- normalization
- softmax
- element-wise operation
- sampling
- memory allocation
- communication
- kernel launch
따라서 GPU 비교 시 다음을 구분해야 한다.
- FP32 CUDA Core FLOPS
- TF32 Tensor FLOPS
- BF16/FP16 Tensor FLOPS
- FP8/FP4 Tensor FLOPS
- dense 성능과 structured-sparse 성능
- HBM bandwidth
- VRAM capacity
- 실제 모델 benchmark
16.1 MFU와 utilization
Model FLOPs Utilization(MFU)은 모델이 이론적으로 필요로 하는 FLOPs가 GPU peak throughput의 얼마만큼으로 실행됐는지를 보는 지표다.
높은 일반 GPU utilization이 항상 높은 MFU를 뜻하지는 않는다. GPU가 memory stall이나 통신 대기로 바쁘게 표시될 수 있기 때문이다.
함께 볼 지표:
- Tensor Core active 비율
- SM occupancy
- achieved FLOPS
- HBM throughput
- kernel별 시간
- collective 시간
- idle/bubble 시간
- CPU launch gap
17. GPU와 모델 구조의 공동 설계
모델 구조는 순수한 알고리즘 선택만이 아니라 하드웨어 효율의 영향을 받는다.
17.1 Shape alignment
Tensor Core는 특정 dimension 정렬과 tile 크기에서 효율이 좋다. 따라서 hidden dimension, head dimension, intermediate size, batch/token 수가 kernel-friendly한 shape인지가 중요하다. [12]
17.2 GQA/MQA
KV head 수를 줄여 KV cache 용량과 decode memory traffic을 줄인다.
17.3 SwiGLU와 MLP dimension
모델 품질뿐 아니라 GEMM shape와 parameter budget을 함께 고려해 intermediate dimension을 선택한다.
17.4 MoE
전체 parameter 규모를 키우면서 token당 활성 계산량을 제한한다. 대신 expert weight 배치와 All-to-All 통신 문제가 생긴다.
17.5 Long-context architecture
긴 context는 단순히 설정값 하나를 늘리는 문제가 아니다.
- Attention FLOPs
- Attention IO
- KV cache
- position encoding
- context parallelism
- serving batch
- latency
가 함께 변한다.
17.6 작은 모델을 더 많이 학습하는 선택
학습 FLOP 예산이 같아도 모델 파라미터 수와 학습 token 수의 조합이 다를 수 있다. GPU compute budget은 모델 크기뿐 아니라 데이터 양과 학습 기간을 결정하며, inference 비용까지 고려하면 더 작은 모델을 오래 학습하는 선택이 유리할 수도 있다. [5]
18. GPU가 모델 품질에 미치는 영향
GPU가 직접 결정하는 것은 실행 능력이다.
- 학습 시간
- 추론 latency
- throughput
- 최대 batch
- 최대 context
- 실행 가능한 model size
- 동시 사용자 수
모델 품질은 주로 다음이 결정한다.
- 데이터 품질과 양
- architecture
- parameter 수
- tokenizer
- objective
- optimizer와 learning-rate schedule
- training stability
- post-training
- preference optimization
- inference-time algorithm
다만 GPU가 많으면 다음이 가능해진다.
- 더 큰 모델 학습
- 더 많은 token 학습
- 더 긴 context 실험
- 더 많은 hyperparameter 탐색
- 더 많은 post-training
- 더 많은 test-time compute
따라서 GPU는 모델 지능을 직접 생성하지 않지만 모델 품질을 높일 수 있는 계산 예산을 간접적으로 제공한다.
19. CPU, GPU, TPU, NPU, ASIC
LLM은 GPU에서만 실행할 수 있는 것은 아니다.
CPU
- 범용성과 큰 system memory가 장점이다.
- 작은 모델, 낮은 요청량, 개발 환경에서 유용하다.
- 대형 행렬 처리량과 memory bandwidth는 일반적으로 고성능 GPU보다 불리하다.
GPU
- 높은 병렬 처리량
- 높은 memory bandwidth
- 범용 programming 가능
- 성숙한 CUDA/PyTorch/JAX 생태계
- 학습과 추론 모두 대응
TPU/NPU/AI ASIC
- tensor 연산과 dataflow에 더 특화될 수 있다.
- 특정 workload에서 전력 효율이나 throughput이 좋을 수 있다.
- software stack, 지원 operation, shape 유연성, 배포 환경의 제약이 있을 수 있다.
FPGA
- 특정 pipeline을 맞춤 구성할 수 있다.
- 개발 복잡도가 높고 빠르게 변하는 모델 구조에 대응하기 어렵다.
GPU가 널리 쓰이는 이유는 peak 연산량만이 아니라 하드웨어 성능, 범용성, compiler, kernel, communication library, profiler, 연구 생태계가 결합되어 있기 때문이다.
20. LLM GPU 소프트웨어 스택
일반적인 학습·추론 스택은 다음과 같다.
Application / Serving API
→ PyTorch, JAX 또는 inference engine
→ graph compiler / runtime / scheduler
→ CUDA, Triton, custom kernel
→ cuBLAS 등 수학 library
→ NCCL collective communication
→ GPU SM / Tensor Core / HBM
각 계층은 서로 다른 병목을 만든다.
| 계층 | 대표 문제 |
|---|---|
| Application | 작은 요청, 비효율적 queue, 과도한 동기화 |
| Framework | 불필요한 tensor 생성, graph break |
| Compiler/kernel | fusion 부족, 비효율적 tile, unsupported shape |
| Runtime | memory fragmentation, launch overhead |
| Communication | 느린 collective, topology 불일치 |
| Hardware | VRAM 부족, HBM/compute/interconnect 한계 |
같은 모델과 같은 GPU를 사용해도 실행 엔진과 설정에 따라 성능이 달라지는 이유다.
21. GPU 선택 시 확인할 항목
21.1 먼저 workload를 구분한다
- 사전학습
- full fine-tuning
- LoRA/QLoRA
- offline batch inference
- 실시간 chat serving
- 긴 context serving
- embedding/reranking
workload에 따라 필요한 자원이 다르다.
21.2 용량 계산
최소한 다음을 계산한다.
weight
+ KV cache
+ activation
+ optimizer/gradient(학습 시)
+ communication/workspace
+ allocator 여유
21.3 성능 지표
- 사용할 dtype의 실제 Tensor throughput
- HBM bandwidth
- VRAM capacity
- GPU 간 interconnect
- 노드 간 network
- 전력·냉각
- ECC와 장시간 안정성
- framework/kernel 지원
21.4 Serving benchmark
다음 조건을 고정해야 비교가 의미 있다.
- 동일 모델과 quantization
- 동일 prompt length
- 동일 output length
- 동일 batch 또는 concurrency
- 동일 latency SLO
- 동일 sampling 설정
- warm-up 여부
- prefix cache hit 여부
보고할 값:
- TTFT p50/p95/p99
- TPOT p50/p95/p99
- request throughput
- token throughput
- peak VRAM
- GPU power
- error/timeout rate
21.5 Training benchmark
- tokens/s
- step time
- MFU
- peak allocated/reserved VRAM
- collective 비율
- checkpoint 시간
- loss curve와 numerical stability
- scale-out efficiency
22. 계산 예시 모음
22.1 Weight 메모리
70B BF16 모델:
70 \times 10^9 \times 2\text{ bytes}
=140\text{GB}
이는 순수 weight만의 값이다.
22.2 INT4 weight
70B INT4 모델의 이론적 최소 weight:
70 \times 10^9 \times 0.5\text{ bytes}
=35\text{GB}
scale, metadata, workspace가 추가된다.
22.3 Adam 학습 상태
70B, 16 bytes/parameter 가정:
70 \times 10^9 \times 16
=1.12\text{TB}
activation과 buffer는 별도다.
22.4 학습 FLOPs
7B 모델, 1T tokens:
6ND
=6 \times 7 \times 10^9 \times 10^{12}
=4.2 \times 10^{22}\text{ FLOPs}
22.5 KV cache
80 layer, 8 KV heads, head dimension 128, BF16:
327{,}680\text{ bytes/token/sequence}
32K context:
327{,}680 \times 32{,}768
\approx 10\text{GiB}
22.6 이상적인 학습 시간
총 학습 FLOPs가 C, GPU 수가 G, GPU당 sustained FLOPS가 F이면:
T_{ideal}=\frac{C}{GF}
실제 시간은 통신, checkpoint, data loading, failure, bubble 때문에 더 길다.
23. 자주 생기는 오해
“GPU가 많으면 모델이 자동으로 똑똑해진다”
아니다. GPU는 더 큰 학습과 더 많은 실험을 가능하게 할 뿐이다. 데이터와 학습 방법이 잘못되면 GPU를 늘려도 품질이 보장되지 않는다.
“VRAM이 크면 무조건 빠르다”
아니다. VRAM capacity는 모델이 들어가는지를 결정한다. 속도는 Tensor throughput, HBM bandwidth, kernel, batch, 통신 영향을 함께 받는다.
“GPU 두 장이면 VRAM이 자동 합산된다”
아니다. 모델 sharding을 적용해야 한다. Data Parallel replica만 만들면 모델 전체가 각 GPU에 중복된다.
“추론은 항상 FLOPS가 가장 중요하다”
아니다. 작은 batch decode는 memory bandwidth 병목이 되기 쉽다.
“긴 context는 KV cache만 늘어난다”
아니다. KV cache, prefill Attention, decode KV read, context parallel communication, batch capacity, latency가 함께 변한다.
“Quantization bit를 절반으로 줄이면 속도가 정확히 두 배다”
아니다. dequantization, kernel 지원, non-GEMM 연산, communication 때문에 end-to-end 비율은 달라진다.
“FlashAttention은 근사 Attention이다”
일반적인 FlashAttention은 exact Attention을 IO-aware하게 계산한다. FLOP 복잡도는 여전히 제곱이지만 HBM 접근과 추가 메모리를 줄인다.
“GPU utilization 100%면 최적이다”
아니다. memory stall이나 비효율적인 kernel로도 GPU가 busy하게 보일 수 있다. MFU, achieved FLOPS, HBM throughput, communication time을 같이 봐야 한다.
“Peak FLOPS가 높은 GPU가 모든 LLM workload에서 빠르다”
아니다. decode는 HBM bandwidth, 대형 모델은 VRAM과 interconnect, 긴 context는 KV cache와 Attention IO가 더 중요할 수 있다.
24. 전체 흐름 요약
학습
텍스트 데이터
→ tokenization
→ batch
→ embedding
→ Transformer forward
→ loss
→ backward
→ gradient collective
→ optimizer update
→ checkpoint
주요 병목:
- Tensor FLOPS
- activation/optimizer memory
- HBM bandwidth
- collective communication
- checkpoint IO
추론
사용자 요청
→ tokenization
→ queue / continuous batch
→ prefill
→ KV cache 생성
→ decode 반복
→ sampling
→ streaming response
주요 병목:
- Prefill: compute와 Attention IO
- Decode: weight·KV cache memory traffic
- Serving: batching, scheduler, memory management
- Multi-GPU: TP collective와 interconnect
25. 최종 정리
- LLM의 대부분은 행렬 곱이므로 GPU의 대량 병렬 구조와 잘 맞는다.
- GPU의 Tensor Core는 큰 GEMM에서 강하지만 모든 LLM 연산이 GEMM인 것은 아니다.
- 학습은 forward보다 backward와 optimizer·activation 때문에 계산량과 메모리가 훨씬 크다.
- Prefill은 많은 token을 병렬 처리해 compute-bound가 되기 쉽다.
- 작은 batch Decode는 weight와 KV cache를 읽는 memory-bound 작업이 되기 쉽다.
- VRAM capacity는 model·batch·context의 상한을 정하고 HBM bandwidth는 특히 decode 속도에 영향을 준다.
- FlashAttention은 전체 Attention matrix의 HBM materialization을 피하는 IO 최적화다.
- PagedAttention은 동적으로 변하는 KV cache의 단편화와 낭비를 줄이는 serving 메모리 관리 기법이다.
- Quantization은 메모리를 확실히 줄이지만 속도와 품질 효과는 kernel과 모델에 따라 측정해야 한다.
- 여러 GPU는 자동으로 하나가 되지 않으며 DP, TP, PP, SP/CP, EP, ZeRO/FSDP 같은 분할 전략이 필요하다.
- GPU 수를 늘릴수록 통신, bubble, 작은 per-GPU workload 때문에 scaling efficiency가 떨어질 수 있다.
- GPU는 모델의 지능을 직접 결정하지 않지만 더 큰 학습·실험·서비스를 가능하게 하는 계산 예산을 제공한다.
용어 정리
| 용어 | 의미 |
|---|---|
| FLOP | 부동소수점 연산 한 번 |
| FLOPS | 초당 부동소수점 연산 수 |
| GEMM | 범용 행렬-행렬 곱 |
| HBM | GPU가 사용하는 고대역폭 메모리 계열 |
| VRAM | GPU device memory를 통칭하는 표현 |
| SM | GPU thread block을 실행하는 Streaming Multiprocessor |
| Tensor Core | 행렬 multiply-accumulate 특화 연산 장치 |
| Kernel | GPU에서 실행되는 함수 단위 |
| Arithmetic intensity | 이동 byte당 수행 FLOP 수 |
| Compute-bound | 연산 처리량이 병목인 상태 |
| Memory-bound | 메모리 대역폭·접근이 병목인 상태 |
| Prefill | 입력 prompt 전체를 처리하고 KV cache를 만드는 단계 |
| Decode | 새 token을 하나씩 생성하는 단계 |
| KV cache | 과거 token의 Key/Value를 layer별로 저장한 cache |
| TTFT | 요청부터 첫 token까지 걸린 시간 |
| TPOT | 생성 token 사이의 시간 |
| DP | 모델 replica가 서로 다른 batch를 처리하는 병렬화 |
| TP | 한 layer의 tensor를 여러 GPU로 나누는 병렬화 |
| PP | layer 범위를 여러 GPU stage로 나누는 병렬화 |
| SP/CP | sequence 또는 context를 여러 GPU로 나누는 병렬화 |
| EP | MoE expert를 여러 GPU로 나누는 병렬화 |
| MFU | 모델 유효 FLOPs 기준 GPU peak 활용률 |
출처
-
NVIDIA, CUDA Programming Guide — Introduction / Programming Model
https://docs.nvidia.com/cuda/cuda-programming-guide/01-introduction/introduction.html
https://docs.nvidia.com/cuda/cuda-programming-guide/01-introduction/programming-model.html -
NVIDIA, CUDA C Programming Guide — GPU 병렬 구조와 메모리 계층
https://docs.nvidia.com/cuda/archive/12.5.0/cuda-c-programming-guide/index.html -
Ashish Vaswani et al., Attention Is All You Need, 2017
https://arxiv.org/abs/1706.03762 -
NVIDIA, Matrix Multiplication Background User's Guide — Arithmetic Intensity와 Math/Memory Bound
https://docs.nvidia.com/deeplearning/performance/dl-performance-matrix-multiplication/index.html -
Jordan Hoffmann et al., Training Compute-Optimal Large Language Models, 2022
https://arxiv.org/abs/2203.15556
상세 FLOP 계산 부록 PDF: https://arxiv.org/pdf/2203.15556 -
Tri Dao et al., FlashAttention: Fast and Memory-Efficient Exact Attention with IO-Awareness, 2022
https://arxiv.org/abs/2205.14135 -
Samyam Rajbhandari et al., ZeRO: Memory Optimizations Toward Training Trillion Parameter Models, 2019
https://arxiv.org/abs/1910.02054 -
Vijay Korthikanti et al., Reducing Activation Recomputation in Large Transformer Models, 2022
https://arxiv.org/abs/2205.05198 -
Woosuk Kwon et al., Efficient Memory Management for Large Language Model Serving with PagedAttention, 2023
https://arxiv.org/abs/2309.06180 -
Mohammad Shoeybi et al., Megatron-LM: Training Multi-Billion Parameter Language Models Using Model Parallelism, 2019
https://arxiv.org/abs/1909.08053 -
NVIDIA, Transformer Engine — Using FP8 and FP4
https://docs.nvidia.com/deeplearning/transformer-engine/user-guide/examples/fp8_primer.html -
NVIDIA, Get Started With Deep Learning Performance — Tensor Core Alignment과 Arithmetic Intensity
https://docs.nvidia.com/deeplearning/performance/dl-performance-getting-started/index.html -
Noam Shazeer, Fast Transformer Decoding: One Write-Head is All You Need, 2019
https://arxiv.org/abs/1911.02150 -
Joshua Ainslie et al., GQA: Training Generalized Multi-Query Transformer Models from Multi-Head Checkpoints, 2023
https://arxiv.org/abs/2305.13245 -
Yaniv Leviathan et al., Fast Inference from Transformers via Speculative Decoding, 2022
https://arxiv.org/abs/2211.17192 -
NVIDIA, CUDA Programming Guide — CUDA Graphs
https://docs.nvidia.com/cuda/cuda-programming-guide/04-special-topics/cuda-graphs.html -
NVIDIA, NCCL User Guide — Collective Operations
https://docs.nvidia.com/deeplearning/nccl/user-guide/docs/usage/collectives.html -
PyTorch, FullyShardedDataParallel 공식 문서
https://docs.pytorch.org/docs/stable/fsdp.html -
NVIDIA, Megatron Core — Context Parallel API Guide
https://docs.nvidia.com/megatron-core/developer-guide/latest/api-guide/context_parallel.html -
vLLM, Automatic Prefix Caching 공식 문서
https://docs.vllm.ai/en/latest/features/automatic_prefix_caching/
댓글