PyTorch 프로파일링 (파트 3): Attention이 전부다

PyTorch 프로파일링 (파트 3): Attention이 전부다

PyTorch 프로파일링 (파트 3): Attention이 전부다

이 블로그 포스트는 NVIDIA A100-SXM4-80GB GPU를 사용하여 PyTorch의 어텐션 메커니즘을 프로파일링하고, 각 변형이 프로파일러 트레이스에 어떻게 나타나는지 보여줍니다.

단순 어텐션

원시 연산 (matmul, mul, masked_fill, softmax, matmul)으로 구성된 단순 어텐션 구현은 순전파당 6개의 GPU 커널을 실행하며, 여기에는 out‑of‑place masked_fill에 의해 발생하는 예상치 못한 메모리 복사가 포함됩니다.

인플레이스 인과 마스킹을 적용한 단순 어텐션

masked_fill을 인플레이스 버전인 masked_fill_으로 교체하면 메모리 복사 커널이 사라져 순전파당 GPU 커널 수가 6개에서 5개로 감소합니다.

스케일드 닷 프로덕트 어텐션

PyTorch의 F.scaled_dot_product_attention은 단일 라인 인터페이스를 제공하며 여러 백엔드로 디스패치됩니다; 각 백엔드는 고유한 프로파일링 특성을 보여줍니다.

Math 백엔드

Math 백엔드에 고정하면 SDPA는 순전파당 약 20개의 GPU 커널을 실행하고, CUDA 코어에서 FP32로 동작하며, 매 호출마다 인과 마스크를 재구성하고, NaN을 방지하기 위해 _safe_softmax를 사용합니다; 이는 단순 인플레이스 버전보다 대략 3.7배 느립니다.

Efficient 백엔드

Efficient 백엔드(xformers)는 순전파당 단일 융합 fmha_cutlassF_bf16_aligned_64x64_rf_sm80 커널을 실행하여 연산을 Tensor 코어에서 bfloat16으로 유지하고, 중간 매트릭스 쓰기를 HBM에 기록하지 않습니다.

Flash 백엔드

Flash 백엔드는 순전파당 단일 융합 pytorch_flash 커널(FlashAttention‑2)을 실행합니다; 프로파일러에서 추정 점유율이 낮게(약 13%) 표시되지만, 레지스터와 공유 메모리를 사용해 어텐션 타일을 칩 내에 유지하기 때문에 가장 빠른 백엔드입니다.

cuDNN 백엔드

cuDNN 백엔드는 순전파당 단일 생성 커널을 실행합니다(예: cudnn_generated_fort_native_sdpa_sm80_flash_fprop_wmma_f16_knob_6_128x64x64_4x1x1_cga1x1x1_kernel0_0); CPU에서 전치 연산을 피하지만 런타임 플랜 선택으로 인해 CPU 시간이 더 높게(~214 µs) 소요되며, GPU 시간은 Efficient와 Flash 백엔드 사이에 위치합니다.

전체 내용 한눈에 보기

변형 변경 내용 순전파당 커널 수 트레이스에서 밝혀진 내용
단순 어텐션 원시 연산(matmul, mul, mask, softmax, matmul)으로 직접 구현한 어텐션 6 out‑of‑place masked_fill에 의해 발생하는 숨겨진 Memcpy.
인플레이스 단순 masked_fillmasked_fill_ 5 Memcpy 커널이 완전히 사라집니다.
SDPA Math F.scaled_dot_product_attention을 Math 백엔드에 고정 20 참조: CUDA 코어에서 FP32, 매 호출마다 마스크 재구성, _safe_softmax. 정확하지만 약 3.7배 느림.
SDPA Efficient Efficient (xformers) 백엔드 1 단일 융합 fmha_cutlassF 커널, Tensor 코어에서 bf16 유지.
SDPA Flash Flash 백엔드 1 단일 융합 pytorch_flash 커널(FlashAttention‑2). 가장 빠르지만 “잘못된” 13% 점유율을 보임.
SDPA cuDNN cuDNN 백엔드 1 문제별 생성 커널: 전치 없음, cuLaunchKernelEx, 하지만 비용이 큰 CPU 부분으로 이동.

시리즈 마무리

핵심 요점은 프로파일러 트레이스가 어떻게 보일지 추측을 만든 뒤 트레이스를 검토하고, 불일치를 가장 흥미로운 인사이트로 다루는 것입니다; 이 습관을 통해 숨겨진 Memcpy, Math 백엔드의 20개 커널, Flash의 낮은 점유율, cuDNN의 CPU 측 비용을 발견했습니다.

이제 이 추측‑검증 방식을 적용해 자신의 모델을 프로파일링할 수 있습니다.

Sources