《GPU Mode》
L045
2025 · MAR
High priority
transcript · 실패 · 외부 자료 + 도메인 지식 기반
Outperforming cuBLAS on H100
H100 의 Hopper 신기능 — TMA, WGMMA, async copy, warp specialization, block cluster, TMA multicast — 을 모두 끌어쓴 직접 작성 GEMM 커널이 cuBLAS 를 어떻게 따라잡는가. pranjalssh 의 강의 발표 (Modal blog 의 동명 시리즈와 같은 결을 공유). transcript 가 누락된 강의이므로 본 노트는 Hopper architecture 도큐먼트 + CUTLASS / Modal 의 공개 자료를 베이스로 정리한 보충 학습 노트.
H100 / Hopper
TMA
WGMMA
producer-consumer
SMEM swizzle
block cluster
cuBLAS baseline
CUTLASS 비교
P
Speaker
pranjalssh
GPU Mode 커뮤니티 contributor · CUDA 커널 엔지니어
§ 01강의가 풀려는 문제· 왜 cuBLAS 보다 빠를 수 있는가
“NVIDIA 가 만든 라이브러리보다 우리가 빠르다” 가 가능한 자리
감각이 헷갈리는 자리. cuBLAS 는 NVIDIA 가 직접 만든 GEMM 라이브러리다. 그런데 어떤 사이즈/조건에서 외부 사용자가 짠 커널이 더 빠를 수 있다. 이게 가능한 이유와 한계를 분명히 하는 게 이 강의의 가치.
강의 transcript 가 누락되었지만, 토픽이 가리키는 자리는 분명하다 — H100 의 새 hardware feature 들이 cuBLAS 에 다 반영되기까지 시간이 걸리고, 그 사이 특정 사이즈와 데이터 타입에 specialize 된 커널이 cuBLAS 의 general 한 path 를 이길 수 있다. 같은 결의 자료를 Modal blog 에서 동명 시리즈로 출간했다 — 본 노트는 Modal blog + Hopper 공식 문서를 베이스로 강의 토픽을 추정한다.
강의의 인지적 frame · 추정
cuBLAS 는 “모든 사이즈, 모든 데이터 타입, 모든 layout” 의 generality 를 지킨다. 그 generality 의 비용 — 일부 path 가 충분히 specialize 되지 않거나, 새 hardware feature 가 늦게 반영. 한 사이즈 (예: M=N=K=4096, FP16) 에 모든 trick 을 짜낸 커널이 그 path 에서는 cuBLAS 를 능가할 수 있다.
“cuBLAS 를 이긴다는 건 cuBLAS 보다 일반적으로 우월하다는 게 아니다 — 한 사이즈, 한 dtype, 한 layout 에서, peak 까지 손으로 짜냈다는 뜻이다.”학습 노트 · 도메인 정리
이 강의의 실용적 산출 — Hopper 의 모든 trick 이 한 자리에 모인 reference GEMM. L043 의 Turing 5단계 사다리를 출발점으로 하면, 이 강의가 그 사다리에 TMA, WGMMA, warp specialization, cluster, swizzle 까지 추가한 H100 버전.
§ 02cuBLAS 가 못 잡는 자리· general-purpose 의 비용
“같은 일을 하는 더 빠른 방법” 이 있다 — 단, 보편적이지 않다
cuBLAS 의 디자인 제약 — 모든 사이즈, 모든 dtype 조합, 모든 stride/layout, 모든 alpha/beta 조합에서 합리적으로 빠르게 동작해야 한다. 이 generality 가 비용으로 돌아오는 자리.
SIZE
"이상한" 크기
M=N=K 가 SM 수의 배수도 아니고, tile 의 자연스러운 크기도 아닐 때. cuBLAS 는 일반화된 padding/tile 로 처리하면서 utilization 떨어짐.
SHAPE
tall/skinny
M=2, N=K=4096 같은 GEMV-급 모양. cuBLAS 는 이런 자리에 specialize 된 별도 path 가 있긴 하지만, 모든 조합을 다 못 잡음.
EPI
epilogue 결합
GEMM 끝에 add bias / activation / scale 등을 fuse 하고 싶을 때. cuBLASLt 가 일부 epilogue 지원하지만 LLM 의 복잡한 fusion 은 직접 짜야 함.
DTYPE
신규 dtype
FP8 같은 새 dtype. cuBLAS 가 지원해도 모든 corner case 가 충분히 specialize 되기까지 시간 차이.
그래서 “cuBLAS 격파” 는 한 자리에서의 격파. 강의가 보여줬을 자리들 (추정).
- 크기 sweep 을 그려서 어떤 사이즈에서 custom 이 cuBLAS 보다 빠른지 확인. 보통 큰 square (M=N=K=8192) 와 매우 tall/skinny 양극단.
- FP16 / BF16 / FP8 별로 격차가 다르다. 보통 새 dtype 일수록 cuBLAS specialize 가 부족 → custom 격차 큼.
- cuBLAS 의 persistent kernel path vs sliced-K split path 등 자기들끼리도 여러 strategy. custom 은 한 strategy 만 깊게.
"이긴다" 의 의미 신중히
cuBLAS 는 모든 사이즈에서 합리적으로 빠르다. custom 커널은 한 사이즈에서 더 빠르고 다른 사이즈에서 훨씬 느릴 수 있다. production 시스템은 보통 cuBLAS 또는 cuBLASLt 를 fallback 으로 두고, 특정 hot path 만 custom 으로 갈아끼운다.
§ 03H100 의 새 자원· TMA · WGMMA · 4th gen tensor core · cluster
Ampere 사다리에 5개 새 도구가 추가됐다
L043 의 Turing 사다리 — column-major → SMEM → register tile → double buffer — 가 Ampere(A100) 위에서 추가로 cp.async 를 만난다. Hopper(H100) 는 거기서 한 번 더, 5개의 새 도구가 추가된다.
HBM3device memory · 80 GB · H100 SXM580 GB3.35 TB/s
L2 cachedevice 전체 공유 · partitioned50 MB~12 TB/s
SMEMSM 당 program-managed cache · L1 과 공유228 KB/SM~33 TB/s
registerthread 직접 접근 · 가장 빠름256 KB/SMpeak
tensor core 4th genFP16/BF16/FP8 + sparse · WGMMA로 호출132 SM~990 TFLOPs FP16
TMA (Tensor Memory Accelerator)
SMEM 으로의 bulk async copy. 좌표 시스템 (descriptor) 으로 N-D tile 을 한 번에 fetch. shape transform/swizzle 까지 free. CUDA core 가 transfer 에 cycle 안 씀.
WGMMA (Warp-Group MMA)
한 instruction 으로 4 warp = 128 thread 가 같이 큰 matmul. Ampere 의 warp-level mma.sync의 4배 단위. SMEM 또는 register 를 operand 로.
async copy + barrier
cp.async 가 Ampere 부터 있었지만, Hopper 의 mbarrier 와 결합해서 arrive/wait 가 hardware 동기화. CUDA cores 가 free.
block cluster
최대 16 block 을 한 cluster 로 묶음. 같은 cluster 안의 block 들이 SMEM 으로 직접 통신 가능. distributed shared memory.
TMA multicast
한 번의 GMEM read 가 cluster 안의 여러 block 의 SMEM 으로 동시에. bandwidth 절약.
FP8 (E4M3 / E5M2)
새 dtype. tensor core 가 FP16 의 2배 throughput. 정확도 손실 trade-off.
H100 GEMM 이 cuBLAS 를 격파하려면 — 이 6개 도구를 한 커널 안에 모두 결합해야 한다. 하나라도 빠지면 격차가 작아진다. 강의의 본론은 그 결합의 모양.
§ 04producer-consumer 파이프라인· warp specialization
한 SM 안에서 “일을 시키는 warp” 와 “계산하는 warp” 가 분리된다
L042 의 Mosaic GPU 에서도 본 핵심 패턴이 — Hopper GEMM 의 표준 구조다. 한 block 안의 warp group 들이 다른 역할을 맡는다.
FIG · Hopper GEMM 의 producer-consumer 파이프라인 (3-stage prefetch)한 block · 1 producer + 2 consumer
Producer WG (1 warp)
TMA A0
TMA B0
arr
TMA A1
TMA B1
arr
TMA A2
TMA B2
arr
TMA A3
TMA B3
Consumer WG 0 (4 warp)
idle (no data yet)
w
WGMMA A0·B0
w
WGMMA A1·B1
w
WGMMA A2·B2
Consumer WG 1 (4 warp)
idle
w
WGMMA
w
WGMMA
w
WGMMA
producer 1 warp 가 TMA 로 SMEM 의 다음 stage 를 prefetch 하는 동안, consumer 2 WG 가 현재 stage 를 WGMMA 로 처리. 3-stage circular SMEM buffer — async 로 producer 가 늘 두 stage 앞서 있다. 첫 두 wave 의 idle 가 warmup 비용.
이 구조의 디자인 결정들.
- 1 producer + 2 consumer 가 흔한 비율. producer 는 TMA 명령만 발행하면 되므로 warp 1개 충분. consumer 는 WGMMA + accumulator 처리.
- num_stages = 3 또는 4. 더 많으면 SMEM 사용량 증가 → occupancy 감소. 적으면 prefetch 가 latency 커버 못 함.
- register 분배 — producer 와 consumer 의 register 사용량이 다르다.
setmaxnreg 로 producer 는 register 적게, consumer 는 많이.
- barrier — Hopper 의
mbarrier. arrive 와 wait 가 SMEM 위 변수로 표현됨.
FlashAttention 3 와의 관계
L042 의 FA3 가 2 consumer WG 사이에서 softmax/MMA 를 갈라 critical section. 본 강의의 GEMM 은 그 구조의 단순 버전 — softmax 가 없으므로 두 consumer 가 같은 일(WGMMA)만 한다. 같은 producer-consumer 골격, 다른 critical section.
§ 05SMEM swizzle 패턴· bank conflict 회피의 정석
WGMMA 가 좋아하는 layout, 사람이 보는 layout 의 충돌
SMEM 은 bank 32개로 분할. 한 word(4B) 가 한 bank 에 있고, warp 의 32 thread 가 같은 bank 의 다른 word 를 동시에 access 하면 bank conflict. 32-way conflict 면 32배 느려진다.
WGMMA 는 SMEM 의 특정 layout 을 요구한다. 단순한 row-major 면 — K 차원으로 stride 하면서 접근 → bank conflict 발생. NVIDIA 의 답: swizzle. SMEM 의 word 를 행에 따라 XOR 패턴으로 재배치해서 같은 bank 에 안 걸리게.
swizzle pattern 의 종류 (Hopper 표준).
NoSwizzle — 기본 row-major. 작은 K 차원에서만 사용.
32B Swizzle — 32 byte 단위로 XOR. K=8, K=16 (FP16) 에 적합.
64B Swizzle — 64 byte 단위. K=32 (FP16) 에 적합.
128B Swizzle — 128 byte 단위. 가장 흔히 쓰이는 패턴. K=64 (FP16) 의 표준.
FIG · 128B swizzle 의 예시 (개념)같은 색 = 같은 bank
0
1
2
3
4
5
6
7
0
1
2
3
4
5
6
7
0
1
2
3
4
5
6
7
0
1
2
3
4
5
6
7
128B swizzled SMEM tile
행마다 column 이 다른 순서로 bank 에 매핑. 한 warp 가 같은 column 을 다른 row 에서 읽어도 — 각 행이 다른 bank 에 들어가서 conflict 없음. TMA 가 swizzle 까지 free 로 처리한다 — descriptor 에 swizzle mode 만 명시.
실전
WGMMA 가 요구하는 SMEM layout 은 swizzle pattern 에 맞아야 한다. CUTLASS 의 tiled_mma, composed_layout 추상이 이 매칭을 자동화. 직접 작성한다면 — TMA descriptor 의 swizzle mode 와 WGMMA instruction 의 SMEM operand layout 을 손으로 매칭해야 한다.
§ 06Hopper TMA descriptor· tensor map · 좌표 시스템
“어떤 N-D 영역을 SMEM 어디에 어떤 layout 으로” 를 한 객체로
TMA 의 핵심 추상. copy 의 모든 결정 — global 의 base address, dimension, stride, swizzle, 데이터 타입, padding mode — 을 한 tensor map 객체에 한 번 묶는다. 그리고 이후엔 좌표만 주면 된다.
// host 측에서 descriptor 한 번 만들기
CUtensorMap tensor_map_a;
cuTensorMapEncodeTiled(
&tensor_map_a,
CU_TENSOR_MAP_DATA_TYPE_FLOAT16, // dtype
/*tensor_rank*/ 2,
/*global_address*/ (void*)A_ptr,
/*global_dim*/ {M, K},
/*global_strides*/ {K * 2 /*bytes*/},
/*box_dim*/ {BLOCK_M, BLOCK_K}, // SMEM 에 가져올 tile 크기
/*element_strides*/ {1, 1},
CU_TENSOR_MAP_INTERLEAVE_NONE,
CU_TENSOR_MAP_SWIZZLE_128B, // 128B swizzle 자동 적용
CU_TENSOR_MAP_L2_PROMOTION_L2_64B,
CU_TENSOR_MAP_FLOAT_OOB_FILL_NONE
);
// device kernel 안에서 — 좌표만 넘기면 끝
asm volatile (
"cp.async.bulk.tensor.2d.shared::cluster.global.mbarrier::complete_tx::bytes "
"[%0], [%1, {%2, %3}], [%4];"
:: "r"(smem_addr), "l"(&tensor_map_a),
"r"(m_offset), "r"(k_offset),
"r"(barrier_addr)
);
TMA 의 큰 장점 4가지.
- 주소 계산이 hardware 에서 — 사용자 코드에서 stride 곱하기, swizzle 비트 XOR 하기 같은 코드가 사라진다.
- coalescing 자동 — TMA engine 이 GMEM 에서 cache line 단위로 가져온다.
- OOB 처리 자동 — descriptor 의 OOB fill mode 로 padding 처리.
- multicast 한 줄 — cluster 차원 따라 broadcast 가능.
.cluster suffix 만 추가.
학습 자료로서의 TMA
TMA descriptor 의 직접 작성은 Hopper 의 모든 디테일이 한 자리에 모이는 자료다. swizzle, OOB, stride, coordinate system, mbarrier 가 모두 이 한 객체에 묶인다. 직접 짜보면 Hopper 의 메모리 모델이 손에 잡힌다.
§ 07cuBLAS vs custom 결과· 크기별 throughput
실제 격차의 모양 — 한 자리에서 1.1×, 다른 자리에서 0.9×
강의 결과 부분의 핵심 — 절대 throughput 보다 크기별 비율의 그래프가 중요하다. 어떤 (M, N, K) 에서 custom 이 cuBLAS 를 이기고, 어떤 자리에서는 지는지.
FIG · cuBLAS vs custom 의 가능한 결과 모양 (도메인 지식 기반 추정)FP16 · H100 SXM5
M=N=K=8192 · cuBLAS
~830 TF
M=N=K=8192 · custom
~900 TF
M=2,N=K=4096 · cuBLAS
~330 TF
M=2,N=K=4096 · custom
~200 TF
정확한 절대 수치는 영상에서 확인 필요. 패턴만 강조 — square 큰 사이즈에서 custom 이 cuBLAS 를 능가하지만, tall/skinny 에서는 cuBLAS 의 전용 path 가 우월. peak 990 TF (FP16) 의 80% 가 production-grade 의 표준 자리.
이 결과에서 cuBLAS 격파의 의미가 다시 분명해진다. 특정 사이즈에서 우월. 그리고 그 우월의 폭은 보통 5–15%. cuBLAS 가 이미 매우 좋다는 사실의 반증.
왜 큰 격차는 안 나는가
cuBLAS 도 H100 의 새 도구를 사용한다 — TMA, WGMMA, warp specialization 모두. 차이가 나는 자리는 — tile 크기 sweep 의 폭, specific 사이즈로의 specialize, 새 dtype 의 path 성숙도. 둘 다 같은 hardware feature 를 쓰는 이상, 격차는 5–15% 가 일반적인 range.
§ 08production 적용의 어려움· edge case · validation · maintenance
“이 사이즈에서 우월” 에서 “모든 production 사이즈에서 안전” 으로의 거리
강의가 다뤘을 (또는 다뤘어야 할) 자리. custom GEMM 이 cuBLAS 를 한 사이즈에서 이긴다고 그대로 production 에 들어가지 않는다. 5가지 어려움.
edge case
M, N, K 가 tile 의 배수가 아닐 때 — padding / mask / tail 처리. cuBLAS 는 모두 처리. custom 은 매번 직접.
numerical 정확도
FP16 / BF16 의 accumulator strategy, alpha/beta 의 scaling 순서, NaN/inf 전파. cuBLAS 와 정확히 일치할 의무는 없지만 시스템 nvm 호환은 확인 필요.
epilogue 결합
production 은 GEMM + bias + GELU + dropout 같은 fusion 을 원함. cuBLASLt 는 일부 epilogue. custom 은 자기 epilogue 만 지원.
multi-stream 안전성
CUDA stream 여러 개에서 호출할 때 race / leak. TMA descriptor 의 lifecycle 관리.
유지보수
새 CUDA 버전, 새 architecture (Blackwell). cuBLAS 는 NVIDIA 가 자동 update. custom 은 직접 포팅.
heuristic dispatch
사이즈에 따라 cuBLAS / custom1 / custom2 중 어느 것이 빠른지 결정. heuristic table or autotuner.
그래서 production GEMM 은 fallback 으로 cuBLAS, hot path 만 custom 의 layered 접근. PyTorch 자체도 aten::matmul 안에서 사이즈별로 cuBLAS / cublasLt / Triton fused / custom 을 분기.
§ 09CUTLASS 와의 관계· DSL 위에서 짤지 직접 짤지
같은 일을 더 적은 노력으로 하는 길 — CUTLASS 3.x
강의가 직접 CUDA C++ 로 풀었지만, NVIDIA 가 같은 일을 위한 라이브러리를 제공한다 — CUTLASS. 3.x 부터는 Hopper 의 모든 도구를 wrapper 로 노출.
CUTLASS 의 추상.
CollectiveMma — producer-consumer 파이프라인 추상. num_stages, schedule 결정.
CollectiveBuilder — tile shape, dtype 만 주면 적절한 schedule 자동 선택.
tiled_mma + composed_layout — WGMMA / TMA 의 layout 매칭 자동화.
EpilogueFunctor — custom epilogue. bias, activation, dropout 결합.
CUTLASS 로 짠 GEMM 의 코드량 — 직접 작성의 1/5 수준. 그리고 NVIDIA 가 새 architecture 에 따라 backbone 을 update 한다.
왜 직접 작성 강의가 가치 있는가
CUTLASS 는 추상의 두께가 두껍다. 처음 봤을 때 — “여기서 무슨 일이 일어나고 있나” 가 흐려진다. 본 강의처럼 한 번 손으로 풀어보면 — 다시 CUTLASS 로 돌아가서 같은 라인 어디가 무엇을 하는지 손에 잡힌다. 학습 자료 vs 생산 자료의 차이.
선택 가이드 — 추정
새로운 GEMM 변형이 필요한가? — CUTLASS 위에서 epilogue 만 custom. 특정 사이즈 한 자리에서 cuBLAS 를 명백히 이겨야 하는가? — 그 자리에 specialize 한 직접 작성 커널. 두 길이 보완적이다.
§ 10기억할 메모와 코드· key takeaways · repo
다시 열었을 때 5분 안에 손에 잡혀야 할 것
"cuBLAS 격파" 의 의미
한 사이즈, 한 dtype 에서 5–15% 우월. 모든 사이즈에서 우월이 아님.
Hopper 의 6 새 도구
TMA, WGMMA, async copy + mbarrier, block cluster, TMA multicast, FP8.
producer-consumer + warp spec
1 producer warp + 2 consumer WG. 3-stage SMEM 버퍼.
SMEM swizzle 128B
WGMMA 와 TMA 가 모두 같은 swizzle 모드. row 별 XOR 패턴.
TMA descriptor
N-D copy 의 모든 결정을 한 객체에. 커널 안에서는 좌표만 넘김.
CUTLASS 3.x
같은 일을 wrapper 로. CollectiveMma 가 핵심. epilogue 까지.
production fallback
heuristic dispatch — 사이즈별로 cuBLAS / custom 선택. PyTorch 자체도 같은 패턴.
peak 990 TFLOPs
H100 SXM5 의 FP16 peak. production-grade 는 보통 80%+ (~800 TF).
Hopper PTX
PTX ISA · cp.async.bulk.tensor / wgmma.mma_async
손에 새기기 — 실습 시퀀스
- cuBLAS baseline 측정 — H100 위에서 M=N=K ∈ {2048, 4096, 8192} 의 FP16 GEMM 을 cuBLAS 로 측정. throughput 의 peak 비율 기록.
- Naive WGMMA 커널 — TMA 없이 직접 GMEM access 로 WGMMA 호출. 이 베이스라인이 얼마나 느린지 확인.
- TMA 추가 — host 측에서 tensor map 만들고, kernel 안에서 cp.async.bulk.tensor PTX 호출. 베이스라인 대비 speedup.
- warp specialization — producer 1 warp + consumer 2 WG 분리.
setmaxnreg 로 register 분배.
- SMEM swizzle 128B — TMA descriptor 와 WGMMA operand layout 매칭. NCU 의 SMEM bank conflict metric 으로 검증.
- cluster + multicast — block cluster 활성화, A 또는 B 를 multicast. bandwidth 사용량 감소를 NCU 로 확인.
- cuBLAS 와 비교 — 단계별로 cuBLAS 대비 % 그래프. 어느 단계에서 격차가 좁혀지는지 추적.
§ 11다른 강의로 이어지는 길· connections
이 강의의 도구가 다음에 어디에 다시 등장하는지
§ 12열린 질문· open questions
transcript 누락으로 더 많은 자리가 비어 있다
강의 transcript 가 누락된 강의 — 본 노트의 구체적 수치와 코드는 도메인 지식과 외부 자료에서 가져왔다. 영상 직접 확인이 필요한 사항들.
- 강의 발표가 보여준 정확한 사이즈와 격차 — 본 노트의 그래프는 도메인 지식 기반 추정. 실제 강의의 측정값은 영상 확인 필요.
- FP8 가 다뤄졌는가 — Hopper 의 새 dtype. cuBLAS 의 FP8 path 와 격차가 어떻게 다른지 — 영상의 specific 결과 확인.
- strategy: persistent vs split-K — 큰 K, 작은 M/N 의 사이즈에서 자주 쓰는 split-K 전략. 본 강의가 이 자리를 다뤘는지 미확인.
- cuBLAS internals — 강의가 cuBLAS 의 어느 path 와 비교했는지 (cuBLAS, cuBLASLt, cuBLAS-DX 의 차이). 영상 직접 확인.
- Hopper 의 FP32 accumulator strategy — FP16 input 에 FP32 accumulator 의 정확도/속도 trade-off 가 다뤄졌는가.
- Modal blog 와의 관계 — pranjalssh 가 Modal blog 에 거의 같은 토픽으로 시리즈 글을 게재. 강의가 그 글의 발표인지, 별도 자료인지 — Modal blog 직접 확인 필요.
- Blackwell 으로의 전환 — 강의 시점(2025-03) 기준. Blackwell 의 새 도구들 (TMEM, 5th gen TC) 과 본 강의의 결과가 어떻게 transferable 한지.
검증 메모
본 노트의 모든 numerical 주장 — peak TFLOPs, SMEM 크기, swizzle pattern 등 — 은 NVIDIA 공식 문서 (Hopper Tuning Guide, PTX ISA, CUDA C Programming Guide) 기준이지 강의의 발화에서 인용한 것이 아니다. 강의의 실제 강조점은 영상을 직접 보고 보충해야 한다.