피드로 돌아가기
Dev.toBackend
원문 읽기
Tracing torch.cuda.empty_cache() on an RTX 4090 - Where Do the 53 MB Go?
PyTorch의 CUDA 메모리 캐싱 할당자가 53.7 MB를 해제하지 못하는 문제를 eBPF 추적으로 분석해 OS 스케줄링 간섭이 root cause임을 규명
AI 요약
Context
PyTorch 사용자가 torch.cuda.empty_cache() 호출 후에도 GPU 메모리의 53.7 MB 갭이 지속적으로 남아있는 문제를 보고했다. RTX 4090에서 Qwen2.5-0.5B-Instruct 모델 추론 3라운드를 실행해도 갭이 동일하게 유지되었다.
Technical Solution
- eBPF uprobes를 libcudart.so와 libcuda.so에 부착해 모든 CUDA 메모리 작업, 커널 실행, 동기화 호출을 추적
- 5개의 인과 관계 체인을 분석해 cudaFree 호출이 p99에서 1.9ms 소요(중위값의 4.6배)되는 패턴 발견
- 워크로드 실행 중 288회 컨텍스트 스위치 기록해 Python 프로세스가 CUDA 작업 중 스케줄링 제거됨을 확인
- PyTorch의 캐싱 할당자가 재사용을 위해 의도적으로 블록을 보유하며, empty_cache()는 할당자가 완전히 해제된 것으로 표시한 블록만 해제함을 분석
- 시스템 서비스(journald, atopacct, resolved)가 CPU 시간을 경합해 cudaFree 호출의 p99 레이턴시를 증가시킴을 확인
Impact
- cudaMemcpyAsync: P50 9us vs P99 887us (98.6배 차이)
- cudaFree: P50 413us vs P99 1.9ms (4.6배 차이)
- cudaLaunchKernel: P50 8us vs P99 25us (3.2배 차이)
- cudaStreamSync: P50 3us vs P99 22us (6.9배 차이)
- 모델 삭제 및 gc.collect() 후에도 11.9 MB가 도달 불가능한 상태로 남음
Key Takeaway
GPU 메모리 누수 진단 시 PyTorch 할당자 수준의 분석만으로는 부족하며, eBPF를 통한 CUDA 런타임 추적으로 호스트 OS의 CPU 스케줄링이 메모리 해제 경로에 미치는 영향까지 가시화해야 근본 원인을 파악할 수 있다.
실천 포인트
PyTorch를 사용한 GPU 애플리케이션 성능 문제 진단 시, eBPF uprobes로 CUDA API 호출의 P99 레이턴시를 측정하면 메모리 할당자의 설계 의도와 OS 스케줄링 간섭을 구분할 수 있으며, 이를 통해 실제 최적화 대상(할당자 개선 vs 시스템 서비스 관리)을 정확히 결정할 수 있다.