Lenguaje

Generación de texto con su propio modelo de lenguaje mediante Windows ML

Importante

El entorno de ejecución de Windows ML y las API de generación de texto son actualmente experimentales y no se admiten para su uso en entornos de producción. Las aplicaciones que prueban estas API no deben publicarse en Microsoft Store.

Importante

Las API de tiempo de ejecución y generación de texto de Windows ML están disponibles actualmente en C++ y Python; Actualmente no se admite C#. Háganos saber si está interesado en usar estas API desde C# publicando una incidencia en el repositorio de GitHub de Windows ML.

La API de generación de texto de Windows ML simplifica ejecutar la generación de texto en su propio modelo de lenguaje. Esta API se encarga de la tokenización, la decodificación autorregresiva, la salida en streaming y la cancelación por ti, además de la API de Windows ML Runtime —de forma similar a como ONNX Runtime GenAI simplifica ese bucle sobre ONNX Runtime. Windows no incluye un modelo para esta API; elige, empaqueta y distribuye el modelo (un archivo ONNX o GGUF, además de un tokenizador) con la aplicación.

Tip

Si no necesita un modelo específico y solo quiere generar texto en el dispositivo con un modelo que Microsoft administra, use uno de los LLM locales listos para usar en su lugar.

Todavía se crean los objetos Runtime subyacentes (el modelo, el destino de ejecución y la canalización) y se pasan a la sesión. La API no oculta la ubicación del hardware; solo quita la necesidad de escribir su propio bucle de token.

Modelos compatibles

La Text Generation API acepta:

  • Los modelos ONNX (.onnx) o en formato ORT (.ort) se ejecutan a través de ONNX Runtime. El modelo debe exponer una entrada de token-ID, una salida de logits y un par de tensores de estado de capacidad fija que contiene la caché de clave-valor y la posición de secuencia. Se proporciona un origen de tokenizador independiente (por ejemplo, un tokenizer.json).
  • Los modelos GGUF (.gguf) se ejecutan a través del backend llama.cpp. El tokenizador está incrustado en el modelo, por lo que no se necesita ningún código fuente del tokenizador independiente.

Los ejemplos validan este contrato frente a la familia de modelos Qwen2.5-0.5B-Instruct, exportada con un gráfico específico de la tarea que empaqueta la caché de clave-valor y la posición de secuencia en un único par de estados. Otros modelos de lenguaje de solo descodificador que exponen la misma entrada de token, la salida de logits y el contrato de estado también deben funcionar.

Generar texto

Una sesión de generación de texto encapsula un tokenizador y una canalización con estado (el modelo que posee la memoria caché de clave y valor). Cargue el modelo y el tokenizador, describa la entrada de tokens del modelo, la salida de logits y el contrato de estado y compile la sesión:

// Create the runtime and an execution target (CPU here; GPU/NPU also available).
ComPtr<IWinMLRuntime> runtime;
THROW_IF_FAILED(WinMLCreateRuntime(IID_PPV_ARGS(runtime.GetAddressOf())));
ComPtr<IWinMLExecutionTarget> target;
THROW_IF_FAILED(runtime->CreateCpuExecutionTarget(target.GetAddressOf()));

// Load your ONNX model and its tokenizer.
ComPtr<IWinMLModel> model;
THROW_IF_FAILED(runtime->LoadModelFromFile(
    L"C:\\models\\qwen2.5-0.5b-instruct\\task_model.onnx",
    nullptr,
    model.GetAddressOf()));
ComPtr<IWinMLTokenizer> tokenizer;
THROW_IF_FAILED(WinMLCreateTokenizerFromFile(
    L"C:\\models\\qwen2.5-0.5b-instruct\\tokenizer.json",
    tokenizer.GetAddressOf()));

// Describe the model's token input, logits output, and KV-cache state pair.
winml::tasks::text_generation::onnx::StateTensorPair stateTensorPairs[] = {{1, 1}};
winml::tasks::text_generation::Options options;
options.values = winml::tasks::MakeTextGenerationOptions(/* maxNewTokens */ 64);

winml::tasks::text_generation::onnx::BuildTextGenerationArguments arguments;
arguments.runtime = runtime.Get();
arguments.model = model.Get();
arguments.target = target.Get();
arguments.tokenizer = tokenizer.Get();
arguments.tokenInputName = L"input_ids";
arguments.outputName = L"logits";
arguments.debugName = L"my-text-generation";
arguments.stateTensorPairs = stateTensorPairs;
arguments.sequenceCapacityHint = 128;
arguments.outputKind = WINML_TEXT_GENERATION_OUTPUT_KIND_LOGITS;
arguments.eosPolicy = WINML_TEXT_GENERATION_EOS_POLICY_TOKENIZER_DEFAULT;
arguments.options = &options;

winml::tasks::text_generation::TextGeneration textGeneration;
THROW_IF_FAILED(winml::tasks::text_generation::onnx::BuildTextGeneration(
    arguments, textGeneration));

Llame a GenerateText con una indicación para iniciar una operación de streaming y, a continuación, extraiga fragmentos de la secuencia devuelta hasta que informe de la finalización:

ComPtr<IWinMLCancellationSource> cancellation;
THROW_IF_FAILED(textGeneration.tasks->CreateCancellationSource(
    cancellation.GetAddressOf()));

ComPtr<IWinMLTextGenerationPullStream> stream;
THROW_IF_FAILED(textGeneration.session->GenerateText(
    L"The sky is often",
    textGeneration.options.Get(),
    cancellation.Get(),
    stream.GetAddressOf()));

// Pull generated text one fragment at a time until the stream completes.
WINML_TEXT_GENERATION_READ_STATUS status{};
UINT32 tokenId = 0;
LPCWSTR fragment = nullptr;
while (SUCCEEDED(stream->ReadNext(&status, &tokenId, &fragment)) &&
    status == WINML_TEXT_GENERATION_READ_STATUS_UPDATE)
{
    std::wprintf(L"%ls", fragment);
}

// The terminal result is the authoritative text, token counts, and finish reason.
ComPtr<IWinMLTextGenerationResult> result;
THROW_IF_FAILED(stream->GetResult(result.GetAddressOf()));

El resultado final muestra:

  • El texto completo generado y los ID de token
  • Petición y recuentos de tokens generados
  • Un motivo de finalización: un token de fin de secuencia, un token de detención, el límite de tokens solicitado, la capacidad de secuencia, la cancelación o un error.

C++ y Python

La API nativa se expone a través de WinMLTasks.h y las utilidades auxiliares de C++ tipadas en winml/tasks/text_generation/TextGeneration.hpp. Las aplicaciones de Python usan la windowsml.tasks proyección junto con windowsml.runtime.

Los ejemplos de Windows ML incluyen un ejemplo de generación de texto en C++ y Python. El ejemplo muestra la configuración completa de Runtime junto a la configuración de generación de texto, para que pueda ver dónde comienza la abstracción y cómo personalizar el flujo de trabajo subyacente.

Consulte también