--- license: apache-2.0 language: - zh - en tags: - gguf - llama.cpp - ollama - tool-calling - function-calling - minicpm - chinese base_model: openbmb/MiniCPM5-2B --- # LycheeAI-coder-2b-II-pro-GGUF > **v7**(2026-09-13)· GGUF 版本 · 基座 [MiniCPM5-2B](https://huggingface.co/openbmb/MiniCPM5-2B) · Apache 2.0 [LycheeAI-coder-2b-II-pro](https://huggingface.co/whcl412/LycheeAI-coder-2b-II-pro) 的 **GGUF / llama.cpp / Ollama** 分发格式。 主仓库(含完整能力说明、局限、训练方法论)请看 [whcl412/LycheeAI-coder-2b-II-pro](https://huggingface.co/whcl412/LycheeAI-coder-2b-II-pro)。 **其他格式**: [MLX 4bit](https://huggingface.co/whcl412/LycheeAI-coder-2b-II-pro)(Mac 日常用,1.42 GB)· [MLX 无损 bf16](https://huggingface.co/whcl412/LycheeAI-coder-2b-II-pro-MLX-bf16)(要再加工/质量基准,5.03 GB)· [f16](https://huggingface.co/whcl412/LycheeAI-coder-2b-II-pro-f16)(与 MLX bf16 同一份权重) 国内用户推荐 **ModelScope**:[modelscope.cn/models/whcl412/LycheeAI-coder-2b-II-pro-GGUF](https://modelscope.cn/models/whcl412/LycheeAI-coder-2b-II-pro-GGUF) 这是一个 2B 的**工具调用(function calling)专用**微调模型:让它调用你提供的工具、而不是自己瞎猜。 **个人开发者的实验作品,能力有限**——请先看下面的「已知问题」再决定是否用在生产里。 --- ## 📦 三个文件,按设备选 | 文件 | 体积 | 建议内存 | 质量 | 建议用途 | |---|---|---|---|---| | `LycheeAI-coder-2b-II-pro-q4_k_m.gguf` | **1.45 GiB** | ~2 GB | ⚠️ 有损 | 8GB 内存机器、想省空间、先试试手感 | | `LycheeAI-coder-2b-II-pro-q8_0.gguf` | **2.50 GiB** | ~3 GB | ✅ 接近无损 | **多数人的推荐档**,质量/体积平衡最好 | | `LycheeAI-coder-2b-II-pro-f16.gguf` | **4.69 GiB** | ~5 GB | ✅ 无损 | 当参考基准、要自己再量化、要转换格式 | > 小模型对量化比大模型敏感得多。**工具调用对格式稳定性要求高,建议优先用 q8_0 或 f16**,q4 只用来快速体验。 --- ## 🚀 快速开始 ### 方式一:Ollama(最省事) ```bash # 1. 下载 q8_0(推荐档)+ Modelfile huggingface-cli download whcl412/LycheeAI-coder-2b-II-pro-GGUF \ LycheeAI-coder-2b-II-pro-q8_0.gguf Modelfile --local-dir ./lychee # 国内更快:modelscope download --model whcl412/LycheeAI-coder-2b-II-pro-GGUF \ # LycheeAI-coder-2b-II-pro-q8_0.gguf Modelfile --local_dir ./lychee # 2. 改 Modelfile 第一行指向你下的文件,然后导入 cd lychee sed -i '' 's/q4_k_m/q8_0/' Modelfile # Linux 上去掉 '' 参数 ollama create lychee-coder2b-pro -f Modelfile # 3. 跑 ollama run lychee-coder2b-pro "递归是什么?一句话。" ``` ### 方式二:llama.cpp ```bash llama-cli -m LycheeAI-coder-2b-II-pro-q8_0.gguf \ -p "<|im_start|>user\n递归是什么?一句话。<|im_end|>\n<|im_start|>assistant\n\n\n\n\n" \ -n 256 --temp 0.4 -no-cnv # 起 OpenAI 兼容服务 llama-server -m LycheeAI-coder-2b-II-pro-q8_0.gguf \ -c 8192 --jinja --host 127.0.0.1 --port 8080 ``` > `--jinja` 会让 llama.cpp 使用 GGUF 内嵌的 chat template,**工具调用必须加这个参数**。 ### 方式三:直链下载单个文件 ```bash # HuggingFace wget https://huggingface.co/whcl412/LycheeAI-coder-2b-II-pro-GGUF/resolve/main/LycheeAI-coder-2b-II-pro-q8_0.gguf # ModelScope wget https://modelscope.cn/models/whcl412/LycheeAI-coder-2b-II-pro-GGUF/resolve/master/LycheeAI-coder-2b-II-pro-q8_0.gguf ``` --- ## 🧰 工具调用怎么接(重要) 这个模型的工具调用契约非常朴素:**它直接输出一段 JSON,不带任何包裹**。 给它工具定义后,它的回复长这样(实测稳定): ```json {"name": "calculate", "arguments": {"expression": "789*123"}} ``` ### ⚠️ 请自己解析这段 JSON,不要依赖运行时的自动解析 我们实测过 Ollama 0.32.6 的自动工具解析:**成功率不稳定**(同一问题重复跑,时好时坏)。 原因很清楚——Ollama 的解析器期望 `` 之类的包裹格式,而这个模型是按「直接输出 JSON」训练的, 所以它大多数时候就吐一段裸 JSON,解析器就漏掉了。 **所以:把 JSON 从 `content` 里解析出来,是 100% 可靠的路径。** 参考实现: ```python import json, re, requests TOOLS = [{ "type": "function", "function": { "name": "calculate", "description": "计算数学表达式", "parameters": { "type": "object", "properties": {"expression": {"type": "string", "description": "表达式,如 789*123"}}, "required": ["expression"], }, }, }] def chat(prompt): r = requests.post("http://127.0.0.1:11434/api/chat", json={ "model": "lychee-coder2b-pro", "stream": False, "think": False, # 关掉思考,输出更干净(见下文) "options": {"temperature": 0.4}, "tools": TOOLS, "messages": [{"role": "user", "content": prompt}], }) return r.json()["message"] def parse_tool_call(msg): """先看运行时有没有帮我们解析;没有就从 content 里捞 JSON。""" if msg.get("tool_calls"): f = msg["tool_calls"][0]["function"] return f["name"], f["arguments"] text = msg.get("content") or "" m = re.search(r'\{\s*"name"\s*:\s*"([^"]+)"\s*,\s*"arguments"\s*:\s*(\{.*?\})\s*\}', text, re.S) if m: return m.group(1), json.loads(m.group(2)) return None, None msg = chat("帮我算一下 789*123") name, args = parse_tool_call(msg) print(name, args) # calculate {'expression': '789*123'} ``` **宿主接入的三个坑**(都踩过,详见主仓库): 1. **无工具时它会心算,而且会算错。** 在 system 里加一句 `需要任何数值计算时,一律调用 calculate,不要自己心算。` —— 实测有效。 2. **不要用「通用 system + 工具列表」去问身份。** 那样它可能自称别的模型。 system 里必须写 `你是 LycheeAI-coder-2b-II-pro,...`。 3. **工具调用建议 `temperature ≤ 0.4`**,格式更稳。 ### 关于 `think`(思考开关) 这个模型支持思考开关,通过 chat template 的 `enable_thinking` 控制: | 调用方式 | 结果 | |---|---| | API 传 `"think": false` | 输出干净,直接给答案 ✅ **推荐** | | API 传 `"think": true` | 思考内容进 `message.thinking` 字段 | | **不传 `think`** | 可能吐出游离的 `` 标签(模板没预设默认值) | `ollama run` 命令行默认不传,所以你会偶尔看到 ``;用 API 时显式带上 `think: false` 即可。 --- ## ⚠️ 已知问题 1. **无工具时会心算,且常常算错**(最实际的短板) `1234+5678→2000`、`13.5×4→7.8`。根因是训练数据里乘法样本占一半,模型学到的是「乘法→调工具」的特例, 不是「算术→调工具」的通则。**规避:system 里明确要求一律调 calculate。** 2. **通用 system 下身份会答错**(见上文坑 2)。 3. **偶发不可见控制字符**:极少数情况下输出里会混入 `\x08`(退格符)。 频率很低(15 次抽样出现 1 次),训练数据里不存在这个问题,属解码层面杂讯。 建议宿主输出前过滤:`re.sub(r'[\x00-\x08\x0b\x0c\x0e-\x1f]', '', text)`。 4. **`tool_calls` 自动解析不被支持**(见上文,请自解析 JSON)。 --- ## 📊 关于这个版本 | 项目 | 说明 | |---|---| | 基座 | MiniCPM5-2B(面壁智能 OpenBMB,Apache 2.0) | | 微调 | MLX-LM QLoRA 4bit,LoRA 层数 16,lr 5e-5,batch 2 | | 数据 | **精选 980 条 × 1 epoch**(490 步) | | 验收 | **26/27**(上一版 25/2)——修好了②算术、多轮追问两项历史失败 | | 已知唯一失败 | 工具定义放在 **user** 消息里时,会退化成心算 | **关于「为什么只有 980 条」**:项目有一项硬约束——单次训练不超过 500 步。 在 batch=2 下即 ≤1000 条样本预算。我们试过 v7b/v7c 两种「定向补强」方案, 结果都是**修好一个考点、挤掉另外两个**(23/27、22/27)。 原因是 1000 条预算内每个考点都要占配额;改配额又会重洗 40% 的样本,让实验无法归因。 所以我们做了「稳定采样」(按内容哈希排序,改配额只做单调扩展),确认 **980 条 / 490 步已是这个预算下的最优解**。 要突破只能加预算。完整复盘写在主仓库 README。 --- ## 📁 文件说明 | 文件 | 说明 | |---|---| | `LycheeAI-coder-2b-II-pro-f16.gguf` | f16 无损,5039007040 字节 | | `LycheeAI-coder-2b-II-pro-q8_0.gguf` | Q8_0 量化,2679711040 字节 | | `LycheeAI-coder-2b-II-pro-q4_k_m.gguf` | Q4_K_M 量化,1561318720 字节 | | `Modelfile` | Ollama 导入用,默认指向 q4_k_m;改第一行即可换档 | | `README.md` | 本文件 | 内嵌了完整的 chat template(含 `tools` 支持),llama.cpp 加 `--jinja` 即可用。 --- ## 🙏 致谢 / 许可 - 基座:[MiniCPM5-2B](https://huggingface.co/openbmb/MiniCPM5-2B)(面壁智能 OpenBMB) - 转换工具:[llama.cpp](https://github.com/ggml-org/llama.cpp) - 许可:**Apache 2.0**(继承自基座) 个人项目,欢迎提 issue。如果它对你有用,[Bilibili 关注一下](https://space.bilibili.com/3493128967293256)就是最大的支持 🤖