uni_xervo/provider/
local_onnx.rs1#[allow(dead_code)]
22mod autoreg;
23mod common;
24mod decoder_inputs;
25mod det;
26mod document_extract;
27mod embed_hybrid;
28mod embed_multi_vector;
29mod embed_sparse;
30mod embedding;
31mod image;
32mod image_embed;
33mod nlp;
34mod ocr;
35mod presets;
36mod raw;
37mod rerank;
38mod rerank_generative;
39
40use std::path::PathBuf;
41use std::sync::Arc;
42
43use async_trait::async_trait;
44use dashmap::DashMap;
45
46use crate::api::{ModelAliasSpec, ModelTask};
47use crate::error::{Result, RuntimeError};
48use crate::traits::{
49 DocumentExtractionModel, EmbeddingModel, HybridEmbeddingModel, ImageEmbeddingModel,
50 LoadedModelHandle, ModelProvider, MultiVectorEmbeddingModel, NlpModel, OcrModel,
51 ProviderCapabilities, ProviderHealth, RawTensorModel, RerankerModel, SparseEmbeddingModel,
52};
53
54pub struct LocalOnnxProvider {
55 base_dir: Option<PathBuf>,
56 sessions: DashMap<String, Arc<raw::LoadedOnnxSession>>,
57}
58
59impl Default for LocalOnnxProvider {
60 fn default() -> Self {
61 Self::new()
62 }
63}
64
65impl LocalOnnxProvider {
66 pub fn new() -> Self {
67 Self {
68 base_dir: None,
69 sessions: DashMap::new(),
70 }
71 }
72
73 pub fn with_base_dir(mut self, base_dir: impl Into<PathBuf>) -> Self {
74 self.base_dir = Some(base_dir.into());
75 self
76 }
77}
78
79#[async_trait]
80impl ModelProvider for LocalOnnxProvider {
81 fn provider_id(&self) -> &'static str {
82 "local/onnx"
83 }
84
85 fn capabilities(&self) -> ProviderCapabilities {
86 ProviderCapabilities {
87 supported_tasks: vec![
88 ModelTask::Raw,
89 ModelTask::Rerank,
90 ModelTask::Embed,
91 ModelTask::Nlp,
92 ModelTask::EmbedImage,
93 ModelTask::Ocr,
94 ModelTask::DocumentExtract,
95 ModelTask::EmbedSparse,
96 ModelTask::EmbedMultiVector,
97 ModelTask::EmbedHybrid,
98 ],
99 }
100 }
101
102 async fn load(&self, spec: &ModelAliasSpec) -> Result<LoadedModelHandle> {
103 match spec.task {
104 ModelTask::Raw => {
105 let runner: Arc<dyn RawTensorModel> =
106 raw::load_raw(spec, self.base_dir.as_deref(), &self.sessions).await?;
107 Ok(Arc::new(runner) as LoadedModelHandle)
108 }
109 ModelTask::Rerank => {
110 let style = spec
111 .options
112 .get("style")
113 .and_then(|v| v.as_str())
114 .unwrap_or("cross-encoder");
115 let reranker: Arc<dyn RerankerModel> = match style {
116 "cross-encoder" => rerank::load_rerank(spec).await?,
117 "generative" => rerank_generative::load(spec).await?,
118 other => {
119 return Err(RuntimeError::Config(format!(
120 "Unknown rerank style '{other}' for alias '{}'; expected one of cross-encoder, generative",
121 spec.alias
122 )));
123 }
124 };
125 Ok(Arc::new(reranker) as LoadedModelHandle)
126 }
127 ModelTask::Embed => {
128 let embedder: Arc<dyn EmbeddingModel> = embedding::load_embedding(spec).await?;
129 Ok(Arc::new(embedder) as LoadedModelHandle)
130 }
131 ModelTask::Nlp => {
132 let model: Arc<dyn NlpModel> = nlp::load_nlp(spec).await?;
133 Ok(Arc::new(model) as LoadedModelHandle)
134 }
135 ModelTask::EmbedImage => {
136 let model: Arc<dyn ImageEmbeddingModel> =
137 image_embed::load_image_embedder(spec).await?;
138 Ok(Arc::new(model) as LoadedModelHandle)
139 }
140 ModelTask::Ocr => {
141 let model: Arc<dyn OcrModel> = ocr::load_ocr(spec).await?;
142 Ok(Arc::new(model) as LoadedModelHandle)
143 }
144 ModelTask::DocumentExtract => {
145 let model: Arc<dyn DocumentExtractionModel> =
146 document_extract::load_document_extractor(spec).await?;
147 Ok(Arc::new(model) as LoadedModelHandle)
148 }
149 ModelTask::EmbedSparse => {
150 let model: Arc<dyn SparseEmbeddingModel> =
151 embed_sparse::load_sparse_embedder(spec).await?;
152 Ok(Arc::new(model) as LoadedModelHandle)
153 }
154 ModelTask::EmbedMultiVector => {
155 let model: Arc<dyn MultiVectorEmbeddingModel> =
156 embed_multi_vector::load_multi_vector_embedder(spec).await?;
157 Ok(Arc::new(model) as LoadedModelHandle)
158 }
159 ModelTask::EmbedHybrid => {
160 let model: Arc<dyn HybridEmbeddingModel> =
161 embed_hybrid::load_hybrid_embedder(spec).await?;
162 Ok(Arc::new(model) as LoadedModelHandle)
163 }
164 _ => Err(RuntimeError::CapabilityMismatch(format!(
165 "ONNX provider does not support task {:?}",
166 spec.task
167 ))),
168 }
169 }
170
171 async fn health(&self) -> ProviderHealth {
172 ProviderHealth::Healthy
173 }
174}