Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Windows ML carga un modelo desde una ruta de acceso de archivo local, por lo que no requiere ningún método de distribución determinado. Tu aplicación o bien incluye el modelo como parte de su paquete, o bien adquiere el modelo por separado: descargándolo mediante su instalador o a través de la propia aplicación la primera vez que lo necesite. En este artículo se comparan los dos enfoques y se explica cómo implementar cada uno.
Elección de un enfoque
| Incluir el modelo en el paquete | Descargar el modelo por separado | |
|---|---|---|
| Ideal para | Modelos pequeños o modelos que deben funcionar sin conexión inmediatamente después de la instalación | Modelos grandes o modelos que desea distribuir por separado de la aplicación |
| Experiencia de primera ejecución | El modelo está disponible inmediatamente | Requiere una descarga antes del primer uso, a menos que la descargues con tu instalador o la precargues en segundo plano. |
| Impacto en el tamaño de la aplicación | Aumenta el tamaño instalado para cada usuario | Solo usa almacenamiento en dispositivos en los que un usuario opta por la característica que necesita el modelo |
| Soporte técnico sin conexión | Siempre disponible sin conexión | Solo disponible sin conexión después de completar correctamente la primera descarga |
Si el modelo es de unos pocos megabytes y rara vez cambia, la agrupación es más sencilla y proporciona a los usuarios una aplicación en funcionamiento inmediatamente. Si el modelo es grande, actualizado con frecuencia o opcional para algunos usuarios, descárguelo por separado.
Tip
Si va a publicar una biblioteca o un SDK en los que dependen varias aplicaciones independientes, y esas aplicaciones deben compartir una sola copia en disco del modelo, use las API de catálogo de modelos de ML de Windows en lugar de escribir su propia lógica de descarga y uso compartido. La mayoría de los desarrolladores de aplicaciones que solo necesitan un modelo para su propia aplicación deben usar uno de los dos enfoques que se describen aquí.
Incluye el modelo en tu paquete
Agregue el archivo de modelo ONNX, junto con los archivos de los que depende, como tokenizador o archivos de etiqueta, como contenido en el proyecto de aplicación. Windows ML carga el modelo directamente desde la ubicación de instalación de la aplicación, sin que se requiera acceso a la red.
Pasos de implementación
- Agregue el archivo de modelo al proyecto y establezca su acción de compilación en Contenido (o el equivalente para el tipo de proyecto) para que se copie en la salida e incluya en el paquete de la aplicación.
- Resuelva la ruta del modelo con respecto a la ubicación de instalación de su aplicación en tiempo de ejecución. No codifique de forma rígida una ruta de acceso absoluta, ya que la ubicación de instalación varía según el tipo de usuario e implementación.
- Cargue el modelo desde esa ruta con las API de inferencia.
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
- Tamaño del paquete: cada instalación incluye el modelo completo, lo que aumenta el tamaño de descarga y el uso del disco para todos los usuarios, incluidos aquellos que nunca podrían usar la característica.
- No se necesita gestión de fallos de descarga: dado que el modelo ya está en disco cuando se inicia la aplicación, no hace falta implementar reintentos, comprobaciones de integridad ni lógica de respaldo sin conexión.
- Paquetes opcionales: si quieres mantener el modelo fuera de la instalación base, pero sigues evitando escribir lógica de descarga, puedes enviarlo en un paquete MSIX opcional que los usuarios o la aplicación instalan a petición. Esto mantiene reducido el paquete base y evita una ruta de descarga personalizada, a costa de depender del despliegue de paquetes en lugar de una descarga directa.
Descargar el modelo por separado
En lugar de agrupar el modelo, lo descargas en el dispositivo por separado del paquete de la aplicación y lo almacenas en el almacenamiento local de la aplicación. Esto mantiene el paquete pequeño. La descarga no tiene que ocurrir desde la aplicación en ejecución; puede descargar el modelo desde la aplicación en la primera ejecución o hacer que el instalador lo descargue como parte de la configuración. En cualquier caso, usted es responsable de descargar, comprobar, almacenar y limpiar el archivo.
Pasos de implementación
- Hospede el archivo de modelo (y cualquier archivo dependiente) en una dirección URL HTTPS, junto con su hash SHA-256 para que pueda comprobar la descarga.
- Decida cuándo se produce la descarga: en el instalador o desde la aplicación la primera vez que necesita el modelo. Cualquier enfoque usa la misma lógica de descarga y comprobación.
- Compruebe si el modelo ya existe en el almacenamiento local antes de volver a descargarlo.
- Guarde el archivo en una carpeta grabable, app-local y compruebe su hash antes de usarlo.
- Informe del progreso de la descarga al usuario y controle los errores de red para que la descarga pueda reintentar o revertir correctamente.
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
- Comprobación de integridad: compruebe siempre un hash SHA-256 (o similar) después de descargarlo, antes de usar el modelo o tratarlo como almacenado en caché. De lo contrario, una descarga parcial o dañada puede producir un error en modo silencioso en el momento de la inferencia.
- Escrituras atómicas: descargue primero en un archivo temporal y renómbrelo a su ubicación definitiva solo después de que la verificación se complete correctamente, para que una descarga fallida o interrumpida nunca deje un archivo dañado en la ruta esperada.
- Reintento y gestión sin conexión: Gestiona explícitamente los errores de red. Decida si la aplicación se puede ejecutar en un modo de funcionalidad reducida, pida al usuario que vuelva a intentarlo o bloquee la característica hasta que la descarga se realice correctamente.
- Ubicación de almacenamiento: use una carpeta grabable local de la aplicación que sobrevive entre las actualizaciones de la aplicación, pero que se limpie si se desinstala la aplicación.
- Limpieza: si reemplaza el modelo por una nueva versión, elimine el archivo antiguo para que no se acumulan archivos sin usar en el dispositivo del usuario.
- Descargar en el instalador frente a la primera ejecución: si el instalador admite la ejecución de una acción personalizada o un script, puede descargar el modelo como parte de la instalación para que esté listo antes de que el usuario inicie la aplicación por primera vez. Esto supone un tiempo de instalación más largo a cambio de una mejor experiencia en la primera ejecución, y utiliza la misma lógica de descarga y verificación que al descargar desde la aplicación en ejecución.
Uso compartido de un modelo descargado entre aplicaciones
Si va a crear una biblioteca o un SDK en los que dependen varias aplicaciones independientes y desea que esas aplicaciones compartan una copia en disco del modelo en lugar de cada descarga propia, use las API del catálogo de modelos de ML de Windows en lugar de escribir su propia lógica de descarga. Para obtener más información, consulte Introducción a las API del catálogo de modelos.