GPU 시스템 20 - Nsight, Triton, FlashAttention까지 이어지는 실전 흐름
GPU 시스템 시리즈를 마무리하며 profiling, Triton, FlashAttention 관점까지 연결하기
이 시리즈를 어디까지 연결해야 할까
GPU 시스템을 공부하는 목적은 CUDA 문법 몇 개를 익히는 데 있지 않다. 중요한 것은 실제 모델 연산을 볼 때:
- 어떤 병목이 있는지
- memory와 compute 중 무엇이 먼저 막히는지
- kernel을 어떤 방향으로 바꿔야 할지
를 판단할 수 있는 감각을 만드는 것이다.
Nsight로 확인하고 Triton으로 실험한다
실무적으로는 다음 흐름이 자주 나온다.
- profiling으로 병목을 본다
- roofline과 stall reason으로 방향을 잡는다
- CUDA 또는 Triton으로 kernel 구조를 바꿔본다
- 다시 측정한다
이 반복이 GPU kernel engineer의 일상에 가깝다.
여기서 Triton이 중요한 이유는 실험 속도다. CUDA가 더 낮은 수준 제어를 주는 반면, Triton은 아이디어를 빠르게 검증하기 좋다. 그래서 실제로는 두 도구가 경쟁 관계라기보다, 같은 최적화 루프 안에서 다른 역할을 맡는 경우가 많다.
FlashAttention이 좋은 마무리 예제인 이유
FlashAttention은 단순히 유명한 최적화 기법이 아니라, 이 시리즈 전체를 압축해서 보여주는 사례다.
- attention matrix 전체를 materialize하지 않으려는 설계
- tile 단위 computation
- memory traffic 최소화
- reduction과 numerical stability 처리
- 실제 모델 수준 bottleneck 해결
즉, GPU 시스템에서 배운 거의 모든 감각이 한데 모인다.
중요한 것은 FlashAttention을 특정 알고리즘 이름으로만 소비하지 않는 것이다. 더 본질적으로는:
- 거대한 intermediate를 만들지 않으려는 태도
- tile 단위로 계산을 흘려보내는 태도
- memory traffic를 계산만큼 진지하게 다루는 태도
가 핵심이다. 이 태도가 바로 GPU 시스템 사고방식이다.
이 시리즈 이후
여기까지 왔다면 다음 두 갈래가 자연스럽다.
- PyTorch 내부 구조로 가서 custom CUDA op와 framework integration을 본다
- Distributed LLM Training으로 가서 multi-GPU와 large-scale training 병목을 본다
실제로는 이 둘이 다시 GPU kernel engineering과 만난다. 결국 큰 모델 시스템에서는 커널, 프레임워크, 통신이 서로 분리되어 있지 않기 때문이다.
예를 들어 PyTorch internals 쪽에서는 지금까지 만든 kernel을 실제 tensor와 autograd 흐름에 연결하는 문제가 중요해진다. 반대로 distributed training 쪽에서는 좋은 kernel이 있어도 communication과 memory sharding 구조를 모르면 전체 throughput을 충분히 못 끌어올릴 수 있다.
즉, GPU 시스템은 독립된 섬이 아니라 더 큰 ML 시스템의 한 축이다.
마무리
GPU 시스템을 이해한다는 것은 GPU를 빠른 상자로 보는 것을 멈추고, 실행 모델과 메모리 구조를 가진 시스템으로 보기 시작한다는 뜻이다. 이 시점부터는 CUDA 코드 한 줄도 단순한 코드가 아니라, 하드웨어 위에 어떤 흐름을 만들고 있는지로 보이기 시작한다.
이 시리즈의 목표도 거기에 있다. API 사용법을 많이 아는 것보다, 성능 문제를 만났을 때 어디를 의심해야 하고 어떤 방향으로 바꿔야 하는지 감을 만드는 것. 그 감각이 생기면 이후 CUDA, Triton, PyTorch internals, distributed training을 모두 더 잘 연결해서 볼 수 있다.