Språk

Generera text med din egen språkmodell med hjälp av Windows ML

Important

API:erna Windows ML Runtime och Text Generation är för närvarande experimentella och stöds inte för användning i produktionsmiljöer. Appar som testar dessa API:er bör inte publiceras till Microsoft Store.

Important

API:erna för Windows ML Runtime och Text Generation är för närvarande tillgängliga i C++ och Python; C# stöds för närvarande inte. Meddela oss om du är intresserad av att använda dessa API:er från C# genom att rapportera ett ärende i Windows ML:s GitHub-repo!

Windows ML API:et för textgenerering förenklar att köra textgenerering med din egen språkmodell. Den hanterar tokenisering, autoregressiv avkodning, strömmande utdata och annullering åt dig, ovanpå Windows ML Runtime API – ungefär som ONNX Runtime GenAI förenklar den loopen ovanpå ONNX Runtime. Windows levereras inte med någon modell för det här API:et. Du väljer, paketar och distribuerar modellen – en ONNX- eller GGUF-fil, plus en tokenizer – med din app.

Tip

Om du inte behöver en specifik modell och bara vill skapa text på enheten med en modell som Microsoft hanterar använder du en av de lokala llm:erna som är redo att användas i stället.

Du skapar fortfarande de underliggande Runtime-objekten – modellen, körningsmålet och pipelinen – och skickar dem till sessionen. API:et döljer inte hur maskinvaran placeras; det tar bara bort behovet av att skriva din egen token-loop.

Modeller som stöds

API:t för textgenerering accepterar:

  • ONNX-modeller (.onnx) eller ORT-format (.ort) modeller som körs via ONNX Runtime. Modellen måste exponera indata för token-ID, logits-utdata och ett tillståndstensor-par med fast kapacitet som innehåller nyckel/värde-cachen och sekvenspositionen. Du anger en separat tokenizerkälla (till exempel en tokenizer.json).
  • GGUF-modeller (.gguf) körs via llama.cpp-backend. Tokenizern är inbäddad i modellen, så ingen separat tokenizerkälla behövs.

Proverna validerar det här kontraktet mot modellfamiljen Qwen2.5-0.5B-Instruct, som exporteras med ett aktivitetsspecifikt diagram som packar nyckel/värde-cachen och sekvenspositionen i ett tillståndspar. Andra språkmodeller med enbart avkodare som exponerar samma tokenindata, logits-utdata och tillståndskontrakt bör också fungera.

Generera text

En textgenereringssession omsluter en tokenizer och en tillståndskänslig pipeline (modellen som äger nyckel/värde-cachen). Läs in modellen och tokeniseraren, beskriv modellens tokenindata, logits-utdata och tillståndskontrakt och skapa sessionen:

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

Anropa GenerateText med en uppmaning om att starta en strömningsåtgärd och hämta sedan fragment från den returnerade strömmen tills den rapporterar slutförande:

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

Det slutförda resultatet rapporterar:

  • Den fullständigt genererade texten och token-ID:n
  • Antal promptar och genererade token
  • En slutorsak – en slutsekvenstoken, en stopptoken, den begärda tokengränsen, sekvenskapacitet, annullering eller ett fel

C++ och Python

Det inbyggda API:et exponeras via WinMLTasks.h och de typinskrivna C++-hjälparna under winml/tasks/text_generation/TextGeneration.hpp. Python program använder projektionen windowsml.tasks tillsammans med windowsml.runtime.

De Windows ML-exemplen innehåller ett exempel för textgenerering i C++ och Python. Kodexemplet visar den fullständiga Runtime-konfigurationen bredvid textgenereringskonfigurationen så att du kan se var abstraktionen börjar och hur du anpassar det underliggande arbetsflödet.

Se även