使用 Windows ML 初始化执行提供程序

本页讨论应用可以使用 Windows ML 正常处理下载和注册执行提供程序(EP)的更高级方法。 即使设备上已下载 EP,每次运行应用时都必须注册 EP,以便它们将显示在 ONNX 运行时中。

在一次呼叫中下载并注册

对于初始开发,只需调用,即可下载 EnsureAndRegisterCertifiedAsync()任何与设备和驱动程序兼容的新 EP(或新版本的 EP)(如果尚未下载),然后注册所有 EP。 请注意,首次运行时,此方法可能需要数秒甚至几分钟时间,具体取决于需要下载的网络速度和 EP。

// 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();

小窍门

在生产应用程序中,将 EnsureAndRegisterCertifiedAsync() 调用包装在 try-catch 块中以正常方式处理潜在的网络或下载失败。

仅注册现有提供程序

如果想要避免下载并仅注册计算机上已存在的执行提供程序:

var catalog = ExecutionProviderCatalog.GetDefault();

// Register only providers already present on the machine
// This avoids potentially long download times
await catalog.RegisterCertifiedAsync();

发现是否有新的 EP (无需下载)

如果想要查看是否有与设备和驱动程序兼容的新 EP 可供下载,但不想开始下载,则可以使用 FindAllProviders() 该方法,然后查看是否有任何提供程序具有 ReadyState of NotPresent。 然后,你可以决定处理此问题(将用户启动到“正在更新的屏幕”中,询问他们是否要更新等)。 如果不想让用户立即等待,可以选择继续使用已下载的 EP(如 RegisterCertifiedAsync() 上所示调用)。

var catalog = ExecutionProviderCatalog.GetDefault();

// Check if there are new EPs that need to be downloaded
if (catalog.FindAllProviders().Any(provider => provider.ReadyState == ExecutionProviderReadyState.NotPresent))
{
    // TODO: There are new EPs, decide how your app wants to handle that
}
else
{
    // All EPs are already present, just register them
    await catalog.RegisterCertifiedAsync();
}

下载并注册特定的 EP

如果您的应用程序要使用特定的执行提供程序,您可以下载并注册该特定执行提供程序,而无需下载所有兼容的执行提供程序。

首先,你将使用FindAllProviders()获取所有兼容的 EP,然后可以调用特定的EnsureReadyAsync()下载特定的执行提供程序,并调用TryRegister()注册特定的执行提供程序。

var catalog = ExecutionProviderCatalog.GetDefault();

// Get the QNN provider, if present
var qnnProvider = catalog.FindAllProviders()
    .FirstOrDefault(i => i.Name == "QNNExecutionProvider");

if (qnnProvider != null)
{
    // Download it
    var result = await qnnProvider.EnsureReadyAsync();

    // If download succeeded
    if (result != null && result.Status == ExecutionProviderReadyResultState.Success)
    {
        // Register it
        bool registered = qnnProvider.TryRegister();
    }
}

生产应用示例

对于生产应用程序,下面是应用可能想要执行的作的示例,让你的用户能够控制何时发生下载。 可以检查新的执行提供程序是否可用,并有条件地下载它们:

using Microsoft.Windows.AI.MachineLearning;

var catalog = ExecutionProviderCatalog.GetDefault();

// Filter to the EPs our app supports/uses
var providers = catalog.FindAllProviders().Where(p =>
    p.Name == "VitisAIExecutionProvider" ||
    p.Name == "OpenVINOExecutionProvider" ||
    p.Name == "QNNExecutionProvider" ||
    p.Name == "NvTensorRtRtxExecutionProvider"
);

if (providers.Any(p => p.ReadyState == ExecutionProviderReadyState.NotPresent))
{
    // Show UI to user asking if they want to download new execution providers
    bool userWantsToDownload = await ShowDownloadDialogAsync();

    if (userWantsToDownload)
    {
        // Download all EPs
        foreach (var p in providers)
        {
            if (p.ReadyState == ExecutionProviderReadyState.NotPresent)
            {
                // Ignore result handling here; production code could inspect status
                await p.EnsureReadyAsync();
            }
        }

        // And register all EPs
        await catalog.RegisterCertifiedAsync();
    }
    else
    {
        // Register only already-present EPs
        await catalog.RegisterCertifiedAsync();
    }
}