2025-10-10 23:25:25 +08:00
|
|
|
pub mod common;
|
2025-11-22 23:27:14 +08:00
|
|
|
pub mod deepseek_ocr;
|
2025-12-03 17:21:01 +08:00
|
|
|
pub mod hunyuan_ocr;
|
2025-09-25 12:25:24 +08:00
|
|
|
pub mod minicpm4;
|
2025-12-09 00:41:30 +08:00
|
|
|
pub mod paddleocr_vl;
|
2025-09-25 12:25:24 +08:00
|
|
|
pub mod qwen2_5vl;
|
2025-10-26 21:39:23 +08:00
|
|
|
pub mod qwen3vl;
|
2025-10-26 21:57:53 +08:00
|
|
|
pub mod voxcpm;
|
2025-09-25 12:09:25 +08:00
|
|
|
|
2025-10-27 10:55:40 +08:00
|
|
|
use aha_openai_dive::v1::resources::chat::{
|
2025-09-22 23:58:08 +08:00
|
|
|
ChatCompletionChunkResponse, ChatCompletionParameters, ChatCompletionResponse,
|
|
|
|
|
};
|
2025-10-27 10:55:40 +08:00
|
|
|
use anyhow::Result;
|
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::{
|
2025-12-03 17:21:01 +08:00
|
|
|
deepseek_ocr::generate::DeepseekOCRGenerateModel,
|
|
|
|
|
hunyuan_ocr::generate::HunyuanOCRGenerateModel, minicpm4::generate::MiniCPMGenerateModel,
|
2025-12-09 00:41:30 +08:00
|
|
|
paddleocr_vl::generate::PaddleOCRVLGenerateModel, qwen2_5vl::generate::Qwen2_5VLGenerateModel,
|
|
|
|
|
qwen3vl::generate::Qwen3VLGenerateModel,
|
2025-11-05 14:46:03 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, clap::ValueEnum)]
|
|
|
|
|
pub enum WhichModel {
|
|
|
|
|
#[value(name = "minicpm4-0.5b")]
|
|
|
|
|
MiniCPM4_0_5B,
|
|
|
|
|
#[value(name = "qwen2.5vl-3b")]
|
|
|
|
|
Qwen2_5vl3B,
|
2025-11-12 03:20:55 -10:00
|
|
|
#[value(name = "qwen2.5vl-7b")]
|
|
|
|
|
Qwen2_5vl7B,
|
2025-11-05 14:46:03 +08:00
|
|
|
#[value(name = "qwen3vl-2b")]
|
|
|
|
|
Qwen3vl2B,
|
2025-11-12 03:20:55 -10:00
|
|
|
#[value(name = "qwen3vl-4b")]
|
|
|
|
|
Qwen3vl4B,
|
|
|
|
|
#[value(name = "qwen3vl-8b")]
|
|
|
|
|
Qwen3vl8B,
|
|
|
|
|
#[value(name = "qwen3vl-32b")]
|
|
|
|
|
Qwen3vl32B,
|
2025-11-27 14:28:47 +08:00
|
|
|
#[value(name = "deepseek-ocr")]
|
|
|
|
|
DeepSeekOCR,
|
2025-12-03 17:21:01 +08:00
|
|
|
#[value(name = "hunyuan-ocr")]
|
|
|
|
|
HunyuanOCR,
|
2025-12-09 00:41:30 +08:00
|
|
|
#[value(name = "paddleocr-vl")]
|
|
|
|
|
PaddleOCRVL,
|
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> {
|
|
|
|
|
MiniCPM4(MiniCPMGenerateModel<'a>),
|
|
|
|
|
Qwen2_5VL(Qwen2_5VLGenerateModel<'a>),
|
|
|
|
|
Qwen3VL(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-11-05 14:46:03 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<'a> GenerateModel for ModelInstance<'a> {
|
|
|
|
|
fn generate(&mut self, mes: ChatCompletionParameters) -> Result<ChatCompletionResponse> {
|
|
|
|
|
match self {
|
|
|
|
|
ModelInstance::MiniCPM4(model) => model.generate(mes),
|
|
|
|
|
ModelInstance::Qwen2_5VL(model) => model.generate(mes),
|
|
|
|
|
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-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 {
|
|
|
|
|
ModelInstance::MiniCPM4(model) => model.generate_stream(mes),
|
|
|
|
|
ModelInstance::Qwen2_5VL(model) => model.generate_stream(mes),
|
|
|
|
|
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-11-05 14:46:03 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn load_model(model_type: WhichModel, path: &str) -> Result<ModelInstance<'_>> {
|
|
|
|
|
let model = match model_type {
|
|
|
|
|
WhichModel::MiniCPM4_0_5B => {
|
|
|
|
|
let model = MiniCPMGenerateModel::init(path, None, None)?;
|
|
|
|
|
ModelInstance::MiniCPM4(model)
|
|
|
|
|
}
|
|
|
|
|
WhichModel::Qwen2_5vl3B => {
|
|
|
|
|
let model = Qwen2_5VLGenerateModel::init(path, None, None)?;
|
|
|
|
|
ModelInstance::Qwen2_5VL(model)
|
|
|
|
|
}
|
2025-11-12 03:20:55 -10:00
|
|
|
WhichModel::Qwen2_5vl7B => {
|
|
|
|
|
let model = Qwen2_5VLGenerateModel::init(path, None, None)?;
|
|
|
|
|
ModelInstance::Qwen2_5VL(model)
|
|
|
|
|
}
|
2025-11-05 14:46:03 +08:00
|
|
|
WhichModel::Qwen3vl2B => {
|
|
|
|
|
let model = Qwen3VLGenerateModel::init(path, None, None)?;
|
|
|
|
|
ModelInstance::Qwen3VL(model)
|
2025-11-13 01:03:52 +08:00
|
|
|
}
|
2025-11-12 03:20:55 -10:00
|
|
|
WhichModel::Qwen3vl4B => {
|
|
|
|
|
let model = Qwen3VLGenerateModel::init(path, None, None)?;
|
|
|
|
|
ModelInstance::Qwen3VL(model)
|
2025-11-13 01:03:52 +08:00
|
|
|
}
|
2025-11-12 03:20:55 -10:00
|
|
|
WhichModel::Qwen3vl8B => {
|
|
|
|
|
let model = Qwen3VLGenerateModel::init(path, None, None)?;
|
|
|
|
|
ModelInstance::Qwen3VL(model)
|
2025-11-13 01:03:52 +08:00
|
|
|
}
|
2025-11-12 03:20:55 -10:00
|
|
|
WhichModel::Qwen3vl32B => {
|
|
|
|
|
let model = Qwen3VLGenerateModel::init(path, None, None)?;
|
|
|
|
|
ModelInstance::Qwen3VL(model)
|
2025-11-05 14:46:03 +08:00
|
|
|
}
|
2025-11-27 14:28:47 +08:00
|
|
|
WhichModel::DeepSeekOCR => {
|
|
|
|
|
let model = DeepseekOCRGenerateModel::init(path, None, None)?;
|
|
|
|
|
ModelInstance::DeepSeekOCR(model)
|
|
|
|
|
}
|
2025-12-03 17:21:01 +08:00
|
|
|
WhichModel::HunyuanOCR => {
|
|
|
|
|
let model = HunyuanOCRGenerateModel::init(path, None, None)?;
|
|
|
|
|
ModelInstance::HunyuanOCR(model)
|
|
|
|
|
}
|
2025-12-09 00:41:30 +08:00
|
|
|
WhichModel::PaddleOCRVL => {
|
|
|
|
|
let model = PaddleOCRVLGenerateModel::init(path, None, None)?;
|
|
|
|
|
ModelInstance::PaddleOCRVL(Box::new(model))
|
|
|
|
|
}
|
2025-11-05 14:46:03 +08:00
|
|
|
};
|
|
|
|
|
Ok(model)
|
2025-09-22 16:38:12 +08:00
|
|
|
}
|