Partilhar via


Inicializar provedores de execução com o Windows ML

Esta página discute maneiras mais avançadas de seu aplicativo lidar com o download e o registro de provedores de execução (EPs) usando o Windows ML. Mesmo que um EP já esteja baixado no dispositivo, você deve registrar os EPs toda vez que seu aplicativo for executado para que eles apareçam no ONNX Runtime.

Faça o download e registe-se numa só chamada

Para o desenvolvimento inicial, pode ser bom simplesmente ligar EnsureAndRegisterCertifiedAsync()para , que baixará quaisquer novos EPs (ou novas versões de EPs) que sejam compatíveis com seu dispositivo e drivers, se ainda não estiverem baixados, e então registrar todos os EPs. Observe que, na primeira execução, esse método pode levar vários segundos ou até minutos, dependendo da velocidade da rede e dos EPs que precisam ser baixados.

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

Sugestão

Em aplicativos de produção, envolva a EnsureAndRegisterCertifiedAsync() chamada em um bloco try-catch para lidar com possíveis falhas de rede ou download normalmente.

Registar apenas fornecedores existentes

Se você quiser evitar o download e registrar apenas os provedores de execução que já estão presentes na máquina:

var catalog = ExecutionProviderCatalog.GetDefault();

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

Descubra se há novos EPs (sem download)

Se você quiser ver se há novos EPs compatíveis com seu dispositivo e drivers disponíveis para download, mas não quiser iniciar o download, você pode usar o FindAllProviders() método e, em seguida, ver se algum provedor tem um ReadyState de NotPresent. Você pode então decidir lidar com isso como quiser (lançando seus usuários em uma "tela de atualização", perguntando se eles querem atualizar, etc). Você pode optar por continuar usando os EPs já baixados (ligando RegisterCertifiedAsync() como mostrado acima) se não quiser fazer seus usuários esperarem agora.

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

Descarregue e registe um EP específico

Se houver um provedor de execução específico que seu aplicativo deseja usar, você pode baixar e registrar um provedor de execução específico sem baixar todos os EPs compatíveis.

Você primeiro usará FindAllProviders() para obter todos os EPs compatíveis e, em seguida, poderá chamar EnsureReadyAsync() um ExecutionProvider específico para baixar o provedor de execução específico e chamar TryRegister() para registrar o provedor de execução específico.

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

Exemplo de aplicativo de produção

Para aplicativos de produção, aqui está um exemplo do que seu aplicativo pode querer fazer para dar a si mesmo e aos usuários controle sobre quando os downloads ocorrem. Você pode verificar se novos provedores de execução estão disponíveis e baixá-los condicionalmente:

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