Image-Text-to-Text
Transformers
Safetensors
Chinese
English
minicpmv4_7
tool-calling
function-calling
agent
multimodal
chinese
conversational
Instructions to use whcl412/FinchAI-Rune1-Preview-f16 with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use whcl412/FinchAI-Rune1-Preview-f16 with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("image-text-to-text", model="whcl412/FinchAI-Rune1-Preview-f16") messages = [ { "role": "user", "content": [ {"type": "image", "url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/p-blog/candy.JPG"}, {"type": "text", "text": "What animal is on the candy?"} ] }, ] pipe(text=messages)# pip install -U transformers accelerate # Load model directly from transformers import AutoProcessor, AutoModelForMultimodalLM processor = AutoProcessor.from_pretrained("whcl412/FinchAI-Rune1-Preview-f16") model = AutoModelForMultimodalLM.from_pretrained("whcl412/FinchAI-Rune1-Preview-f16", device_map="auto") messages = [ { "role": "user", "content": [ {"type": "image", "url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/p-blog/candy.JPG"}, {"type": "text", "text": "What animal is on the candy?"} ] }, ] inputs = processor.apply_chat_template( messages, add_generation_prompt=True, tokenize=True, return_dict=True, return_tensors="pt", ).to(model.device) outputs = model.generate(**inputs, max_new_tokens=256) print(processor.decode(outputs[0][inputs["input_ids"].shape[-1]:])) - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use whcl412/FinchAI-Rune1-Preview-f16 with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "whcl412/FinchAI-Rune1-Preview-f16" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "whcl412/FinchAI-Rune1-Preview-f16", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Describe this image in one sentence." }, { "type": "image_url", "image_url": { "url": "https://cdn.britannica.com/61/93061-050-99147DCE/Statue-of-Liberty-Island-New-York-Bay.jpg" } } ] } ] }'Use Docker
docker model run hf.co/whcl412/FinchAI-Rune1-Preview-f16
- SGLang
How to use whcl412/FinchAI-Rune1-Preview-f16 with SGLang:
Install from pip and serve model
# Install SGLang from pip: pip install sglang # Start the SGLang server: python3 -m sglang.launch_server \ --model-path "whcl412/FinchAI-Rune1-Preview-f16" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "whcl412/FinchAI-Rune1-Preview-f16", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Describe this image in one sentence." }, { "type": "image_url", "image_url": { "url": "https://cdn.britannica.com/61/93061-050-99147DCE/Statue-of-Liberty-Island-New-York-Bay.jpg" } } ] } ] }'Use Docker images
docker run --gpus all \ --shm-size 32g \ -p 30000:30000 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ --env "HF_TOKEN=<secret>" \ --ipc=host \ lmsysorg/sglang:latest \ python3 -m sglang.launch_server \ --model-path "whcl412/FinchAI-Rune1-Preview-f16" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "whcl412/FinchAI-Rune1-Preview-f16", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Describe this image in one sentence." }, { "type": "image_url", "image_url": { "url": "https://cdn.britannica.com/61/93061-050-99147DCE/Statue-of-Liberty-Island-New-York-Bay.jpg" } } ] } ] }' - Docker Model Runner
How to use whcl412/FinchAI-Rune1-Preview-f16 with Docker Model Runner:
docker model run hf.co/whcl412/FinchAI-Rune1-Preview-f16
File size: 9,984 Bytes
f5b0b3a e5f98db ce27ff7 e5f98db | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 | ---
license: apache-2.0
base_model: openbmb/MiniCPM-V-4.7-1B
library_name: transformers
pipeline_tag: image-text-to-text
language:
- zh
- en
tags:
- tool-calling
- function-calling
- agent
- multimodal
- chinese
---
# FinchAI-Rune1-Preview
> 首个 **FinchAI** 系列模型。底座 [MiniCPM-V 4.7-1B](https://huggingface.co/openbmb/MiniCPM-V-4.7-1B)(面壁智能 OpenBMB),
> 用 LoRA 微调而成,**重点是工具调用时的「判断力」**。
| | |
|---|---|
| **本仓库** | `-f16`(bfloat16 完整权重,2.9 GB) |
| **能力范围** | 文本 + **视觉**(多模态完整) |
| **加载方式** | `AutoModelForImageTextToText`(transformers ≥ 5.18.0) |
| **许可** | Apache 2.0 |
**这是当前唯一发布的版本,也是能力最完整的一份**:含视觉塔,可继续微调、可二次量化。
(GGUF 转换已验证可行,但导出的 GGUF 不含视觉,与「最完整」的定位不符,故暂不单独发布。)
---
## 一、这是什么
一个 1.55B 的本地小助手,专攻**什么时候该调工具、该调哪个**。
大多数小模型的工具调用只学会了「看到工具就调」或者「照抄工具名」。
Rune1-Preview 训练的重点是**判断**:
| 场景 | 期望行为 |
|---|---|
| 用户给了完整参数 | **直接调**,不要再问 |
| 用户漏了必填参数 | **反问**,不要瞎猜一个去试 |
| 两个工具都「能看文件」 | 按语义**选对**那个(按内容筛 vs 列目录) |
| 问题根本不需要工具 | **不调**,直接回答 |
| 调用报错了 | 读错误、**改对再来**,而不是放弃或硬编 |
## 二、验收数据(微调前 vs 微调后)
同一份基座权重,靠切换 adapter 跑两遍,27 条探针:
| 组 | 微调后 | 基座 |
|---|---|---|
| **判断力**(该不该调 / 要不要反问 / 选哪个) | **9/9** | 3/9 |
| 身份 | **3/3** | 0/3 |
| 留出沙箱(训练时从未见过的工具) | **6/6** | 6/6 |
| 已训沙箱 | **6/6** | 6/6 |
| 通用(问答 / 代码 / 拒绝) | **3/3** | 3/3 |
| **合计** | **27/27** | 21/27 |
**净增量 = 判断力 +6、身份 +3,合计 +9 项。**
其中有代表性的对比:
```
问:帮我看下目录里有什么文件。 (没给路径)
微调后 → 「哪个目录?给我具体路径,我就去看。」 ✓ 反问
基座 → 直接拿一个猜的路径去调了 ✗
问:D:/inbox 里哪些文件提到 error? (两个工具都能碰文件)
微调后 → 调用搜索工具 seek_* ✓ 选对
基座 → 调用列表工具 catalog_* ✗ 选错(但看起来"能跑")
```
### 关于「留出沙箱」
**留出沙箱 = 训练时结构上不可能产出样本的沙箱**(生成器里直接抛异常拦截)。
它存在的意义是给「数据有没有泄漏」一个硬指标:
模型在那些**从未见过的工具名、路径、参数 schema** 上也能正确调用,
说明它学的是「读工具定义、按语义选」,而不是把训练时见过的名字背下来。
## 三、快速开始
### transformers
```bash
pip install "transformers>=5.18.0" torch accelerate
```
```python
from transformers import AutoProcessor, AutoModelForImageTextToText
model_id = "whcl412/FinchAI-Rune1-Preview-f16"
proc = AutoProcessor.from_pretrained(model_id)
model = AutoModelForImageTextToText.from_pretrained(
model_id, dtype="bfloat16", device_map="auto")
tools = [{"type": "function", "function": {
"name": "list_files", "description": "列出目录内容",
"parameters": {"type": "object",
"properties": {"path": {"type": "string", "description": "目录路径"}},
"required": ["path"]}}}]
msgs = [{"role": "user", "content": "看下 /var/log 里有哪些文件。"}]
text = proc.apply_chat_template(msgs, tools=tools, tokenize=False,
add_generation_prompt=True)
out = model.generate(**proc(text=[text], return_tensors="pt").to(model.device),
max_new_tokens=256, do_sample=False)
print(proc.tokenizer.decode(out[0], skip_special_tokens=True))
```
**工具调用的输出格式是 XML:**
```
<tool_call>
<function=list_files>
<parameter=path>
/var/log
</parameter>
</function>
</tool_call>
```
思考内容走 `reasoning_content`(不在 `content` 里)。
### Ollama / llama.cpp
**尚未发布。** GGUF 转换本身已验证可行(llama.cpp 自 2026-10-17 起支持
`MiniCPMV4_7ForConditionalGeneration`),但导出的 GGUF **不含视觉能力**
(LoRA 只训了文本主干),与「最完整版本」的定位不符,因此暂不单独发布。
⚠️ **两个必须知道的限制**:
1. 我们**没有发布 MLX 4bit 版本** —— 底座架构 `minicpmv4_7` 不被 `mlx_lm` 支持
(连最新 main 都没有)。Apple Silicon 用户请走 transformers,MPS 实测可用
(训练峰值内存 6.5 GB)。
2. 全链路(加载 / 微调 / 融合)**只在 Apple Silicon 的 MPS 上验证过**,未在 CUDA 上实测。
## 四、能力边界
**擅长**
- 本地 agent 的「工具选择大脑」——判断该不该调、调哪个、参数够不够
- 读一份没见过的工具定义并按它调用
- 简短、不谄媚的中文/英文回答
**不擅长**
- 复杂多步推理和算法设计(1B 容量限制)
- 长文档理解(训练时序列 ≤950 token)
- 视觉任务——底座支持图像输入,但**本版 LoRA 只训了文本主干**,视觉能力未经强化
**实测性能**(MacBook Pro M4 / 16 GB,MPS)
| 项目 | 数值 |
|---|---|
| 权重体积 | 2.9 GB(bfloat16) |
| 加载后常驻内存 | ~3.1 GB |
| 训练/推理峰值 | ~6.5 GB |
| 训练速度 | 2.2~3.5 s/样本(≤950 token) |
**已知问题**
| # | 问题 | 规避 |
|---|---|---|
| 1 | 没有 MLX 4bit 版(底座架构不被 `mlx_lm` 支持) | Apple Silicon 走 transformers + MPS |
| 2 | 未发布 GGUF(转出来的不含视觉能力) | 要视觉就用本仓库的 f16 |
| 3 | 输出里偶发游离的 `</think>` 标签 | 宿主输出前过滤 |
| 4 | 思考文案带模板生成痕迹(如中英混排) | 不影响功能 |
| 5 | **偶发工具名幻觉**(吐出不在列表里的名字) | **宿主分发必须查注册表,绝不直接执行** |
| 6 | **工具结果不足时会编数字** | 让工具返回直接可得答案,别让它自己数 |
| 7 | 跨句式泛化有限 | 没见过的说法可能掉线 |
| 8 | 身份细节会补充编造 | 只采信「名字 + 底座」两项 |
| 9 | **工具的顺序会影响它选哪个** | 见下方说明 |
#### 关于第 6 条:工具结果不足时会编数字
如果工具返回的信息不足以回答,它可能**直接编一个结果**,而不是说"信息不够"。
实测:问「目录里有几个 `.gguf` 文件」,它只调了 `list_files`(返回的是目录列表),
却直接答「**有 269 个**」——它根本没数过(真实值是 20)。
**规避**:让工具的返回**直接可得答案**。例如不要指望它"从列表里数个数",
而是提供一个 `count_files(pattern, path)` 这类专用工具。这是 1B 模型的可靠边界。
#### 关于第 9 条:工具的顺序会影响它选哪个
给同一组工具,**只换顺序、问题一字不改**,它的选择会变。
实测(工具:`get_weather` / `query_database` / `send_notification`):
| 工具顺序 | 「查 users 表有多少条」 | 「给张三发通知」 |
|---|---|---|
| 天气, SQL, 通知 | ✗ 没调用工具 | ✓ |
| SQL, 天气, 通知 | ✓ | ✗ |
| 通知, SQL, 天气 | ✓ | ✗ |
**根因**:训练沙箱里工具顺序是固定的,模型学到了一点**位置先验**——
换一组语义完全不同的工具时,它不完全只看描述。
**规避**:
1. 把最可能被用到的工具**排在前面**
2. 一次只传相关的少数工具(工具越少选得越准)
3. 宿主侧校验结果,发现调了不相关工具就重试
**注意:这不是"必须用某个框架"** —— 工具仍然完全由调用方定义,模型没有内置工具,
只是对排列顺序比理想情况更敏感一些。
## 五、怎么训的(简述)
**沙箱式数据**:每个训练样本来自一个程序化生成的「沙箱」,包含独立的
工具名、参数 schema、路径风格、错误消息风格。任务是**真的去读工具定义**才能做对。
**Agent 分五个子类型**,这是模型价值的来源:
| 子类型 | 教什么 | 占比 |
|---|---|---|
| `single` | 标准两步调用 | 25% |
| `recover` | 撞错 → 读错误 → 改对重试 | 20% |
| `disambig` | 两个相似工具里按语义选对 | 20% |
| `no_tool` | 有工具但这个问题不该用 | 20% |
| `ask_back` / `ask_direct` | 缺参数才反问,给了参数就直接调 | 15% |
**防泄漏五层**:命名空间物理隔离 / 生成器硬拦截留出沙箱 / 渲染后 token 预算 /
渲染后文本审计 / 非 Agent 样本禁含沙箱标识符 —— 外加第六层「参数名必须属于该工具定义」。
**防遗忘**(增量训练时):数据保持完整六类配比 + 学习率减半 + 只训 0.5 epoch。
## 六、局限与许可
- 底座 MiniCPM-V 4.7-1B 为 Apache 2.0,本模型沿用
- 这是 **Preview** 版本:判断力已达标(9/9),但句式泛化和拒绝场景仍在扩充
- 训练数据是**合成的**,用于教学/研究/自建 agent 均可,请自测后再用于生产
## 七、项目信息
```
权重 HuggingFace whcl412/FinchAI-Rune1-Preview-f16
ModelScope whcl412/FinchAI-Rune1-Preview-f16
代码 GitHub hwc-cell/FinchAI-Rune1-Preview
```
GitHub 仓库含训练脚本、数据生成器、验收脚本与 LoRA adapter。
训练数据为**程序化合成**(600 条),不使用任何真实用户数据。
---
*FinchAI 系列 · 训练于 Apple Silicon(transformers + PEFT + MPS)*
|