From 3e3036099899f75ca0cdd5ba88fa48577f4c3f64 Mon Sep 17 00:00:00 2001
From: jhqxxx <18280426169@163.com>
Date: Fri, 10 Apr 2026 23:06:09 +0800
Subject: [PATCH] fix LiquidAI/LFM2.5-VL-450M chat_template load bug
---
README.md | 10 +++-------
README.zh-CN.md | 10 +++-------
docs/changelog.md | 3 +++
docs/changelog.zh-CN.md | 3 +++
docs/supported-models.md | 3 ++-
docs/supported-models.zh-CN.md | 2 +-
scripts/download_and_run.sh | 4 ++++
src/chat_template/mod.rs | 9 ++++++++-
src/cli/mod.rs | 2 +-
src/models/common/model_mapping.rs | 5 ++++-
src/models/mod.rs | 2 +-
tests/test_lfm2vl.rs | 3 ++-
tests/test_voxcpm2.rs | 14 ++++++++++----
13 files changed, 45 insertions(+), 25 deletions(-)
diff --git a/README.md b/README.md
index 018b131..0822e41 100644
--- a/README.md
+++ b/README.md
@@ -49,6 +49,9 @@ aha is a high-performance, cross-platform AI inference engine built with Rust an
- **🧠 Attention Optimization** - Optional Flash Attention support for optimized long sequence processing
## Changelog
+### 2026-04-10
+- fix LiquidAI/LFM2.5-VL-450M chat_template load bug
+
### 2026-04-08
- add VoxCPM2
@@ -75,13 +78,6 @@ aha is a high-performance, cross-platform AI inference engine built with Rust an
- Usage add time info
- dependencies delete aha_openai_dive,chrono
-### 2026-03-30
-- add LFM2.5VL-1.6B
-- add LFM2VL-1.6B
-
-### v0.2.4 (2026-03-23)
-- add LFM2.5-1.2B-Instruct
-- add LFM2-1.2B
**[View full changelog](docs/changelog.md)** →
diff --git a/README.zh-CN.md b/README.zh-CN.md
index 98f40c1..4a3d0f6 100644
--- a/README.zh-CN.md
+++ b/README.zh-CN.md
@@ -47,6 +47,9 @@ aha 是一款基于 Rust 和 Candle 框架构建的高性能跨平台 AI 推理
- **🧠 注意力优化** - 可选 Flash Attention 支持,优化长序列处理
## 更新日志
+### 2026-04-10
+- 修复 LiquidAI/LFM2.5-VL-450M chat_template 加载bug
+
### 2026-04-08
- 添加 VoxCPM2
@@ -74,13 +77,6 @@ aha 是一款基于 Rust 和 Candle 框架构建的高性能跨平台 AI 推理
- Usage 增加时间信息
- 删除 aha_openai_dive, chrono 依赖
-### 2026-03-30
-- 新增 LFM2.5VL-1.6B
-- 新增 LFM2VL-1.6B
-
-### v0.2.4 (2026-03-23)
-- 新增 LFM2.5-1.2B-Instruct
-- 新增 LFM2-1.2B
**[查看完整更新日志](docs/changelog.zh-CN.md)** →
diff --git a/docs/changelog.md b/docs/changelog.md
index 21beaff..47f8aaf 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-04-10
+- fix LiquidAI/LFM2.5-VL-450M chat_template load bug
+
### 2026-04-08
- add VoxCPM2
diff --git a/docs/changelog.zh-CN.md b/docs/changelog.zh-CN.md
index 64aaf5c..2c60aba 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-04-10
+- 修复 LiquidAI/LFM2.5-VL-450M chat_template 加载bug
+
### 2026-04-08
- 添加 VoxCPM2
diff --git a/docs/supported-models.md b/docs/supported-models.md
index 746b4ce..a8f8d41 100644
--- a/docs/supported-models.md
+++ b/docs/supported-models.md
@@ -78,9 +78,10 @@ ZhipuAI/GLM-OCR ZhipuAI ocr ✔
| **Qwen2.5-VL** | 3B
7B | Qwen/Qwen2.5-VL-3B-Instruct
Qwen/Qwen2.5-VL-7B-Instruct | [Qwen 研究许可协议](https://huggingface.co/Qwen/Qwen2.5-VL-3B-Instruct/blob/main/LICENSE)
[Apache 2.0](https://huggingface.co/datasets/choosealicense/licenses/blob/main/markdown/apache-2.0.md) |
| **Qwen3-VL** | 2B
4B
8B
32B | Qwen/Qwen3-VL-2B-Instruct
Qwen/Qwen3-VL-4B-Instruct
Qwen/Qwen3-VL-8B-Instruct
Qwen/Qwen3-VL-32B-Instruct | [Apache 2.0](https://huggingface.co/datasets/choosealicense/licenses/blob/main/markdown/apache-2.0.md) |
| **Qwen3.5** | 0.8B
2B
4B
9B | Qwen/Qwen3.5-0.8B
Qwen/Qwen3.5-2B
Qwen/Qwen3.5-4B
Qwen/Qwen3.5-9B | [Apache 2.0](https://huggingface.co/datasets/choosealicense/licenses/blob/main/markdown/apache-2.0.md) |
-| **LFM2.5-VL-1.6B** | 1.6B | LiquidAI/LFM2.5-VL-1.6B | [lfm1.0](https://huggingface.co/LiquidAI/LFM2.5-1.2B-Instruct/blob/main/LICENSE) |
+| **LFM2.5-VL** | 450M
1.6B | LiquidAI/LFM2.5-VL-450M
LiquidAI/LFM2.5-VL-1.6B | [lfm1.0](https://huggingface.co/LiquidAI/LFM2.5-1.2B-Instruct/blob/main/LICENSE) |
| **LFM2-VL-1.6B** | 1.6B | LiquidAI/LFM2-VL-1.6B | [lfm1.0](https://huggingface.co/LiquidAI/LFM2.5-1.2B-Instruct/blob/main/LICENSE) |
+
## OCR
| Model | Languages | Model Id | License |
diff --git a/docs/supported-models.zh-CN.md b/docs/supported-models.zh-CN.md
index d48dda3..d6c219c 100644
--- a/docs/supported-models.zh-CN.md
+++ b/docs/supported-models.zh-CN.md
@@ -77,7 +77,7 @@ ZhipuAI/GLM-OCR ZhipuAI ocr ✔
| **Qwen2.5-VL** | 3B
7B | Qwen/Qwen2.5-VL-3B-Instruct
Qwen/Qwen2.5-VL-7B-Instruct | [Qwen 研究许可协议](https://huggingface.co/Qwen/Qwen2.5-VL-3B-Instruct/blob/main/LICENSE)
[Apache 2.0](https://huggingface.co/datasets/choosealicense/licenses/blob/main/markdown/apache-2.0.md) |
| **Qwen3-VL** | 2B
4B
8B
32B | Qwen/Qwen3-VL-2B-Instruct
Qwen/Qwen3-VL-4B-Instruct
Qwen/Qwen3-VL-8B-Instruct
Qwen/Qwen3-VL-32B-Instruct | [Apache 2.0](https://huggingface.co/datasets/choosealicense/licenses/blob/main/markdown/apache-2.0.md) |
| **Qwen3.5** | 0.8B
2B
4B
9B | Qwen/Qwen3.5-0.8B
Qwen/Qwen3.5-2B
Qwen/Qwen3.5-4B
Qwen/Qwen3.5-9B | [Apache 2.0](https://huggingface.co/datasets/choosealicense/licenses/blob/main/markdown/apache-2.0.md) |
-| **LFM2.5-VL-1.6B** | 1.6B | LiquidAI/LFM2.5-VL-1.6B | [lfm1.0](https://huggingface.co/LiquidAI/LFM2.5-1.2B-Instruct/blob/main/LICENSE) |
+| **LFM2.5-VL** | 450M
1.6B | LiquidAI/LFM2.5-VL-450M
LiquidAI/LFM2.5-VL-1.6B | [lfm1.0](https://huggingface.co/LiquidAI/LFM2.5-1.2B-Instruct/blob/main/LICENSE) |
| **LFM2-VL-1.6B** | 1.6B | LiquidAI/LFM2-VL-1.6B | [lfm1.0](https://huggingface.co/LiquidAI/LFM2.5-1.2B-Instruct/blob/main/LICENSE) |
## OCR
diff --git a/scripts/download_and_run.sh b/scripts/download_and_run.sh
index 30efafe..a51bd72 100755
--- a/scripts/download_and_run.sh
+++ b/scripts/download_and_run.sh
@@ -18,6 +18,7 @@ show_help() {
echo " LiquidAI/LFM2-1.2B"
echo " LiquidAI/LFM2.5-1.2B-Instruct"
echo " LiquidAI/LFM2.5-VL-1.6B"
+ echo " LiquidAI/LFM2.5-VL-450M"
echo " LiquidAI/LFM2-VL-1.6B"
echo " OpenBMB/MiniCPM4-0.5B"
echo " Qwen/Qwen2.5-VL-3B-Instruct"
@@ -79,6 +80,9 @@ case $MODEL_ALIAS in
;;
"LiquidAI/LFM2.5-VL-1.6B")
MODEL_ID="LiquidAI/LFM2.5-VL-1.6B"
+ ;;
+ "LiquidAI/LFM2.5-VL-450M")
+ MODEL_ID="LiquidAI/LFM2.5-VL-450M"
;;
"LiquidAI/LFM2-VL-1.6B")
MODEL_ID="LiquidAI/LFM2-VL-1.6B"
diff --git a/src/chat_template/mod.rs b/src/chat_template/mod.rs
index c680d5f..efa179c 100644
--- a/src/chat_template/mod.rs
+++ b/src/chat_template/mod.rs
@@ -30,6 +30,8 @@ pub fn fix_template(chat_template: &str) -> String {
"content.lstrip('\\n')",
"content | lstrip('\\n')", // 使用自定义的过滤器替换
)
+ .replace("{%- generation -%}", "") // MiniJinja 不支持 generation 和 endgeneration
+ .replace("{%- endgeneration -%}", "")
}
pub fn get_template(path: String) -> Result {
@@ -104,6 +106,9 @@ impl<'a> ChatTemplate<'a> {
Some(chars_str) => s.trim_end_matches(chars_str.as_str()).to_string(),
None => s.trim_end().to_string(),
});
+
+ // 添加 string filter
+ env.add_filter("string", |v: MiniJinjaValue| -> String { format!("{}", v) });
}
pub fn init(path: &str) -> Result {
let path: String = path.to_string();
@@ -112,10 +117,12 @@ impl<'a> ChatTemplate<'a> {
}
let template = get_template(path.clone())?;
let template = string_to_static_str(template);
+ // println!("template: {}", template);
// 加载jinjaenv处理chat_template
let mut env = Environment::new();
Self::setup_environment(&mut env);
- let _ = env.add_template("chat", template);
+ env.add_template("chat", template)?;
+ // println!("env: {:?}", env);
Ok(Self { env })
}
diff --git a/src/cli/mod.rs b/src/cli/mod.rs
index 27cf70a..6f71100 100644
--- a/src/cli/mod.rs
+++ b/src/cli/mod.rs
@@ -247,7 +247,7 @@ pub(crate) fn run_run(args: RunArgs) -> anyhow::Result<()> {
WhichModel::LFM2_1_2B | WhichModel::LFM2_5_1_2BInstruct => {
lfm2::Lfm2Exec::run(&input, output.as_deref(), &weight_path)?;
}
- WhichModel::LFM2_5VL1_6B | WhichModel::LFM2VL1_6B => {
+ WhichModel::LFM2_5VL1_6B | WhichModel::LFM2VL1_6B | WhichModel::LFM2_5VL450M => {
lfm2vl::Lfm2VLExec::run(&input, output.as_deref(), &weight_path)?;
}
WhichModel::Qwen2_5VL3B | WhichModel::Qwen2_5VL7B => {
diff --git a/src/models/common/model_mapping.rs b/src/models/common/model_mapping.rs
index 7d38e37..dc06db2 100644
--- a/src/models/common/model_mapping.rs
+++ b/src/models/common/model_mapping.rs
@@ -10,6 +10,8 @@ pub enum WhichModel {
LFM2_5_1_2BInstruct,
#[value(name = "LiquidAI/LFM2.5-VL-1.6B")]
LFM2_5VL1_6B,
+ #[value(name = "LiquidAI/LFM2.5-VL-450M")]
+ LFM2_5VL450M,
#[value(name = "LiquidAI/LFM2-VL-1.6B")]
LFM2VL1_6B,
#[value(name = "OpenBMB/MiniCPM4-0.5B")]
@@ -152,7 +154,8 @@ impl WhichModel {
| WhichModel::Qwen3_5_9B
| WhichModel::Qwen3_5Gguf
| WhichModel::LFM2_5VL1_6B
- | WhichModel::LFM2VL1_6B => "vlm",
+ | WhichModel::LFM2VL1_6B
+ | WhichModel::LFM2_5VL450M => "vlm",
// OCR models
WhichModel::DeepSeekOCR
| WhichModel::DeepSeekOCR2
diff --git a/src/models/mod.rs b/src/models/mod.rs
index b2d0ec7..dd4511b 100644
--- a/src/models/mod.rs
+++ b/src/models/mod.rs
@@ -218,7 +218,7 @@ pub fn load_model<'a>(
let model = Lfm2GenerateModel::init(path, device, dtype)?;
ModelInstance::Lfm2(model)
}
- WhichModel::LFM2_5VL1_6B | WhichModel::LFM2VL1_6B => {
+ WhichModel::LFM2_5VL1_6B | WhichModel::LFM2VL1_6B | WhichModel::LFM2_5VL450M => {
let model = Lfm2VLGenerateModel::init(path, device, dtype)?;
ModelInstance::Lfm2VL(model)
}
diff --git a/tests/test_lfm2vl.rs b/tests/test_lfm2vl.rs
index 8ab7150..6a3bab4 100644
--- a/tests/test_lfm2vl.rs
+++ b/tests/test_lfm2vl.rs
@@ -12,8 +12,9 @@ fn lfm2vl_generate() -> Result<()> {
let save_dir =
aha::utils::get_default_save_dir().ok_or(anyhow::anyhow!("Failed to get save dir"))?;
- let model_path = format!("{}/LiquidAI/LFM2.5-VL-1.6B/", save_dir);
+ // let model_path = format!("{}/LiquidAI/LFM2.5-VL-1.6B/", save_dir);
// let model_path = format!("{}/LiquidAI/LFM2-VL-1.6B/", save_dir);
+ let model_path = format!("{}/LiquidAI/LFM2.5-VL-450M/", save_dir);
let message = r#"
{
"model": "lfm2vl",
diff --git a/tests/test_voxcpm2.rs b/tests/test_voxcpm2.rs
index 8c054ab..f80dfaa 100644
--- a/tests/test_voxcpm2.rs
+++ b/tests/test_voxcpm2.rs
@@ -20,15 +20,21 @@ fn voxcpm2_use_message_generate() -> Result<()> {
"messages": [
{
"role": "user",
- "content": [
+ "content": [
+ {
+ "type": "audio",
+ "audio_url":
+ {
+ "url": "https://package-release.coderbox.cn/aiway/test/other/%E5%93%AA%E5%90%92.wav"
+ }
+ },
{
"type": "text",
- "text": "哎呀姐姐,好久没看到你了,来来来坐坐坐,我给你摆个龙门阵。你莫看我这两天闲得很,上个月我可是搞了个大事情。"
+ "text": "你好,这是aha在说话"
}
]
}
- ],
- "metadata": {"control_instruction": "四川话,男生"}
+ ]
}
"#;
let mes: ChatCompletionParameters = serde_json::from_str(message)?;