Dlaczego błędy z kształtami tensorów pojawiają się znikąd (i jak lepsza notacja może je powstrzymać)
Dlaczego błędy w kształtach tensorów pozostają niewidoczne
Znasz ten moment. Trening działa, strata spada, metryki wyglądają sensownie. A potem, po trzech tygodniach na produkcji, ktoś zauważa, że wyniki modelu są systematycznie błędne i nie da się tego łatwo wytłumaczyć.
Przyczyna? Oś, która w Twojej głowie miała jedno znaczenie, ale w kodzie została zinterpretowana inaczej.
To nie jest błąd kompilacji. Nie jest to też crash w czasie działania. To coś gorszego — cicha awaria poprawności, która wpływa na każdą predykcję Twojego modelu.
Problem z notacją
Prawda jest taka: czego nie nazwiesz, tego nie sprawdzisz.
Większość frameworków tensorowych nie interesuje się tym, co znaczą wymiary. Kształt (32, 768, 12, 64) może oznaczać:
(batch, sequence, heads, dim_per_head)w jednym kontekście(batch, features, height, width)w innym(batch, tokens, layers, channels)w jeszcze innym
Kompilator nie widzi różnicy. Kształt to po prostu krotka liczb. Dopóki wymiary się mnożą, operacja jest legalna. Framework wykonuje ją z radością — i zapomina, co naprawdę oznaczały te liczby.
Tędy właśnie wchodzą ciche błędy. Nie przez matematykę. Przez intencję.
Co daje lepsza notacja
W idealnym świecie operacje na tensorach nie tylko wnoszą wymiary — przenoszą też ich znaczenie przez system types.
Zamiast zastanawiać się później, która oś jest która, deklarujesz to od razu:
tensor: [batch=32, sequence=128, heads=12, dim_per_head=64]
Wtedy kompilator może sprawdzić:
- Czy broadcastujesz tylko wzdłuż osi, które powinny się broadcastować
- Czy redukcja usuwa właściwe osie
- Czy heads pozostają rozdzielone od wymiarów cech
- Czy LayerNorm normalizuje właściwe wymiary
Kompilator staje się Twoim partnerem. Wychwyca miszmasz osi jeszcze przed treningiem.
Jakie koszty ponosimy przez ciche błędy
Taka mała pomyłka może mieć dalekosiężne konsekwencje:
W badaniach: godzi<|eos|>