diff --git a/docs/model-card.md b/docs/model-card.md
new file mode 100644
index 0000000..13f7462
--- /dev/null
+++ b/docs/model-card.md
@@ -0,0 +1,63 @@
+## PaddleOCR-VL
+#### Options prompt:
+"OCR:" | "Table Recognition:" | "Formula Recognition:" | "Chart Recognition:"
+
+## PaddleOCR-VL1.5
+#### Options prompt:
+"OCR:" | "Table Recognition:" | "Formula Recognition:" | "Chart Recognition:" | "Spotting:" | "Seal Recognition:"
+
+## DeepSeekOCR
+#### Metadata
+* base_size: 512 | 640 | 1024 | 1280
+* image_size: 512 | 640 | 1024 | 1280
+* crop_mode: false | true
+
+##### Example:
+```json
+{"base_size": "640", "image_size": "640", "crop_mode": "false"}
+```
+#### Processing Types
+| Type | base_size | image_size | crop_mode |
+|------|-----------|------------|-----------|
+| Tiny | 512 | 512 | false |
+| Small | 640 | 640 | false |
+| Base | 1024 | 1024 | false |
+| Large | 1280 | 1280 | false |
+| Gundam | 1024 | 640 | true |
+
+## GLM-OCR
+#### Prompt Limited
+##### Document Parsing prompt:
+"Text Recognition:" | "Formula Recognition:" | "Table Recognition:"
+###### Information Extraction:
+extract structured information from documents. Prompts must follow a strict JSON schema, For example, to extract personal ID information:
+```json
+Please output the information in the image in the following JSON format:
+{
+ "id_number": "",
+ "last_name": "",
+ "first_name": "",
+ "date_of_birth": "",
+ "address": {
+ "street": "",
+ "city": "",
+ "state": "",
+ "zip_code": ""
+ },
+ "dates": {
+ "issue_date": "",
+ "expiration_date": ""
+ },
+ "sex": ""
+}
+```
+
+## HunyuanOCR
+Application-oriented Prompts
+
+| Task | English | Chinese |
+|------|---------|---------|
+| Spotting | Detect and recognize text in the image, and output the text coordinates in a formatted manner. | 检测并识别图片中的文字,将文本坐标格式化输出。|
+| Parsing | 1. Identify the formula in the image and represent it using LaTeX format.
2.Parse the table in the image into HTML.
3. Parse the chart in the image; use Mermaid format for flowcharts and Markdown for other charts.
4.Extract all information from the main body of the document image and represent it in markdown format, ignoring headers and footers. Tables should be expressed in HTML format, formulas in the document should be represented using LaTeX format, and the parsing should be organized according to the reading order. | 1. 识别图片中的公式,用 LaTeX 格式表示。
2. 把图中的表格解析为 HTML。
3. 解析图中的图表,对于流程图使用 Mermaid 格式表示,其他图表使用 Markdown 格式表示。
4. 提取文档图片中正文的所有信息用 markdown 格式表示,其中页眉、页脚部分忽略,表格用 html 格式表达,文档中公式用 latex 格式表示,按照阅读顺序组织进行解析。 |
+| Information Extraction | 1. Output the value of Key.
2. Extract the content of the fields: ['key1','key2', ...] from the image and return it in JSON format.
3. Extract the subtitles from the image. | 1. 输出 Key 的值。
2. 提取图片中的: ['key1','key2', ...] 的字段内容,并按照 JSON 格式返回。
3. 提取图片中的字幕。 |
+| Translation | First extract the text, then translate the text content into English. If it is a document, ignore the header and footer. Formulas should be represented in LaTeX format, and tables should be represented in HTML format. | 先提取文字,再将文字内容翻译为英文。若是文档,则其中页眉、页脚忽略。公式用latex格式表示,表格用html格式表示。 |
diff --git a/docs/model-card.zh-CN.md b/docs/model-card.zh-CN.md
new file mode 100644
index 0000000..fd4e062
--- /dev/null
+++ b/docs/model-card.zh-CN.md
@@ -0,0 +1,63 @@
+## PaddleOCR-VL
+#### 可选提示词:
+"OCR:" | "Table Recognition:" | "Formula Recognition:" | "Chart Recognition:"
+
+## PaddleOCR-VL1.5
+#### 可选提示词:
+"OCR:" | "Table Recognition:" | "Formula Recognition:" | "Chart Recognition:" | "Spotting:" | "Seal Recognition:"
+
+## DeepSeekOCR
+#### Metadata
+* base_size: 512 | 640 | 1024 | 1280
+* image_size: 512 | 640 | 1024 | 1280
+* crop_mode: false | true
+
+##### 示例:
+```json
+{"base_size": "640", "image_size": "640", "crop_mode": "false"}
+```
+#### 处理模式
+| Type | base_size | image_size | crop_mode |
+|------|-----------|------------|-----------|
+| Tiny | 512 | 512 | false |
+| Small | 640 | 640 | false |
+| Base | 1024 | 1024 | false |
+| Large | 1280 | 1280 | false |
+| Gundam | 1024 | 640 | true |
+
+## GLM-OCR
+#### 限定提示词
+##### 文档解析:
+"Text Recognition:" | "Formula Recognition:" | "Table Recognition:"
+###### 信息提取:
+extract structured information from documents. Prompts must follow a strict JSON schema, For example, to extract personal ID information:
+```json
+请以以下 JSON 格式输出图像中的信息:
+{
+ "id_number": "",
+ "last_name": "",
+ "first_name": "",
+ "date_of_birth": "",
+ "address": {
+ "street": "",
+ "city": "",
+ "state": "",
+ "zip_code": ""
+ },
+ "dates": {
+ "issue_date": "",
+ "expiration_date": ""
+ },
+ "sex": ""
+}
+```
+
+## HunyuanOCR
+场景化提示词
+
+| 任务 | 英文 | 中文 |
+|------|---------|---------|
+| 检测 | Detect and recognize text in the image, and output the text coordinates in a formatted manner. | 检测并识别图片中的文字,将文本坐标格式化输出。|
+| 解析 | 1. Identify the formula in the image and represent it using LaTeX format.
2.Parse the table in the image into HTML.
3. Parse the chart in the image; use Mermaid format for flowcharts and Markdown for other charts.
4.Extract all information from the main body of the document image and represent it in markdown format, ignoring headers and footers. Tables should be expressed in HTML format, formulas in the document should be represented using LaTeX format, and the parsing should be organized according to the reading order. | 1. 识别图片中的公式,用 LaTeX 格式表示。
2. 把图中的表格解析为 HTML。
3. 解析图中的图表,对于流程图使用 Mermaid 格式表示,其他图表使用 Markdown 格式表示。
4. 提取文档图片中正文的所有信息用 markdown 格式表示,其中页眉、页脚部分忽略,表格用 html 格式表达,文档中公式用 latex 格式表示,按照阅读顺序组织进行解析。 |
+| 信息提取 | 1. Output the value of Key.
2. Extract the content of the fields: ['key1','key2', ...] from the image and return it in JSON format.
3. Extract the subtitles from the image. | 1. 输出 Key 的值。
2. 提取图片中的: ['key1','key2', ...] 的字段内容,并按照 JSON 格式返回。
3. 提取图片中的字幕。 |
+| 翻译 | First extract the text, then translate the text content into English. If it is a document, ignore the header and footer. Formulas should be represented in LaTeX format, and tables should be represented in HTML format. | 先提取文字,再将文字内容翻译为英文。若是文档,则其中页眉、页脚忽略。公式用latex格式表示,表格用html格式表示。 |
diff --git a/src/api/mod.rs b/src/api/mod.rs
index f8181f0..b0fb7fd 100644
--- a/src/api/mod.rs
+++ b/src/api/mod.rs
@@ -264,6 +264,7 @@ fn which_model_to_id(which_model: WhichModel) -> &'static str {
WhichModel::DeepSeekOCR => "deepseek-ocr",
WhichModel::HunyuanOCR => "hunyuan-ocr",
WhichModel::PaddleOCRVL => "paddleocr-vl",
+ WhichModel::PaddleOCRVL1_5 => "paddleocr-vl1.5",
WhichModel::RMBG2_0 => "rmbg2.0",
WhichModel::VoxCPM => "voxcpm",
WhichModel::VoxCPM1_5 => "voxcpm1.5",
@@ -290,7 +291,7 @@ fn which_model_to_owner(which_model: WhichModel) -> &'static str {
| WhichModel::Qwen3_5_9B => "Qwen",
WhichModel::DeepSeekOCR => "deepseek-ai",
WhichModel::HunyuanOCR => "Tencent-Hunyuan",
- WhichModel::PaddleOCRVL => "PaddlePaddle",
+ WhichModel::PaddleOCRVL | WhichModel::PaddleOCRVL1_5 => "PaddlePaddle",
WhichModel::RMBG2_0 => "AI-ModelScope",
WhichModel::VoxCPM | WhichModel::VoxCPM1_5 => "OpenBMB",
WhichModel::GlmASRNano2512 | WhichModel::GlmOCR => "ZhipuAI",
diff --git a/src/main.rs b/src/main.rs
index 27ec4a5..9787ca6 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -260,6 +260,7 @@ fn run_list(args: ListArgs) -> anyhow::Result<()> {
WhichModel::DeepSeekOCR,
WhichModel::HunyuanOCR,
WhichModel::PaddleOCRVL,
+ WhichModel::PaddleOCRVL1_5,
WhichModel::RMBG2_0,
WhichModel::VoxCPM,
WhichModel::VoxCPM1_5,
@@ -527,6 +528,10 @@ fn run_run(args: RunArgs) -> anyhow::Result<()> {
use aha::exec::paddleocr_vl::PaddleOVLExec;
PaddleOVLExec::run(&input, output.as_deref(), &weight_path)?;
}
+ WhichModel::PaddleOCRVL1_5 => {
+ use aha::exec::paddleocr_vl::PaddleOVLExec;
+ PaddleOVLExec::run(&input, output.as_deref(), &weight_path)?;
+ }
WhichModel::RMBG2_0 => {
use aha::exec::rmbg2_0::RMBG2_0Exec;
RMBG2_0Exec::run(&input, output.as_deref(), &weight_path)?;
diff --git a/src/models/mod.rs b/src/models/mod.rs
index 2e6ea3a..1c8230a 100644
--- a/src/models/mod.rs
+++ b/src/models/mod.rs
@@ -74,6 +74,8 @@ pub enum WhichModel {
HunyuanOCR,
#[value(name = "paddleocr-vl", hide = true)]
PaddleOCRVL,
+ #[value(name = "paddleocr-vl1.5", hide = true)]
+ PaddleOCRVL1_5,
#[value(name = "rmbg2.0")]
RMBG2_0,
#[value(name = "voxcpm", hide = true)]
@@ -110,6 +112,7 @@ impl WhichModel {
WhichModel::DeepSeekOCR => "deepseek-ai/DeepSeek-OCR",
WhichModel::HunyuanOCR => "Tencent-Hunyuan/HunyuanOCR",
WhichModel::PaddleOCRVL => "PaddlePaddle/PaddleOCR-VL",
+ WhichModel::PaddleOCRVL1_5 => "PaddlePaddle/PaddleOCR-VL-1.5",
WhichModel::RMBG2_0 => "AI-ModelScope/RMBG-2.0",
WhichModel::VoxCPM => "OpenBMB/VoxCPM-0.5B",
WhichModel::VoxCPM1_5 => "OpenBMB/VoxCPM1.5",
@@ -139,7 +142,8 @@ impl WhichModel {
WhichModel::DeepSeekOCR
| WhichModel::HunyuanOCR
| WhichModel::GlmOCR
- | WhichModel::PaddleOCRVL => "ocr",
+ | WhichModel::PaddleOCRVL
+ | WhichModel::PaddleOCRVL1_5 => "ocr",
// ASR models
WhichModel::Qwen3ASR0_6B
| WhichModel::Qwen3ASR1_7B
@@ -316,6 +320,10 @@ pub fn load_model<'a>(
let model = PaddleOCRVLGenerateModel::init(path, None, None)?;
ModelInstance::PaddleOCRVL(Box::new(model))
}
+ WhichModel::PaddleOCRVL1_5 => {
+ let model = PaddleOCRVLGenerateModel::init(path, None, None)?;
+ ModelInstance::PaddleOCRVL(Box::new(model))
+ }
WhichModel::RMBG2_0 => {
let model = RMBG2_0Model::init(path, None, None)?;
ModelInstance::RMBG2_0(Box::new(model))
diff --git a/tests/test_paddleocr_vl.rs b/tests/test_paddleocr_vl.rs
index 3afe232..d530d37 100644
--- a/tests/test_paddleocr_vl.rs
+++ b/tests/test_paddleocr_vl.rs
@@ -5,6 +5,55 @@ use aha_openai_dive::v1::resources::chat::ChatCompletionParameters;
use anyhow::Result;
use rocket::futures::StreamExt;
+#[test]
+fn paddleocr_vl_1_5_generate() -> Result<()> {
+ // RUST_BACKTRACE=1 cargo test -F cuda --test test_paddleocr_vl paddleocr_vl_1_5_generate -r -- --nocapture
+ let message = r#"
+ {
+ "model": "paddleocr_vl1.5",
+ "messages": [
+ {
+ "role": "user",
+ "content": [
+ {
+ "type": "image",
+ "image_url":
+ {
+ "url": "file://./assets/img/ocr_test1.png"
+ }
+ },
+ {
+ "type": "text",
+ "text": "Spotting:"
+ }
+ ]
+ }
+ ],
+ "stream": false
+ }
+ "#;
+ let save_dir =
+ aha::utils::get_default_save_dir().ok_or(anyhow::anyhow!("Failed to get save dir"))?;
+ let model_path = format!("{}/PaddlePaddle/PaddleOCR-VL-1.5/", save_dir);
+ let mes: ChatCompletionParameters = serde_json::from_str(message)?;
+ let i_start = Instant::now();
+ let mut model = PaddleOCRVLGenerateModel::init(&model_path, None, None)?;
+ let i_duration = i_start.elapsed();
+ println!("Time elapsed in load model is: {:?}", i_duration);
+ let i_start = Instant::now();
+ let res = model.generate(mes)?;
+ let i_duration = i_start.elapsed();
+ println!("generate: \n {:?}", res);
+ if let Some(usage) = &res.usage {
+ let num_token = usage.total_tokens;
+ let duration_secs = i_duration.as_secs_f64();
+ let tps = num_token as f64 / duration_secs;
+ println!("Tokens per second (TPS): {:.2}", tps);
+ }
+ println!("Time elapsed in generate is: {:?}", i_duration);
+ Ok(())
+}
+
#[test]
fn paddleocr_vl_generate() -> Result<()> {
// RUST_BACKTRACE=1 cargo test -F cuda --test test_paddleocr_vl paddleocr_vl_generate -r -- --nocapture