두 명의 저자가 한 강의에서 풀어낸 두 갈래 — William Brandon 의 GPU 프로그래밍 fundamentals (memory hierarchy, warp, async copy 의 원리적 정리) 와 Simran Arora 의 ThunderKittens (HazyResearch 의 tile-DSL 위에서 H100 의 855 TFLOPs 를 100 줄 안에 짜는 실증). "왜 또 다른 DSL 이 필요한가" 의 답을 모듈 단위로 깐 학습 노트.
2024 년 시점에서 GPU 프로그래밍의 풍경은 이미 복잡하다 — CUDA, Triton, CUTLASS, cuDNN, torch.compile 의 Inductor. 그 위에 또 하나의 라이브러리(ThunderKittens) 가 왜 필요한지부터 답하지 않으면 강의는 시작될 수 없다.
강의는 두 명의 화자가 두 단계로 답을 나눈다.
William Brandon — fundamentals. H100 의 메모리 계층(HBM ↔ L2 ↔ SMEM ↔ register), warp 와 warpgroup, TMA(Tensor Memory Accelerator), WGMMA(Warpgroup Matrix Multiply-Accumulate) 같은 하드웨어 사실들을 정리한다. 이 사실들이 곧 DSL 이 어떤 형태가 되어야 하는지를 결정한다.
Simran Arora — ThunderKittens. 위 fundamentals 위에 얹는 mini-DSL 의 디자인 — tile 을 1급 시민으로, producer/consumer 를 명시적 abstraction 으로, 그러면서도 CUDA 처럼 직접 PTX 까지 내려갈 수 있게.
강의의 인지적 frame
"DSL 의 추상 레벨이 hardware tile 의 실제 모양과 1:1 로 맞을 때 가장 빠르고 쓰기 쉽다." Hopper 의 WGMMA 는 16×16, TMA 는 box copy 단위, async barrier 는 mbarrier — 이 모양들을 그대로 노출한 게 ThunderKittens.
"우리는 fancy compiler 트릭이 아니라 tile 단위 primitive 를 내놓는다 — hardware 가 그 모양으로 동작하기 때문에."ThunderKittens 저자 · 확인 필요
§ 02H100 위 mini DSL 의 동기· why ThunderKittens
Hopper 가 만든 새로운 자리 — async, warpgroup, large registers
A100(Ampere) 에서 H100(Hopper) 로 넘어가면서 GPU 프로그래밍 모델 자체가 변했다. async copy 가 first-class 가 되고, warpgroup (4 warp = 128 thread) 단위의 행렬곱 명령(WGMMA)이 등장했다. 기존 CUDA / Triton 의 추상은 이 변화에 자연스럽게 맞지 않는다.
FIG · H100 의 새로운 자리왜 기존 DSL 추상이 새는가
HBM3 bandwidth
3.35 TB/s
SMEM (per SM)
228 KB
register file (per SM)
256 KB
peak BF16 tensor
989 TFLOPs
peak FP8 tensor
1979 TFLOPs
SMEM 과 register 는 더 이상 "작은" 자리가 아니다 — 한 SM 에 register 만 256KB, SMEM 228KB. 이 만한 공간을 효과적으로 채우려면 tile 단위 lifetime 관리가 핵심이고, 그것이 ThunderKittens 의 출발점.
왜 기존 도구로는 부족한가 — 세 가지 구체적 부담.
WGMMA 의 메모리 layout 요구 — 결과가 register tile 안에 특정 swizzling 으로 떨어진다. 이 layout 을 사람이 직접 들고 다니면 코드가 PTX 같아지고, 컴파일러에 맡기면 layout 변환 비용이 새는 자리에서 발생.
TMA 의 box copy + barrier 모델 — async memcpy 가 mbarrier 의 arrival 로 동기화된다. CUDA stream 모델보다 fine-grained, Triton 의 자동화 모델보다 explicit.
warpgroup specialization — 4 warp 묶음이 다른 역할을 동시에 한다 (예: producer warp 와 consumer warp). 이게 FA3 의 ping-pong, FA4 의 5-way specialization 의 핵심.
§ 03tile · register · smem 추상· three core abstractions
tile 이 1급 시민이 되는 mini-algebra
ThunderKittens 의 모든 코드는 tile 위에서 돈다. 최소 단위 16×16, 자료형은 register 에 있는 rt 와 shared memory 에 있는 st. 그리고 row/column vector 는 tile 의 reduction 결과로 자연스럽게 따라온다.
FIG · ThunderKittens 의 핵심 자료형 4 가지모두 16×16 tile 의 변형
REG TILE
rt<T,M,N>
register 에 분산. warp 단위 ownership. WGMMA accumulator 의 자리.
SMEM TILE
st<T,M,N>
shared memory 에 상주. block 단위 ownership. TMA 의 destination/source.
REG VEC
rv<T,N>
tile 의 row 또는 column reduction 결과. softmax 의 max/sum 자리.
GLOBAL TILE
gl<T,…,M,N>
HBM 의 indexed view. TMA descriptor 의 wrapper.
이 네 자료형 위에서 copy, load, store, mul, mma_AB, row_max, exp, sub_row 같은 연산이 정의된다. 모두 tile 단위라서 inner loop 에서 사람이 thread index 를 들고 다닐 일이 없다.
대표 연산 몇 가지의 의미.
kittens::load(st, gl) — global → smem TMA copy 발사. 비동기, mbarrier 로 완료 통지.
kittens::mma_AB(rt_acc, rt_a, st_b) — WGMMA. accumulator 는 register, B 는 SMEM. Hopper 가 요구하는 layout 자동 처리.
kittens::row_max(rv, rt) — tile 의 행별 max 를 vector 로 reduction. softmax 의 첫 단계.
모든 연산이 scope hierarchy (warp / warpgroup / block) 위에서 정의되며, 같은 함수의 warpgroup 버전은 4 warp 협업으로 큰 tile 을 한 번에 처리한다.
// ThunderKittens 의 GEMM inner loop (개념)using a_t = st<bf16,128,64>;
using b_t = st<bf16,64,128>;
using c_t = rt<float,128,128>;
c_t acc; kittens::zero(acc);
for (int k = 0; k < K; k += 64) {
// async TMA copy
kittens::load_async(a_smem, A.tile_at(m,k));
kittens::load_async(b_smem, B.tile_at(k,n));
kittens::wait(barrier, phase);
// WGMMA on warpgroup of 4 warps
warpgroup::mma_AB(acc, a_smem, b_smem);
warpgroup::mma_commit_group();
}
warpgroup::mma_async_wait();
kittens::store(C.tile_at(m,n), acc);
대조 — Triton
Triton 에서 같은 일을 짜면 tl.dot 한 줄로 끝나지만, 그 한 줄이 어떻게 WGMMA 로 lowering 되는지 는 컴파일러가 결정한다. ThunderKittens 는 그 lowering 을 사람의 손에 돌려준다 — 더 긴 코드, 더 직접적인 통제.
§ 04producer-consumer 패턴· async pipeline
"warp 의 역할을 분리한다" 가 H100 시대 커널의 표준
CUDA 의 전통은 모든 thread 가 동일한 일을 한다 (SIMT). H100 시대에는 그 모델이 깨진다 — 일부 warp 는 TMA 만 발사하고, 다른 warp 는 MMA 만 돌린다. 이게 warp specialization, ThunderKittens 가 가장 잘 잡아주는 패턴.
Producer warps
1. tile load 발사 (TMA, async)
2. mbarrier::arrive 로 완료 알림
3. 다음 K iteration 의 tile 으로 이동
4. 멀티 stage buffer 를 round-robin 사용
→ 결국 SMEM 채우는 일만 한다
Consumer warps
1. mbarrier::wait — tile 도착 대기
2. WGMMA 발사 (current stage)
3. 결과 register 에 누적
4. next stage 로 이동, producer 에 release
→ MMA 만 돌린다
FIG · 멀티 stage producer-consumer timeline2-stage 예시 — actual FA3/FA4 는 더 복잡
core idea: producer 의 load 와 consumer 의 mma 가 시간상 겹친다. SMEM 의 stage buffer 가 그 겹침을 가능하게 한다. 단계 수 (stage) 는 보통 2-4. ThunderKittens 의 template 이 stage 갯수를 parameter 로 받는다.
§ 05예제: attention· FlashAttention-3 in TK
FA3 의 ping-pong 을 ThunderKittens 의 추상으로 다시 짜기
강의에서 가장 진하게 다뤄진 예제. FlashAttention-3 의 핵심 트릭(warpgroup 두 그룹이 ping-pong 으로 softmax 와 MMA 를 번갈아 돌린다)을 ThunderKittens 의 producer/consumer 추상으로 풀어 본다.
FA3 가 H100 에서 잘 도는 이유는 두 가지.
QK^T MMA 와 softmax 의 register 의존 — softmax 는 row-wise reduction 이라 register tile 안에 leftover dependency 가 생긴다. 두 warpgroup 이 번갈아 돌면 그 dependency 가 직렬화되지 않는다.
Output PV MMA 의 별도 stream — softmax 결과 P 를 다시 V 와 곱해 O 를 만든다. 이걸 같은 warpgroup 이 하면 ping-pong 이 다시 막힌다.
ThunderKittens 가 자연스럽게 잡는 부분
warpgroup::<G0> 와 warpgroup::<G1> 의 명시적 분리, 그리고 stage buffer 의 round-robin. ping-pong 패턴을 코드 구조로 표현하므로 컴파일러의 의도 추론이 필요 없다.
실제 ThunderKittens repo 의 examples/attn/h100/ 안에 FA3 와 호환되는 reference 구현이 있고 — 강의에서는 그 코드의 핵심 30 여 줄이 어떻게 FA3 의 trick 들을 그대로 노출하는지 line-by-line 로 짚는다 (확인 필요).
"Triton 으로 FA3 를 짤 수 없는 게 아니다 — 다만 ping-pong 의 의도를 코드 구조에서 보고 싶다면 ThunderKittens 가 더 가까운 표현이다."학습 노트
§ 06예제: GEMM· 855 TFLOPs in 100 lines
"H100 peak 의 86% 를 100 줄 안에" — 의 진짜 의미
ThunderKittens 의 가장 자주 인용되는 숫자 — H100 위 BF16 GEMM 에서 855 TFLOPs (peak 989 의 86%) 를 100 줄 미만 코드로. 비교 기준을 어떻게 잡느냐에 따라 의미가 달라진다.
TAB · GEMM 구현 비교H100 SXM · BF16 · 4096³ · 개념적
구현
코드 길이
TFLOPs
peak%
특징
cuBLAS
(closed source)
~900
~91%
NVIDIA 의 hand-tuned. arch 별 변형.
CUTLASS 3
~수천 줄 template
~880
~89%
full-feature, all dtypes, but 진입 장벽 높음
Triton
~80 줄
~750-800
~76-81%
autotuner 없으면 더 낮음. 매우 짧음.
ThunderKittens
<100 줄
~855
~86%
tile primitive 직접. WGMMA explicit.
raw CUDA + WMMA
~수백 줄
~880
~89%
가장 빠르지만 가장 어려움
"86% 를 100 줄 안에" 의 의미는 단순히 빠른 게 아니다 — 그 속도를 사람이 코드를 읽고 이해할 수 있는 형태로 얻었다는 것. CUTLASS 의 코드는 빠르지만 학습 자료로는 거의 사용 불가능하다.
왜 ThunderKittens 가 86% 를 받는지 두 가지 핵심.
WGMMA 를 직접 부른다 — 컴파일러가 dot product 를 보고 lowering 하는 게 아니라 사람이 warpgroup::mma_AB 를 명시적으로 적는다. layout 변환 비용 0.
TMA 의 box copy 추상 — global → SMEM 이 single instruction 으로 발사되고 mbarrier 로 완료. async pipeline 의 fall-through case 가 없다.
§ 07Triton 과 비교· where TK fits
"같은 산을 다른 길로 오른다" — 두 도구의 위치
ThunderKittens 는 Triton 의 대체재가 아니라 다른 추상 레벨의 도구다. 강의에서 두 저자가 명시적으로 짚은 비교.
TAB · ThunderKittens vs Tritonwhere each shines
차원
Triton
ThunderKittens
언어
Python DSL, jit
C++ template + CUDA
tile 정의
tl.arange + indexing
rt<T,M,N> first-class type
WGMMA
compiler 가 tl.dot 에서 lowering
사람이 warpgroup::mma_AB 직접
TMA / async
대부분 자동, 통제 제한
explicit TMA descriptor + mbarrier
autotuning
Triton 의 강점, BLOCK_SIZE sweep
없음 — template parameter 직접
학습 곡선
완만, Python 만 알면 시작
가파름, CUDA + Hopper 모델 이해 필요
최적 use case
새 op 빨리 짜기, fusion experiment
FA / GEMM 같은 경계까지 짜내기
portability
NV / AMD 모두
H100 (TK), B200 (TK4), AMD (HipKittens), Apple (ThunderMittens) 분기
언제 어떤 걸 쓰는가
새 attention variant 를 빠르게 prototype → Triton. peak 에 가까운 production kernel → ThunderKittens. 두 단계의 워크플로가 자연스럽다 — 먼저 Triton 으로 정확성 확인, 핫패스만 TK 로 다시 짠다.
"ThunderKittens 는 fancy 한 게 아니라 단순한 거다 — hardware 가 tile 단위로 동작하니 DSL 도 tile 단위로 짠다."Simran Arora · 확인 필요
§ 08채택 사례· production users
research toy 가 아니다 — 산업 코드베이스 안에 들어가 있다
Together AI — inference 백엔드의 H100 attention/GEMM 핫패스. Together 의 enginereing 블로그에서 ThunderKittens 기반 커널 사용 사실을 명시.
채택의 공통 패턴 — 모두 "기존 cuBLAS / FlashAttention 으로는 풀기 어려운 한 자리" 가 있는 곳. 새 attention variant, 비표준 GEMM shape, 또는 fused custom operator.
채택 곡선의 분기점
ThunderKittens 가 "또 다른 DSL" 에서 "쓸만한 도구" 로 넘어간 시점은 H100 의 폭넓은 가용성이 만들어진 2024 중반. 그 전까지는 A100 의 CUTLASS 가 dominant 했고, ThunderKittens 의 추상 가치는 Hopper 의 새 기능들 (TMA, WGMMA, async warpgroup) 위에서만 진하게 드러났다.
§ 09다음 방향· HipKittens · ThunderMittens
"같은 추상, 다른 하드웨어" 로의 확장
HipKittens — AMD MI300 위로의 포팅. matrix core 와 LDS 의 양상이 다르므로 1:1 mapping 은 아니지만 tile-first 추상은 보존.
ThunderMittens — Apple Silicon (M-series) 의 GPU. Metal performance shader 위에 비슷한 abstraction 시도.
Blackwell (B200) 대응 — TMA 의 5th-gen tensor core 인 tcgen05.mma, async warp specialization 의 5-way 분리. ThunderKittens 가 FA4 같은 커널의 reference 구현 자리로 다시 호출됨 (L080 참조).
compiler 레이어 추가 — TK 코드를 기반으로 하는 더 높은 level 의 schedule autotuner. 강의에서 언급되었는지 확인 필요.
큰 그림 — tile-first DSL 이 단일 회사의 single-arch 도구가 아니라 크로스 아키텍처 추상 으로 자리잡으려는 시도. 성공 여부는 AMD/Apple 위 성능과 채택 곡선이 결정.
§ 10기억할 메모· key takeaways
다시 열었을 때 손에 잡혀야 할 것
tile = first-class
코드 안에서 thread 가 아니라 16×16 tile 이 계산의 단위. ownership 은 warp / warpgroup / block.
rt vs st
register tile vs SMEM tile. WGMMA 의 accumulator 는 항상 rt, B 행렬은 st.
producer / consumer
warp 가 같은 일 안 한다. async TMA 는 producer 가, WGMMA 는 consumer 가. mbarrier 로 동기.
stage buffer
producer 가 채우고 consumer 가 비우는 SMEM 의 round-robin. 보통 2-4 stage. parameter 로 노출.
855 TFLOPs / 100 lines
H100 peak 의 86% 를 사람이 읽을 수 있는 코드로. CUTLASS 의 wall 을 부수는 가치.
vs Triton
대체재가 아닌 다른 레벨. prototype 은 Triton, 핫패스는 TK 의 두 단계 워크플로.
cross-arch 분기
HipKittens (AMD), ThunderMittens (Apple). 같은 추상의 다른 하드웨어 매핑.
FA3 / FA4 reference
attention 의 ping-pong / 5-way specialization 이 TK 코드 안에 자연스럽게 떨어짐.
FA4 reference 가 ThunderKittens 위에 올라왔는가 — Modal 블로그가 reverse-engineer 한 FA4 가 TK 의 어느 commit 부근에서 reference 가 됐는지. 강의가 영상 시점 (2025) 에 FA4 를 다뤘는지 확인.
autotuner 의 부재 — TK 는 template parameter 를 사람이 고른다. autotuner 가 없는 게 의도인가, 추후 추가될 것인가.
HipKittens 의 성능 격차 — AMD MI300 위 GEMM 의 peak% 가 H100 의 86% 만큼 잘 나오는지. (확인 필요)
compile time — C++ template 기반이라 nvcc 컴파일 시간이 무거울 수 있다. flash-attention build 시간만큼 부담스러운지.
backward pass 의 자리 — forward pass 의 ping-pong 이 fancy 한데 backward 는 같은 추상에 자연스럽게 들어가는지. 강의가 다뤘는지 확인.
industry adoption 의 진짜 깊이 — Together / Jump / Cursor 가 어떤 커널을 정확히 어디에 쓰는지의 구체.
검증 메모
이 노트는 ThunderKittens 공식 repo / blog post / 도메인 지식으로 재구성. 자막이 없어 두 화자의 발화 순서, 시연 코드의 정확한 라인 수 등은 영상 직접 확인 필요. 특히 § 06 의 비교표 수치는 추정값으로 — 직접 GEMM 을 돌려 확인 권장.