gpumode · 강의 아카이브
《GPU Mode》 L096 2025 · 후반 High priority transcript · failed · TLX repo 보강 · 스피커 명단 확인 필요

TLX — Triton 의 hardware-near 확장

Triton 의 강점은 “compiler 가 알아서” 였다 — BLOCK_SIZE, num_warps, num_stages 만 정하면 나머지는 lowering 이 풀어준다. 그러나 Hopper/Blackwell 의 새 기능 (TMA · async tensor core · warp specialization) 은 compiler heuristic 만으로는 못 짠다. TLX (Tile-Level eXtensions / Triton Low-level eXtensions) 는 expert 사용자가 그 자리에 직접 손을 대게 해주는 layer. transcript 가 실패해서 본 노트는 facebookexperimental/triton:tlx branch 와 일반 GPU kernel 도메인 지식 기반.

TLX warp specialization async tensor core TMA Hopper Blackwell flash attention pipelined GEMM
?
Speaker
스피커 명단 (확인 필요)
notes 에 speaker missing · facebookexperimental/triton 의 TLX 메인테이너로 추정
강의 번호
L096
스피커
확인 필요
학습 우선순위
High · 정독
자막 상태
failed · repo 보강
§ 01강의가 풀려는 문제· why this lecture exists

Hopper 의 새 기능을 Triton 의 자동화로는 못 잡는다

강의의 출발점. Triton 의 lowering 은 “compiler heuristic 이 충분히 똑똑하다” 는 가정 위에 산다. 그러나 H100 의 진짜 성능은 — warp specialization · async tensor core · TMA · multi-stage pipelining 같은 새 기능을 직접 조합해야 나온다. 이게 compiler 자동화의 한계.

강의의 frame

“Triton 은 80% 의 사용자에게 80% 의 성능을 준다. 나머지 20%—frontier kernel의 마지막 20% 는 compiler 가 못 한다. TLX 는 그 자리에 expert 가 손을 댈 수 있게 한다.”

강의에서 자주 인용되는 예 — flash attention 3. CUTLASS 로 짠 hand-tuned 버전이 H100 에서 700+ TFLOP/s. Triton 으로 같은 로직을 짜면 60–70% 수준. 그 차이가 warp specialization · async tensor core 의 직접 조작에서 온다. TLX 가 그걸 Triton 안에서 가능하게 한다.

“Triton 의 자동화가 모든 걸 해주는 건 아니다 — 그러나 자동화를 선택적으로 끌 수 있어야 hand-tuned 와 경쟁할 수 있다.”학습 노트
정확한 이름 — 확인 필요

TLX 의 표준 풀네임은 “Triton Low-level eXtensions” 또는 “Tile-Level eXtensions” 로 불린다 — 본 노트는 facebookexperimental/triton 의 tlx branch 의 README 표현을 따른다. 강의 시점에 정확한 이름을 영상에서 확인 필요. 둘 다 같은 의도 — Triton 의 high-level 자동화 위에 hardware-near 의 직접 제어 layer.

§ 02TLX 의 추상· core abstractions

4가지 영역 — local memory · async ops · sync · warp specialization

TLX repo 의 README 가 정리하는 4영역. Triton 의 high-level 추상 위에 추가되는 hardware-near 도구들.

A · local memory tlx.local_alloc() — shared/tensor memory 에 buffer 직접 할당. tlx.local_load/local_store 로 layer 간 직접 transfer. compiler 가 알아서 풀던 자리에 사용자가 손.
B · async ops 비차단 메모리 transfer + async tensor core. global → local, local → tensor core 가 token 으로 추적. token = tlx.async_copy(...)tlx.wait(token).
C · synchronization barrier · named barrier · phase-based protocol. warpgroup 사이의 producer/consumer 관계를 명시적으로.
D · warp specialization tlx.async_tasks(...) — block 의 thread 를 task 별로 분할. 어떤 warp 는 load 만, 어떤 warp 는 compute 만. Hopper/Blackwell 의 핵심 기법.

이 4영역의 공통점 — Triton 의 자동화를 부분적으로 끄고, 사용자가 명시적으로 통제. 그래서 TLX 코드는 vanilla Triton 보다 길고 복잡하지만, compiler 가 못 잡는 자리를 잡는다.

TLX 의 위치 — Triton 의 fork branch

TLX 는 standalone 라이브러리가 아니다. facebookexperimental/triton 의 tlx branch 안에 들어간 확장. import triton.language as tl 옆에 import triton.language.extra.tlx as tlx 같은 형태로 사용. Triton 본가와 별개로 진화하는 실험 가지.

§ 03lower-level 컨트롤· local memory · async tensor core

Hopper 의 새 hardware feature 가 직접 코드에 노출된다

TLX 가 가능하게 하는 핵심 — H100 의 hardware feature 를 Triton 안에서 직접 호출. CUTLASS 의 정신을 Python 으로.

vanilla Triton 의 한계

vanilla Triton 도 H100 위에서 도는 PTX 를 생성한다. 그러나 그 PTX 가 이 4가지 feature 를 충분히 활용하지 않는다. compiler 가 conservative 하게 schedule 하기 때문. TLX 는 — “여기는 async, 여기는 producer, 여기는 consumer” 를 사용자가 직접 적게 한다.

§ 04Triton 과의 비교· trade-offs

같은 일을 다른 추상 — vanilla 가 깨끗, TLX 가 빠름

차원
vanilla Triton
TLX
memory 관리
tl.load · tl.store — compiler 가 shared memory 사용 결정
tlx.local_alloc — buffer 직접 할당, layer 간 transfer 명시
async
implicit (compiler heuristic 으로 일부 async)
explicit token-based — async_copy / wait
warp 관리
num_warps 만 명시. 모든 warp 가 같은 일
async_tasks 로 warp group 분리. 각 group 이 다른 일
코드 길이
짧음 (50–100 줄 typical)
길어짐 (200–400 줄 typical)
성능
peak 의 60–80%
peak 의 85–95% (well-tuned 시)
debug 난이도
interpret 모드, breakpoint OK
async / sync 의 deadlock 가능성
portability
A100 · H100 · Blackwell · MI300 (대체로)
arch-specific (특히 Hopper 이상)
대상 사용자
대부분의 ML 엔지니어
kernel 라이브러리 저자, frontier kernel
“TLX 는 Triton 을 ‘C 같은’ DSL 로 바꾸지 않는다 — 같은 DSL 에 ‘이 자리는 hardware-near’ 라고 표시할 수 있게 해준다.”학습 노트
언제 TLX 를 쓸 가치

1. frontier kernel (flash attention, GEMM-K) — 마지막 20% 성능이 의미 있을 때. 2. Hopper/Blackwell 전용 — 새 hardware 의 feature 를 적극 활용. 3. kernel 라이브러리 저자 — 한 번 짜고 많이 호출되는 코드. 일반 모델 코드는 vanilla Triton 이 더 효율적.

§ 05example — pipelined GEMM· walkthrough

multi-stage buffer 로 load 와 compute 를 overlap

TLX repo 의 첫 example — pipelined GEMM. vanilla Triton 으로 짜면 compiler 가 일부 pipeline 을 만들지만, TLX 로 직접 짜면 N-stage 의 timing 을 사용자가 통제.

FIG · 3-stage pipelined GEMM 의 시간축load / compute / store overlap
stage 0 buffer
load tile 0
mma 0
idle
stage 1 buffer
idle
load tile 1
mma 1
idle
stage 2 buffer
idle
load tile 2
mma 2
store
tensor core
idle (warmup)
mma 0 → mma 1 → mma 2 → … (continuous)
warmup phase 후 tensor core 가 거의 비지 않는다. async load 가 다음 tile 을 미리 가져오고, mma 가 이전 tile 위에서 도는 동안 그것이 끝남. 3-stage 면 보통 충분. 4 이상 stage 는 메모리 사용만 늘고 이득 적음.
# pseudo-code — TLX pipelined GEMM 의 골격
@triton.jit
def gemm_kernel(...):
    # 3-stage shared memory buffer
    a_buf = tlx.local_alloc(
        shape=(3, BM, BK),
        dtype=tl.float16,
    )
    b_buf = tlx.local_alloc(
        shape=(3, BK, BN),
        dtype=tl.float16,
    )

    # warmup — 첫 2 tile 미리 load
    tok0 = tlx.async_copy(a_ptr, a_buf[0])
    tok1 = tlx.async_copy(a_ptr+BK, a_buf[1])

    acc = tl.zeros(...)
    for k in range(K // BK):
        slot = k % 3
        next_slot = (k + 2) % 3

        # 다음 tile async load 시작
        tok = tlx.async_copy(
            a_ptr + (k+2)*BK, a_buf[next_slot]
        )

        # 현재 tile 의 load 완료 대기
        tlx.wait(toks[slot])

        # mma — async tensor core
        acc = tlx.async_mma(
            a_buf[slot], b_buf[slot], acc
        )

    tlx.wait_all()
    tl.store(c_ptr, acc)

이 패턴이 가르치는 것 — async + buffer rotation이 multi-stage pipelining 의 본질. compiler 가 못 보던 timing 을 사용자가 직접 표현. 실제 코드는 더 길지만 (boundary 처리, prologue/epilogue) 핵심은 위 골격.

§ 06example — warp-specialized flash attention· walkthrough

한 block 안의 warp 를 producer/consumer 로 분리 — async 의 진짜 활용

TLX 의 가장 중요한 example. flash attention 의 새 변형이 — TLX 의 async_tasks 로 자연스럽게 표현. 한 block 의 warp 들을 두 그룹으로 분리.

이 분리가 만들어내는 효과 — memory 와 compute 가 다른 hardware unit 에서 동시에. CUTLASS 의 producer-consumer pattern 을 Triton 안에서.

# TLX warp specialization 의 골격
@triton.jit
def attention(...):
    # shared memory + barrier 셋업
    q_buf = tlx.local_alloc(...)
    k_buf = tlx.local_alloc(...)
    v_buf = tlx.local_alloc(...)
    barrier = tlx.named_barrier()

    with tlx.async_tasks() as tasks:
        @tasks.task(num_warps=4)
        def load_loop():
            for i in range(N_BLOCKS):
                tlx.tma_load(k_ptr, k_buf[i])
                tlx.tma_load(v_ptr, v_buf[i])
                barrier.arrive(i)

        @tasks.task(num_warps=4)
        def compute_loop():
            for i in range(N_BLOCKS):
                barrier.wait(i)
                qk = tlx.async_mma(q_buf, k_buf[i])
                p  = softmax(qk)
                acc = tlx.async_mma(p, v_buf[i], acc)

    tl.store(out_ptr, acc)

이 코드의 mental model.

  • async_tasks 안에 두 def 함수 가 있음 — 두 warpgroup 의 코드.
  • 각 warpgroup 은 num_warps 로 지정된 warp 수를 차지.
  • named_barrier 가 두 warpgroup 사이의 producer-consumer 동기.
  • load warpgroup 은 TMA 만, compute warpgroup 은 WGMMA 만 — hardware unit 의 자연 분리.

vanilla Triton 으로 같은 효과를 내려면 — compiler 가 알아서 warp 를 분리해줘야 한다. 그게 일반화하기 어려운 자리.

왜 이 패턴이 큰 차이를 만드는가

H100 의 tensor core 와 memory unit 은 hardware 레벨에서 별도 unit. SPMD 적인 코드 (모든 warp 가 같은 일) 면 한쪽이 항상 idle. warp specialization 으로 두 unit 을 동시에 굴리면 50% 의 hardware utilization 이 90%+ 로. 그게 flash attention 3 이 700+ TFLOP/s 를 내는 본질.

§ 07채택· in the wild

아직 실험적 — 그러나 frontier kernel 의 자리

TLX 가 facebookexperimental 이라는 이름에서 드러나듯 아직 실험. 그러나 frontier kernel 영역에서는 흥미로운 자리.

§ 08한계 — 휴대성 · 학습 곡선· limitations

TLX 는 비싸다 — 학습 시간, 코드 길이, portability

cost-benefit

TLX 의 가치는 한 kernel 이 매우 자주 호출되는 자리에서만 회수. flash attention 같은 자리는 LLM serving 의 hot path 라 회수 빠름. 일반 모델 코드는 vanilla Triton 또는 torch.compile 이 더 합리적. “너의 kernel 이 백만 번 도는가? 그렇다면 TLX. 아니면 vanilla.”

§ 09다음 — Triton 본가와의 관계· future

TLX 의 일부 추상이 Triton 본가에 흡수될 가능성

현재 TLX 는 facebookexperimental fork. 그러나 Triton 본가가 Hopper/Blackwell 지원을 깊게 가져가면 — TLX 의 일부 추상 (특히 async tensor core, warp specialization) 이 흡수될 가능성.

§ 10기억할 메모와 실습· key takeaways

다시 열었을 때 5분 안에 잡혀야 할 것

4 영역의 추상
local memory · async ops · sync · warp specialization. Triton 의 자동화 위에 hardware-near 통제.
tlx.local_alloc
shared memory 직접 할당. multi-stage buffer 로 pipelining 표현.
async_copy + token + wait
explicit async memory transfer. compiler 가 못 잡는 timing 을 직접.
async_tasks
block 의 warp 를 그룹으로 분리. 각 group 이 다른 일 (load / compute / store).
named_barrier
warpgroup 사이 producer-consumer 동기. phase-based protocol.
TMA + WGMMA
Hopper 의 새 hardware unit 을 직접 호출. memory 와 compute 의 동시 가동.
arch-specific
Hopper/Blackwell 우선. A100 / AMD 는 fallback 별도.
언제 채택
frontier kernel + 매우 자주 호출 + Hopper 이상. 일반 모델 코드는 vanilla.

실습 시퀀스

  1. repo clone + build — facebookexperimental/triton 의 tlx branch. cmake build, H100 에서 hello world example 실행.
  2. vanilla GEMM vs TLX pipelined GEMM — 같은 size 의 GEMM 을 두 버전으로. NCU 로 SM occupancy / tensor core utilization 비교.
  3. flash attention 비교 — TLX 의 attention example 과 vanilla Triton 의 attention 의 throughput. CUTLASS hand-tuned 와도 비교.
  4. warp specialization 직접 짜기 — 단순 vector add 를 load/compute warpgroup 으로 분리. 작은 예제로 mental model 정착.
  5. NCU 로 hardware utilization — TLX 코드와 vanilla 의 NCU dump 비교. tensor core idle time, memory unit busy time 의 차이.
ReferenceCUTLASS · flash attention 3 paper · Hopper architecture whitepaper
§ 11다른 강의로 이어지는 길· connections

Triton / kernel 시리즈 안에서

§ 12열린 질문· open questions

다음에 다시 들었을 때 직접 검증해야 할 것들

검증 메모

본 노트의 4영역 분류 (local memory · async ops · sync · warp specialization) 와 코드 예시는 facebookexperimental/triton 의 tlx branch README 의 정리를 기반으로 한다. 강의에서 다른 framing 이나 이름이 등장했을 수 있다 — 영상 직접 확인 후 보강 필요.

← Lecture 095Single controller programming with Monarch Lecture 097 →HipKittens — William Hu