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 zweryfikować buforowany skompilowany model przed jego ponownym użyciem.

Wymagania wstępne

Interfejsy API do obsługi zgodności skompilowanych modeli wymagają Windows ML 2.3 lub nowszej wersji. W głównym projekcie ONNX Runtime, GetModelCompatibilityForEpDevices() jest dostępny w wersji 1.23, a GetCompatibilityInfoFromModel() jest dostępny w wersji 1.24.

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 — platforma obsługuje sprawdzanie, czy skompilowany model jest optymalny dla urządzeń wybranych przez aplikację przed utworzeniem sesji wnioskowania.
  • 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) — kompilować podczas kompilacji lub instalacji i dostarczać skompilowany artefakt. Kontrolowane floty sprzętu i sterowników lub instalatorów dla poszczególnych urządzeń. Wymaga narzędzi do krzyżowej kompilacji dla obiektów docelowych, których nie można uruchomić na maszynie kompilacji. Zweryfikuj artefakt na urządzeniu docelowym i zapewnij mechanizm awaryjny w postaci ponownej kompilacji.
Kompiluj przy pierwszym uruchomieniu(zalecane w przypadku szerokiej dystrybucji) — sprawdź skompilowany artefakt, skompiluj go, jeśli brakuje, a następnie buforuj i ponownie użyj go. Aplikacje sklepowe i ogólna dystrybucja konsumencka na zróżnicowanej bazie sprzętowej. Użytkownicy płacą koszt kompilacji raz po pierwszym uruchomieniu.

Przewodnik Windows ML demonstruje podstawową mechanikę kompilowania na pierwszym uruchomieniu, sprawdzając, czy istnieje skompilowany artefakt. Nie jest to kompletny przykład zarządzania pamięcią podręczną. Przed ponownym użyciem istniejącego skompilowanego modelu w aplikacji zastosuj sprawdzanie zgodności opisane w tym artykule. Aby zapoznać się z interfejsem API kompilacji w kontekście, zobacz Kompilowanie modeli.

Weryfikowanie skompilowanego modelu przed ponownym użyciem

Skompilowany model może zależeć od konfiguracji EP i urządzenia, które go utworzyły. EP określa, czy model buforowany pozostaje zgodny i optymalny dla zestawu urządzeń.

Podczas kompilacji moduł EP może wygenerować ciąg zgodności UTF-8 zakończony znakiem null, który ONNX Runtime zapisuje do właściwości metadanych skompilowanego modelu. Format i zawartość ciągu są definiowane przez EP. Aplikacja nie powinna analizować ani interpretować jej.

Aplikacja przekazuje ciąg znaków i docelowe urządzenia EP do GetModelCompatibilityForEpDevices(). ONNX Runtime wywołuje implementację walidacji fabryki EP i zwraca stan OrtCompiledModelCompatibility. W przypadku kontraktów źródłowych zobacz GetModelCompatibilityForEpDevices() i ValidateCompiledModelCompatibilityInfo() w repozytorium środowiska uruchomieniowego ONNX.

Scenariusze sprawdzania zgodności

W dwóch scenariuszach można użyć tego samego interfejsu API sprawdzania poprawności:

  • Zweryfikuj model, który jest już na urządzeniu. Wywołaj metodę GetCompatibilityInfoFromModel() wyodrębniania ciągu z skompilowanego pliku modelu. Jeśli model jest już w pamięci, wywołaj metodę GetCompatibilityInfoFromModelBytes(). Następnie przekaż ciąg do GetModelCompatibilityForEpDevices().
  • Przed pobraniem skompilowanego modelu zweryfikuj poprawność. Opublikuj nieprzezroczysty ciąg jako lekkie metadane wraz ze skompilowanym modelem. Aplikacja może najpierw pobrać ciąg, zweryfikować go za pomocą GetModelCompatibilityForEpDevices(), a potencjalnie duży model pobrać tylko wtedy, gdy zwrócony status jest zgodny z zasadami pamięci podręcznej lub wdrażania.

Przechowuj metadane zgodności zdalnej powiązane z dokładnie tym skompilowanym artefaktem, który je wygenerował. Jeśli artefakt ulegnie zmianie, zaktualizuj skojarzony ciąg zgodności.

W obu scenariuszach:

  1. Wywołaj metodę GetEpDevices(), aby wykryć dostępne urządzenia EP, a następnie zastosuj te same zasady dotyczące EP lub urządzenia, których używasz do skonfigurowania sesji wnioskowania.
  2. Uzyskaj ciąg zgodności z modelu lokalnego lub metadanych skojarzonych z modelem zdalnym.
  3. Przekaż ciąg i odpowiadającą grupę urządzeń do GetModelCompatibilityForEpDevices().
  4. Zastosuj zasady pamięci podręcznej lub pobierania do zwróconego stanu. Przykłady Windows ML stosują konserwatywną politykę i akceptują skompilowany model wyłącznie dla EP_SUPPORTED_OPTIMAL.

GetCompatibilityInfoFromModel() Analizuje pełną wartość ONNX ModelProto z dysku. Użyj wzorca metadanych zdalnych, jeśli musisz podjąć decyzję dotyczącą zgodności przed pobraniem samego modelu.

Interfejsy API zwracają wartość OrtCompiledModelCompatibility:

Status Meaning Zalecana akcja
EP_SUPPORTED_OPTIMAL Skompilowany model jest obsługiwany i optymalny dla urządzeń EP. Użyj ponownie skompilowanego modelu.
EP_SUPPORTED_PREFER_RECOMPILATION Skompilowany model jest obsługiwany, ale EP zaleca ponowne kompilowanie w celu uzyskania lepszej wydajności. Ten model może działać, ale strategia pamięci podręcznej wyłącznie dla trybu optymalnego powoduje jego ponowną kompilację.
EP_UNSUPPORTED Skompilowany model nie jest obsługiwany przez bieżące urządzenia EP. Nie ładuj skompilowanego modelu. Ponownie skompiluj lub użyj oryginalnego modelu.
EP_NOT_APPLICABLE EP nie dostarczyła ustalenia zgodności dla dostarczonych urządzeń. Jest to również ustawienie domyślne, gdy EP nie implementuje walidacji zgodności. Nie traktuj tego statusu jako dowodu na to, że pamięć podręczna jest kompatybilna. Użyj oryginalnego modelu, chyba że aplikacja ma inne zasady sprawdzania poprawności.

W ramach polityki pamięci podręcznej ograniczonej wyłącznie do optimum brakujące metadane zgodności dla preferowanego EP należy traktować jako chybienie pamięci podręcznej. Jeśli ocena zgodności zwróci błąd, użyj oryginalnego modelu w tym uruchomieniu i nie promuj nowo skompilowanego artefaktu, ponieważ aplikacja nie może go zweryfikować.

Zdarzenia, które mogą wymagać nowego wpisu pamięci podręcznej, obejmują:

  • Zainstalowano nowy EP.
  • Sterownik procesora GPU lub procesora NPU jest aktualizowany.
  • Zmiany sprzętowe użytkownika.
  • Źródłowy model ONNX zmienia się.
  • Aplikacja zmienia ustawienia środowiska uruchomieniowego ONNX, EP lub kompilacji używane do tworzenia artefaktu.

Interfejsy API zgodności weryfikują istniejący skompilowany artefakt pod kątem urządzeń EP; nie określają, czy artefakt został utworzony na podstawie aktualnego modelu źródłowego. Uwzględnij wersję modelu źródłowego lub skrót w kluczu pamięci podręcznej i unieważnij pamięć podręczną podczas zmiany danych wejściowych kompilacji.

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.

Podstawowe sprawdzanie zgodności

Następujące funkcje pomocnicze sprawdzają skompilowany model dla jednego EP. Przed wywołaniem funkcji pomocniczej zastosuj te same zasady EP lub urządzenia, których używasz do skonfigurowania sesji wnioskowania. Kolekcja urządzeń nie może być pusta i musi zawierać urządzenia z tego samego punktu końcowego (EP).

static bool IsCompiledModelOptimal(
    OrtEnv ortEnv,
    string compiledModelPath,
    string epName,
    IReadOnlyList<OrtEpDevice> epDevices)
{
    string compatibilityInfo =
        ortEnv.GetCompatibilityInfoFromModel(compiledModelPath, epName);

    return !string.IsNullOrWhiteSpace(compatibilityInfo) &&
        ortEnv.GetModelCompatibilityForEpDevices(
            epDevices,
            compatibilityInfo) ==
        OrtCompiledModelCompatibility.EP_SUPPORTED_OPTIMAL;
}

Użyj sprawdzenia przed utworzeniem sesji:

  • Jeśli wynik spełnia zasady zgodności aplikacji, użyj skompilowanego modelu.
  • W przeciwnym razie użyj lub ponownie skompiluj oryginalny model.

Przykłady Windows ML używają konserwatywnej polityki i akceptują tylko EP_SUPPORTED_OPTIMAL. Aplikacja określa sposób przechowywania, odświeżania i zastępowania skompilowanych modeli.

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