In diesem Thema erfahren Sie, wie Sie Windows ML installieren und verwenden, um Ausführungsanbieter (EPs) für die Verwendung mit der ONNX-Runtime zu ermitteln, herunterzuladen und zu registrieren, die mit Windows ML ausgeliefert wird. Windows ML behandelt die Komplexität der Paketverwaltung und der Hardwareauswahl, sodass Sie die neuesten Ausführungsanbieter herunterladen können, die mit der Hardware Ihrer Benutzer kompatibel sind.
Wenn Sie mit der ONNX-Runtime noch nicht vertraut sind, empfehlen wir, die ONNX-Runtime-Dokumente zu lesen. Kurz gesagt bietet Windows ML eine Kopie der ONNX-Runtime sowie die Möglichkeit, Ausführungsanbieter (EPs) dynamisch herunterzuladen.
Voraussetzungen
- .NET 8 oder höher, um alle Windows ML-APIs zu verwenden
- Mit .NET 6 können Sie Ausführungsanbieter mithilfe der
Microsoft.Windows.AI.MachineLearning APIs installieren, aber Sie können die Microsoft.ML.OnnxRuntime APIs nicht verwenden.
- Festlegen eines Windows 10-spezifischen TFM wie
net8.0-windows10.0.19041.0 oder höher
- Visual Studio 2022 mit C++-Workload (enthält den C-Compiler)
- CMake 3.21 oder höher
Python-Versionen 3.10 bis 3.13, auf x64- und ARM64-Geräten.
Schritt 1: Installieren oder Aktualisieren von Windows ML
Windows ML-C-APIs sind in der Microsoft.WindowsAppSDK.ML NuGet-Paketversion1.8.2141 oder höher enthalten. Das NuGet-Paket enthält CMake-Konfigurationsdateien, die build/cmake/ direkt genutzt werden können. Das @WINML_VERSION@ Token wird zur NuGet-Buildzeit aufgelöst, sodass keine zusätzliche Verarbeitung erforderlich ist.
So verwenden Sie das NuGet-Paket...
- Herunterladen oder Wiederherstellen des NuGet-Pakets (z. B. über
nuget restore oder manuelles Herunterladen)
- Extrahieren oder Verweisen auf das Paketstammverzeichnis
- Auf
CMAKE_PREFIX_PATH im Unterverzeichnis des Pakets build/cmake festlegen
BeispielCMakeLists.txt
cmake_minimum_required(VERSION 3.21)
project(MyApp LANGUAGES CXX)
# C++20 standard for modern features (std::format, etc.)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(microsoft.windows.ai.machinelearning CONFIG REQUIRED)
add_executable(MyApp main.cpp)
target_link_libraries(MyApp PRIVATE WindowsML::Api WindowsML::OnnxRuntime)
add_custom_command(TARGET MyApp POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
$<TARGET_RUNTIME_DLLS:MyApp> $<TARGET_FILE_DIR:MyApp>
COMMAND_EXPAND_LISTS
VERBATIM
)
Beispiel-Buildbefehle
# Point CMAKE_PREFIX_PATH to the NuGet package's cmake directory
cmake -B build -S . -DCMAKE_PREFIX_PATH="C:/packages/Microsoft.WindowsAppSDK.ML/build/cmake"
cmake --build build --config Release
Das NuGet-Paket enthält eine eigene CMake-Konfiguration unter build/cmake/, die die NuGet-Verzeichnisstruktur versteht (architekturspezifische Verzeichnisse unter lib/native/ und runtimes/). Die Architektur wird aus CMAKE_GENERATOR_PLATFORM, CMAKE_VS_PLATFORM_NAME oder CMAKE_SYSTEM_PROCESSOR bestimmt.
Die vcpkg-Portdatei generiert eine separate, dünne Konfigurationsdatei, die dem standardmäßigen vcpkg-Layout (lib/ und bin/) zugeordnet ist. Beide Konfigurationen verwenden dieselbe Zieldatei (microsoft.windows.ai.machinelearning-targets.cmake), die die IMPORTIERTen Ziele definiert.
Die gleichen Ziele (WindowsML::WindowsML, WindowsML::Api, WindowsML::OnnxRuntime, WindowsML::DirectML) sind in beiden Verbrauchsmodi verfügbar. Verwenden Sie den standardmäßigen CMake 3.21-Generatorausdruck $<TARGET_RUNTIME_DLLS>, um Laufzeit-DLLs in das Build-Ausgabeverzeichnis zu kopieren.
Die Python-Bindung nutzt das Pywinrt-Projekt für die Windows App SDK-Projektion. Stellen Sie sicher, dass Ihre Python-Installation nicht aus dem Microsoft Store stammt (Sie können eine entpackte Version von python.org oder über Winget installieren). Das Beispiel hängt von der Verwendung der dynamischen Abhängigkeits-API des Windows App SDK ab, die nur für entpackte Apps gültig ist.
Installieren Sie die Python-Pakete mit den folgenden Befehlen:
pip install wasdk-Microsoft.Windows.AI.MachineLearning[all] wasdk-Microsoft.Windows.ApplicationModel.DynamicDependency.Bootstrap onnxruntime-windowsml
Stellen Sie sicher, dass die Version der wasdk- Pakete mit der WindowsAppRuntime-Version übereinstimmt.
Schritt 2: Herunterladen und Registrieren von EPs
Die einfachste Möglichkeit, loszulegen, besteht darin, Windows ML automatisch die neueste Version aller kompatiblen Ausführungsprovider ermitteln, herunterladen und registrieren zu lassen. Ausführungsanbieter müssen bei der ONNX-Runtime innerhalb von Windows ML registriert werden, bevor Sie sie verwenden können. Und wenn sie noch nicht heruntergeladen wurden, müssen sie zuerst heruntergeladen werden. Ein Aufruf von EnsureAndRegisterCertifiedAsync() erledigt beides in einem Schritt.
using Microsoft.ML.OnnxRuntime;
using Microsoft.Windows.AI.MachineLearning;
// First we create a new instance of EnvironmentCreationOptions
EnvironmentCreationOptions envOptions = new()
{
logId = "WinMLDemo", // Use an ID of your own choice
logLevel = OrtLoggingLevel.ORT_LOGGING_LEVEL_ERROR
};
// And then use that to create the ORT environment
using var ortEnv = OrtEnv.CreateInstanceWithOptions(ref envOptions);
// Get the default ExecutionProviderCatalog
var catalog = ExecutionProviderCatalog.GetDefault();
// Ensure and register all compatible execution providers with ONNX Runtime
// This downloads any necessary components and registers them
await catalog.EnsureAndRegisterCertifiedAsync();
Die einfachste Möglichkeit, loszulegen, besteht darin, Windows ML automatisch die neueste Version aller kompatiblen Ausführungsprovider ermitteln, herunterladen und registrieren zu lassen. Ausführungsanbieter müssen bei der ONNX-Runtime innerhalb von Windows ML registriert werden, bevor Sie sie verwenden können. Und wenn sie noch nicht heruntergeladen wurden, müssen sie zuerst heruntergeladen werden. Ein Aufruf von EnsureAndRegisterCertifiedAsync() erledigt beides in einem Schritt.
#include <winrt/Microsoft.Windows.AI.MachineLearning.h>
#include <winml/onnxruntime_cxx_api.h>
// First we need to create an ORT environment
Ort::Env env(ORT_LOGGING_LEVEL_ERROR, "WinMLDemo"); // Use an ID of your own choice
// Get the default ExecutionProviderCatalog
winrt::Microsoft::Windows::AI::MachineLearning::ExecutionProviderCatalog catalog =
winrt::Microsoft::Windows::AI::MachineLearning::ExecutionProviderCatalog::GetDefault();
// Ensure and register all compatible execution providers with ONNX Runtime
catalog.EnsureAndRegisterCertifiedAsync().get();
Mit den C-APIs müssen Sie einen bestimmten Ausführungsanbieter herunterladen und dann den Pfad manuell bei ONNX-Runtime registrieren.
#include <WinMLEpCatalog.h>
#include <onnxruntime_cxx_api.h> // Or <onnxruntime_c_api.h> if just using C
#include <filesystem>
#include <string>
// Initialize ONNX Runtime
Ort::Env env(ORT_LOGGING_LEVEL_ERROR, "WinMLDemo"); // Use an ID of your own choice
// --- Windows ML: Get EP catalog handle ---
WinMLEpCatalogHandle catalog = nullptr;
HRESULT hr = WinMLEpCatalogCreate(&catalog);
if (FAILED(hr))
{
// Handle error
return;
}
// --- Windows ML: Find, download, and register a specific EP (in this case, QNN) ---
WinMLEpHandle ep = nullptr;
hr = WinMLEpCatalogFindProvider(catalog, "QNN", NULL, &ep);
if (SUCCEEDED(hr))
{
// Windows ML: Download the EP if it isn't already downloaded
WinMLEpEnsureReady(ep);
// Windows ML: Get the EP library path
size_t pathSize = 0;
WinMLEpGetLibraryPathSize(ep, &pathSize);
std::string libraryPathUtf8(pathSize, '\0');
WinMLEpGetLibraryPath(ep, pathSize, libraryPathUtf8.data(), nullptr);
// Register the EP with ONNX Runtime using the C++ API
std::filesystem::path libraryPath(libraryPathUtf8);
env.RegisterExecutionProviderLibrary("QNN", libraryPath.wstring());
}
// --- Windows ML: Release the EP catalog handle ---
WinMLEpCatalogRelease(catalog);
Mit den Python-APIs können Sie alle kompatiblen Ausführungsanbieter aufzählen und dann ihre Pfade manuell bei ONNX-Runtime registrieren.
import sys
from pathlib import Path
import traceback
_winml_instance = None
class WinML:
def __new__(cls, *args, **kwargs):
global _winml_instance
if _winml_instance is None:
_winml_instance = super(WinML, cls).__new__(cls, *args, **kwargs)
_winml_instance._initialized = False
return _winml_instance
def __init__(self):
if self._initialized:
return
self._initialized = True
self._fix_winrt_runtime()
from winui3.microsoft.windows.applicationmodel.dynamicdependency.bootstrap import (
InitializeOptions,
initialize
)
import winui3.microsoft.windows.ai.machinelearning as winml
self._win_app_sdk_handle = initialize(options=InitializeOptions.ON_NO_MATCH_SHOW_UI)
self._win_app_sdk_handle.__enter__()
catalog = winml.ExecutionProviderCatalog.get_default()
self._providers = catalog.find_all_providers()
self._ep_paths : dict[str, str] = {}
for provider in self._providers:
provider.ensure_ready_async().get()
if provider.library_path == '':
continue
self._ep_paths[provider.name] = provider.library_path
self._registered_eps : list[str] = []
def __del__(self):
self._providers = None
self._win_app_sdk_handle.__exit__(None, None, None)
def _fix_winrt_runtime(self):
"""
This function removes the msvcp140.dll from the winrt-runtime package.
So it does not cause issues with other libraries.
"""
from importlib import metadata
site_packages_path = Path(str(metadata.distribution('winrt-runtime').locate_file('')))
dll_path = site_packages_path / 'winrt' / 'msvcp140.dll'
if dll_path.exists():
dll_path.unlink()
def register_execution_providers_to_ort(self) -> list[str]:
import onnxruntime as ort
for name, path in self._ep_paths.items():
if name not in self._registered_eps:
try:
ort.register_execution_provider_library(name, path)
self._registered_eps.append(name)
except Exception as e:
print(f"Failed to register execution provider {name}: {e}", file=sys.stderr)
traceback.print_exc()
return self._registered_eps
WinML().register_execution_providers_to_ort()
Tipp
Schließen Sie in Produktionsanwendungen den EnsureAndRegisterCertifiedAsync() Anruf in einen Try-Catch-Block ein, um potenzielle Netzwerk- oder Downloadfehler ordnungsgemäß zu verarbeiten.
Nächste Schritte
Nach der Registrierung von Ausführungsanbietern können Sie die ONNX-Runtime-APIs in Windows ML verwenden! Sie möchten...
-
Auswählen von Ausführungsanbietern – Teilen Sie der Laufzeit mit, welche Ausführungsanbieter Sie verwenden möchten.
-
Abrufen Ihrer Modelle – Verwenden des Modellkatalogs, um Modelle dynamisch herunterzuladen oder lokal einzuschließen
-
Modellinferenz ausführen – Kompilieren, Laden und Inferenz des Modells
Siehe auch