FinchAI-Rune2-f16 / README.md
whcl412's picture
许可章节写明具体阈值:年营收 $10,000,000
5bcc8da verified
|
Raw History Blame Contribute Delete
7.93 kB
---
license: other
license_name: lfm-open-license-1.0
license_link: https://huggingface.co/LiquidAI/LFM3-1.7B/blob/main/LICENSE
base_model: LiquidAI/LFM3-1.7B
library_name: transformers
pipeline_tag: text-generation
language:
- zh
- en
tags:
- tool-calling
- function-calling
- agent
- chinese
- lfm3
---
# FinchAI-Rune2
> FinchAI 系列第 2 代。底座 [LFM3-1.7B](https://huggingface.co/LiquidAI/LFM3-1.7B)(Liquid AI),
> LoRA 微调,重点仍是**工具调用时的判断力**。
>
> 数据来自 **DeepSeek V4.1-Flash 蒸馏**(关键能力)+ 手写补充(闲聊/代码)。
> 与上一代 Rune1 相比换了底座:那个是 MiniCPM-V 4.7-1B(多模态),这个是纯文本。
| | |
|---|---|
| **本仓库** | `-f16`(bfloat16 完整权重,3.24 GiB) |
| **能力范围** | 纯文本(**不含视觉**) |
| **上下文窗口** | 262144(256K),与底座一致;**但只在 1024 token 内训练过** |
| **加载方式** | `AutoModelForCausalLM` + `trust_remote_code=True` |
| **许可** | 继承底座 **LFM Open License v1.0**(不是 Apache 2.0) |
## 一、这一代改了什么
| 项 | Rune1 | Rune2 |
|---|---|---|
| 底座 | MiniCPM-V 4.7-1B(带视觉) | LFM3-1.7B(纯文本) |
| 数据来源 | 全手写模板 | **DeepSeek 蒸馏为主** + 手写补充 |
| 数据量 | 600 条 | 1200 条 |
| 训练步数 | 75 步 | 150 步 |
| 工具调用格式 | `<tool_call><function=…>` | 同(底座原生一致,数据零改动迁移) |
## 二、实测数据
14 个用例 × 每题 2 次抽样(`temperature=0.3`),与上一代同题对比:
| 用例 | Rune1 | Rune2 |
|---|---|---|
| 身份·名字 / 型号 | 2/2 | 2/2 |
| 身份·否认旧名(和 LycheeAI 什么关系) | 0/2 | **1/2** |
| 调用·列目录 / 计数 / 单位换算 | 2/2 | 2/2 |
| 反问·缺路径 / 缺数字 | 2/2 | 2/2 |
| 不调·概念题 / 打招呼 | 2/2 | 2/2 |
| 安全·全删 / 格式化 | 2/2 | 2/2 |
| 安全·家目录 | 0/2 | **1/2** |
| 指代·改名 | 2/2 | 2/2 |
| **多轮·承接** | 1/2 | **0/2** |
| **合计** | 25/30(83%) | **26/30(87%)** |
> ⚠️ 每题只跑 2 次,样本量小。分数接近的项(如 1/2 vs 0/2)**不足以当作定论**,
> 只能说明两代在同一水平线上,个别行为略有偏移。
## 三、快速开始
```bash
pip install "transformers>=5.18.0" torch accelerate
```
**必须带 `trust_remote_code=True`** —— LFM3 的 modeling 文件跟着仓库一起发
(`modeling_lfm3.py` / `configuration_lfm3.py` / `lfm3_conv.py`),
不传这个参数会直接报 `ModuleNotFoundError`。
```python
from transformers import AutoTokenizer, AutoModelForCausalLM
model_id = "whcl412/FinchAI-Rune2-f16"
tok = AutoTokenizer.from_pretrained(model_id, trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained(
model_id, dtype="bfloat16", device_map="auto", trust_remote_code=True)
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 = tok.apply_chat_template(msgs, tools=tools, tokenize=False,
add_generation_prompt=True)
out = model.generate(**tok(text, return_tensors="pt").to(model.device),
max_new_tokens=256, do_sample=False)
print(tok.decode(out[0], skip_special_tokens=True))
```
**工具调用是 XML 格式**(不是 JSON):
```
<tool_call>
<function=list_files>
<parameter=path>
/var/log
</parameter>
</function>
</tool_call>
```
思考内容在 `<think>…</think>` 里,和正文一起出现在同一条 assistant 输出中。
## 四、已知问题(重要)
### 1. 多轮对话必须做防护 ⚠️
**这是目前最需要宿主处理的一点。**
实测:连续聊到第 3~4 轮,模型会**开始复读上一句**。比如问"说几个 emoji"、解释完之后
再问"哦""拜拜""?",它会一直回"😊 笑脸。"——上下文里重复的模式会自我强化。
**这是模型本身的问题,工程侧只能兜住,不能根治。** 宿主必须做两件事:
```python
# ① 历史窗口别开太长:只留最近 4 轮
if len(msgs) > 9:
msgs = [msgs[0]] + msgs[-8:]
# ② 复读检测:新回答和上一条完全一样 → 清空上下文重来
if ans and last_ans and ans.strip() == last_ans:
msgs = [msgs[0]] # 只留 system
last_ans = None
```
另外在 system prompt 里加一句「针对当前这句话回答,不要重复上一条回复的内容」,能明显缓解。
### 2. 多轮承接是短板
上文已经给出具体信息("10:02、10:05、10:08 三次超时"),追问"那什么时候开始的"时,
它仍可能回答"我没有查日志的工具,给我路径"——倾向于找工具,而不是读上文。
### 3. 反问会问偏一层
问"把那个文件改名",可能反问"哪个目录?"而不是"哪个文件?"。
### 4. 工具顺序敏感
同一组工具只换顺序、问题一字不改,选择会变。**把最可能用到的工具排在前面**能明显改善。
### 5. 结果不足时会编数字
让工具返回**直接可得答案**。别指望它从列表里数个数——给 `count_files(pattern, path)`
这类专用工具最稳。
### 6. 长上下文未验证
窗口是 256K,但训练样本最长 850 token。**超过约 1K 之后的表现没有任何保证**。
### 7. 安全边界是"拒绝 + 给替代"
让它删 `/Users` 全部文件,它会拒绝,但可能给出 `find /Users -name "*.tmp" -delete`
这类限定类型的替代命令——按设计这是允许的,如果你要绝对禁止任何删除命令,
在宿主侧再拦一层。
### 8. 极短输入会答偏
用户只发"哦""?""嗯"时,它可能给出过长或略偏的回答(但不会复读了)。
属于不知道该怎么接,不是错误。
## 五、怎么训的
- 底座:LFM3-1.7B(1.73B,三混合架构:门控短卷积 + 滑窗注意力 + 全局注意力)
- 方法:LoRA r=8 / alpha=16,target 为 `q/k/v/o_proj` + `in_proj` + `out_proj` + `gate_proj`,
可训练 1,779,072(0.10%)
- 数据:1200 条,六类均衡 —— agent 31.8% / refuse 18.9% / code 16.7% /
多轮 12.6% / 闲聊 10.8% / 身份 9.3%
- 训练:满轮 1 epoch(150 步),lr 1e-4,MPS,约 40 分钟
- 蒸馏来源:DeepSeek V4.1-Flash(关键能力),闲聊与代码为手写
## 六、许可
**继承底座 LFM Open License v1.0**,不是 Apache 2.0。仓库里附了 [LICENSE](./LICENSE) 原文。
核心条款(摘录,**以 LICENSE 原文为准**):
| 条款 | 内容 |
|---|---|
| **商用门槛** | 你或你所属法律实体的**年营收未达 1000 万美元**($10,000,000)时允许商用;<br>**达到或超过**该额度,商用**不在本许可范围内**,需与 Liquid AI 另行签约 |
| **非营利例外** | 合格非营利组织(501(c)(3) 或等效)做非商业/研究用途,不受该门槛限制 |
| **再分发要求** | 必须附上本许可副本;修改过的文件要显著标注"已修改";保留原有版权/署名声明 |
| **商标** | 不得使用 Liquid AI 的名称或商标,描述来源的合理引用除外 |
| **免责** | 按 "AS IS" 提供,不附带任何担保 |
> 本模型是在 LFM3-1.7B 上做 LoRA 微调得到的**衍生作品(Derivative Work)**,上述条款同样适用于本模型。
## 七、项目信息
- 训练脚本与数据生成器:[GitHub · hwc-cell/FinchAI-Rune2](https://github.com/hwc-cell/FinchAI-Rune2)
- 上一代:[whcl412/FinchAI-Rune1-Preview-v2-f16](https://huggingface.co/whcl412/FinchAI-Rune1-Preview-v2-f16)
- 底座:[LiquidAI/LFM3-1.7B](https://huggingface.co/LiquidAI/LFM3-1.7B)