2026-04-06 15:35:49 +08:00
|
|
|
pub mod all_minilm_l6_v2;
|
2026-02-14 15:52:30 +08:00
|
|
|
pub mod bigvgan;
|
2026-01-30 22:04:23 +08:00
|
|
|
pub mod campplus;
|
2026-02-05 00:43:49 +08:00
|
|
|
pub mod common;
|
2025-11-22 23:27:14 +08:00
|
|
|
pub mod deepseek_ocr;
|
2026-01-30 22:04:23 +08:00
|
|
|
pub mod feature_extractor;
|
2026-01-15 21:57:12 +08:00
|
|
|
pub mod fun_asr_nano;
|
2026-01-07 21:46:01 +08:00
|
|
|
pub mod glm_asr_nano;
|
2026-03-05 23:49:49 -05:00
|
|
|
pub mod glm_ocr;
|
2025-12-03 17:21:01 +08:00
|
|
|
pub mod hunyuan_ocr;
|
2026-03-23 22:09:20 +08:00
|
|
|
pub mod lfm2;
|
2026-03-27 11:16:31 +08:00
|
|
|
pub mod lfm2vl;
|
2026-01-30 22:04:23 +08:00
|
|
|
pub mod mask_gct;
|
2025-09-25 12:25:24 +08:00
|
|
|
pub mod minicpm4;
|
2025-12-09 00:41:30 +08:00
|
|
|
pub mod paddleocr_vl;
|
2026-03-18 19:15:21 +08:00
|
|
|
pub mod qwen2;
|
2025-09-25 12:25:24 +08:00
|
|
|
pub mod qwen2_5vl;
|
2026-01-15 21:57:12 +08:00
|
|
|
pub mod qwen3;
|
2026-03-05 21:57:03 +08:00
|
|
|
pub mod qwen3_5;
|
2026-02-02 21:30:52 +08:00
|
|
|
pub mod qwen3_asr;
|
2026-04-06 15:35:49 +08:00
|
|
|
pub mod qwen3_embedding;
|
2026-04-06 17:48:15 +08:00
|
|
|
pub mod qwen3_reranker;
|
2025-10-26 21:39:23 +08:00
|
|
|
pub mod qwen3vl;
|
2025-12-12 20:40:57 +08:00
|
|
|
pub mod rmbg2_0;
|
2025-12-23 19:23:21 +08:00
|
|
|
pub mod voxcpm;
|
2026-01-30 22:04:23 +08:00
|
|
|
pub mod w2v_bert_2_0;
|
2025-09-25 12:09:25 +08:00
|
|
|
|
2026-03-31 18:45:01 +08:00
|
|
|
use crate::{
|
2026-04-06 15:35:49 +08:00
|
|
|
models::{
|
|
|
|
|
all_minilm_l6_v2::AllMiniLML6V2Embedding,
|
2026-04-06 17:48:15 +08:00
|
|
|
common::{embedding::TextEmbedding, model_mapping::WhichModel, reranker::TextRerank},
|
2026-04-06 15:35:49 +08:00
|
|
|
qwen3_embedding::Qwen3Embedding,
|
2026-04-06 17:48:15 +08:00
|
|
|
qwen3_reranker::Qwen3Reranker,
|
2026-04-06 15:35:49 +08:00
|
|
|
},
|
2026-03-31 18:45:01 +08:00
|
|
|
params::chat::{ChatCompletionChunkResponse, ChatCompletionParameters, ChatCompletionResponse},
|
2025-09-22 23:58:08 +08:00
|
|
|
};
|
2026-03-17 15:39:34 +08:00
|
|
|
use anyhow::{Result, anyhow};
|
2026-04-06 15:35:49 +08:00
|
|
|
use candle_core::{DType, Device};
|
2025-09-22 23:49:58 +08:00
|
|
|
use rocket::futures::Stream;
|
2025-09-22 16:38:12 +08:00
|
|
|
|
2025-11-05 14:46:03 +08:00
|
|
|
use crate::models::{
|
2026-03-23 22:09:20 +08:00
|
|
|
deepseek_ocr::generate::DeepseekOCRGenerateModel,
|
|
|
|
|
fun_asr_nano::generate::FunAsrNanoGenerateModel,
|
|
|
|
|
glm_asr_nano::generate::GlmAsrNanoGenerateModel, glm_ocr::generate::GlmOcrGenerateModel,
|
|
|
|
|
hunyuan_ocr::generate::HunyuanOCRGenerateModel, lfm2::generate::Lfm2GenerateModel,
|
2026-03-30 00:44:41 +08:00
|
|
|
lfm2vl::generate::Lfm2VLGenerateModel, minicpm4::generate::MiniCPMGenerateModel,
|
|
|
|
|
paddleocr_vl::generate::PaddleOCRVLGenerateModel, qwen2_5vl::generate::Qwen2_5VLGenerateModel,
|
|
|
|
|
qwen3::generate::Qwen3GenerateModel, qwen3_5::generate::Qwen3_5GenerateModel,
|
|
|
|
|
qwen3_asr::generate::Qwen3AsrGenerateModel, qwen3vl::generate::Qwen3VLGenerateModel,
|
|
|
|
|
rmbg2_0::generate::RMBG2_0Model, voxcpm::generate::VoxCPMGenerate,
|
2025-11-05 14:46:03 +08:00
|
|
|
};
|
|
|
|
|
|
2025-09-22 16:38:12 +08:00
|
|
|
pub trait GenerateModel {
|
2025-09-22 23:49:58 +08:00
|
|
|
fn generate(&mut self, mes: ChatCompletionParameters) -> Result<ChatCompletionResponse>;
|
2025-09-22 23:58:08 +08:00
|
|
|
fn generate_stream(
|
|
|
|
|
&mut self,
|
|
|
|
|
mes: ChatCompletionParameters,
|
2025-11-05 14:46:03 +08:00
|
|
|
) -> Result<
|
|
|
|
|
Box<
|
|
|
|
|
dyn Stream<Item = Result<ChatCompletionChunkResponse, anyhow::Error>>
|
|
|
|
|
+ Send
|
|
|
|
|
+ Unpin
|
|
|
|
|
+ '_,
|
|
|
|
|
>,
|
|
|
|
|
>;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub enum ModelInstance<'a> {
|
2026-04-06 15:35:49 +08:00
|
|
|
AllMiniLML6V2(AllMiniLML6V2Embedding),
|
2025-11-05 14:46:03 +08:00
|
|
|
MiniCPM4(MiniCPMGenerateModel<'a>),
|
2026-03-23 22:07:41 +08:00
|
|
|
Lfm2(Lfm2GenerateModel<'a>),
|
2026-03-30 00:44:41 +08:00
|
|
|
Lfm2VL(Lfm2VLGenerateModel<'a>),
|
2025-11-05 14:46:03 +08:00
|
|
|
Qwen2_5VL(Qwen2_5VLGenerateModel<'a>),
|
2026-01-15 21:57:12 +08:00
|
|
|
Qwen3(Qwen3GenerateModel<'a>),
|
2026-03-05 21:57:03 +08:00
|
|
|
Qwen3_5(Qwen3_5GenerateModel<'a>),
|
2026-02-05 00:43:49 +08:00
|
|
|
Qwen3ASR(Qwen3AsrGenerateModel<'a>),
|
2026-04-06 15:35:49 +08:00
|
|
|
Qwen3Embedding(Qwen3Embedding),
|
2026-04-06 17:48:15 +08:00
|
|
|
Qwen3Reranker(Qwen3Reranker),
|
2026-03-16 14:50:59 +08:00
|
|
|
Qwen3VL(Box<Qwen3VLGenerateModel<'a>>),
|
2025-11-27 14:28:47 +08:00
|
|
|
DeepSeekOCR(DeepseekOCRGenerateModel),
|
2025-12-03 17:21:01 +08:00
|
|
|
HunyuanOCR(HunyuanOCRGenerateModel<'a>),
|
2025-12-09 00:41:30 +08:00
|
|
|
PaddleOCRVL(Box<PaddleOCRVLGenerateModel<'a>>),
|
2025-12-25 20:25:52 +08:00
|
|
|
RMBG2_0(Box<RMBG2_0Model>),
|
|
|
|
|
VoxCPM(Box<VoxCPMGenerate>),
|
2026-01-07 21:46:01 +08:00
|
|
|
GlmASRNano(GlmAsrNanoGenerateModel<'a>),
|
2026-01-15 21:57:12 +08:00
|
|
|
FunASRNano(FunAsrNanoGenerateModel),
|
2026-03-07 18:08:06 +08:00
|
|
|
GlmOCR(GlmOcrGenerateModel),
|
2025-11-05 14:46:03 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<'a> GenerateModel for ModelInstance<'a> {
|
|
|
|
|
fn generate(&mut self, mes: ChatCompletionParameters) -> Result<ChatCompletionResponse> {
|
|
|
|
|
match self {
|
2026-04-06 15:35:49 +08:00
|
|
|
ModelInstance::AllMiniLML6V2(_) => {
|
|
|
|
|
Err(anyhow!("embedding model does not support chat completions"))
|
|
|
|
|
}
|
2025-11-05 14:46:03 +08:00
|
|
|
ModelInstance::MiniCPM4(model) => model.generate(mes),
|
2026-03-23 22:07:41 +08:00
|
|
|
ModelInstance::Lfm2(model) => model.generate(mes),
|
2026-03-30 00:44:41 +08:00
|
|
|
ModelInstance::Lfm2VL(model) => model.generate(mes),
|
2025-11-05 14:46:03 +08:00
|
|
|
ModelInstance::Qwen2_5VL(model) => model.generate(mes),
|
2026-01-15 21:57:12 +08:00
|
|
|
ModelInstance::Qwen3(model) => model.generate(mes),
|
2026-04-06 18:23:23 +08:00
|
|
|
|
2026-04-06 15:35:49 +08:00
|
|
|
ModelInstance::Qwen3Embedding(_) => {
|
|
|
|
|
Err(anyhow!("embedding model does not support chat completions"))
|
|
|
|
|
}
|
2026-04-06 17:48:15 +08:00
|
|
|
ModelInstance::Qwen3Reranker(_) => {
|
|
|
|
|
Err(anyhow!("reranker model does not support chat completions"))
|
|
|
|
|
}
|
2026-03-05 21:57:03 +08:00
|
|
|
ModelInstance::Qwen3_5(model) => model.generate(mes),
|
2026-04-06 18:23:23 +08:00
|
|
|
|
2026-02-05 00:43:49 +08:00
|
|
|
ModelInstance::Qwen3ASR(model) => model.generate(mes),
|
2025-11-05 14:46:03 +08:00
|
|
|
ModelInstance::Qwen3VL(model) => model.generate(mes),
|
2025-11-27 14:28:47 +08:00
|
|
|
ModelInstance::DeepSeekOCR(model) => model.generate(mes),
|
2025-12-03 17:21:01 +08:00
|
|
|
ModelInstance::HunyuanOCR(model) => model.generate(mes),
|
2025-12-09 00:41:30 +08:00
|
|
|
ModelInstance::PaddleOCRVL(model) => model.generate(mes),
|
2025-12-25 20:25:52 +08:00
|
|
|
ModelInstance::RMBG2_0(model) => model.generate(mes),
|
|
|
|
|
ModelInstance::VoxCPM(model) => model.generate(mes),
|
2026-01-07 21:46:01 +08:00
|
|
|
ModelInstance::GlmASRNano(model) => model.generate(mes),
|
2026-01-15 21:57:12 +08:00
|
|
|
ModelInstance::FunASRNano(model) => model.generate(mes),
|
2026-03-05 23:49:49 -05:00
|
|
|
ModelInstance::GlmOCR(model) => model.generate(mes),
|
2025-11-05 14:46:03 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn generate_stream(
|
|
|
|
|
&mut self,
|
|
|
|
|
mes: ChatCompletionParameters,
|
|
|
|
|
) -> Result<
|
|
|
|
|
Box<
|
|
|
|
|
dyn Stream<Item = Result<ChatCompletionChunkResponse, anyhow::Error>>
|
|
|
|
|
+ Send
|
|
|
|
|
+ Unpin
|
|
|
|
|
+ '_,
|
|
|
|
|
>,
|
|
|
|
|
> {
|
|
|
|
|
match self {
|
2026-04-06 15:35:49 +08:00
|
|
|
ModelInstance::AllMiniLML6V2(_) => {
|
|
|
|
|
Err(anyhow!("embedding model does not support chat completions"))
|
|
|
|
|
}
|
2025-11-05 14:46:03 +08:00
|
|
|
ModelInstance::MiniCPM4(model) => model.generate_stream(mes),
|
2026-03-23 22:07:41 +08:00
|
|
|
ModelInstance::Lfm2(model) => model.generate_stream(mes),
|
2026-03-30 00:44:41 +08:00
|
|
|
ModelInstance::Lfm2VL(model) => model.generate_stream(mes),
|
2025-11-05 14:46:03 +08:00
|
|
|
ModelInstance::Qwen2_5VL(model) => model.generate_stream(mes),
|
2026-01-15 21:57:12 +08:00
|
|
|
ModelInstance::Qwen3(model) => model.generate_stream(mes),
|
2026-04-06 18:23:23 +08:00
|
|
|
|
2026-04-06 15:35:49 +08:00
|
|
|
ModelInstance::Qwen3Embedding(_) => Err(anyhow!(
|
|
|
|
|
"embedding model does not support streaming chat completions"
|
|
|
|
|
)),
|
2026-03-24 16:18:39 +08:00
|
|
|
ModelInstance::Qwen3Reranker(_) => Err(anyhow!(
|
|
|
|
|
"reranker model does not support streaming chat completions"
|
|
|
|
|
)),
|
2026-03-05 21:57:03 +08:00
|
|
|
ModelInstance::Qwen3_5(model) => model.generate_stream(mes),
|
2026-02-05 00:43:49 +08:00
|
|
|
ModelInstance::Qwen3ASR(model) => model.generate_stream(mes),
|
2025-11-05 14:46:03 +08:00
|
|
|
ModelInstance::Qwen3VL(model) => model.generate_stream(mes),
|
2025-11-27 14:28:47 +08:00
|
|
|
ModelInstance::DeepSeekOCR(model) => model.generate_stream(mes),
|
2025-12-03 17:21:01 +08:00
|
|
|
ModelInstance::HunyuanOCR(model) => model.generate_stream(mes),
|
2025-12-09 00:41:30 +08:00
|
|
|
ModelInstance::PaddleOCRVL(model) => model.generate_stream(mes),
|
2025-12-25 20:25:52 +08:00
|
|
|
ModelInstance::RMBG2_0(model) => model.generate_stream(mes),
|
|
|
|
|
ModelInstance::VoxCPM(model) => model.generate_stream(mes),
|
2026-01-07 21:46:01 +08:00
|
|
|
ModelInstance::GlmASRNano(model) => model.generate_stream(mes),
|
2026-01-15 21:57:12 +08:00
|
|
|
ModelInstance::FunASRNano(model) => model.generate_stream(mes),
|
2026-03-05 23:49:49 -05:00
|
|
|
ModelInstance::GlmOCR(model) => model.generate_stream(mes),
|
2025-11-05 14:46:03 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-06 15:35:49 +08:00
|
|
|
impl<'a> ModelInstance<'a> {
|
|
|
|
|
pub fn embedding(&mut self, input: &[String]) -> Result<Vec<Vec<f32>>> {
|
|
|
|
|
match self {
|
|
|
|
|
ModelInstance::Qwen3Embedding(model) => model.embed_texts(input),
|
|
|
|
|
ModelInstance::AllMiniLML6V2(model) => model.embed_texts(input),
|
|
|
|
|
_ => Err(anyhow!("current model does not support embeddings")),
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-04-06 17:48:15 +08:00
|
|
|
pub fn rerank(&mut self, query: &str, documents: &[String]) -> Result<Vec<f32>> {
|
|
|
|
|
match self {
|
|
|
|
|
ModelInstance::Qwen3Reranker(model) => model.rerank(query, documents),
|
|
|
|
|
_ => Err(anyhow!("current model does not support rerank")),
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-04-06 15:35:49 +08:00
|
|
|
}
|
|
|
|
|
|
2026-04-03 20:43:51 +08:00
|
|
|
#[allow(unused)]
|
|
|
|
|
pub fn load_gguf_model<'a>(
|
2026-03-17 15:39:34 +08:00
|
|
|
model_type: WhichModel,
|
2026-04-03 20:43:51 +08:00
|
|
|
config_path: Option<&str>, // 有些gguf未包含模型其他配置,需额外指定
|
|
|
|
|
gguf_path: &str,
|
|
|
|
|
mmproj_path: Option<&str>,
|
2026-04-06 15:35:49 +08:00
|
|
|
device: Option<&Device>,
|
2026-03-17 15:39:34 +08:00
|
|
|
) -> Result<ModelInstance<'a>> {
|
2026-04-03 20:43:51 +08:00
|
|
|
let model = match model_type {
|
|
|
|
|
WhichModel::Qwen3_5Gguf => {
|
2026-04-06 15:35:49 +08:00
|
|
|
let model = Qwen3_5GenerateModel::init_from_gguf(gguf_path, mmproj_path, device)?;
|
2026-04-03 20:43:51 +08:00
|
|
|
ModelInstance::Qwen3_5(model)
|
|
|
|
|
}
|
|
|
|
|
_ => {
|
|
|
|
|
let model_id = model_type.as_string();
|
|
|
|
|
return Err(anyhow!("model id {model_id} is not gguf model"));
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
Ok(model)
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-06 15:35:49 +08:00
|
|
|
pub fn load_model<'a>(
|
|
|
|
|
model_type: WhichModel,
|
|
|
|
|
path: &str,
|
|
|
|
|
device: Option<&Device>,
|
|
|
|
|
dtype: Option<DType>,
|
|
|
|
|
) -> Result<ModelInstance<'a>> {
|
2025-11-05 14:46:03 +08:00
|
|
|
let model = match model_type {
|
2026-04-06 15:35:49 +08:00
|
|
|
WhichModel::AllMiniLML6V2 => {
|
|
|
|
|
let model = AllMiniLML6V2Embedding::init(path, device, dtype)?;
|
|
|
|
|
ModelInstance::AllMiniLML6V2(model)
|
|
|
|
|
}
|
2025-11-05 14:46:03 +08:00
|
|
|
WhichModel::MiniCPM4_0_5B => {
|
2026-04-06 15:35:49 +08:00
|
|
|
let model = MiniCPMGenerateModel::init(path, device, dtype)?;
|
2025-11-05 14:46:03 +08:00
|
|
|
ModelInstance::MiniCPM4(model)
|
|
|
|
|
}
|
2026-04-06 15:35:49 +08:00
|
|
|
WhichModel::LFM2_1_2B | WhichModel::LFM2_5_1_2BInstruct => {
|
|
|
|
|
let model = Lfm2GenerateModel::init(path, device, dtype)?;
|
2026-03-23 22:07:41 +08:00
|
|
|
ModelInstance::Lfm2(model)
|
|
|
|
|
}
|
2026-04-10 23:06:09 +08:00
|
|
|
WhichModel::LFM2_5VL1_6B | WhichModel::LFM2VL1_6B | WhichModel::LFM2_5VL450M => {
|
2026-04-06 15:35:49 +08:00
|
|
|
let model = Lfm2VLGenerateModel::init(path, device, dtype)?;
|
2026-03-30 00:44:41 +08:00
|
|
|
ModelInstance::Lfm2VL(model)
|
|
|
|
|
}
|
2026-04-06 15:35:49 +08:00
|
|
|
WhichModel::Qwen2_5VL3B | WhichModel::Qwen2_5VL7B => {
|
|
|
|
|
let model = Qwen2_5VLGenerateModel::init(path, device, dtype)?;
|
2025-11-05 14:46:03 +08:00
|
|
|
ModelInstance::Qwen2_5VL(model)
|
|
|
|
|
}
|
2026-04-06 15:35:49 +08:00
|
|
|
WhichModel::Qwen3_0_6B | WhichModel::Qwen3_1_7B | WhichModel::Qwen3_4B => {
|
|
|
|
|
let model = Qwen3GenerateModel::init(path, device, dtype)?;
|
2026-01-15 21:57:12 +08:00
|
|
|
ModelInstance::Qwen3(model)
|
|
|
|
|
}
|
2026-04-06 15:35:49 +08:00
|
|
|
WhichModel::Qwen3_5_0_8B
|
|
|
|
|
| WhichModel::Qwen3_5_2B
|
|
|
|
|
| WhichModel::Qwen3_5_4B
|
|
|
|
|
| WhichModel::Qwen3_5_9B => {
|
|
|
|
|
let model = Qwen3_5GenerateModel::init(path, device, dtype)?;
|
2026-03-05 21:57:03 +08:00
|
|
|
ModelInstance::Qwen3_5(model)
|
|
|
|
|
}
|
2026-04-06 15:35:49 +08:00
|
|
|
WhichModel::Qwen3ASR0_6B | WhichModel::Qwen3ASR1_7B => {
|
|
|
|
|
let model = Qwen3AsrGenerateModel::init(path, device, dtype)?;
|
2026-02-05 00:43:49 +08:00
|
|
|
ModelInstance::Qwen3ASR(model)
|
|
|
|
|
}
|
2026-04-06 15:35:49 +08:00
|
|
|
WhichModel::Qwen3Embedding0_6B
|
|
|
|
|
| WhichModel::Qwen3Embedding4B
|
|
|
|
|
| WhichModel::Qwen3Embedding8B => {
|
|
|
|
|
let model = Qwen3Embedding::init(path, device, dtype)?;
|
|
|
|
|
ModelInstance::Qwen3Embedding(model)
|
|
|
|
|
}
|
2026-04-06 17:48:15 +08:00
|
|
|
WhichModel::Qwen3Reranker0_6B
|
|
|
|
|
| WhichModel::Qwen3Reranker4B
|
|
|
|
|
| WhichModel::Qwen3Reranker8B => {
|
|
|
|
|
let model = Qwen3Reranker::init(path, device, dtype)?;
|
|
|
|
|
ModelInstance::Qwen3Reranker(model)
|
|
|
|
|
}
|
2026-04-06 15:35:49 +08:00
|
|
|
WhichModel::Qwen3VL2B
|
|
|
|
|
| WhichModel::Qwen3VL4B
|
|
|
|
|
| WhichModel::Qwen3VL8B
|
|
|
|
|
| WhichModel::Qwen3VL32B => {
|
|
|
|
|
let model = Qwen3VLGenerateModel::init(path, device, dtype)?;
|
2026-03-16 14:50:59 +08:00
|
|
|
ModelInstance::Qwen3VL(Box::new(model))
|
2025-11-13 01:03:52 +08:00
|
|
|
}
|
2026-04-06 15:35:49 +08:00
|
|
|
WhichModel::DeepSeekOCR | WhichModel::DeepSeekOCR2 => {
|
|
|
|
|
let model = DeepseekOCRGenerateModel::init(path, device, dtype)?;
|
2026-03-18 19:15:21 +08:00
|
|
|
ModelInstance::DeepSeekOCR(model)
|
|
|
|
|
}
|
2025-12-03 17:21:01 +08:00
|
|
|
WhichModel::HunyuanOCR => {
|
2026-04-06 15:35:49 +08:00
|
|
|
let model = HunyuanOCRGenerateModel::init(path, device, dtype)?;
|
2025-12-03 17:21:01 +08:00
|
|
|
ModelInstance::HunyuanOCR(model)
|
|
|
|
|
}
|
2026-04-06 15:35:49 +08:00
|
|
|
WhichModel::PaddleOCRVL | WhichModel::PaddleOCRVL1_5 => {
|
|
|
|
|
let model = PaddleOCRVLGenerateModel::init(path, device, dtype)?;
|
2026-03-17 21:30:50 +08:00
|
|
|
ModelInstance::PaddleOCRVL(Box::new(model))
|
2025-12-09 00:41:30 +08:00
|
|
|
}
|
2025-12-25 20:25:52 +08:00
|
|
|
WhichModel::RMBG2_0 => {
|
2026-04-06 15:35:49 +08:00
|
|
|
let model = RMBG2_0Model::init(path, device, dtype)?;
|
2025-12-25 20:25:52 +08:00
|
|
|
ModelInstance::RMBG2_0(Box::new(model))
|
|
|
|
|
}
|
2026-04-08 18:55:03 +08:00
|
|
|
WhichModel::VoxCPM | WhichModel::VoxCPM1_5 | WhichModel::VoxCPM2 => {
|
2026-04-06 15:35:49 +08:00
|
|
|
let model = VoxCPMGenerate::init(path, device, dtype)?;
|
2025-12-25 20:25:52 +08:00
|
|
|
ModelInstance::VoxCPM(Box::new(model))
|
|
|
|
|
}
|
2026-01-07 21:46:01 +08:00
|
|
|
WhichModel::GlmASRNano2512 => {
|
2026-04-06 15:35:49 +08:00
|
|
|
let model = GlmAsrNanoGenerateModel::init(path, device, dtype)?;
|
2026-01-07 21:46:01 +08:00
|
|
|
ModelInstance::GlmASRNano(model)
|
|
|
|
|
}
|
2026-01-15 21:57:12 +08:00
|
|
|
WhichModel::FunASRNano2512 => {
|
2026-04-06 15:35:49 +08:00
|
|
|
let model = FunAsrNanoGenerateModel::init(path, device, dtype)?;
|
2026-01-15 21:57:12 +08:00
|
|
|
ModelInstance::FunASRNano(model)
|
|
|
|
|
}
|
2026-03-05 23:49:49 -05:00
|
|
|
WhichModel::GlmOCR => {
|
2026-04-06 15:35:49 +08:00
|
|
|
let model = GlmOcrGenerateModel::init(path, device, dtype)?;
|
2026-03-05 23:49:49 -05:00
|
|
|
ModelInstance::GlmOCR(model)
|
|
|
|
|
}
|
2026-04-03 20:43:51 +08:00
|
|
|
_ => {
|
|
|
|
|
let model_id = model_type.as_string();
|
2026-04-06 15:35:49 +08:00
|
|
|
if model_id.to_lowercase().contains("gguf") || model_id.to_lowercase().contains("onnx")
|
|
|
|
|
{
|
|
|
|
|
return Err(anyhow!("model id {model_id} is not safetensor model"));
|
|
|
|
|
} else {
|
|
|
|
|
return Err(anyhow!("model id {model_id} not impl load_model function"));
|
|
|
|
|
}
|
2026-04-03 20:43:51 +08:00
|
|
|
}
|
2025-11-05 14:46:03 +08:00
|
|
|
};
|
|
|
|
|
Ok(model)
|
2025-09-22 16:38:12 +08:00
|
|
|
}
|