Partilhar via


Introdução às APIs do Catálogo de Modelos do Windows ML

Este guia mostra como usar as APIs do Catálogo de Modelos do Windows ML para gerenciar modelos de IA em seus aplicativos do Windows. Você aprenderá como configurar fontes de catálogo, encontrar modelos compatíveis e baixá-los para um local compartilhado no dispositivo para todos os aplicativos usarem.

Pré-requisitos

Etapa 1: Criar uma fonte de catálogo de modelos

Você deve primeiro criar ou obter uma fonte de catálogo de modelos, que é um índice de modelos, incluindo informações sobre como acessar o modelo. Consulte os documentos de origem do catálogo de modelos para obter mais informações.

O arquivo JSON de origem do catálogo de modelos pode ser hospedado online, referenciado por meio https:// de pontos de extremidade ou usado a partir de um arquivo local, referenciado por caminhos de arquivo como C:\Users\....

Etapa 2: Inicialize o seu catálogo com a sua fonte

Inicialize um catálogo com uma única fonte de catálogo:

using Microsoft.Windows.AI.MachineLearning;
using Windows.Foundation;
using System;
using System.Threading.Tasks;

// Create a catalog source from a URI
var source = await ModelCatalogSource.CreateFromUriAsync(
    new Uri("https://contoso.com/models"));

// Create the catalog with the source
var catalog = new ModelCatalog(new ModelCatalogSource[] { source });

Você também pode configurar várias fontes de catálogo com prioridades diferentes:

var catalog = new ModelCatalog(new ModelCatalogSource[0]);

// Add sources in order of preference (highest priority first)
catalog.Sources.Add(await ModelCatalogSource.CreateFromUriAsync(
    new Uri("https://contoso.com/models")));
catalog.Sources.Add(await ModelCatalogSource.CreateFromUriAsync(
    new Uri("https://contoso.com/secondaryModels")));

Passo 3: Encontrar um modelo por nome

Procure um modelo em todas as fontes configuradas:

// Find a model by its name
CatalogModelInfo model = await catalog.FindModelAsync("phi-3.5-reasoning");

if (model != null)
{
    Console.WriteLine($"Found model: {model.Name}");
    Console.WriteLine($"Version: {model.Version}");
    Console.WriteLine($"Publisher: {model.Publisher}");
    Console.WriteLine($"Size: {model.ModelSizeInBytes / (1024 * 1024)} MB");
    Console.WriteLine($"Supported execution providers: {string.Join(", ", model.ExecutionProviders)}");
}

Passo 4: Transferir e utilizar um modelo

Obtenha uma instância de modelo e use-a com a estrutura desejada:

// Get an instance of the model (downloads if necessary)
var progress = new Progress<double>(percent => 
    Console.WriteLine($"Download progress: {percent:P}"));

CatalogModelInstanceResult result = await model.GetInstanceAsync().AsTask(progress);

if (result.Status == CatalogModelInstanceStatus.Available)
{
    CatalogModelInstance instance = result.GetInstance();

    // Get the model path
    string modelPath = instance.ModelPaths[0];
    
    Console.WriteLine($"Model path: {modelPath}");
    
    // Inference your model using your own code
}
else
{
    Console.WriteLine($"Failed to get model: {result.ExtendedError}");
    Console.WriteLine($"Details: {result.DiagnosticText}");
}

Exemplo completo

Aqui está um exemplo completo que junta tudo:

using Microsoft.Windows.AI.MachineLearning;
using System;
using System.Threading.Tasks;

try
{
    // Create catalog with source
    var source = await ModelCatalogSource.CreateFromUriAsync(
        new Uri("https://contoso.com/models"));
    var catalog = new ModelCatalog(new ModelCatalogSource[] { source });
    
    // Find a model
    Console.WriteLine("Searching for model...");
    CatalogModelInfo model = await catalog.FindModelAsync("phi-3.5-reasoning");
    
    if (model != null)
    {
        Console.WriteLine($"Found model: {model.Name}");
        Console.WriteLine($"Version: {model.Version}");
        Console.WriteLine($"Publisher: {model.Publisher}");
        Console.WriteLine($"Size: {model.ModelSizeInBytes / (1024 * 1024)} MB");
        Console.WriteLine($"Supported execution providers: {string.Join(", ", model.ExecutionProviders)}");
        
        // Get an instance of the model (downloads if necessary)
        var progress = new Progress<double>(percent => 
            Console.WriteLine($"Download progress: {percent:P}"));
        
        CatalogModelInstanceResult result = await model.GetInstanceAsync().AsTask(progress);
        
        if (result.Status == CatalogModelInstanceStatus.Available)
        {
            CatalogModelInstance instance = result.GetInstance();

            // Get the model path
            string modelPath = instance.ModelPaths[0];
            
            Console.WriteLine($"Model path: {modelPath}");
            
            // Inference your model using your own code
        }
        else
        {
            Console.WriteLine($"Failed to get model: {result.ExtendedError}");
            Console.WriteLine($"Details: {result.DiagnosticText}");
        }
    }
    else
    {
        Console.WriteLine("Model not found");
    }
}
catch (Exception ex)
{
    Console.WriteLine($"Error: {ex.Message}");
}

Filtragem por provedores de execução

Personalize quais provedores de execução considerar:

public async Task FilterByExecutionProvidersAsync(ModelCatalog catalog)
{
    // Only look for CPU-compatible models
    catalog.ExecutionProviders.Clear();
    catalog.ExecutionProviders.Add("cpuexecutionprovider");
    
    var cpuModels = await catalog.FindAllModelAsync();
    Console.WriteLine($"Found {cpuModels.Count} CPU-compatible models");
    
    // Look for DirectML-compatible models
    catalog.ExecutionProviders.Clear();
    catalog.ExecutionProviders.Add("dmlexecutionprovider");
    
    var dmlModels = await catalog.FindAllModelAsync();
    Console.WriteLine($"Found {dmlModels.Count} DirectML-compatible models");
}

Verificando o status do modelo

Verifique se um modelo já está disponível localmente:

public void CheckModelStatus(ModelCatalog catalog)
{
    var availableModels = catalog.GetAvailableModels();
    
    foreach (var model in availableModels)
    {
        var status = model.GetStatus();
        Console.WriteLine($"Model {model.Name}: {status}");
        
        switch (status)
        {
            case CatalogModelStatus.Ready:
                Console.WriteLine("  ✓ Available locally");
                break;
            case CatalogModelStatus.NotReady:
                Console.WriteLine("  ⚠ Needs to be downloaded");
                break;
        }
    }
}

Usando arquivos de catálogo local

Crie uma fonte de catálogo a partir de um arquivo local:

public async Task<ModelCatalog> CreateLocalCatalogAsync()
{
    // Load catalog from a local JSON file
    var localFile = Path.Combine(Package.Current.EffectivePath, "my-models.json");
    var source = await ModelCatalogSource.CreateFromUriAsync(new Uri(localFile));
    
    var catalog = new ModelCatalog(new ModelCatalogSource[] { source });
    return catalog;
}

Adicionando cabeçalhos personalizados para downloads

Forneça autenticação ou cabeçalhos personalizados para downloads de modelos:

public async Task DownloadWithCustomHeadersAsync(CatalogModelInfo model)
{
    var headers = new Dictionary<string, string>
    {
        ["Authorization"] = "Bearer your-token-here",
        ["User-Agent"] = "MyApp/1.0"
    };
    
    var result = await model.GetInstanceAsync(headers);
    // Handle result...
}

Tratamento de erros

Sempre inclua o tratamento adequado de erros ao trabalhar com o Catálogo de Modelos:

public async Task<bool> SafeModelUsageAsync(string modelName)
{
    try
    {
        var source = await ModelCatalogSource.CreateFromUriAsync(
            new Uri("https://contoso.com/models"));
        var catalog = new ModelCatalog(new ModelCatalogSource[] { source });
        
        var model = await catalog.FindModelAsync(modelName);
        if (model == null)
        {
            Console.WriteLine($"Model '{modelName}' not found");
            return false;
        }
        
        var result = await model.GetInstanceAsync();
        if (result.Status != CatalogModelInstanceStatus.Available)
        {
            Console.WriteLine($"Failed to get model: {result.ExtendedError}");
            if (!string.IsNullOrEmpty(result.DiagnosticText))
            {
                Console.WriteLine($"Details: {result.DiagnosticText}");
            }
            return false;
        }
        
        using var instance = result.GetInstance();
        // Use the model...
        return true;
    }
    catch (UnauthorizedAccessException)
    {
        Console.WriteLine("Access denied - check permissions");
        return false;
    }
    catch (System.Net.Http.HttpRequestException ex)
    {
        Console.WriteLine($"Network error: {ex.Message}");
        return false;
    }
    catch (Exception ex)
    {
        Console.WriteLine($"Unexpected error: {ex.Message}");
        return false;
    }
}

Melhores práticas

  1. Reutilizar instâncias de catálogo: reutilize ModelCatalog instâncias em seu aplicativo
  2. Gerir o progresso do download: providencie feedback ao utilizador durante os downloads do modelo
  3. Descartar instâncias de modelo: use as instruções using para descartar corretamente instâncias de modelo
  4. Verifique a compatibilidade: verifique se os provedores de execução do modelo correspondem aos seus requisitos
  5. Lidar com falhas normalmente: sempre verifique o status dos resultados antes de usar modelos
  6. Usar nomes de modelo: use FindModelAsync com nomes de modelo para seleção automática da melhor variante de modelo com base nos recursos do dispositivo

Próximos passos