Problemy z debugowaniem X10

Zaplecze akceleratora X10 może zapewnić znacznie wyższą przepustowość w przypadku obliczeń równoległych opartych na grafach, ale jego odroczone śledzenie i kompilacja na czas mogą czasami prowadzić do nieoczywistych zachowań. Może to obejmować częstą rekompilację śladów ze względu na zmiany kształtu wykresu lub tensora lub duże wykresy, które prowadzą do problemów z pamięcią podczas kompilacji.

Jednym ze sposobów diagnozowania problemów jest użycie metryk i liczników wykonania dostarczonych przez X10. Pierwszą rzeczą, którą należy sprawdzić, gdy model jest powolny, jest wygenerowanie raportu metryk.

Metryka

Aby wydrukować raport metryk, dodaj do swojego programu wywołanie PrintX10Metrics() :

import TensorFlow

...
PrintX10Metrics()
...

Spowoduje to rejestrowanie różnych metryk i liczników na poziomie INFO .

Opis raportu metryk

Raport zawiera takie rzeczy jak:

  • Ile razy uruchamiamy kompilacje XLA i całkowity czas spędzony na kompilacji.
  • Ile razy uruchamiamy obliczenia XLA i całkowity czas spędzony na wykonaniu.
  • Ile danych urządzenia obsługujemy, tworzymy/zniszczamy itp.

Informacje te są podawane w percentylach próbek. Przykładem jest:

Metric: CompileTime
  TotalSamples: 202
  Counter: 06m09s401ms746.001us
  ValueRate: 778ms572.062us / second
  Rate: 0.425201 / second
  Percentiles: 1%=001ms32.778us; 5%=001ms61.283us; 10%=001ms79.236us; 20%=001ms110.973us; 50%=001ms228.773us; 80%=001ms339.183us; 90%=001ms434.305us; 95%=002ms921.063us; 99%=21s102ms853.173us

Dostarczamy również liczniki, zwane zmiennymi całkowitymi, które śledzą wewnętrzny stan oprogramowania. Na przykład:

Counter: CachedSyncTensors
  Value: 395

Znane zastrzeżenia

Tensor wspierane przez X10 zachowują się semantycznie jak domyślny tryb chętny Tensor s. Istnieją jednak pewne zastrzeżenia dotyczące wydajności i kompletności:

  1. Obniżona wydajność z powodu zbyt wielu rekompilacji.

    Kompilacja XLA jest droga. X10 automatycznie kompiluje wykres za każdym razem, gdy napotkane zostaną nowe kształty, bez interwencji użytkownika. Modele muszą zobaczyć ustabilizowane kształty w ciągu kilku kroków szkoleniowych i od tego momentu nie jest wymagana ponowna kompilacja. Dodatkowo ścieżki wykonania muszą się szybko ustabilizować z tego samego powodu: X10 kompiluje się ponownie, gdy napotkana zostanie nowa ścieżka wykonania. Podsumowując, aby uniknąć rekompilacji:

    • Unikaj bardzo zmiennych, dynamicznych kształtów. Jednak niewielka liczba różnych kształtów może być w porządku. Jeśli to możliwe, należy ustawić tensory w ustalonych rozmiarach.
    • Unikaj pętli z różną liczbą iteracji pomiędzy krokami szkoleniowymi. X10 obecnie rozwija pętle, dlatego różna liczba iteracji pętli przekłada się na różne (rozwinięte) ścieżki wykonania.
  2. Niewielka liczba operacji nie jest jeszcze obsługiwana przez X10.

    Obecnie mamy kilka operacji, które nie są obsługiwane, albo dlatego, że nie ma dobrego sposobu na wyrażenie ich za pomocą XLA i kształtów statycznych (obecnie tylko nonZeroIndices ), albo z powodu braku znanych przypadków użycia (kilka operacji na algebrze liniowej i inicjalizacja wielomianowa). . Podczas gdy drugą kategorię można łatwo rozwiązać w razie potrzeby, pierwszą kategorię można rozwiązać jedynie poprzez interoperacyjność z procesorem, bez implementacji XLA. Zbyt częste używanie interoperacyjności ma znaczący wpływ na wydajność ze względu na objazdy hosta i fragmentację w pełni połączonego modelu na wiele śladów. Dlatego użytkownikom zaleca się unikanie stosowania takich operacji w swoich modelach.

    W systemie Linux użyj XLA_SAVE_TENSORS_FILE (udokumentowane w następnej sekcji), aby uzyskać ślad stosu Swift, który wywołał nieobsługiwaną operację. Nazwy funkcji można ręcznie rozmieniać za pomocą swift-demangle .

Pozyskiwanie i wykresy śladów

Jeśli podejrzewasz, że występują problemy ze sposobem śledzenia wykresów lub chcesz zrozumieć proces śledzenia, dostępne są narzędzia umożliwiające wylogowanie się i wizualizację śladów. Możesz sprawić, że X10 wyloguje znalezione ślady, ustawiając zmienną środowiskową XLA_SAVE_TENSORS_FILE :

export XLA_SAVE_TENSORS_FILE=/home/person/TraceLog.txt

Te dzienniki śledzenia są dostępne w trzech formatach: text , hlo i dot , przy czym format można ustawić za pomocą zmiennej środowiskowej XLA_SAVE_TENSORS_FMT:

export XLA_SAVE_TENSORS_FMT=text

Po uruchomieniu aplikacji wylogowana reprezentacja text pokaże każdy indywidualny ślad w notacji tekstowej wysokiego poziomu używanej przez X10. Reprezentacja hlo pokazuje reprezentację pośrednią przekazywaną do kompilatora XLA. Możesz chcieć ograniczyć liczbę iteracji w pętlach szkoleniowych lub obliczeniowych, aby zapobiec nadmiernemu powiększaniu się tych dzienników. Ponadto każde uruchomienie aplikacji zostanie dołączone do tego pliku, więc możesz chcieć go usunąć pomiędzy uruchomieniami.

Ustawienie zmiennej XLA_LOG_GRAPH_CHANGES na 1 wskaże również w dzienniku śledzenia, gdzie nastąpiły zmiany na wykresie. Jest to niezwykle pomocne w znajdowaniu miejsc, w których nastąpi rekompilacja.

Aby uzyskać wizualną reprezentację śladu, opcja dot wyloguje wykresy kompatybilne z Graphviz. Jeśli wyodrębnisz część śladu, która wygląda jak

digraph G {
    ...
}

do własnego pliku, Graphviz (zakładając, że jest zainstalowany) może wygenerować diagram wizualny poprzez

dot -Tpng trace.dot -o trace.png

Należy pamiętać, że ustawienie zmiennej środowiskowej XLA_SAVE_TENSORS_FILE , szczególnie gdy jest używane w połączeniu z XLA_LOG_GRAPH_CHANGES , będzie miało znaczny negatywny wpływ na wydajność. Używaj ich tylko podczas debugowania, a nie do regularnej pracy.

Dodatkowe zmienne środowiskowe

Dodatkowe zmienne środowiskowe do debugowania obejmują:

  • XLA_USE_BF16 : Jeśli ustawione na 1, przekształca wszystkie wartości Float na BF16. Należy go używać tylko do debugowania, ponieważ oferujemy automatyczną precyzję mieszaną.

  • XLA_USE_32BIT_LONG : Jeśli ustawione na 1, mapuje typ S4TF Long na 32-bitowy typ całkowity XLA. W TPU 64-bitowe obliczenia na liczbach całkowitych są drogie, więc ustawienie tej flagi może pomóc. Oczywiście użytkownik musi mieć pewność, że wartości nadal mieszczą się w 32-bitowej liczbie całkowitej.