cudatraining · 학습 기록
《The Stack》 EP.42 2026 · APR · 19 38 MIN IMAGINARY

너희 GPT 는 왜
내 GPU 를 이렇게 쓰게 됐을까

7주 만에 vector_add 에서 Flash Attention 까지 걸어온 한 엔지니어의 경로를 역순으로 재생해본다 — 그러면 현대 LLM 이 왜 정확히 이 모양으로 진화했는지, 하드웨어와 모델이 어떻게 공진화해왔는지가 드러난다.

S
Host
샘 (Sam)
가상 · 모델 쪽에서 묻는 사람
J
Guest
젠슨 (Jensen)
가상 · 칩 쪽에서 대답하는 사람
00 · 02:14Cold Open

역순으로 가보자 — 그러면 모든 게 설명돼.

SAM
오늘 좀 이상한 컨셉으로. 엔지니어 한 명이 CUDA 배우는 걸 옆에서 지켜봤어. 7주 만에 vector_add 에서 Flash Attention 까지. 그걸 보다 보니 계속 질문이 맴돌아. 왜 GPGPU 는 하필 이 모양으로 진화했을까?
JENSEN
(웃음) 그럼 역순으로 가보자고. 요즘 사람들이 제일 많이 부르는 커널이 Flash Attention 이잖아. 거기서 거꾸로 가보면 대충 모든 게 설명돼.
01 · 08:03거리가 제일 비싸다

계산은 공짜에 가깝고, 데이터 이동이 100배 비싸다.

GPU 안에서 숫자 하나 더하는 건 1 나노초. 그걸 HBM 에서 가져오는 건 100 나노초. 이 비율 하나가 GPU 프로그래밍의 모든 결정을 지배한다.

FIG 1 · 계층별 접근 비용lower = faster
FMA (register)~1 ns
L1 / smem~5 ns
L2 cache~20 ns
HBM~100 ns
PCIe H↔D~10 µs
InfiniBand~2 µs /byte²
레슨 1 · 2 에서 몸으로 확인한 것

vector_add 커널은 3.5 ms. 그런데 같은 데이터의 PCIe 복사만 60 ms. 커널이 17 배 짧다. pinned memory 를 쓰지 않으면 end-to-end 가 5.6 배 느려진다.

SAM
음… GPU 안에서 숫자 하나 더하는 데 얼마나 걸려?
JENSEN
대략 1 나노초. 근데 그 숫자를 HBM 에서 가져오는 데는 400–500 사이클, 거의 100 나노초. 계산은 공짜에 가깝고, 데이터 이동이 100 배 비싸.
"실리콘 밖으로 나가는 순간 100배.
그 사실이 LLM 아키텍처의 절반을 정했어."— Jensen, 09:41
SAM
그러니까 게임은 계산을 빨리 하는 것 이 아니라 데이터 이동을 피하는 것.
JENSEN
바로 그거. 그래서 NVLink 만들고, HBM 집적도 올리고, L2 캐시 48 MB 까지 키운 거야. 자꾸 이 "거리" 를 줄이려는 거지. 근데 물리학이 허락 안 해주는 부분이 있어.
SAM
GPU 클러스터 묶을 때 제발 같은 노드에 두려고 애쓰는 이유가 이거였구나.
02 · 13:41병렬은 공짜가 아니다

병렬 하드웨어에 직렬 알고리즘을 넣으면 하드웨어가 직렬로 변한다.

쓰레드가 수만 개니까 원자적 덧셈을 다 같이 하면 빠르겠지? 아니다. 100 배 느려진다. 그래서 GPU 에는 __shfl_down_sync 같은 이상한 명령어가 박혀 있다.

SAM
GPU 는 쓰레드가 수만 개잖아. 그냥 다 동시에 더하면 빠르지 않아?
JENSEN
그게 레슨 3 의 함정이야. 버전 1: 모든 쓰레드가 같은 주소에 atomicAdd. 결과가 몇 ms 나왔게?
SAM
… 빠를 것 같은데?
133 ms. 다른 버전은 1 ms.
100 배 차이.— Jensen, 14:58
SAM
잠깐, 그러니까 GPU 하드웨어의 이상한 feature 들 — shared memory, warp shuffle — 이게 다 "소프트웨어가 이런 패턴을 필요로 하니까 하드웨어에 넣은 것" 이라고?
JENSEN
그게 co-design 이야. __shfl_down_sync 는 1.0 에는 없었어. 사람들이 tree reduction 을 너무 많이 쓰니까 6년 뒤에 넣어준 거지. 지금은 표준이고.
FIG 2A · atomicAdd — 한 줄에 선 백만 명SERIAL
sum … 백만 개 하나씩, 순서대로 ATM hardware serializes writers → 133 ms
FIG 2B · tree reduction — log N 단계PARALLEL
level log N reg / smem swap bar.sync between warp-shuffle level (no sync, reg swap) result: 1 ms · 100× faster
__syncthreads() 도 공짜가 아니다

5 번을 지우면 29% 빨라진다. 작은 커널에서는 sync 한 번이 실행시간의 1/3. 그래서 마지막 warp 는 sync 없이 shuffle 만 돌리는 게 관용구가 됐다.

03 · 20:02행렬곱이 LLM을 먹여 살린다

네 번의 점프 — 그리고 마지막 점프는 하드웨어가 등장한다.

레슨 4 가 제일 길었던 이유. tiling 과 register blocking 이 연산 강도를 올리는 소프트웨어의 기술이라면, 그 다음 8 TFLOPS 천장을 뚫은 건 Tensor Core 라는 새 유닛 이었다.

FIG 3 · matmul v1 → v4 — T4, 4096³TFLOPS
0 2 4 6 8 TFLOPS FP32 FMA peak · 8.1 TFLOPS Tensor Core · 65 TFLOPS → v1 · naive 0.4 global-only loads v2 · smem tiling 0.8 re-use tile in smem v3 · register blk 2.0 4×4 per-thread v4 · Tensor Core 7.9 mma · new hardware (Triton fp16) 54 ref · Lesson 08 2.5×
SAM
v4 에서 축이 점프했네.
JENSEN
나머지 세 개는 "HBM 덜 읽게 만드는 법" — 연산 강도(AI)를 올리는 거야. byte 당 몇 flop 뽑냐. 근데 아무리 해도 FP32 peak 8 TFLOPS 에서 막혀. 그래서 Volta 때 하드웨어에 4×4 matmul 블록을 박아넣은 거지.
SAM
2023년에 GPT-4 훈련하면서 FP16, BF16, FP8 얘기 들었던 게 다 Tensor Core 에 맞추려고 그랬던 거구나.
100% 그거야. Tensor Core 는 정밀도를 낮춘 입력에만 동작해. FP4 로 계속 내려가는 건 모델 때문이 아니라 내 칩 때문이기도 해.— Jensen, 22:48
occupancy trap

"타일을 크게 하면 AI 가 올라가서 빠르겠지" 는 반만 맞다. 블록 수가 SM 수보다 충분히 많아야 의미가 있다. 그래서 decode 커널과 prefill 커널은 다르게 생겼다.

04 · 25:38Fusion, 어두운 기술

세 커널을 하나로 합치면 HBM trip 이 절반이 된다 — 그게 2× speedup.

FIG 4A · BEFORE · 3 kernel, 4 HBM tripsunfused
k1max(x) → mR → W
k2exp(x − m) → num, sumR → W
k3num / sum → yR → W
total4 trips · 1.0×
FIG 4B · AFTER · 1 kernel, 2 HBM tripsfused online
k1pass 1: running (m, s) in registersR
k1pass 2: y = exp(x−m)/sR → W
total2 trips · ~2×
SAM
Softmax 는 수학적으로 세 단계지. 그냥 편하게 커널 세 번 부르면 되잖아.
JENSEN
그러면 HBM trip 4 번. 세 단계를 한 커널에 합치면 HBM trip 2 번. 2× 빨라져. 측정치 — 2.02×, 1.86×, 1.92×. 거의 이론치 그대로. 이게 operator fusion 이야.
왜 다 합쳐서 하나의 거대 커널로 안 만들지?
— shared memory 가 유한, 코드 조합 폭발, 정밀도 이슈.
"항상 좋은 것" 이 아니라 "핫패스에만 골라서 하는 기술."
— Jensen, 27:10
SAM
그리고 online softmax — 레슨 5 의 v3 — 이 뭔가 중요한 느낌이던데.
JENSEN
그게 Flash Attention 의 수학적 절반이야. 전체 행을 못 담을 때 (max, sum) 을 정확하게 병합하는 공식. 1985 년에 NVIDIA 직원 논문에 있었고, 2022년에 Tri Dao 가 attention 에 적용했지.
ONLINE MERGE · 수식exact, O(N) memory
# merging two partial softmax statistics
new_max = max(m1, m2)
new_sum = s1 * exp(m1 − new_max)
        + s2 * exp(m2 − new_max)
05 · 28:16모든 것이 수렴하는 순간

Flash Attention 은 근본적으로 새로운 기술이 없다 — 다만 조합이 너무 날카로웠을 뿐.

N×N 중간 행렬을 아예 물리적으로 만들지 않는다. 앞서 본 5 가지 기술 — coalesced load, HBM 감각, warp reduce, tiled matmul, online softmax — 이 한 커널 안에 모두 들어간다.

FIG 5 · N=4096 에서의 HBM 트래픽65× 감소
naive attention S, P 를 전부 HBM 에 써버림 Q · 4096×d S = QKᵀ N × N = 64 MB materialized softmax V O HBM traffic 260 MB · baseline 1.0× flash attention S, P 를 HBM 에 한 번도 쓰지 않음 Q blocks Br=64 K/V blocks · Bc=32 tile Sᵢⱼ = QᵢKⱼᵀ · only in registers online (mᵢ, sᵢ) running ← Act 4 Oᵢ ← αᵢ · Oᵢ + P · V discard tile. never touches HBM. O HBM traffic 4 MB · 65× 감소 · time 4.79×
SAM
65 배 감소면 65 배 빨라져야 할 것 같은데?
JENSEN
(웃음) 실제로는 4.79 배. 왜? naive 도 실은 HBM-bound 가 아니었거든. L2 캐시가 S 행렬의 상당 부분을 캐싱해버려. FA 의 진가는 L2 가 못 담는 크기 에서 나와 — N=8k, 16k, 32k. 거기서 naive 는 아예 돌지도 못해.
GPT-4o 의 128k context 가 돌아가는 이유가 FA-2 + FA-3 때문이야. 없으면 불가능해.— Jensen, 31:44
FIG 5B · FA 한 커널에 들어간 5 가지 레슨synthesis
L1Q / K / V coalesced load→ reg
L2HBM ↔ L2 감각 · 타일 크기Br, Bc
L3warp-reduce for row max / sum__shfl_xor
L4tiled matmul in registersQ@Kᵀ, P@V
L5online (m, s) mergeAct 4 공식
06 · 33:07왜 PyTorch 야

현대 LLM 서빙 스택의 단일 접점 — torch.ops.*.

SAM
2018 년까진 CUDA 커널 짜면 대개 standalone 바이너리였잖아. 이제 아무도 그렇게 안 해.
JENSEN
생태계 때문이야. GPT-5 학습하는 PyTorch 안에 체크포인팅, 데이터 로딩, FSDP, autograd, 옵티마이저, 모델 zoo… 다 있어. 이걸 다시 만드는 건 미친 짓이야. 그래서 새 커널을 쓰려면 PyTorch 에 꽂을 수 있어야 해.
vLLM, FlashAttention-3, Mamba — 전부 torch.ops.* 에 등록된 CUDA 커널.
이게 프로덕션 LLM 서빙의 단일 접점 이 된 거야.— Jensen, 35:20
FIG 6 · 커널 하나가 생태계에 꽂히는 순간torch.compile fullgraph
Triton FA 268 lines @custom_op torch.ops.* + register_fake wrap torch.compile · fullgraph autograd integration CUDA graph capture ONNX / TorchScript stream-aware dispatch device dispatch
측정치 · 레슨 9

AttentionBlock 을 torch.compile(..., fullgraph=True) 에 통째로 넣었다. 그래프 브레이크 0 건. eager vs compiled err = 0.00e+00 — 비트 단위 동일.

그래서 왜 이런 모양이 됐나

그 친구가 7주 만에 걸어간 경로를 거꾸로 보면, 실은 Flash Attention 이 필연 이었다는 게 보인다.

FIG 7 · 6 단계 필연 체인forward → reverse
메모리는 멀다 100× gap trip 을 줄여야 한다 fusion softmax 는 전역 row max N² 은 못 담는다 online update Flash Attention tile + online 128k context GPT-4o · Claude · Gemini 이 체인의 마지막 링크가 빠지면 ChatGPT 는 지금 모양으로 존재하지 못 한다. 10 년간 GPU 는 attention 하나를 더 빨리 돌리도록 점진적으로 특화됐다.
SAM
근데 한 가지만. 너 5 년 뒤에 매트릭스곱 말고 뭘 최적화할 것 같아?
JENSEN
(잠시 침묵) … 그건 다음 편에 얘기하자고.

모든 수치는 cudatraining 레슨 1–9 핸드오프 문서, T4 sm_75 / L4 sm_89 실측.

← Back Index · 11편 기록 Ep.43 → Triton 이 숨기는 것, 노출하는 것