concepten voor Windows ML Runtime-API

Important

De Windows ML Runtime-API is momenteel experimenteel en wordt niet ondersteund voor gebruik in productieomgevingen. Apps die deze API uitproberen, mogen niet worden gepubliceerd naar de Microsoft Store.

De Windows ML Runtime-API is een systeemeigen lokaal AI-inferentieframework dat speciaal is gebouwd voor Windows. Met de Windows ML Runtime-API hebt u expliciet controle over het laden van modellen, hardwareplaatsing, eigendom van tensor, pijplijnsamenstelling, compilatie en diagnostiek.

We raden u aan de Runtime-API te gebruiken voor de beste modelinferentieprestaties op Windows, maar als uw app moet worden uitgevoerd op andere platforms of als u al platformoverschrijdende ONNX Runtime-code hebt, kunt u ook ONNX Runtime gebruiken via Windows ML.

Hoe de objecten bij elkaar passen

IWinMLRuntime
  |-- loads --> IWinMLModel
  |-- creates -> IWinMLExecutionTarget
  `-- creates -> IWinMLPipelineBuilder
                   |-- adds/connects -> IWinMLStage
                   `-- Build() ------> IWinMLPipeline

IWinMLExecutionTarget -- creates --> IWinMLTensor
IWinMLStage ----------- binds -----> IWinMLTensor
IWinMLPipeline -------- Run() -----> stage outputs

Elke methode retourneert HRESULT, en elke interfacepointer volgt de normale COM-referentietelling. Optionele mogelijkheden worden gedetecteerd met QueryInterface; een niet-beschikbare mogelijkheid retourneert E_NOINTERFACE.

Runtime

Maak IWinMLRuntime met WinMLCreateRuntime. Gebruik deze om modelartefacten te laden, uitvoeringsdoelen te maken en pijplijnbouwers te maken.

Modellen en schema

IWinMLModel is een onveranderbaar, niet-transparant modelartefact. LoadModelFromFile accepteert een absoluut of relatief bestandspad dat uw app kan lezen; de locatie van het model hangt af van hoe uw app is verpakt.

Bij het laden wordt gecontroleerd of het artefact wordt herkend en structureel leesbaar is. Doelcompatibiliteit wordt later vastgelegd, wanneer de Build-methode van de pipeline builder slaagt.

Het gedeclareerde ordinale schema van een model weergeven via IWinMLModelSchema. Sommige ONNX-artefacten maken ook namen beschikbaar via de optionele IWinMLOrtModelSchema, maar de uitvoeringsidentiteit blijft positioneel.

Vormen en operatoren

Een gedeclareerd modelschema kan vrije dimensies bevatten, vertegenwoordigd door UINT64_MAX. Een concreet IWinMLTensor heeft altijd vastgestelde afmetingen. Door ORT ondersteunde pijplijnen kunnen concrete waarden binden en uitvoeren voor een vrije dimensie.

Vaste of expliciet begrensde shapes blijven het centrum van het geoptimaliseerde ontwerp, omdat ze Build compatibiliteit laten valideren, stabiele resources kunnen toewijzen en kunnen bepalen of replay of apparaatresidente iteratie toegestaan is. Ze bieden ook de breedste compatibiliteit met verschillende uitvoeringsback-ends. Dit is een optimalisatie- en draagbaarheidsscheiding, niet een algemene afwijzing van modellen waarvan het gedeclareerde ONNX-schema vrije dimensies bevat.

Standaard ONNX-operators verbeteren eveneens de portabiliteit van de back-end. Het succesvol laden van een model garandeert niet dat elk doelplatform elke operator kan uitvoeren; Build is de compatibiliteitscontrole.

Backends

Het modelbestand selecteert de back-end. Uw app maakt gebruik van dezelfde Runtime-objecten: model, uitvoeringsdoel, pijplijnbouwer, fasen, bindingen en Run.

Modelbestand Backend Hardwareversnelling
.onnx, .ort ONNX Runtime Uitvoeringsproviders (EP's) die door Windows worden geïnstalleerd en up-to-date gehouden via de Windows ML EP-catalogus
.gguf llama.cpp llama.cpp modules meegeleverd met uw app: een CPU-module in het pakket en een optionele CUDA-module voor NVIDIA GPU's. CPU en CUDA zijn de enige llama.cpp-back-ends die Windows ML voor deze release valideert.

De back-ends verschillen in wat een fase kan uitdrukken:

Vermogen ONNX Runtime llama.cpp
Vorm van het werkvlak Elke ONNX-grafiek; meerdere fasen kunnen in één pijplijn worden verbonden Eén decoderfase per GGUF-bestand: token-id's in (invoer 0), logits out (uitvoer 0)
Reeksstatus (KV-cache) Toestandstensorparen declareren met IWinMLStatefulStageOptions; de Runtime beheert deze Beheerd door de backend; niets te declareren
Contextlengte SetSequenceCapacityHint vóór Build, of de opgegeven capaciteit van het model SetSequenceCapacityHint stelt vóór Build de llama.cpp-contextlengte in
Opties voor providers vastzetten en ORT-fase Ondersteund (WinMLRuntimeOrt.h) Niet ondersteund; Build retourneert HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED)
Plaatsingsrapport na Build IWinMLOrtStageDiagnostics benoemt de aangevraagde en geselecteerde providers IWinMLStage::GetExecutionTarget-rapporten CPU of GPU

Eén pipeline kan meerdere backends gebruiken. Een Whisper-fase in ONNX Runtime kan bijvoorbeeld een GGUF-taalmodel aansturen met behulp van llama.cpp.

Doelen voor uitvoering

IWinMLExecutionTarget is een onveranderbaar plaatsingstoken dat een hardwareklasse aanvraagt en eventueel een specifieke adapter. Elke back-end lost dit op wanneer Build wordt uitgevoerd:

Fasedoel ONNX Runtime llama.cpp
nullptr doorgegeven aan AddModelStage Automatische plaatsing selecteert een compatibele GPU EP wanneer deze beschikbaar is, met CPU-terugval. Offloads naar de CUDA-module wanneer er een CUDA-module beschikbaar is en het model erin past; anders wordt uitgevoerd op de CPU.
CreateCpuExecutionTarget Selecteert een compatibele CPU-EP, met DE CPU-provider van ORT als basislijn. Wordt uitgevoerd op de CPU.
CreateExecutionTarget met het GPU-type, CreateExecutionTargetFromAdapterof CreateExecutionTargetFromD3D12 Hiermee wordt de adapteridentiteit toegewezen aan een compatibel GPU EP-apparaat. Als er geen providerapparaat overeenkomt, mislukt Build. Vereist ten minste gedeeltelijke offload naar de CUDA-module. Build geeft HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED) terug wanneer er geen CUDA-module is geïnstalleerd en HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY) wanneer het model niet past. De module kiest de GPU; de adapteridentiteit wordt niet gebruikt.
CreateExecutionTarget met de soort NPU of een NPU-adapter Wordt toegewezen aan een compatibel NPU EP-apparaat. Niet ondersteund; Build retourneert HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED).
IWinMLOrtCompatibility::CreateExecutionTarget(provider, kind, hardwareTarget) Pint één geregistreerde EP vast. Als hardwareTarget is ingesteld op nullptr, koppelt de runtime de provider aan een van de eigen apparaten; op een pc met twee GPU's wordt voorkomen dat de provider wordt gekoppeld aan een adapter die niet wordt ondersteund. Niet ondersteund; Build retourneert HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED).

IWinMLRuntime::CreateExecutionTarget(kind, preference) kiest een adapter van de aangevraagde klasse zonder dat u zelf adapters hoeft op te sommen en preference adapters rangschikt wanneer er meer dan één is, bijvoorbeeld een geïntegreerde en discrete GPU:

ComPtr<IWinMLExecutionTarget> target;
THROW_IF_FAILED(runtime->CreateExecutionTarget(
    WINML_EXECUTION_TARGET_KIND_GPU,
    WINML_EXECUTION_TARGET_PREFERENCE_PERFORMANCE,
    target.GetAddressOf()));

Voor expliciete adapterselectie is een compatibele ONNX Runtime-provider vereist om die hardware-identiteit beschikbaar te maken via ORT. Als er geen providerapparaat overeenkomt, mislukt Build in plaats van op de achtergrond een andere adapter of CPU te selecteren.

CreateExecutionTargetFromD3D12 behoudt het apparaat van de beller en de optionele wachtrij op het doel, maar DE UITVOERING van ORT gebruikt alleen de adapteridentiteit voor EP-selectie. De ORT-provider is eigenaar van de uitvoeringsbronnen en de opdrachtwachtrij van de beller wordt niet gebruikt voor indiening bij ORT.

Een D3D12-doel stelt nog steeds IWinMLD3D12ExecutionTarget beschikbaar via QueryInterface. Het hergebruik van één expliciete target in verschillende fasen geeft affiniteit met dezelfde adapter aan; afzonderlijke targets maken overdrachtsgrenzen expliciet.

Een GGUF-model uitvoeren

  1. Laad het bestand met LoadModelFromFile. De .gguf extensie selecteert llama.cpp. Voor een shard-model moet u elke shard in één map bewaren en de eerste shard laden.
  2. Voeg één modelfase toe met een CPU-, GPU- of nullptr-target. Als u de contextlengte wilt instellen, voert u een query IWinMLStatefulStageOptions in de stage uit en roept u SetSequenceCapacityHint aan.
  3. Roep Build aan. Bind vervolgens de token-id's van de prompt aan invoer 0, vraag uitvoer 0 op en roep Run aan. Elke latere uitvoering neemt het volgende token; de back-end houdt de KV-cache tussen uitvoeringen.
  4. Roep ResetExecutionState aan vóór een onafhankelijke reeks.
// Create the runtime and an execution target (CPU here; GPU also available).
ComPtr<IWinMLRuntime> runtime;
THROW_IF_FAILED(WinMLCreateRuntime(IID_PPV_ARGS(runtime.GetAddressOf())));
ComPtr<IWinMLExecutionTarget> target;
THROW_IF_FAILED(runtime->CreateCpuExecutionTarget(target.GetAddressOf()));

ComPtr<IWinMLModel> model;
THROW_IF_FAILED(runtime->LoadModelFromFile(
    L"C:\\models\\qwen2.5-0.5b-instruct.gguf", nullptr, model.GetAddressOf()));

ComPtr<IWinMLPipelineBuilder> builder;
THROW_IF_FAILED(runtime->CreatePipelineBuilder(builder.GetAddressOf()));

ComPtr<IWinMLStage> stage;
THROW_IF_FAILED(builder->AddModelStage(
    model.Get(), target.Get(), L"decoder", stage.GetAddressOf()));
THROW_IF_FAILED(stage->RequestOutput(0));

// Set the llama.cpp context length before Build.
ComPtr<IWinMLStatefulStageOptions> stateOptions;
THROW_IF_FAILED(stage->QueryInterface(IID_PPV_ARGS(stateOptions.GetAddressOf())));
THROW_IF_FAILED(stateOptions->SetSequenceCapacityHint(4096));

ComPtr<IWinMLPipeline> pipeline;
THROW_IF_FAILED(builder->Build(pipeline.GetAddressOf()));

// Bind token IDs to input 0 and run one token at a time; the backend keeps
// the KV cache between runs.
THROW_IF_FAILED(stage->BindInput(0, tokenIdsTensor.Get()));
THROW_IF_FAILED(pipeline->Run());

ComPtr<IWinMLTensor> logits;
THROW_IF_FAILED(stage->GetOutput(0, logits.GetAddressOf()));

// Start an independent sequence on the same pipeline.
THROW_IF_FAILED(pipeline->ResetExecutionState());

De tokenizer en gespreksopmaak zijn afkomstig uit het GGUF-bestand, dus een GGUF-model heeft geen afzonderlijke tokenizer-bestanden nodig. Als u de tokenlus wilt overslaan, gebruikt u de Text Generation-API, die werkt met GGUF- en ONNX-modellen.

De llama.cpp-backend uitrollen

De llama.cpp back-end is app-lokaal. Wanneer een project ervoor kiest deel te nemen, kopieert het Windows ML NuGet-pakket de llama.cpp-adapter van de Runtime, de llama.cpp-kern en de CPU-module naast uw app. GPU-versnelling heeft de optionele CUDA-module nodig, gebouwd voor dezelfde llama.cpp revisie als het pakket en naast uw app geplaatst.

Zie de voorbeelden van het GGUF-model en llama.cpp voorbeelden voor een overzicht van beide stappen.

pipelines en stadia

Bouw een pipeline met de one-shot IWinMLPipelineBuilder:

  1. Voeg model- of processorfasen toe met hun uitvoeringsdoelen.
  2. Verbind stagepoorten via ordinale index.
  3. Roep Build eenmaal aan om de grafiek te blokkeren, plaatsing op te lossen en compatibiliteit te valideren.

Voor twee modelfasen voegt u beide fasen toe, verbindt u de uitvoerordinaal van de eerste fase met de invoerordinaal van de tweede fase en bouwt u één keer. Uw app levert de modellen en verbindt eventuele externe input. Er is geen modelspecifieke Runtime-API nodig: embedding, decoderen, voorverwerking van afbeeldingen en andere toepassingsarchitecturen gebruiken dezelfde stap- en tensorprimitieven.

Elk IWinMLStage is eigenaar van positionele invoerbindingen en stelt de huidige uitvoertensors beschikbaar. Toetsbindingen blijven behouden tussen sessies. Roep BindOutput aan vóór een run wanneer uw app uitvoeropslag levert.

Optionele fasemogelijkheden zijn onder andere opgelost doeleindpunt, gematerialiseerd schema, uitvoerresidencybeleid en controle over de volgordestatus. Gebruik QueryInterface om elke mogelijkheid te testen.

Pipeline-uitvoering

IWinMLPipeline::Run voert de voorbereide pijplijn synchroon uit. Roep ResetExecutionState tussen onafhankelijke reeksen aan om de door runtime beheerde status te wissen.

Optionele uitvoeringsinterfaces bieden device-timeline-submit en iteratieve herhaling met vaste tellingen wanneer de opgebouwde graaf en geselecteerde back-end deze ondersteunen. Het pad Run blijft de gemeenschappelijke basis.

Tensoren en sloten

IWinMLTensor vertegenwoordigt getypeerde, multidimensionale gegevens. Maak tensors op basis van een factory die wordt opgevraagd vanuit het uitvoeringsdoel, zodat tensorplaatsing volgt op de doelplaatsing.

Factories hebben betrekking op onbewerkte bytes, afbeeldingsgegevens, audiogegevens, token-id's en composable tensor-processors. Optionele tensor-interfaces bieden mutatie, D3D12-bufferbindingen en synchronisatie.

Roep IWinMLTensor::Lock aan voordat u tensorbytes op de CPU benadert. Het geretourneerde IWinMLTensorDataLock brengt het CPU-toegangsvenster tot stand, voert de vereiste toewijzing of synchronisatie uit en beheert de levensduur van de aanwijzer die door GetData wordt geretourneerd.

Compilatie en externe gewichten

Ahead-of-time-compilatie is een optionele mogelijkheid van een uitvoeringsdoel, beschikbaar gesteld via IWinMLModelCompiler. Gecompileerde artefacten worden opnieuw geladen via de normale modellaadmethoden. Apps kunnen geëxternaliseerde gewichten leveren via IWinMLResourceMapReader.

Tekstwerklasten

Tekstworkloads maken gebruik van dezelfde runtime, target, pijplijn, fase en tensor-primitieven. Uw app kan metagegevens van modelpakketten, sampling, stopbeleid en accumulatie van gegenereerde tokens rechtstreeks beheren, of de API voor het genereren van tekst gebruiken om deze bewerkingen te coördineren via een compatibele Runtime-pijplijn.

IWinMLTokenizer biedt bewerkingen op laag niveau voor coderen en decoderen. Een IWinMLTokenizerDecoder onderhoudt een onafhankelijke incrementele decodeercursor voor één reeks. Met de Text Generation-API worden sessies, opties, streaming-updates, annulering, voltooiingsredenen en voltooide resultaten toegevoegd zonder het eigendom van de onderliggende Runtime-objecten te wijzigen.

Compatibiliteit met ONNX Runtime

De optionele interfaces in WinMLRuntimeOrt.h bieden ONNX-gemak:

  • IWinMLOrtCompatibility selecteert een al geregistreerde ONNX Runtime-uitvoeringsprovider.
  • IWinMLOrtModelSchema geeft invoer- en uitvoernamen weer.
  • IWinMLOrtNamedBindings bindt een door ORT ondersteunde fase op basis van de naam.
  • IWinMLOrtStageDiagnostics rapporteert de aangevraagde en geselecteerde providers na Build.

Deze interfaces voeren naamomzetting uit en bepalen het providerbeleid tijdens de installatie. De uitvoering blijft hetzelfde positionele pijplijncontract gebruiken.

Vraag IWinMLOrtCompatibility op vanuit de runtime om een ONNX-modelfase vast te maken aan een uitvoeringsprovider die u al hebt geregistreerd, in plaats van er automatisch een te laten Build kiezen:

ComPtr<IWinMLOrtCompatibility> ortCompatibility;
THROW_IF_FAILED(runtime->QueryInterface(IID_PPV_ARGS(ortCompatibility.GetAddressOf())));

ComPtr<IWinMLExecutionTarget> target;
THROW_IF_FAILED(ortCompatibility->CreateExecutionTarget(
    L"MyRegisteredProvider",
    WINML_EXECUTION_TARGET_KIND_GPU,
    /* hardwareTarget */ nullptr,
    target.GetAddressOf()));

Door hardwareTarget voor nullptr door te geven, kan de Runtime de provider koppelen aan een van zijn eigen apparaten van die hardwareklasse; geef in plaats daarvan een bestaande IWinMLExecutionTarget door om de provider aan die specifieke adapter vast te maken. Deze target wordt niet ondersteund voor .gguf fasen; Build retourneert HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED).

Zie ook