Idioma

Gera texto com o teu próprio modelo de linguagem usando Windows ML

Importante

As APIs do Windows ML Runtime e de Geração de Texto são atualmente experimentais e não são suportadas para utilização em ambientes de produção. Os aplicativos que experimentam essas APIs não devem ser publicados na Microsoft Store.

Importante

As APIs de Runtime e Geração de Texto do Windows ML estão atualmente disponíveis em C++ e Python; O C# não é atualmente suportado. Diz-nos se estiveres interessado em usar estas APIs do C# abrindo um issue no repositório GitHub do Windows ML!

A API de Geração de Texto do Windows ML simplifica a execução da geração de texto no seu próprio modelo de linguagem. Trata da tokenização, decodificação autoregressiva, streaming de saída e cancelamento por si, além da API do Windows ML Runtime — semelhante a como o ONNX Runtime GenAI simplifica esse ciclo em cima do ONNX Runtime. O Windows não fornece um modelo para esta API; escolhe-se, empacota-se e distribui-se o modelo — um ficheiro ONNX ou GGUF, mais um tokenizador — com a sua aplicação.

Tip

Se não precisas de um modelo específico e só queres geração de texto no dispositivo com um modelo que a Microsoft gere, usa um dos LLMs locais prontos a usar em vez disso.

Continua a criar os objetos de Runtime subjacentes — o modelo, o alvo de execução e o pipeline — e passá-los para a sessão. A API não esconde a colocação do hardware; apenas elimina a necessidade de escrever o seu próprio token loop.

Modelos suportados

A API de Geração de Texto aceita:

  • Modelos em formato ONNX (.onnx) ou ORT (.ort), executados através do ONNX Runtime. O modelo deve expor uma entrada de token-ID, uma saída logits e um par de tensores de estado de capacidade fixa que detém a cache chave/valor e a posição da sequência. O utilizador fornece uma fonte de tokenizador separada (por exemplo, um tokenizer.json).
  • Modelos GGUF (.gguf), executados através do backend llama.cpp. O tokenizador está embutido no modelo, pelo que não é necessária uma origem separada para o tokenizador.

As amostras validam este contrato contra a família de modelos Qwen2.5-0.5B-Instruct , exportada com um grafo específico para a Tarefa que agrupa a cache chave/valor e a posição da sequência num único par de estados. Outros modelos de linguagem só de descodificação que expõem a mesma entrada de token, logits output e contrato de estado também devem funcionar.

Gerar texto

Uma sessão de geração de texto envolve um tokenizador e um pipeline com estado (o modelo que detém a cache chave/valor). Carregue o modelo e o tokenizador, descreva a entrada de tokens do modelo, a saída de logits e o contrato de estado, e construa a sessão:

// 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));

Chame GenerateText com um prompt para iniciar uma operação de streaming, depois extraia fragmentos do stream devolvido até reportar a conclusão:

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()));

O resultado concluído apresenta:

  • O texto completo gerado e os IDs dos tokens
  • Contagens de prompts e tokens gerados
  • Uma razão de finalização — um token de fim de sequência, um token de stop, o limite do token solicitado, capacidade da sequência, cancelamento ou um erro

C++ e Python

A interface API nativa é exposta através de WinMLTasks.h e os auxiliares C++ tipados em winml/tasks/text_generation/TextGeneration.hpp. As aplicações Python utilizam a windowsml.tasks projeção juntamente com windowsml.runtime.

Os exemplos do Windows ML incluem um exemplo de geração de texto em C++ e outro em Python. O exemplo mostra a configuração completa do Runtime ao lado da configuração de geração de texto, para que possas ver onde começa a abstração e como personalizar o fluxo de trabalho subjacente.

Ver também