ONNX Developer Flow¶
This page describes the full developer experience for local/onnx.
1. Enable the provider¶
provider-onnx is on by default, so the minimal setup is just:
If you want a lean ONNX-only build (no candle, no mistralrs, no remote providers):
For CUDA-enabled ORT builds (Linux / Windows + NVIDIA), add gpu-cuda:
For Apple GPU + Neural Engine via the CoreML EP, add gpu-metal:
2. Decide how the model is addressed¶
model_id can be either:
- a local path to a
.onnxfile, or - a Hugging Face repo ID
Examples:
HF-backed aliases download a full repo snapshot into cache before loading the selected model.
3. Add a catalog alias¶
local/onnx always uses:
provider_id: "local/onnx"task: "raw"
Example:
{
"alias": "raw/classifier",
"task": "raw",
"provider_id": "local/onnx",
"model_id": "smokxy/sequence_classification_onnx",
"warmup": "lazy",
"options": {
"artifact": "model.onnx",
"execution_providers": ["cpu"]
}
}
If the HF repo contains multiple .onnx files, set options.artifact.
4. Register the provider¶
use uni_xervo::provider::local_onnx::LocalOnnxProvider;
use uni_xervo::runtime::ModelRuntime;
let runtime = ModelRuntime::builder()
.register_provider(LocalOnnxProvider::new())
.catalog_from_file("model-catalog.json")?
.build()
.await?;
5. Resolve the runner¶
This gives you an Arc<dyn RawTensorModel>.
Useful methods:
input_signature()output_signature()max_batch_size()run(&batch)run_batch(&batches)
6. Inspect signatures before wiring inputs¶
This is the first thing to do when integrating a new model. It tells you:
- input/output names,
- tensor dtypes,
- rank and dimensions,
- whether symbolic or dynamic dimensions are present.
7. Build TensorBatch¶
Inputs and outputs use TensorBatch, an ordered map from tensor name to TensorValue.
use ndarray::arr2;
use uni_xervo::traits::{TensorBatch, TensorValue};
let mut batch = TensorBatch::new();
batch.insert(
"input_ids".to_string(),
TensorValue::I64(arr2(&[[101_i64, 1045, 2293, 3185, 102]]).into_dyn()),
);
batch.insert(
"attention_mask".to_string(),
TensorValue::I64(arr2(&[[1_i64, 1, 1, 1, 1]]).into_dyn()),
);
Supported tensor value families:
f32f64i32i64boolstring
8. Run inference¶
Or for batched execution:
Uni-Xervo validates:
- required input names,
- dtype matches,
- fixed-shape dimensions,
- batch stacking compatibility for
run_batch().
9. Interpret outputs in application code¶
Uni-Xervo does not decide what output tensors mean.
Typical application-side logic:
- classifier: read logits, apply argmax, map class IDs to labels
- NER: read token logits, align tokens to offsets, rebuild spans
- embeddings: pool or normalize hidden states if the export requires it
- tabular regression: read a scalar output tensor
That is by design. local/onnx stops at validated raw execution.
10. HF transformer-style flow¶
For a typical Hugging Face ONNX export:
- Put the HF repo ID in
model_id. - Set
options.artifactwhen the repo contains multiple.onnxfiles. - Resolve
runtime.raw_tensor_model(alias). - Use your tokenizer/preprocessing layer in app code.
- Convert the prepared arrays into
TensorBatch. - Run inference.
- Decode outputs in app code.
The live repo tests exercise this pattern for:
- sequence classification
- token classification / NER
See tests/local_onnx_hf_e2e_test.rs.
11. Prefetching¶
Use uni-prefetch when you want model artifacts available before first request:
For HF-backed local/onnx aliases, this materializes the full repo snapshot into cache ahead of time.
DX summary¶
The intended DX is:
- Uni-Xervo owns runtime and artifact orchestration
- your app owns task semantics
That keeps local/onnx lightweight, composable, and useful for both simple numeric models and harder custom pipelines.