Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
O Windows ML carrega um modelo a partir de um caminho de ficheiro local, por isso não requer nenhum método de distribuição específico. A sua aplicação ou envia o modelo como parte do seu pacote, ou adquire o modelo separadamente — descarregado no seu instalador, ou pela sua aplicação na primeira vez que for necessário. Este artigo compara as duas abordagens e explica a implementação de cada uma.
Escolha uma abordagem
| Inclua o modelo na sua embalagem | Descarregue o modelo separadamente | |
|---|---|---|
| Ideal para | Modelos pequenos, ou modelos que têm de funcionar offline imediatamente após a instalação | Modelos grandes, ou modelos que queira distribuir separadamente da sua aplicação |
| Experiência de estreia | O modelo está disponível imediatamente | Necessita de uma transferência antes da primeira utilização, a menos que efetue a transferência no instalador ou o pré-carregamento em segundo plano |
| Impacto no tamanho da aplicação | Aumenta o tamanho instalado para cada utilizador | Só utiliza armazenamento em dispositivos onde o utilizador opta pela funcionalidade que necessita do modelo |
| Suporte offline | Sempre disponível offline | Disponível apenas offline após o primeiro download bem-sucedido |
Se o seu modelo tem alguns megabytes e raramente muda, agrupá-lo é mais simples e dá aos utilizadores uma aplicação funcional imediatamente. Se o seu modelo for grande, atualizado frequentemente ou opcional para alguns utilizadores, descarregue-o separadamente.
Sugestão
Se estiveres a publicar uma biblioteca ou SDK da qual dependem várias aplicações independentes, e essas aplicações devem partilhar uma única cópia em disco do modelo, usa as APIs do Catálogo de Modelos ML do Windows em vez de escreveres a tua própria lógica de download e partilha. A maioria dos programadores de aplicações que só precisa de um modelo para a sua própria aplicação deve usar uma das duas abordagens aqui descritas.
Inclua o modelo na sua embalagem
Adicione o ficheiro modelo ONNX, juntamente com quaisquer ficheiros de que dependa, como tokenizadores ou ficheiros de etiquetas, como conteúdo no seu projeto de aplicação. O Windows ML carrega então o modelo diretamente a partir da localização de instalação da sua aplicação, sem necessidade de acesso à rede.
Passos de implementação
- Adiciona o ficheiro modelo ao teu projeto e define a Ação de Construção como Conteúdo (ou equivalente para o tipo de projeto) para que seja copiado para a saída e incluído no pacote da aplicação.
- Determine o caminho do modelo relativamente à localização de instalação da sua aplicação em tempo de execução. Não codifique um caminho absoluto, porque o local de instalação varia consoante o utilizador e o tipo de implementação.
- Carrega o modelo a partir desse caminho usando as tuas 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.
Considerações
- Tamanho do pacote: Cada instalação transporta o modelo completo, o que aumenta o tamanho do download e o uso do disco para todos os utilizadores, incluindo aqueles que talvez nunca usem a funcionalidade.
- Não é necessário tratamento de falhas no descarregamento: Como o modelo já está em disco quando a aplicação é iniciada, não é necessária lógica de repetição, de verificação de integridade ou de recurso em modo offline.
- Pacotes opcionais: Se quiseres manter o modelo fora da instalação base mas ainda assim evitar escrever lógica de download, podes enviá-lo num pacote MSIX opcional que os utilizadores ou a tua aplicação instalem a pedido. Isto mantém o pacote base pequeno, evitando um caminho de download personalizado, à custa de depender da implementação do pacote em vez de um download simples.
Descarregue o modelo separadamente
Em vez de incluir o modelo, descarrega-o para o dispositivo separadamente do pacote da aplicação e armazena-o no armazenamento local da aplicação. Isto mantém o tamanho do seu pacote reduzido. A transferência não tem de ser feita a partir da sua aplicação em execução — pode descarregar o modelo a partir da sua aplicação na primeira execução, ou fazer com que o instalador o descarregue como parte da instalação. De qualquer forma, és responsável por descarregar, verificar, armazenar e limpar o ficheiro.
Passos de implementação
- Aloja o ficheiro do modelo (e quaisquer ficheiros dependentes) numa URL HTTPS, juntamente com o seu hash SHA-256 para poderes verificar o download.
- Decide quando o download acontece: no teu instalador ou na tua app na primeira vez que precisar do modelo. Ambas as abordagens usam a mesma lógica de download e verificação.
- Verifica se o modelo já existe no armazenamento local antes de o descarregar novamente.
- Guarde o ficheiro numa pasta scriptável, app-local, e verifique o seu hash antes de o usar.
- Reporte o progresso do download ao utilizador e trate de falhas de rede para que o download possa tentar novamente ou recuar de forma natural.
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);
}
Considerações
- Verificação de integridade: Verifique sempre um hash SHA-256 (ou similar) após o download, antes de usar o modelo ou tratá-lo como armazenado em cache. Caso contrário, um download parcial ou corrompido pode falhar silenciosamente no momento da inferência.
- Escritas atómicas: Descarrega para um ficheiro temporário e só o renomeia para o destino final após a verificação ser concluída com êxito, para que uma transferência falhada ou interrompida nunca deixe um ficheiro corrompido no caminho esperado.
- Nova tentativa e tratamento offline: Tratar os erros de rede de forma explícita. Decida se a sua aplicação pode correr em modo de funcionalidade reduzida, pede ao utilizador para tentar novamente ou bloqueie a funcionalidade até que o download seja bem-sucedido.
- Localização de armazenamento: Use uma pasta local da app, gravável, que sobreviva a todas as atualizações, mas que seja limpa se a aplicação for desinstalada.
- Limpeza: Se substituir o modelo por uma nova versão, apague o ficheiro antigo para não acumular ficheiros não usados no dispositivo do utilizador.
- Descarregue no seu instalador vs. primeira execução: Se o seu instalador suportar a execução de uma ação ou script personalizado, pode descarregar o modelo como parte da instalação para que esteja pronto antes do utilizador lançar a aplicação pela primeira vez. Isto troca um tempo de instalação mais longo por uma melhor experiência na primeira execução, e usa a mesma lógica de download e verificação que o download da aplicação em execução.
Partilhe um modelo descarregado entre aplicações
Se estás a construir uma biblioteca ou SDK da qual dependem várias aplicações independentes, e queres que essas aplicações partilhem uma cópia no disco do modelo em vez de cada uma descarregar a sua própria, usa as APIs do Catálogo de Modelos ML do Windows em vez de escreveres a tua própria lógica de download. Para mais informações, consulte Começar com as APIs do Catálogo de Modelos.