🟢 🏥 실무 게시일: · 3 분 읽기 ·

PyTorch가 몇 가지 템플릿 클래스에서 수천 개의 테스트를 생성하는 방법 — 테스트 인프라 가이드

에디토리얼 일러스트레이션: PyTorch CI 인프라의 자동 테스트 및 최적화 도구

Red Hat의 Riya Punia가 작성한 PyTorch 블로그 포스트는 CI 실패에서 TestMatmul.test_basic 대신 TestMatmulCUDA.test_basic_cuda_float32와 같은 이상한 이름이 나타나는 이유를 설명합니다. 테스트는 임포트 시 디바이스와 dtype 조합을 통해 생성됩니다.

🤖

이 기사는 AI가 1차 출처를 기반으로 생성했습니다.

PyTorch CI가 TestMatmulCUDA.test_basic_cuda_float32와 같은 이름으로 실패를 보고할 때, 소스 코드를 살펴보는 개발자는 그 클래스를 찾지 못하는 경우가 많습니다. 이는 버그가 아니라 의도된 설계입니다. Red Hat의 Riya Punia는 2026년 7월 3일 PyTorch 블로그에 이 시스템의 메커니즘을 밝히는 상세한 가이드를 게시했습니다.

임포트 시 테스트 생성

PyTorch 테스트 인프라의 핵심은 torch/testing/_internal/common_device_type.py에 정의된 instantiate_device_type_tests() 함수입니다. 이 함수는 템플릿 클래스—그 자체로는 실행 불가능한—를 받아 지원되는 각 디바이스에 대한 구체적인 클래스를 런타임에 생성합니다.

하나의 test_basic 메서드를 가진 템플릿 클래스 TestMatmul은 세 가지 구체적인 클래스가 됩니다. TestMatmulCPU, TestMatmulCUDA, TestMatmulMPS. 각 메서드는 모든 관련 dtype 조합에 대한 접미사를 받습니다. test_basic_cuda_float32, test_basic_cuda_float16, test_basic_cuda_bfloat16 등. 지원되는 디바이스에는 CPU, CUDA, MPS(Apple Silicon), XPU(Intel)가 포함되며, dtype은 float16, float32, float64, bfloat16이 포함됩니다.

명명 규칙은 일관됩니다. <클래스이름><디바이스>.<메서드>_<디바이스>_<dtype>. 이 규칙에 대한 이해는 CI 실패 디버깅에 필수적입니다.

일반적인 함정: pytest 필터에서 템플릿 클래스 타겟팅

Punia가 언급하는 가장 흔한 실수 중 하나는 pytest -k 필터에서 원본 템플릿 이름을 사용하는 것입니다. pytest test/test_torch.py -k "TestMatmul" 명령은 아무것도 찾지 못하는데, 런타임에 TestMatmul 클래스는 실행 가능한 형태로 존재하지 않기 때문입니다. TestMatmulCPU, TestMatmulCUDA 및 기타 생성된 변형만 존재합니다. 올바른 타겟팅은 pytest test/test_torch.py -k "test_basic_cuda_float32" -x입니다.

OpInfo: 연산자를 위한 메타데이터 레이어

테스트 인프라의 두 번째 기둥은 OpInfo입니다. 각 PyTorch 연산자가 어떻게 테스트되어야 하는지 설명하는 중앙 집중식 항목입니다. torch/testing/_internal/opinfo/core.py에 정의되어 있으며, 전역 연산자 레지스트리는 torch/testing/_internal/common_methods_invocations.py에 있습니다.

각 OpInfo 항목에는 연산자 이름, 호출 변형, 지원되는 dtype, 샘플 입력 생성기, 수치 허용오차, 특정 조합에 대한 스킵이 포함됩니다. @ops 데코레이터로 표시된 일반 테스트 템플릿은 자동으로 모든 등록된 연산자를 반복하고 각 조합에 대한 테스트를 실행합니다. 중복된 코드 한 줄도 없습니다.

결과적으로 더 적은 수의 템플릿 테스트가 수천 개의 구체적인 테스트 케이스를 커버합니다. Punia는 이를 거대한 수의 연산자와 하드웨어 타겟을 아우르는 PyTorch의 테스트 스위트 유지 보수를 가능하게 하는 근본적인 메커니즘으로 지목합니다.

주요 파일 구조

Punia는 인프라 기반을 형성하는 5가지 주요 파일을 언급합니다.

  • torch/testing/_internal/common_utils.py — 공통 테스트 유틸리티, 기본 TestCase 클래스, run_tests()
  • torch/testing/_internal/common_device_type.pyinstantiate_device_type_tests(), @dtypes, @ops 데코레이터
  • torch/testing/_internal/opinfo/core.py — OpInfo 항목 정의 및 메타데이터
  • torch/testing/_internal/common_methods_invocations.py — 모든 연산자의 op_db 레지스트리
  • test/run_test.py — 샤딩 지원을 갖춘 CI 스타일 러너

CI 실패를 어떻게 디버그하나요?

PyTorch CI는 Dr. CI를 사용합니다. 그룹화된 실패와 실패가 기록된 샤드에 대한 정보를 풀 리퀘스트에 자동으로 댓글로 다는 도구입니다. Punia가 권장하는 디버깅 흐름: (1) Dr. CI 댓글에서 샤드 정보 추출, (2) hud.pytorch.org에서 특정 CI 작업의 로그 찾기, (3) 생성된 테스트 이름 추출, (4) 정확한 생성된 이름으로 로컬에서 재현.

실행 제어를 위해 환경 변수도 사용할 수 있습니다. PYTORCH_TESTING_DEVICE_ONLY_FOR는 선택한 디바이스로 테스트를 제한하고, PYTORCH_TEST_WITH_SLOW는 느린 테스트를 포함하며, PYTORCH_TEST_WITH_DYNAMOtorch.compile 아래의 테스트를 커버합니다. 또한 EXPECTTEST_ACCEPT는 스냅샷을 사용하는 테스트의 캡처된 출력을 자동으로 업데이트합니다.

Punia는 또 다른 흔한 실수에 대해 경고합니다. dtype 제네릭 테스트 내에서 torch.randn() 사용. torch.randn()은 항상 float32 텐서를 생성합니다. bfloat16에 대해 실행되는 테스트에서 이는 올바르지 않습니다. 권장 대체 호출은 생성된 테스트에서 받은 dtype 인수를 존중하는 make_tensor()입니다.

실용적인 시사점

이 가이드는 PyTorch에 기여하거나 이상한 CI 실패를 디버그하는 모든 사람을 위한 것이지만, 더 광범위하게도 유효합니다. 임포트 시 동적 테스트 생성은 코드 폭발 없이 조합적 공간을 커버해야 하는 더 큰 Python 프로젝트 어디서나 나타나는 패턴입니다. 템플릿 클래스와 생성된 클래스의 차이를 이해하는 것이 그러한 시스템과 생산적으로 작업하기 위한 첫 번째 단계입니다. PyTorch에 있어 이 통찰은 「CI가 알 수 없는 이름으로 실패했음」에서 「로컬에서 재현을 얻었음」까지의 경로를 hud.pytorch.org에서의 단일 검색으로 단축시켜 줍니다.

자주 묻는 질문

CI에서의 테스트 이름이 소스 코드에서 보이는 이름과 왜 일치하지 않나요?
PyTorch는 instantiate_device_type_tests() 함수를 사용하여 임포트 시 구체적인 테스트를 생성합니다. test_basic 메서드를 가진 템플릿 클래스 TestMatmul은 런타임에 TestMatmulCPU, TestMatmulCUDA, TestMatmulMPS와 같은 클래스로 확장되며 test_basic_cuda_float32와 같은 메서드를 갖게 됩니다. 즉, 소스 코드의 원본 템플릿은 실행 가능한 클래스로 존재하지 않습니다.
OpInfo란 무엇이며 어떤 용도로 사용되나요?
OpInfo는 개별 연산자가 테스트되어야 하는 방식을 중앙에서 설명하는 메타데이터 항목입니다. 지원되는 dtype, 입력 샘플, 허용오차, 스킵을 포함합니다. @ops 데코레이터가 있는 일반 테스트 템플릿은 자동으로 모든 조합을 받아 각각에 대한 테스트를 실행합니다. 연산자당 코드 중복이 없습니다.
CI에서 발생한 실패를 로컬에서 어떻게 재현하나요?
Dr. CI 댓글에서 샤드 이름을 추출하고, 생성된 테스트 이름(예: TestMatmulCUDA.test_basic_cuda_float32)을 찾아 실행합니다. pytest test/test_torch.py -k 「test_basic_cuda_float32」 -x. 디바이스 접미사 없이 템플릿 클래스를 타겟으로 하면 테스트를 찾을 수 없습니다.