gpumode · 강의 아카이브
《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 커널 엔지니어
강의 번호
L045
스피커
pranjalssh
학습 우선순위
High · Hopper 의 표준 자료
상태
transcript fetch failed
§ 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=2048
~720 TF
M=N=K=4096
~860 TF
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).
YouTube youtube.com/watch?v=ErTmTCRP1_U · 길이 미상
Modal blog modal.com/blog · pranjalssh 의 동명 시리즈
CUTLASS github.com/NVIDIA/cutlass · 3.x
Hopper PTX PTX ISA · cp.async.bulk.tensor / wgmma.mma_async
Hopper Tuning CUDA Hopper Tuning Guide

손에 새기기 — 실습 시퀀스

  1. cuBLAS baseline 측정 — H100 위에서 M=N=K ∈ {2048, 4096, 8192} 의 FP16 GEMM 을 cuBLAS 로 측정. throughput 의 peak 비율 기록.
  2. Naive WGMMA 커널 — TMA 없이 직접 GMEM access 로 WGMMA 호출. 이 베이스라인이 얼마나 느린지 확인.
  3. TMA 추가 — host 측에서 tensor map 만들고, kernel 안에서 cp.async.bulk.tensor PTX 호출. 베이스라인 대비 speedup.
  4. warp specialization — producer 1 warp + consumer 2 WG 분리. setmaxnreg 로 register 분배.
  5. SMEM swizzle 128B — TMA descriptor 와 WGMMA operand layout 매칭. NCU 의 SMEM bank conflict metric 으로 검증.
  6. cluster + multicast — block cluster 활성화, A 또는 B 를 multicast. bandwidth 사용량 감소를 NCU 로 확인.
  7. cuBLAS 와 비교 — 단계별로 cuBLAS 대비 % 그래프. 어느 단계에서 격차가 좁혀지는지 추적.
§ 11다른 강의로 이어지는 길· connections

이 강의의 도구가 다음에 어디에 다시 등장하는지

§ 12열린 질문· open questions

transcript 누락으로 더 많은 자리가 비어 있다

강의 transcript 가 누락된 강의 — 본 노트의 구체적 수치와 코드는 도메인 지식과 외부 자료에서 가져왔다. 영상 직접 확인이 필요한 사항들.

검증 메모

본 노트의 모든 numerical 주장 — peak TFLOPs, SMEM 크기, swizzle pattern 등 — 은 NVIDIA 공식 문서 (Hopper Tuning Guide, PTX ISA, CUDA C Programming Guide) 기준이지 강의의 발화에서 인용한 것이 아니다. 강의의 실제 강조점은 영상을 직접 보고 보충해야 한다.

← Lecture 044 NVIDIA Profiling Lecture 046 → Distributed GEMM — Ali Hassani