このトピックでは、Windows ML をインストールして使用して、Windows ML に付属する ONNX ランタイムで使用する実行プロバイダー (IP) を検出、ダウンロード、および登録する方法について説明します。 Windows ML は、パッケージ管理とハードウェアの選択の複雑さを処理するため、ユーザーのハードウェアと互換性のある最新の実行プロバイダーをダウンロードできます。
ONNX ランタイムにまだ慣れていない場合は、 ONNX Runtime のドキュメントを読むことをお勧めします。つまり、Windows ML には ONNX ランタイムのコピーと、実行プロバイダー (IP) を動的にダウンロードする機能が用意されています。
[前提条件]
- すべての Windows ML API を使用する .NET 8 以降
- .NET 6 では、
Microsoft.Windows.AI.MachineLearning API を使用して実行プロバイダーをインストールできますが、 Microsoft.ML.OnnxRuntime API を使用することはできません。
-
net8.0-windows10.0.19041.0以上など、Windows 10 固有の TFM を対象とする
- Visual Studio 2022 と C++ ワークロード (C コンパイラを含む)
- CMake 3.21 以降
x64 および ARM64 デバイス上の Python バージョン 3.10 から 3.13。
手順 1: Windows ML をインストールまたは更新する
Windows ML C API は、 Microsoft.WindowsAppSDK.ML NuGet パッケージ バージョン 1.8.2141 以上に含まれています。 NuGet パッケージは、直接使用できる CMake 構成ファイルを build/cmake/ の下に出荷します。
@WINML_VERSION@ トークンは NuGet ビルド時に解決されるため、追加の処理は必要ありません。
NuGet パッケージを使用するには...
- NuGet パッケージをダウンロードまたは復元する (例:
nuget restore または手動ダウンロード)
- パッケージのルート ディレクトリを抽出または参照する
-
CMAKE_PREFIX_PATHパッケージの build/cmake サブディレクトリに設定する
CMakeLists.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
)
ビルド コマンドの例
# 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
NuGet パッケージは、NuGet ディレクトリ構造 (build/cmake/ および lib/native/ のアーキテクチャ固有のディレクトリ) を理解する独自の cmake 構成をruntimes/に提供します。 アーキテクチャは、 CMAKE_GENERATOR_PLATFORM、 CMAKE_VS_PLATFORM_NAME、または CMAKE_SYSTEM_PROCESSORから決定されます。
vcpkg portfile は、標準の vcpkg レイアウト (lib/ と bin/) にマップされる別個の薄い構成ファイルを生成します。 どちらの構成も、IMPORTED ターゲットを定義する同じターゲット ファイル (microsoft.windows.ai.machinelearning-targets.cmake) を共有します。
両方の消費モードで同じターゲット (WindowsML::WindowsML、 WindowsML::Api、 WindowsML::OnnxRuntime、 WindowsML::DirectML) を使用できます。 標準の CMake 3.21 $<TARGET_RUNTIME_DLLS> ジェネレーター式を使用して、ランタイム DLL をビルド出力ディレクトリにコピーします。
Python バインドは、Windows App SDK プロジェクションに pywinrt プロジェクトを利用します。 Python のインストールが Microsoft Store からではないことを確認します (パッケージ化されていないバージョンは、python.org または winget からインストールできます)。 このサンプルは、パッケージ化されていないアプリでのみ有効な Windows App SDK 動的依存関係 API の使用に依存しています。
次のコマンドを使用して Python パッケージをインストールしてください。
pip install wasdk-Microsoft.Windows.AI.MachineLearning[all] wasdk-Microsoft.Windows.ApplicationModel.DynamicDependency.Bootstrap onnxruntime-windowsml
wasdk- パッケージのバージョンが WindowsAppRuntime のバージョンと一致していることを確認してください。
手順 2: EP をダウンロードして登録する
開始する最も簡単な方法は、互換性のあるすべての実行プロバイダーの最新バージョンを Windows ML が自動的に検出、ダウンロード、登録できるようにすることです。 実行プロバイダーを使用するには、実行プロバイダーを Windows ML 内の ONNX ランタイムに登録する必要があります。 まだダウンロードされていない場合は、最初にダウンロードする必要があります。
EnsureAndRegisterCertifiedAsync()を呼び出すと、これらの両方が 1 つの手順で実行されます。
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();
開始する最も簡単な方法は、互換性のあるすべての実行プロバイダーの最新バージョンを Windows ML が自動的に検出、ダウンロード、登録できるようにすることです。 実行プロバイダーを使用するには、実行プロバイダーを Windows ML 内の ONNX ランタイムに登録する必要があります。 まだダウンロードされていない場合は、最初にダウンロードする必要があります。
EnsureAndRegisterCertifiedAsync()を呼び出すと、これらの両方が 1 つの手順で実行されます。
#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();
C API では、特定の実行プロバイダーをダウンロードし、そのパスを ONNX Runtime に手動で登録する必要があります。
#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);
Python API を使用すると、互換性のあるすべての実行プロバイダーを列挙し、そのパスを ONNX Runtime に手動で登録できます。
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()
ヒント
運用アプリケーションでは、 EnsureAndRegisterCertifiedAsync() 呼び出しを try-catch ブロックにラップして、潜在的なネットワーク障害やダウンロード エラーを適切に処理します。
次のステップ
実行プロバイダーを登録したら、Windows ML 内で ONNX ランタイム API を使用する準備ができました。 お勧めしたいことは、...
-
実行プロバイダーの選択 - 使用する実行プロバイダーをランタイムに通知する
-
モデルを取得する - モデル カタログを使用してモデルを動的にダウンロードするか、ローカルに含める
-
モデル推論の実行 - モデル のコンパイル、読み込み、推論
こちらも参照ください