PyTorch `torch.profiler`로 행렬 곱셈(matmul)과 바이어스 덧셈(add) 연산을 분석하는 실전 입문 가이드다. 64×64 행렬에서는 GPU 연산 시간(23μs)보다 CPU 디스패치 시간(2.3ms)이 압도적으로 길어 오버헤드 바운드 상태이며, 4096×4096으로 키우면 CPU·GPU 시간이 모두 ms 단위로 균등해지는 컴퓨트 바운드로 전환됨을 프로파일러 테이블과 Perfetto 트레이스로 확인한다. `torch.compile` 적용 시 두 연산이 디스패처 수준에서 `aten::addmm`으로 병합되지만, GPU에서는 cuBLAS GEMM과 Device-to-Device 메모리 복사가 분리 실행되어 진정한 커널 융합과는 다르다. 단일 연산에서는 컴파일 CPU 오버헤드가 2배 증가하므로, 수십 개 이상의 연산을 가진 실제 모델에서야 비로소 이득이 발생한다.
- •64×64 행렬에서 Self CPU 2.3ms vs CUDA 23μs로 GPU는 1%만 활용되는 오버헤드 바운드 패턴이며, 4096×4096으로 키우면 CPU·GPU 시간이 그 ms 단위로 균등해지는 컴퓨트 바운드로 전환된다.
- •cuBLAS는 matmul 전 SM 점유율 질의(cudaOccupancyMax...)를 통해 커널 변형을 런타임에 선택하며, 이 단계는 add 같은 고정 리소스 경량 커널에서는 발생하지 않는다.
- •`torch.compile`은 두 연산을 `aten::addmm`으로 디스패쳄 수준에서 병합하지만, GPU에서는 DtoD memcpy와 GEMM 에필로그가 분리 실행되어 메모리 트래픽이 줄지 않는다.
- •동일 커널을 동일 입력으로 반복해도 GPU 클럭·발열·전력 관리로 스텝마다 실행 시간이 다르므로, 평균값만 보면 실제 성능을 오판할 수 있다.
- •단일 연산에서 `torch.compile` CPU 스텝 시간은 약 2배 증가한다. Dynamo→AOTAutograd→Inductor 스택 비용이 매 호출마다 부과되므로 수십 개 이상 연산 모델에서만 효과적이다.
Profiling in PyTorch (Part 1): A Beginner's Guide to torch.profiler
- 1.torch.profiler는 table(핫스팟 통계)과 trace(시간 흐름) 두 아티팩트로 CPU·GPU 병목을 각각 진단한다.
- 2.행렬 크기 64→4096 확대 시 overhead-bound에서 compute-bound로 전환되며 GPU 가동률이 대폭 개선된다.
- 3.torch.compile 시 addmm dispatcher 퓨전 발생, GPU 커널은 GEMM+DtoD memcpy 2개, CPU 비용 2배.
- 4.동일 커널도 GPU 클록·발열·전력 관리로 실행마다 타이밍이 달라 평균값이 아닌 trace 직접 확인이 필수다.
왜 중요한가?
딥러닝 모델 최적화의 시작점인 프로파일링을 입문자 관점에서 단계적으로 풀어내, torch.profiler로 overhead-bound vs compute-bound를 실제로 진단하고, torch.compile의 퓨전 효과가 기대와 다를 수 있음을 구체적 트레이스로 확인하는 방법을 제시한다. LLM·추론 최적화 작업에 바로 적용 가능한 실무 진단 체크리스트도 포함되어 있다.
🏷️ 언급 프로젝트
전체 내용이 궁금하다면?
원문을 직접 읽어보세요