diff --git a/README.md b/README.md
index b14ca71..50c3e15 100644
--- a/README.md
+++ b/README.md
@@ -35,7 +35,7 @@ aha is a high-performance, cross-platform AI inference engine built with Rust an
|----------|--------|
| **Text** | Qwen3, MiniCPM4, MiniCPM5, LFM2, LFM2.5 |
| **Vision** | Qwen2.5-VL, Qwen3-VL, Qwen3.5,
LFM2.5-VL, LFM2-VL |
-| **OCR** | DeepSeek-OCR, DeepSeek-OCR-2 , PaddleOCR-VL
PaddleOCR-VL1.5, Hunyuan-OCR, GLM-OCR |
+| **OCR** | DeepSeek-OCR, DeepSeek-OCR-2 , PaddleOCR-VL
PaddleOCR-VL1.5, PaddleOCR-VL1.5, Hunyuan-OCR
GLM-OCR |
| **ASR** | GLM-ASR-Nano, Fun-ASR-Nano, Qwen3-ASR |
| **TTS** | VoxCPM, VoxCPM1.5, VoxCPM2, Moss-TTS-Nano |
| **Image** | RMBG-2.0 (background removal) |
@@ -43,6 +43,9 @@ aha is a high-performance, cross-platform AI inference engine built with Rust an
| **Reranker** | Qwen3-Reranker |
## Changelog
+### 2026-06-06
+- add PaddleOCR-VL-1.6
+
### 2026-05-29
- generate code refactored
@@ -58,8 +61,6 @@ aha is a high-performance, cross-platform AI inference engine built with Rust an
### 2026-05-11
- add Moss-TTS-Nano,its performance is worse than the original Python version
-### 2026-05-09
-- merge pr/eastgold15/46, add aha-ui
**[View full changelog](docs/changelog.md)** →
diff --git a/README.zh-CN.md b/README.zh-CN.md
index 4cd56af..be413a8 100644
--- a/README.zh-CN.md
+++ b/README.zh-CN.md
@@ -42,6 +42,9 @@ aha 是一款基于 Rust 和 Candle 框架构建的高性能跨平台 AI 推理
| **重排序** | Qwen3-Reranker |
## 更新日志
+### 2026-06-06
+- 新增 PaddleOCR-VL-1.6
+
### 2026-05-29
- generate代码重构完成
@@ -57,10 +60,6 @@ aha 是一款基于 Rust 和 Candle 框架构建的高性能跨平台 AI 推理
### 2026-05-11
- 添加Moss-TTS-Nano,该模型比较小,计算误差影响较大,效果比python原版差
-### 2026-05-09
-- 合并 pr/eastgold15/46, 添加 aha-ui
-
-
**[查看完整更新日志](docs/changelog.zh-CN.md)** →
diff --git a/assets/img/aha_weixinqun.png b/assets/img/aha_weixinqun.png
index 511f74d..cac4457 100644
Binary files a/assets/img/aha_weixinqun.png and b/assets/img/aha_weixinqun.png differ
diff --git a/docs/changelog.md b/docs/changelog.md
index 7450b46..80bf065 100644
--- a/docs/changelog.md
+++ b/docs/changelog.md
@@ -5,6 +5,9 @@ All notable changes to aha will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+### 2026-06-06
+- add PaddleOCR-VL-1.6
+
### 2026-05-29
- generate code refactored
diff --git a/docs/changelog.zh-CN.md b/docs/changelog.zh-CN.md
index 4809833..84d1426 100644
--- a/docs/changelog.zh-CN.md
+++ b/docs/changelog.zh-CN.md
@@ -5,6 +5,9 @@
格式基于 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.0.0/),
本项目遵循 [语义化版本](https://semver.org/lang/zh-CN/spec/v2.0.0.html)。
+### 2026-06-06
+- 新增 PaddleOCR-VL-1.6
+
### 2026-05-29
- generate代码重构完成
diff --git a/docs/model-card.md b/docs/model-card.md
index 18e20e3..3fd0f78 100644
--- a/docs/model-card.md
+++ b/docs/model-card.md
@@ -3,7 +3,7 @@
#### Options prompt:
"OCR:" | "Table Recognition:" | "Formula Recognition:" | "Chart Recognition:"
-## PaddleOCR-VL1.5
+## PaddleOCR-VL1.5/1.6
#### Options prompt:
"OCR:" | "Table Recognition:" | "Formula Recognition:" | "Chart Recognition:" | "Spotting:" | "Seal Recognition:"
diff --git a/docs/model-card.zh-CN.md b/docs/model-card.zh-CN.md
index ce33964..69ba343 100644
--- a/docs/model-card.zh-CN.md
+++ b/docs/model-card.zh-CN.md
@@ -3,7 +3,7 @@
#### 可选提示词:
"OCR:" | "Table Recognition:" | "Formula Recognition:" | "Chart Recognition:"
-## PaddleOCR-VL1.5
+## PaddleOCR-VL1.5/1.6
#### 可选提示词:
"OCR:" | "Table Recognition:" | "Formula Recognition:" | "Chart Recognition:" | "Spotting:" | "Seal Recognition:"
diff --git a/src/cli/mod.rs b/src/cli/mod.rs
index d0a7cc9..82b43eb 100644
--- a/src/cli/mod.rs
+++ b/src/cli/mod.rs
@@ -298,7 +298,9 @@ pub(crate) fn run_run(args: RunArgs) -> anyhow::Result<()> {
WhichModel::HunyuanOCR => {
hunyuan_ocr::HunyuanORExec::run(&input, output.as_deref(), &weight_path)?;
}
- WhichModel::PaddleOCRVL | WhichModel::PaddleOCRVL1_5 => {
+ WhichModel::PaddleOCRVL
+ | WhichModel::PaddleOCRVL1_5
+ | WhichModel::PaddleOCRVL1_6 => {
paddleocr_vl::PaddleOVLExec::run(&input, output.as_deref(), &weight_path)?;
}
WhichModel::RMBG2_0 => {
diff --git a/src/models/common/model_mapping.rs b/src/models/common/model_mapping.rs
index 009833b..d0ec53f 100644
--- a/src/models/common/model_mapping.rs
+++ b/src/models/common/model_mapping.rs
@@ -72,6 +72,8 @@ pub enum WhichModel {
PaddleOCRVL,
#[value(name = "PaddlePaddle/PaddleOCR-VL-1.5")]
PaddleOCRVL1_5,
+ #[value(name = "PaddlePaddle/PaddleOCR-VL-1.6")]
+ PaddleOCRVL1_6,
#[value(name = "AI-ModelScope/RMBG-2.0")]
RMBG2_0,
#[value(name = "OpenBMB/VoxCPM-0.5B")]
@@ -165,7 +167,8 @@ impl WhichModel {
| WhichModel::HunyuanOCR
| WhichModel::GlmOCR
| WhichModel::PaddleOCRVL
- | WhichModel::PaddleOCRVL1_5 => "ocr",
+ | WhichModel::PaddleOCRVL1_5
+ | WhichModel::PaddleOCRVL1_6 => "ocr",
// ASR models
WhichModel::Qwen3ASR0_6B
| WhichModel::Qwen3ASR1_7B
diff --git a/src/models/mod.rs b/src/models/mod.rs
index 482257a..7a112af 100644
--- a/src/models/mod.rs
+++ b/src/models/mod.rs
@@ -284,7 +284,9 @@ pub fn load_model<'a>(
let model = HunyuanOCRGenerateModel::init(path, device, dtype)?;
ModelInstance::HunyuanOCR(model)
}
- WhichModel::PaddleOCRVL | WhichModel::PaddleOCRVL1_5 => {
+ WhichModel::PaddleOCRVL
+ | WhichModel::PaddleOCRVL1_5
+ | WhichModel::PaddleOCRVL1_6 => {
let model = PaddleOCRVLGenerateModel::init(path, device, dtype)?;
ModelInstance::PaddleOCRVL(Box::new(model))
}
diff --git a/tests/test_paddleocr_vl.rs b/tests/test_paddleocr_vl.rs
index a6ff2e6..84d7aa8 100644
--- a/tests/test_paddleocr_vl.rs
+++ b/tests/test_paddleocr_vl.rs
@@ -5,6 +5,55 @@ use aha::params::chat::ChatCompletionParameters;
use anyhow::Result;
use rocket::futures::StreamExt;
+#[test]
+fn paddleocr_vl_1_6_generate() -> Result<()> {
+ // RUST_BACKTRACE=1 cargo test -F cuda --test test_paddleocr_vl paddleocr_vl_1_6_generate -r -- --nocapture
+ let message = r#"
+ {
+ "model": "paddleocr_vl1.6",
+ "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.6/", 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_1_5_generate() -> Result<()> {
// RUST_BACKTRACE=1 cargo test -F cuda --test test_paddleocr_vl paddleocr_vl_1_5_generate -r -- --nocapture