🟢 🏥 U praksi Objavljeno: · 3 min čitanja ·

Kako PyTorch generira tisuće testova iz nekoliko template klasa — vodič kroz test-infrastrukturu

Editorial ilustracija: PyTorch alati za automatsko testiranje i optimizaciju CI infrastrukture

PyTorch blog autorice Riye Punia (Red Hat) objašnjava zašto CI padovi nose čudna imena poput TestMatmulCUDA.test_basic_cuda_float32 umjesto izvornog TestMatmul.test_basic — testovi se generiraju u trenutku importa kroz kombinacije uređaja i dtype-ova.

🤖

Ovaj članak generiran je uz pomoć umjetne inteligencije na temelju primarnih izvora.

Kada PyTorch CI prijavi pad s imenom poput TestMatmulCUDA.test_basic_cuda_float32, programer koji pogleda izvorni kod nerijetko ne pronađe tu klasu. Nije bug — to je namjerno. Riya Punia iz Red Hata objavila je 3. srpnja 2026. na PyTorch blogu detaljan vodič koji razotkriva mehanizme koji stoje iza tog sustava.

Generiranje testova u trenutku importa

Srž PyTorchove test-infrastrukture je funkcija instantiate_device_type_tests() definirana u torch/testing/_internal/common_device_type.py. Ta funkcija prima template klasu — koja sama po sebi nije izvršiva — i iz nje u runtimeu stvara konkretne klase za svaki podržani uređaj.

Template klasa TestMatmul s jednom metodom test_basic postaje tri konkretne klase: TestMatmulCPU, TestMatmulCUDA i TestMatmulMPS. Svaka metoda dobiva sufikse za sve relevantne kombinacije dtype-ova: test_basic_cuda_float32, test_basic_cuda_float16, test_basic_cuda_bfloat16 i tako dalje. Podržani uređaji uključuju CPU, CUDA, MPS (Apple Silicon) i XPU (Intel), a dtype-ovi obuhvaćaju float16, float32, float64 i bfloat16.

Konvencija imenovanja je dosljedna: <ImeKlase><UREĐAJ>.<metoda>_<uređaj>_<dtype>. Znanje o toj konvenciji ključno je za bilo kakvo debugiranje CI padova.

Česta zamka: ciljanje template-klase u pytest filteru

Jedna od najčešćih grešaka koje Punia navodi je korištenje izvornog template-imena u pytest -k filteru. Komanda pytest test/test_torch.py -k "TestMatmul" neće pronaći ništa jer klasa TestMatmul u runtimeu ne postoji kao izvršiva — postoje samo TestMatmulCPU, TestMatmulCUDA i ostale generirane varijante. Ispravno ciljanje je pytest test/test_torch.py -k "test_basic_cuda_float32" -x.

OpInfos: metapodatkovni sloj za operatore

Drugi stup test-infrastrukture su OpInfos — centralizirani unosi koji opisuju kako se svaki PyTorch operator treba testirati. Definirani su u torch/testing/_internal/opinfo/core.py, a globalni registar operatora u torch/testing/_internal/common_methods_invocations.py.

Svaki OpInfo unos sadrži: ime operatora, varijante pozivanja, podržane dtype-ove, generatore uzornih ulaza, numeričke tolerancije i skipove za specifične kombinacije. Generički test template označen @ops dekoratorom automatski iterira kroz sve unesene operatore i pokreće test za svaku kombinaciju — bez ijednog reda dupliciranog koda.

Rezultat je da manji broj template-testova pokriva tisuće konkretnih testnih slučajeva. Punia navodi to kao temeljni mehanizam koji omogućuje održivost PyTorchove test suite-a koja inače obuhvaća ogroman broj operatora i hardverskih ciljeva.

Struktura ključnih datoteka

Punia navodi pet ključnih datoteka koje čine infrastrukturni temelj:

  • torch/testing/_internal/common_utils.py — zajednički testni utilities, bazna TestCase klasa, run_tests()
  • torch/testing/_internal/common_device_type.pyinstantiate_device_type_tests(), dekoratori @dtypes, @ops
  • torch/testing/_internal/opinfo/core.py — definicije i metapodaci OpInfo unosa
  • torch/testing/_internal/common_methods_invocations.pyop_db registar svih operatora
  • test/run_test.py — CI-style runner sa sharding podrškom

Kako debugirati CI pad?

PyTorch CI koristi Dr. CI — alat koji automatski komentira pull requestove s grupiranim padovima i informacijama o shard-u gdje je pad zabilježen. Tijek debugiranja koji Punia preporučuje: (1) iz Dr. CI komentara izvuci shard informaciju, (2) na hud.pytorch.org pronađi logove konkretnog CI joba, (3) izvuci generirano ime testa, (4) reproduciraj lokalno s točnim generiranim imenom.

Za kontrolu izvođenja dostupne su i environment varijable: PYTORCH_TESTING_DEVICE_ONLY_FOR ograničava testove na odabrani uređaj, PYTORCH_TEST_WITH_SLOW uključuje spore testove, a PYTORCH_TEST_WITH_DYNAMO pokriva testove pod torch.compile. Postoji i EXPECTTEST_ACCEPT koji automatski ažurira snimljene izlaze (snapshots) za testove koji ih koriste.

Punia upozorava i na drugu čestu pogrešku: korištenje torch.randn() unutar dtype-generičkih testova. torch.randn() uvijek producira float32 tensor — u testu koji se pokreće za bfloat16 to je neispravno. Preporučeni zamjenski poziv je make_tensor() koji poštuje dtype argument koji dobiva od generiranog testa.

Praktična implikacija

Vodič je namijenjen svim koji doprinose PyTorchu ili debugiraju neobične CI padove, ali vrijedi i šire: dinamičko generiranje testova u importu je obrazac koji se pojavljuje u većim Python projektima svuda gdje je potrebno pokriti kombinatoričke prostore bez eksplozije koda. Razumijevanje razlike između template-klase i generiranih klasa prvi je korak prema produktivnom radu s takvim sustavima. Za PyTorch konkretno, taj uvid skraćuje put od „CI je pao s nepoznatim imenom” do „imam reprodukciju lokalno” s jedne pretrage na hud.pytorch.org.

Česta pitanja

Zašto ime testa u CI-u ne odgovara imenu koje vidim u izvornom kodu?
PyTorch generira konkretne testove u trenutku importa pomoću funkcije instantiate_device_type_tests(). Template klasa TestMatmul s metodom test_basic u runtimeu se širi u klase TestMatmulCPU, TestMatmulCUDA, TestMatmulMPS s metodama poput test_basic_cuda_float32 — što znači da izvorni template u kodu ne postoji kao izvršiva klasa.
Što su OpInfos i čemu služe?
OpInfos su metapodatkovni unosi koji centralizirano opisuju kako se pojedini operator treba testirati: podržane dtype-ove, ulazne uzorke, tolerancije, skipove. Generički test template s @ops dekoratorom automatski prima sve te kombinacije i pokreće test za svaku — bez dupliciranja koda po operatoru.
Kako lokalno reproducirati pad koji se vidi u CI-u?
Iz Dr. CI komentara izvuci ime shard-a, pronađi generirano ime testa (npr. TestMatmulCUDA.test_basic_cuda_float32) i pokreni: pytest test/test_torch.py -k 'test_basic_cuda_float32' -x. Ciljanje template-klase bez sufiksa uređaja neće naći test.