PyTorch 내부 구조 01 - 왜 PyTorch internals를 알아야 하는가
PyTorch를 단순한 파이썬 라이브러리가 아니라 런타임으로 이해해야 성능과 확장 문제를 제대로 다룰 수 있다
이 시리즈의 목적
PyTorch를 오래 쓰다 보면 어느 순간 사용법만으로는 안 풀리는 문제가 나온다.
- 왜 어떤 연산은 예상보다 느릴까
- view와 clone이 언제 숨은 복사를 만들까
- custom CUDA kernel을 붙이려면 어디까지 알아야 할까
- distributed training에서 autograd와 communication은 어떻게 연결될까
이 질문들은 nn.Module 문법만으로는 답하기 어렵다. PyTorch를 내부 구조를 가진 런타임으로 봐야 한다.
PyTorch는 어디서 중요한가
PyTorch는 GPU kernel engineer와 distributed training engineer에게 단순 프레임워크가 아니다. 커널, 텐서 저장 구조, dispatcher, autograd, extension, compiler가 만나는 접점이다.
예를 들어 Triton이나 CUDA로 빠른 kernel을 만들었다고 해보자. 거기서 끝이 아니다.
- PyTorch tensor를 입력으로 받아야 한다
- dtype, device, layout 검증이 필요하다
- backward가 필요하면 autograd 경로를 만들어야 한다
- 실제 학습 코드에서 자연스럽게 호출되어야 한다
즉 "빠른 kernel"과 "쓸 수 있는 operator" 사이에는 꽤 긴 연결층이 있다.
이 시리즈의 흐름
이 시리즈는 다음 순서로 간다.
- tensor의 storage, size, stride
- contiguous와 memory format
- dispatcher와 operator registry
- autograd graph와 engine
- custom autograd function
- allocator, stream, async execution
- C++ / CUDA extension
- custom operator와 fused op 설계
- profiling,
torch.compile, Triton 연결 - distributed training과의 접점
읽을 때의 기준
각 글에서 계속 봐야 하는 질문은 같다.
- 이 계층은 무엇을 추상화하는가
- 어떤 비용을 숨기고 어떤 비용은 노출하는가
- 성능 문제는 여기서 생기는가, 아니면 아래 계층에서 생기는가
이 기준이 잡히면 PyTorch 코드를 덜 블랙박스처럼 보게 된다.
다음 글에서는 tensor가 실제로 어떤 구조 위에 올라가는지부터 본다. storage, shape, stride를 이해하지 못하면 이후의 view, layout, custom op 문제도 계속 모호하게 남는다.