Kompilowanie i buforowanie modeli ONNX w usłudze Windows ML

Kompilacja to etap, w którym model ONNX jest przekształcany w plik binarny specyficzny dla danego sprzętu, który jest faktycznie uruchamiany przez dostawcę wykonania (EP). W przypadku jednostek NPU i procesorów GPU krok ten może potrwać od kilku sekund do kilku minut w przypadku dużych modeli — a jeśli aplikacja nie buforuje wyniku, użytkownicy płacą ten koszt za każdym razem, gdy aplikacja się uruchamia.

Na tej stronie wyjaśniono, co obejmuje kompilacja, kiedy należy wstępnie skompilować i jak Windows ML buforuje skompilowany artefakt.

Dwa rodzaje kompilacji

"Kompilacja" może oznaczać dwie różne rzeczy. Oddzielenie ich sprawia, że reszta tej strony jest łatwiejsza do rozumowania:

  • Optymalizacja grafu — łączenie, stałe składanie i układ pracy wykonywane przez środowisko uruchomieniowe ONNX podczas tworzenia sesji. Jest to tanie, niezależne od EP i uruchamiane za każdym razem, gdy tworzysz sesję.
  • Kompilacja EP — konwersja grafu ONNX na własny format EP, a następnie kompilacja w dół do pliku binarnego specyficznego dla sprzętu. Sprzętowe EP (QNN, OpenVINO, VitisAI, NvTensorRtRtx, MIGraphX) wykonują to i jest to kosztowny etap. Na jednostkach NPU może to zająć od kilkudziesięciu sekund do kilku minut w przypadku większych modeli.

Windows ML unika ponownego ponoszenia kosztu kompilacji EP dzięki mechanizmowi EPContext środowiska ONNX Runtime. Pierwsza kompilacja serializuje plik binarny gotowy do uruchomienia na sprzęcie do modelu *_ctx.onnx (lub do pliku sidecar .bin); późniejsze sesje ładują wstępnie zbudowany plik binarny i całkowicie pomijają konwersję.

Dlaczego warto wstępnie skompilować?

Windows ML zdecydowanie zaleca wstępne kompilacje podczas korzystania z dostawców wykonywania. Prekompilacja sprowadza wielosekundowy — a czasem nawet wielominutowy — zimny start do jednorazowego kosztu i daje aplikacji:

  • Szybkie zimne starty — kolejne uruchomienia pomijają konwersję grafu i kompilację sprzętu.
  • Przewidywalne zachowanie — niezgodność wersji sterownika, SDK lub EP objawia się jawnym INVALID_GRAPH błędem, który można obsłużyć, zamiast powodować niewidoczne spowolnienia.
  • Mniejsze zużycie procesora i baterii — przestajesz ponownie kompilować ten sam graf przy każdym uruchomieniu.

Bez wstępnej kompilacji aplikacja ponownie uruchamia konwersję EP i kompilację podczas każdej sesji tworzenia, a użytkownicy czują opóźnienie za każdym razem.

Kiedy kompilować wstępnie

Kompiluj wstępnie za każdym razem, gdy aplikacja jest przeznaczona dla sprzętowego EP. Dostępne są dwie opcje ustawienia czasu:

Strategy Najlepsze dla Trade-offs
Kompilacja z wyprzedzeniem (AOT)(zalecana w przypadku większości aplikacji) — kompilowanie na etapie budowania lub instalacji i dostarczenie skompilowanego artefaktu. Wdrożenia dla przedsiębiorstw, aplikacje przeznaczone dla stałego profilu urządzenia, instalatory poszczególnych urządzeń. Wymaga narzędzi do krzyżowej kompilacji dla obiektów docelowych, których nie można uruchomić na maszynie kompilacji.
Kompiluj przy pierwszym uruchomieniu (najprostszym) — sprawdź skompilowany artefakt, skompiluj go, jeśli go brakuje, a następnie buforuj i użyj go ponownie. Aplikacje sklepowe i ogólna dystrybucja konsumencka na zróżnicowanej bazie sprzętowej. Użytkownicy płacą koszt kompilacji raz po pierwszym uruchomieniu.

Kompilowanie na pierwszym uruchomieniu to wzorzec pokazany w przewodniku Windows ML. Używa OrtModelCompilationOptions.CompileModel() (dostępnego w module ONNX Runtime dostarczanym z Windows ML, ORT 1.22 lub nowszym) do utworzenia skompilowanego artefaktu obok modelu i ponownego wykorzystania go przy każdym kolejnym uruchomieniu. Aby zapoznać się z interfejsem API w kontekście, zobacz Kompilowanie modeli.

Skompilowane modele są specyficzne dla urządzenia

Skompilowany model jest powiązany z konkretnym EP, dla którego został skompilowany.

Skompilowane modele mogą wymagać ponownego kompilowania

Aktualizacje EP i aktualizacje sterowników mogą spowodować, że wcześniej skompilowany model nie będzie już prawidłowy. Zalecamy, aby po zmianie wersji ep lub sterownika deweloperzy przetestowali wcześniej skompilowany model (ładując sesję wnioskowania) i zweryfikowali dane wyjściowe, w przeciwnym razie ponownie skompilowali dane wyjściowe. Przewidź unieważnianie pamięci podręcznej: wychwyć błędy INVALID_GRAPH z sesji i skompiluj ponownie, aby odświeżyć artefakt zapisany w pamięci podręcznej. Typowe wyzwalacze obejmują:

  • Zainstalowano nowy EP.
  • Sterownik procesora GPU lub procesora NPU jest aktualizowany.
  • Zmiany sprzętowe użytkownika.

Jeśli aplikacja jest dystrybuowana na różnych urządzeniach, zapisz skompilowane artefakty w lokalnej lokalizacji pamięci podręcznej, aby każde urządzenie tworzyło własne dane binarne i używało ich ponownie.

Kompilowanie modeli

Przed użyciem modelu ONNX w sesji wnioskowania często należy ją skompilować w zoptymalizowaną reprezentację, która może być wydajnie wykonywana na podstawowym sprzęcie urządzenia.

Od wersji ONNX Runtime 1.22 istnieją nowe interfejsy API, które lepiej hermetyzują kroki kompilacji. Więcej szczegółów można znaleźć w dokumentacji kompilowania środowiska uruchomieniowego ONNX (zobacz OrtCompileApi struct).

// Prepare compilation options
OrtModelCompilationOptions compileOptions = new(sessionOptions);
compileOptions.SetInputModelPath(modelPath);
compileOptions.SetOutputModelPath(compiledModelPath);

// Compile the model
compileOptions.CompileModel();

Note

Kompilacja może potrwać kilka minut. Aby każdy interfejs użytkownika pozostał dynamiczny, rozważ wykonanie tej czynności jako operacji w tle w aplikacji lub zaalarmowanie użytkownika, że model jest przygotowywany.

Zobacz także