✷ 创客
给机器人装一层反射:0.8B 小模型,200 毫秒,不等大模型
上一篇里那台 30 块钱的玩具机器人,听懂一句「back up」(往后退),要等语音识别、大模型、语音合成走完一整个来回。这一篇讲我怎么在大模型前面挡了一个 0.8B 的小模型:在免费的 Colab 上训练半个小时,跑在一台 Mac mini 上,听懂一句简单口令只要 200 毫秒左右。也讲它为什么只有 86.6% 的准确率,用起来却不怕出错,以及机器人的大脑为什么从手机搬到了电脑上。
先说这段视频。我说了一句「back up」,机器人马上往后退,退得太快,背上的手机太重,重心一偏,整台翻了过去。
翻车是真翻车,后面会讲它带来的变化。但请先注意它动起来有多快:从我说完话到它开始退,中间没有等大模型。
一、喊「停」,要等一个来回
上一篇写过,这台机器人的一句话是这么走的:麦克风收音,语音识别转成文字,大模型想好说什么、做什么,语音合成念出来,同时把动作发给电机。
聊天的时候,这个来回没什么问题。你问它一道科学题,等两秒再听答案,很自然。
开车就不一样了。「停」这个字说出口的时候,车已经在动。要是还得等大模型想完,车早就撞到桌腿上了。
上一篇里我的办法是急停词:手机上跑一个关键词识别模型,听到「all stop」就直接刹车,不经过大模型。后来我把它删了,原因有三个:
- 一句英文短语,对中文用户不友好。我试过加一行拼音写法,实测一次都没触发过;
- 机器人自己也会说话。得在提示词里专门叮嘱大模型「永远不许说 all stop」,不然它一开口就把自己刹住了;
- 这个项目开源出去以后,大多数人接的并不是会跑的车,而是一个只会说话的角色。
现在的刹车是屏幕上的停止键。可我还是想要一个能听懂话、又不用等大模型的东西。而且它不该只听得懂一个固定的词,「停」「停下」「stop there」「够了别动了」都应该算。
二、决策模型:只做选择题,不写作文
上一篇末尾讲过「反射层」:孩子冲机器人学狗叫,一个叫 JEV 的决策模型先判断这是不是在逗它,是的话直接叫回去,不用大模型。
决策模型跟聊天模型不是一种东西。你给它一段「状态」(比如机器人上一句说了什么、人刚才说了什么),再给它一道选择题,它不写一个字,只告诉你每个选项的概率。不用一个字一个字地生成,所以快。
后来 Unsloth 发了一篇教程,教你训练自己的决策模型。我读完就想:狗叫能这么判断,简单口令为什么不行?
于是我给它出了这样一道题:
一个人在跟一台小轮式机器人说话。这个人是不是在让机器人马上做一个简单动作?
选项有七个:stop(停)、forward(往前一点)、backward(往后一点)、left(左转)、right(右转)、keep_going(一直往前开,直到叫停),还有 pass:不是简单口令,交给大模型去想。
三、数据:拿不准就 pass
整件事里最花心思的是数据,而数据里最花心思的是 pass。
两种错的代价完全不一样。把一句闲聊当成口令,车会猛地冲出去;把一句口令当成闲聊,只是交给大模型,慢一点而已。所以 pass 是我故意做成最多的一类,而且专门收了一批「看着像口令、其实不是」的句子:
| 人说的 | 应该选 |
|---|---|
| I can't stop laughing(我笑得停不下来) | pass:带 stop 的习语 |
| i turned left at the light today(我今天在红绿灯那儿左转了) | pass:讲故事,不是命令 |
| Do you ever get tired of driving?(你开车会累吗?) | pass:问题 |
| okay turn around(掉个头) | pass:不止一个简单动作 |
| hey go forward ten seconds(往前走十秒) | pass:带精确时长,交给大模型 |
| Turn the TV on(把电视打开) | pass:不是对它说的 |
还有一类句子,要看机器人上一句说了什么。机器人问「我要过来吗?」,你答「hey come here」,这是 forward;机器人问「往左还是往右?」,你答「Left.」,这是 left。所以每条数据都带着机器人的上一句话,跟真正运行时一样。大多数时候,机器人的上一句跟口令毫无关系,有些还故意提到了「stop」或者「left」,模型得学会别被它带偏。
这些短语不是我一句句手写的,是用 Claude Code 蒸馏出来的:我把规则讲清楚——七个选项各是什么意思、pass 要多、难例要覆盖哪几类——让它写出一大批英文短语,存进一个短语库。然后再用脚本变出各种写法:全小写、去掉标点、前面加个「um」或者「hey robot」。最后是 490 条训练、164 条测试。切分的时候,同一个短语的所有变体只会落在同一边。否则模型在测试集上看到的,其实是训练时见过的句子换了个大小写,分数会虚高。
数据集公开在 Hugging Face:beasaltfish/robot-simple-commands。
四、在 Colab 上训练,半小时,免费
训练照着 Unsloth 的教程走,没什么需要自己发明的:
- 底座模型是 Qwen3.5-0.8B;
- 用 Unsloth 的
FastDecisionModel做 LoRA 微调,rank 16,学习率 2e-4; - 60 步,大约 4 个 epoch;
- 训练完合并成 16 位权重,另外导出了一份 GGUF。
整个过程在 Google Colab 的免费 GPU 上跑完,大概半个小时,一分钱没花。
测试集上的准确率是 86.6%,164 条对了 142 条。模型也公开了:beasaltfish/robot-simple-commands-qwen3.5-0.8b(还有 GGUF 版)。
五、86.6%,为什么够用
86.6% 听起来不高,每七八句就错一句。可它错在哪儿,比错多少更重要。
决策模型给的是概率。我的规则是:某个动作的概率超过 0.8,才真的去做;否则一律当作 pass,交给大模型。也就是说,模型心里没底的那些句子,根本不会变成动作,只会走慢一点的路。
再加上数据里 pass 本来就占大头,它犯错时更容易错向「不动」那一边。实际在车上用下来,效果比 86.6% 这个数字好得多。我想要的就是这样:反射这一层宁可慢,也不能错。
六、接进机器人
模型跑在家里一台 Mac mini M4 上,用的是 Unsloth Studio。启动时指一下模型的位置,它就在局域网里提供一个 /v1/systemone 接口:
UNSLOTH_SYSTEMONE_MODEL=~/.cache/huggingface/hub/models--beasaltfish--robot-simple-commands-qwen3.5-0.8b/snapshots/… \
unsloth studio -H 0.0.0.0 -p 8888
机器人的大脑每听到一句话,在问大模型之前,先把这句话和机器人的上一句发给这个接口:
- 某个动作超过 0.8:直接执行。往前、往后、左转、右转各开 0.6 秒,停就是停,「一直开」就一直开到你叫停。这一轮不出声音,只出动作;
- 没有超过 0.8,或者选的是
pass:照常交给大模型; - 接口出错、超时(1.5 秒),或者 Studio 根本没开:也照常交给大模型。反射只是一条近路,近路断了,机器人照样得能回话。
还有个小细节:反射做完动作以后,大模型的对话记录里会补上一行说明,大意是「你还没来得及想,反射已经替你做了:往后退 0.6 秒」。不然下一轮你问它「你刚才干嘛退那么快」,它会一脸茫然。

这是那段视频录制时服务器的日志。第一次请求要把模型加载进内存,花了 3.6 秒;之后每一次都在 203 到 220 毫秒之间。这 200 毫秒是从拿到语音识别的文字,到决定做哪个动作,不包括语音识别本身。
问什么、每个选项做什么,都不是写死在代码里的,是数据。管理页上自带两套预设:一套是上一篇的「学狗叫」,一套就是这次的「简单口令」。选一套复制过来,之后想怎么改都行:换个问题,加个选项,让「左转」开 1 秒而不是 0.6 秒。
七、大脑为什么从手机搬到了电脑
细心的读者会发现,上一篇的机器人全靠一部手机:手机浏览器里跑语音检测、调云端接口,大脑就在手机里。现在不一样了。
现在大脑是电脑上的一个 Node 服务。手机只当身体:听、放声音、开车、显示表情。每个机器人是一个「角色」,有自己的名字、声音、服务商和密钥,都在电脑浏览器里的管理页上配好。手机扫一下二维码,就成了那个角色的身体。
搬家有两个原因。
一是本地化。听你说话、理解你的这些环节,以后都可以跑在你自己的机器上,不出家门。反射模型已经是这样了:它跑在 Mac mini 上,没有调用任何云端服务。语音识别、大模型、语音合成,目前还是走云端接口,以后会一步步搬回来。
二是换身体。大脑不在手机里了,身体就可以是任何能收音、能放声、能开电机的东西,比如一块几十块钱的 ESP32 板子。开头那次翻车,就是这件事最好的理由:一部手机对这台小车来说实在太重了。ESP32 的固件已经写好,还没上车。
这两件事都值得单独写一篇,下次再讲。
想自己试试?
- 代码:github.com/beasaltfish/bot-reborn,MIT 协议。生成数据的脚本在
training/commands/里。 - 数据集:beasaltfish/robot-simple-commands
- 模型:beasaltfish/robot-simple-commands-qwen3.5-0.8b
- 训练方法:Unsloth:训练你自己的决策模型
- 视频:在 YouTube 上看
没有车也能玩:在管理页把角色的身体设成「不能动」,一部旧安卓手机加一台电脑,就是一个会聊天的角色。
谢谢 Unsloth 把决策模型的训练流程整理得这么清楚。我只是照着走了一遍,换了一道题。