不用显卡就能运行的本地小模型能做啥-用 pi 实测两个 2B 模型的工具调用与真实任务

我手里这台机器是 Apple M4,10 核 CPU,16 GB 内存。这种配置想跑本地大模型,要想不影响其他工具的日常运行,就不能全都跑慢,粗略估计适合在 0.5B 到 3B 这个区间里挑。我之前也一直用小模型,不过大多是在聊聊天、写写摘要。真正让一些同学好奇的是另一件事:这种小模型,能不能当 coding agent 用,也就是会不会调用工具、能不能完成一个具体的小任务。

所以这回咱们来实测一轮。这篇文章里的数字都是我自己在这台机器上跑出来的,不是抄的榜单。

先说清楚被测的两个模型

本机 Ollama(0.34.2)里我留了两个 2B 级别、且支持工具调用的模型:

模型 参数 量化 能力
qwen3.5:2b 2.3B Q8_0 completion, vision, tools, thinking
LiquidAI-dev/lfm2.5-2.6b:latest 2.7B Q4_K_M completion, tools, thinking

(参数和量化都是从 ollama show 原样抄的,不是我估的。)

之前我还试过更小的几个:350M 的、0.8B 的,结论很直接——太小的一是根本带不动工具调用,二是太小了容易幻觉起飞甚至随时乱编。所以最后就留了这两个 2B 以上的。

用 pi 来测

工具调用这种能力,光让模型"聊天"是测不出来的。必须有一个外壳把工具定义发给它、解析它的工具调用、真正去执行,才算数。我用的是 pi(Mario Zechner 写的极简终端 agent)。

pi 的接法很简单:在 ~/.pi/agent/models.json 里声明一个 OpenAI 兼容的提供方指向本机 Ollama,然后:

pi -p --provider ollama-local --model <模型> "你的指令"

为了测的干净,我把技能、扩展、上下文文件全关掉,只留最核心的 agent 循环和工具(readwriteeditbash 等)。这样测出来的就是模型本身,而不是各种插件带来的加成。

关于 SOTA 榜单:小模型在这个维度确实吃亏

开始之前先说个背景。公开评测里,衡量"会不会用工具、听不听话"这类能力的标准集主要有这几套:

这些榜单上排前面的基本都是几十 B 甚至上百 B 的模型。2B 级别在这些维度上普遍靠后,尤其是需要多步规划、格式严格的任务。所以下面的实测结果,你可以当作"低配机器上小模型的真实上限"来看。

本次具体测了什么

我给两个模型、中英双语,各安排了 5 个任务,一共 20 次运行。每跑一次,模型生成的原始文件我都留在单独目录里,方便事后人工翻看。

这 5 个任务是这样:

任务 指令 判定标准
T1 精确写文件 创建 hello.txt,内容正好是 hello small model 文件里有这句话
T2 读并求和 data.txt(每行一个整数),求和 答案出现 224
T3 写+运行 fib.py 打印前 10 个斐波那契数,并运行 脚本能跑,输出 0 1 1 2 3 5 8 13 21 34
T4 生成产物 report.md,标题加三条要点 有标题且至少三条要点
T5 修 bug 修掉 buggy.py 里平均值多加了 1 的 bug,并运行 去掉 + 1 且输出 4.0

结果

先看任务维度:

任务 通过
T1 精确写文件 3/4
T2 读并求和 3/4
T3 写+运行 2/4
T4 生成产物 4/4
T5 修 bug 4/4

再看模型和语言:

维度 结果
qwen3.5:2b 8/10
LiquidAI-dev/lfm2.5-2.6b 8/10
中文 8/10
英文 8/10

两个模型完全打平,中英文也没有差别。总共 20 次里过了 16 次。样本不大,但方向很清楚:单步任务基本能过,T3 这种"写代码再运行"的是重灾区。

真正有意思的是它们错在哪

跑完看生成的原始文件,失败方式非常集中,而且很"小模型":

一、把换行写成了字面量 \n 这是最典型的。模型在工具参数里放的不是真换行,而是反斜杠加字母 n 两个字符。LiquidAI 尤其容易这样,它写的 fib.py 整份文件就一行:

print("Fibonacci test")\n

拿去运行直接报 SyntaxError: unexpected character after line continuation character。注意这不是 pi 的错——外壳只是把模型要求的内容原样写进文件。是模型自己没分清"内容里的换行"和"转义后的文本"。四次 T3 里,LiquidAI 的两次全栽在这上面。

二、没读文件,凭自己编数据。 有一次让它读 data.txt 再求和,结果它没去读,直接给了个"100 + 200 + 300 = 600"。文件里根本没有这些数,正确的是 224。这种错最危险,因为它答得很自信、格式也漂亮,你不去核对根本发现不了。

三、写错路径还谎报成功。 还有一次让它把文件写到当前目录,它把文件写到了根目录的 /hello.txt(只读文件系统,其实失败了),然后回复说"文件已成功创建"。它报告的成功是假的。

说白了:写文件基本没问题,读文件汇报也一般没问题,但只要进入"写完还得运行"这一步,就崩了——因为它得先通过工具调用吐出一份语法完全正确的代码,再让系统执行,中间任何一个字符错位,整件事就废了。

顺带测了速度

既然是低配机器,速度也是关键。我用 Ollama 原生接口,它返回纳秒级的预填充(prefill)和解码(decode)耗时,比拿总时间除一下准得多。3 次取中位数,输出上限 128 token。

模型 提示规模 Prefill (t/s) Decode (t/s) 首包延迟
qwen3.5:2b 短 15 token 142 17.2 0.11s
qwen3.5:2b 长 2210 token 25188 17.1
LiquidAI-dev/lfm2.5-2.6b 短 17 token 109 19.1 0.32s
LiquidAI-dev/lfm2.5-2.6b 长 2210 token 12675 18.8

几个观察:

  • 解码速度差不多,都在 17 到 19 t/s。这个速度写代码是慢的,但应付短任务够用。
  • 预填充 qwen 明显更快,长上下文下差不多是 LiquidAI 的两倍(25k 对 12.7k t/s)。提示越长,这个差距越值钱。
  • 短提示那行的 prefill 数字别当真,全被固定开销盖住了,只有中长提示才有参考意义。
  • 首包延迟两个都快(0.1 到 0.3 秒),但这里有个坑:qwen3.5:2b 是思考型模型,它把推理先写进单独的 thinking 字段,response 一直空着,所以你要等到它"想完"才看到正文。实测在 128 token 上限下,第一个可见的答案 token 差不多要到 7.5 秒才出现。LiquidAI 反过来,把 <think> 标记直接写进正文流里,文字立刻就有,代价是输出里混着思考标记。

所以论"聊天时的即时手感",LiquidAI 更跟手;论"长提示的处理速度",qwen 更快。

那本地小模型到底适合干什么

测完我的结论是:别拿这种2B小模型当可以完全依赖的 coding agent,但把它当"本地小助手"用,还是有价值的。

适合的:

  • 短文本的翻译、改写、摘要(其实还是以前我就常用的场景)。
  • 单步的文件操作:读一个文件、写一个文件、改一行、算个数(注意有可能会有错,要有核验环节)。
  • 结构简单的指令,比如"把这份 CSV 转成 Markdown 表格"。
  • 要绝对本地、绝对不联网的场景,哪怕结果粗糙也能接受。
  • 离线、断网、或者不想把数据发出去的时候做个兜底。

不适合的:

  • 多步任务,尤其是"写代码再运行"这种带反馈闭环的。
  • 需要严格格式的任务(JSON、复杂 Markdown),它们动不动就把换行写成 \n
  • 任何需要读取真实数据再作答的任务——它会直接编。
  • 任何你没法一眼看出对错的输出。

真要在这台机器上稳定跑 agent,我的建议还是拉一个 4B 到 8B、且明确支持 tools 的模型。2B 这个级别,能跑通简单的单步任务,但别指望它扛复杂流程。

最后扯几句

说句实在的,小模型这几年的进步是看得见的,2B 能做到今天这样,放在两年前不敢想。但它跟"能帮你干活的 agent"之间,还差一些,这道坎不仅仅体现在参数量的绝对值上,而更多事在多步任务的稳定性上——单步它行,一旦要连着做两三步、还要根据中间结果调整,就很容易散架。

特别值得警惕的是那两类"看起来很对"的错:一种是编数据(100+200+300=600),一种是谎报成功(写到只读路径还说建好了)。这两类错不会报错、不会崩,但会实打实地误导你。所以我一直强调,用任何模型做 agent,最终判断权都得留在人手里

低配机器上跑本地小模型,是个有趣的、也能干点事的小工具,但如果需要可靠的开发伙伴,建议还是要9b起步。


测试环境:Apple M4(10 核 CPU),16 GB 内存,macOS;Ollama 0.34.2;pi 0.85.1。所有数字均为本机实测。