Konsep API Windows ML Runtime

Important

API ML Runtime Windows saat ini bersifat eksperimental dan tidak didukung untuk digunakan di lingkungan produksi. Aplikasi yang mencoba API ini tidak boleh diterbitkan ke Microsoft Store.

ML Runtime API Windows adalah kerangka kerja inferensi AI lokal asli yang dibangun khusus untuk Windows. Dengan WINDOWS ML Runtime API, Anda memiliki kontrol eksplisit atas pemuatan model, penempatan perangkat keras, kepemilikan tensor, komposisi alur, kompilasi, dan diagnostik.

Sebaiknya gunakan API Runtime untuk performa inferensi model terbaik pada Windows, tetapi jika aplikasi Anda perlu berjalan di platform lain, atau jika Anda sudah memiliki kode ONNX Runtime lintas platform, Anda juga dapat menggunakan ONNX Runtime melalui Windows ML.

Bagaimana objek cocok bersama-sama

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

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

Setiap metode mengembalikan HRESULT, dan setiap penunjuk antarmuka mengikuti penghitungan referensi COM normal. Kemampuan opsional ditemukan dengan QueryInterface; kemampuan yang tidak tersedia mengembalikan E_NOINTERFACE.

Runtime

Buat IWinMLRuntime dengan WinMLCreateRuntime. Gunakan untuk memuat artefak model, membuat target eksekusi, dan membuat builder pipeline.

Model dan skema

IWinMLModel adalah artefak model opak yang tidak dapat diubah. LoadModelFromFile menerima jalur file absolut atau relatif apa pun yang dapat dibaca aplikasi Anda; lokasi model adalah keputusan pengemasan aplikasi Anda.

Pemuatan memverifikasi bahwa artefak dikenali dan dapat dibaca secara struktural. Kompatibilitas target ditetapkan kemudian, ketika metode pipeline builder Build berhasil.

Cerminkan skema ordinal model yang dinyatakan melalui IWinMLModelSchema. Beberapa artefak ONNX juga mengekspos nama melalui IWinMLOrtModelSchema opsional, tetapi identitas eksekusi tetap bersifat posisional.

Objek dan operator

Skema model yang dideklarasikan dapat berisi dimensi bebas, yang diwakili oleh UINT64_MAX. Objek konkret IWinMLTensor selalu memiliki dimensi yang diselesaikan. Alur yang didukung ORT dapat mengikat dan menjalankan nilai konkret untuk dimensi bebas.

Bentuk tetap atau terikat secara eksplisit tetap menjadi pusat desain yang dioptimalkan karena memungkinkan Build memvalidasi kompatibilitas, mengalokasikan sumber daya yang stabil, dan menentukan apakah pemutaran ulang atau iterasi yang berada di perangkat legal. Mereka juga memberikan kompatibilitas terluas di seluruh backend eksekusi. Ini adalah perbedaan pengoptimalan dan portabilitas, bukan penolakan menyeluruh terhadap model yang skema ONNX yang dideklarasikan berisi dimensi bebas.

Operator standar ONNX juga meningkatkan portabilitas backend. Pemuatan model yang berhasil tidak menjamin bahwa setiap target dapat menjalankan setiap operator; Build adalah pemeriksaan kompatibilitas.

Backends

Berkas model yang memilih backend. Aplikasi Anda menggunakan objek Runtime yang sama: model, target eksekusi, penyusun alur, tahapan, pengikatan, dan Run.

Berkas model Backend Akselerasi perangkat keras
.onnx, .ort ONNX Runtime Penyedia eksekusi (EPs) yang Windows menginstal dan terus memperbarui melalui katalog ML EP Windows
.gguf llama.cpp modul llama.cpp yang disebarkan bersama aplikasi Anda: modul CPU dalam paket, dan modul CUDA opsional untuk GPU NVIDIA. CPU dan CUDA adalah satu-satunya backend llama.cpp Windows ML yang divalidasi untuk rilis ini.

Backend berbeda dalam apa yang dapat diekspresikan oleh stage:

Capability ONNX Runtime llama.cpp
Bentuk panggung Graf ONNX apa pun; beberapa tahap dapat dihubungkan dalam satu alur Satu tahap dekoder per file GGUF: ID token masuk (input 0), logit keluar (output 0)
Status sekuens (KV cache) Deklarasikan pasangan tensor status dengan IWinMLStatefulStageOptions; Runtime mengelolanya Dimiliki oleh backend; tidak ada yang perlu dideklarasikan
Panjang konteks SetSequenceCapacityHint sebelum Build, atau kapasitas model yang dideklarasikan SetSequenceCapacityHint sebelum Build mengatur panjang konteks llama.cpp
Opsi penyematan provider dan tahap ORT Didukung (WinMLRuntimeOrt.h) Tidak didukung; Build mengembalikan HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED)
Laporan penempatan setelah Build IWinMLOrtStageDiagnostics mencantumkan penyedia yang diminta dan dipilih IWinMLStage::GetExecutionTarget melaporkan CPU atau GPU

Satu pipeline dapat mencampur backend. Misalnya, tahap Whisper pada ONNX Runtime dapat memberi umpan model bahasa GGUF pada llama.cpp.

Sasaran eksekusi

IWinMLExecutionTarget adalah token penempatan yang tidak dapat diubah yang meminta penempatan pada kelas perangkat keras, dan secara opsional adaptor tertentu. Setiap backend menyelesaikannya saat Build dijalankan:

Target tahap ONNX Runtime llama.cpp
nullptr diteruskan ke AddModelStage Penempatan otomatis memilih EP GPU yang kompatibel jika tersedia, dengan fallback CPU. Offload ke modul CUDA ketika modul CUDA diterapkan dan model cocok; jika tidak, berjalan pada CPU.
CreateCpuExecutionTarget Memilih CPU EP yang kompatibel, dengan penyedia CPU ORT sebagai dasar. Berjalan pada CPU.
CreateExecutionTarget dengan jenis GPU, CreateExecutionTargetFromAdapter, atau CreateExecutionTargetFromD3D12 Memetakan identitas adaptor ke perangkat EP GPU yang kompatibel. Jika tidak ada perangkat penyedia yang cocok, Build gagal. Memerlukan setidaknya offload parsial ke modul CUDA. Build mengembalikan HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED) ketika tidak ada modul CUDA yang diterapkan, dan HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY) mengembalikan ketika model tidak cocok. Modul memilih GPU; identitas adaptor tidak digunakan.
CreateExecutionTarget dengan tipe NPU, atau adaptor NPU Memetakan ke perangkat NPU EP yang kompatibel. Tidak didukung; Build mengembalikan HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED).
IWinMLOrtCompatibility::CreateExecutionTarget(provider, kind, hardwareTarget) 1 EP terdaftar yang disematkan Dengan hardwareTarget diatur ke nullptr, Runtime memasangkan penyedia dengan salah satu perangkat milik Runtime; pada PC dengan dua GPU, ini menghindari pemasangan penyedia dengan adaptor yang tidak didukung oleh penyedia. Tidak didukung; Build mengembalikan HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED).

IWinMLRuntime::CreateExecutionTarget(kind, preference) memilih adaptor dari kelas yang diminta tanpa mengharuskan Anda mendaftar perangkat sendiri, dan preference memberi peringkat adaptor ketika ada lebih dari satu, misalnya GPU terintegrasi dan diskrit:

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

Pemilihan adaptor eksplisit memerlukan penyedia Runtime ONNX yang kompatibel untuk mengekspos identitas perangkat keras tersebut melalui ORT. Jika tidak ada perangkat penyedia yang cocok, Build akan gagal, alih-alih diam-diam memilih adaptor lain atau CPU.

CreateExecutionTargetFromD3D12 mempertahankan perangkat pemanggil dan antrean opsional pada target, tetapi eksekusi ORT hanya menggunakan identitas adaptor untuk pemilihan EP. Penyedia ORT memiliki sumber daya eksekusinya, dan antrean perintah pemanggil tidak digunakan untuk submisi ORT.

Target D3D12 masih memaparkan IWinMLD3D12ExecutionTarget melalui QueryInterface. Menggunakan kembali satu target eksplisit di seluruh tahap mengekspresikan afinitas adaptor yang sama; target yang berbeda membuat batas transfer menjadi eksplisit.

Menjalankan model GGUF

  1. Muat file dengan LoadModelFromFile. Ekstensi .gguf menggunakan llama.cpp. Untuk model sharded, simpan setiap shard dalam satu folder dan muat shard pertama.
  2. Tambahkan satu tahap model dengan target CPU, GPU, atau nullptr. Untuk mengatur panjang konteks, kueri IWinMLStatefulStageOptions dari stage dan panggil SetSequenceCapacityHint.
  3. Hubungi Build. Kemudian ikat ID token prompt ke input 0, minta output 0, dan panggil Run. Setiap eksekusi kemudian mengambil token berikutnya; backend menyimpan cache KV di antara eksekusi.
  4. Jalankan ResetExecutionState sebelum sekuens independen.
// 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());

Tokenizer dan pemformatan percakapan berasal dari file GGUF, sehingga model GGUF tidak memerlukan file tokenizer terpisah. Untuk melewati perulangan token, gunakan TEXT Generation API, yang berfungsi dengan model GGUF dan ONNX.

Terapkan backend llama.cpp

Backend llama.cpp bersifat lokal aplikasi. Saat proyek memilih ikut serta, paket Windows ML NuGet menyalin adaptor llama.cpp Runtime, inti llama.cpp, dan modul CPU di samping aplikasi Anda. Akselerasi GPU memerlukan modul CUDA opsional, dibuat untuk revisi llama.cpp yang sama dengan paket dan ditempatkan di samping aplikasi Anda.

Untuk panduan kedua langkah tersebut, lihat sampel model GGUF dan sampel llama.cpp.

Pipeline dan tahapan

Buat alur dengan one-shot IWinMLPipelineBuilder:

  1. Tambahkan tahap model atau prosesor dengan target eksekusinya.
  2. Sambungkan port stage menurut indeks ordinal.
  3. Jalankan Build sekali untuk membekukan grafik, menyelesaikan penempatan, dan memvalidasi kompatibilitas.

Untuk dua tahap model, tambahkan kedua tahap, sambungkan ordinal output tahap pertama ke ordinal input tahap kedua, dan bangun sekali. Aplikasi Anda menyediakan model dan menghubungkan input eksternal apa pun. Ini tidak memerlukan API Runtime khusus model: penyematan, dekoder, praproscesing gambar, dan arsitektur aplikasi lainnya menggunakan tahap dan primitif tensor yang sama.

Masing-masing IWinMLStage memiliki pengikatan input posisional dan mengekspos tensor outputnya saat ini. Binding input tetap tersimpan antar sesi. Panggil metode BindOutput sebelum eksekusi saat aplikasi Anda menyediakan penyimpanan output.

Kemampuan tahap opsional termasuk target yang di-resolve, skema termaterialisasi, kebijakan residensi output, dan kontrol state urutan. Gunakan QueryInterface untuk menguji setiap kapabilitas.

Eksekusi pipeline

IWinMLPipeline::Run menjalankan pipeline yang disiapkan secara sinkron. Panggil ResetExecutionState antara urutan independen untuk menghapus status yang dikelola runtime.

Antarmuka eksekusi opsional menyediakan submission ke linimasa perangkat dan pemutaran ulang iteratif jumlah tetap saat graf yang dibangun dan backend yang dipilih mendukungnya. Jalur dasar Run tetap menjadi dasar umum.

tensor dan kunci

IWinMLTensor merepresentasikan data multidimensi yang diketik. Buat tensor dari pabrik yang dikueri dari target eksekusi sehingga penempatan tensor mengikuti penempatan target.

Factory mencakup byte mentah, data gambar, data audio, ID token, dan prosesor tensor yang dapat disusun. Antarmuka tensor opsional mengekspos mutasi, pengikatan buffer D3D12, dan sinkronisasi.

Panggil IWinMLTensor::Lock sebelum mengakses byte tensor pada CPU. IWinMLTensorDataLock yang dikembalikan menetapkan jendela akses CPU, melakukan pemetaan atau sinkronisasi yang diperlukan, dan bertanggung jawab atas masa hidup pointer yang dikembalikan oleh GetData.

Kompilasi dan bobot eksternal

Kompilasi ahead-of-time (AOT) adalah kemampuan opsional dari target eksekusi, yang diekspos melalui IWinMLModelCompiler. Artefak terkompilasi dimuat ulang melalui metode pemuatan model normal. Aplikasi dapat menyediakan bobot yang dieksternalisasi melalui IWinMLResourceMapReader.

Beban kerja berbasis teks

Beban kerja teks menggunakan runtime, target, alur, tahap, dan primitif tensor yang sama. Aplikasi Anda dapat memiliki metadata paket model, pengambilan sampel, kebijakan penghentian, dan akumulasi token yang dihasilkan secara langsung, atau menggunakan TEXT Generation API untuk mengoordinasikan operasi tersebut melalui alur Runtime yang kompatibel.

IWinMLTokenizer menyediakan operasi pengodean dan dekode tingkat rendah. Sebuah IWinMLTokenizerDecoder mempertahankan kursor dekode inkremental independen untuk satu urutan. TEXT Generation API menambahkan sesi pembuatan teks, opsi, pembaruan streaming, pembatalan, alasan selesai, dan hasil yang diselesaikan tanpa mengubah kepemilikan objek Runtime yang mendasarinya.

Kompatibilitas Runtime ONNX

Antarmuka opsional dalam WinMLRuntimeOrt.h memberikan kenyamanan ONNX:

  • IWinMLOrtCompatibility memilih penyedia eksekusi ONNX Runtime yang sudah terdaftar.
  • IWinMLOrtModelSchema mencerminkan nama input dan output.
  • IWinMLOrtNamedBindings mengaitkan stage yang didukung ORT berdasarkan nama.
  • IWinMLOrtStageDiagnostics laporan penyedia yang diminta dan dipilih setelah Build.

Antarmuka ini menentukan nama dan kebijakan penyedia selama penyiapan. Eksekusi terus menggunakan kontrak pipeline posisional yang sama.

Kueri IWinMLOrtCompatibility dari runtime untuk menyematkan tahap model ONNX ke penyedia eksekusi yang telah Anda daftarkan, alih-alih membiarkan Build memilihnya secara otomatis:

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

Meneruskan nullptr untuk hardwareTarget memungkinkan Runtime memasangkan penyedia dengan salah satu perangkatnya sendiri dari kelas perangkat keras tersebut; teruskan IWinMLExecutionTarget yang sudah ada untuk menyematkan penyedia ke adaptor tertentu itu sebagai gantinya. Target ini tidak didukung untuk .gguf tahapan; Build mengembalikan HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED).

Baca juga