Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Windows ML carrega um modelo de um caminho de arquivo local, portanto, ele não requer nenhum método de distribuição específico. Seu aplicativo envia o modelo como parte de seu pacote ou adquire o modelo separadamente – baixado em seu instalador ou pelo aplicativo na primeira vez em que ele é necessário. Este artigo compara as duas abordagens e explica a implementação de cada uma.
Escolher uma abordagem
| Inclua o modelo em seu pacote | Baixar o modelo separadamente | |
|---|---|---|
| Mais adequado para | Modelos pequenos ou modelos que devem funcionar offline imediatamente após a instalação | Modelos grandes ou modelos que você deseja distribuir separadamente do seu aplicativo |
| Experiência de primeira execução | O modelo está disponível imediatamente | É necessário fazer o download antes do primeiro uso, a menos que você o baixe no instalador ou faça o pré-carregamento em segundo plano. |
| Impacto no tamanho do aplicativo | Aumenta o tamanho instalado para cada usuário | Usa armazenamento apenas em dispositivos em que o usuário opta por usar o recurso que requer o modelo |
| Suporte offline | Sempre disponível offline | Disponível somente offline após o primeiro download bem-sucedido |
Se o seu modelo tiver alguns megabytes e raramente mudar, incluí-lo no aplicativo é mais simples e permite que os usuários tenham um aplicativo funcional imediatamente. Se o modelo for grande, atualizado com frequência ou opcional para alguns usuários, baixe-o separadamente.
Dica
Se você estiver publicando uma biblioteca ou SDK da qual vários aplicativos independentes dependem e esses aplicativos devem compartilhar uma única cópia em disco do modelo, use as APIs do Catálogo de Modelos de Windows ML em vez de escrever sua própria lógica de download e compartilhamento. A maioria dos desenvolvedores de aplicativos que só precisam de um modelo para seu próprio aplicativo deve usar uma das duas abordagens descritas aqui.
Incluir o modelo em seu pacote
Adicione o arquivo de modelo ONNX, juntamente com todos os arquivos dos quais ele depende, como tokenizador ou arquivos de rótulo, como conteúdo em seu projeto de aplicativo. Windows ML carrega o modelo diretamente do local de instalação do aplicativo, sem a necessidade de acesso à rede.
Etapas de implementação
- Adicione o arquivo de modelo ao seu projeto e defina sua Ação de Build como Conteúdo (ou o equivalente para o tipo de projeto) para que ele seja copiado para a saída e incluído no pacote do aplicativo.
- Resolva o caminho do modelo em relação ao diretório de instalação do aplicativo em tempo de execução. Não codifique um caminho absoluto, pois o local de instalação varia de acordo com o usuário e o tipo de implantação.
- Carregue o modelo desse caminho usando suas APIs de inferência.
using System;
using System.IO;
// Resolve the model path relative to the app's install location.
string modelPath = Path.Combine(AppContext.BaseDirectory, "Assets", "Models", "model.onnx");
if (!File.Exists(modelPath))
{
throw new FileNotFoundException("The bundled model is missing from the app package.", modelPath);
}
// Load modelPath with your inference APIs.
Considerations
- Tamanho do pacote: cada instalação carrega o modelo completo, o que aumenta o tamanho do download e o uso do disco para todos os usuários, incluindo aqueles que talvez nunca usem o recurso.
- Não é necessário tratar falhas de download: Como o modelo já está em disco quando o aplicativo é iniciado, você não precisa de tentativa novamente, verificação de integridade nem lógica de contingência offline.
- Pacotes opcionais: se você quiser manter o modelo fora da instalação base, mas ainda evitar escrever a lógica de download, poderá enviar em um pacote MSIX opcional que os usuários ou seu aplicativo instalam sob demanda. Isso mantém o pacote base pequeno, evitando um caminho de download personalizado, ao custo de depender da distribuição do pacote em vez de um download simples.
Baixar o modelo separadamente
Em vez de agrupar o modelo, baixe-o para o dispositivo separadamente do pacote do aplicativo e armazene-o no armazenamento local do aplicativo. Isso mantém seu pacote pequeno. O download não precisa acontecer do aplicativo em execução. Você pode baixar o modelo do aplicativo na primeira execução ou fazer com que o instalador o baixe como parte da instalação. De qualquer forma, você é responsável por baixar, verificar, armazenar e limpar o arquivo.
Etapas de implementação
- Hospede o arquivo de modelo (e quaisquer arquivos dependentes) em uma URL HTTPS, juntamente com seu hash SHA-256 para que você possa verificar o download.
- Decida quando o download acontece: no instalador ou no aplicativo na primeira vez em que precisar do modelo. Qualquer abordagem usa a mesma lógica de download e verificação.
- Verifique se o modelo já existe no armazenamento local antes de baixá-lo novamente.
- Salve o arquivo em uma pasta gravável, app-local, e verifique seu hash antes do uso.
- Relatar o progresso do download para o usuário e lidar com falhas de rede para que o download possa tentar novamente ou recuar normalmente.
using System;
using System.IO;
using System.Net.Http;
using System.Security.Cryptography;
using System.Threading;
using System.Threading.Tasks;
public static async Task<string> GetModelPathAsync(
Uri modelUri,
string expectedSha256,
IProgress<double>? progress = null,
CancellationToken cancellationToken = default)
{
string modelsFolder = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
"Contoso", "Models");
Directory.CreateDirectory(modelsFolder);
string modelPath = Path.Combine(modelsFolder, Path.GetFileName(modelUri.LocalPath));
// Reuse the file if it's already downloaded and passes integrity verification.
if (File.Exists(modelPath) && await VerifyHashAsync(modelPath, expectedSha256, cancellationToken))
{
return modelPath;
}
string tempPath = modelPath + ".download";
using (var httpClient = new HttpClient())
using (var response = await httpClient.GetAsync(
modelUri, HttpCompletionOption.ResponseHeadersRead, cancellationToken))
{
response.EnsureSuccessStatusCode();
long? totalBytes = response.Content.Headers.ContentLength;
long bytesRead = 0;
using var contentStream = await response.Content.ReadAsStreamAsync(cancellationToken);
using var fileStream = File.Create(tempPath);
var buffer = new byte[81920];
int read;
while ((read = await contentStream.ReadAsync(buffer, cancellationToken)) > 0)
{
await fileStream.WriteAsync(buffer.AsMemory(0, read), cancellationToken);
bytesRead += read;
if (totalBytes.HasValue)
{
progress?.Report((double)bytesRead / totalBytes.Value);
}
}
}
if (!await VerifyHashAsync(tempPath, expectedSha256, cancellationToken))
{
File.Delete(tempPath);
throw new InvalidOperationException("Downloaded model failed integrity verification.");
}
File.Move(tempPath, modelPath, overwrite: true);
return modelPath;
}
private static async Task<bool> VerifyHashAsync(
string filePath, string expectedSha256, CancellationToken cancellationToken)
{
using var sha256 = SHA256.Create();
using var fileStream = File.OpenRead(filePath);
byte[] hash = await sha256.ComputeHashAsync(fileStream, cancellationToken);
string actualSha256 = Convert.ToHexString(hash);
return string.Equals(actualSha256, expectedSha256, StringComparison.OrdinalIgnoreCase);
}
Considerations
- Verificação de integridade: sempre verifique um hash SHA-256 (ou semelhante) após o download, antes de usar o modelo ou tratá-lo como armazenado em cache. Caso contrário, um download parcial ou corrompido poderá falhar silenciosamente em tempo de inferência.
- Escritas atômicas: baixe para um arquivo temporário e renomeie-o para o local de destino somente após a verificação ser bem-sucedida, para que um download com falha ou interrompido nunca deixe um arquivo corrompido no caminho previsto.
- Nova tentativa e tratamento de modo offline: Trate erros de rede de forma explícita. Decida se seu aplicativo pode ser executado em um modo de funcionalidade reduzida, solicite ao usuário que tente novamente ou bloqueie o recurso até que o download seja bem-sucedido.
- Local de armazenamento: Use uma pasta gravável do próprio aplicativo, que permaneça após atualizações do aplicativo, mas seja removida se o aplicativo for desinstalado.
- Limpeza: se você substituir o modelo por uma nova versão, exclua o arquivo antigo para não acumular arquivos não utilizados no dispositivo do usuário.
- Baixe em seu instalador vs. primeira execução: se o instalador der suporte à execução de uma ação ou script personalizado, ele poderá baixar o modelo como parte da instalação para que ele esteja pronto antes que o usuário inicie o aplicativo pela primeira vez. Isso implica um tempo de instalação maior em troca de uma experiência melhor na primeira execução, e usa a mesma lógica de download e verificação usada ao baixar pelo aplicativo em execução.
Compartilhar um modelo baixado entre aplicativos
Se você estiver criando uma biblioteca ou SDK da qual vários aplicativos independentes dependem e quiser que esses aplicativos compartilhem uma cópia em disco do modelo em vez de cada um baixando seus próprios aplicativos, use as APIs do Catálogo de Modelos do Windows ML em vez de escrever sua própria lógica de download. Para obter mais informações, consulte Introdução às APIs do Catálogo de Modelos.