Andrej Karpathy 刚刚分享了一件挺有意思的事:教他的超小型语言模型 nanochat d32 数单词里有几个字母 r。
这听起来简单,但对一个"大脑只有蜜蜂大小"的模型来说,难度不小。要知道,连 ChatGPT 这样的大模型都经常在这种任务上翻车。
Karpathy 的解决方案很实用:创建一个叫 SpellingBee 的合成任务(代码见文末),生成大量用户询问字母计数的例子,然后用这些数据对模型进行微调。

关键在于细节。对小模型来说,你得把任务拆得很细:先把单词标准化加引号,然后逐字母拼出来(避免分词问题),最后用显式计数器一个个数过去。还得教模型用两种方法解决:手工计算和调用 Python 解释器验证。
这种做法有点像填鸭式教学。如果模型够大,这种能力可能会自然涌现。但对于参数量极小的 nanochat,你只能通过在数据中过度表示这类任务,强迫它早点学会。
有人质疑这是不是过拟合。Karpathy 在回复中提到,目前所有解决方案都是"干净的",没有错误示例。理想情况下,应该加入一些错误和恢复的例子,或者用强化学习让它更鲁棒。

不过,有用户测试发现,这个功能在多轮对话中不太稳定,Karpathy说需要清空对话历史重新开始才最可靠。这从侧面说明小模型的上下文处理能力还是有限的。
Karpathy 用这个例子现场示范了在资源受限的情况下,针对性的数据增强仍然是让小模型掌握特定能力的有效方法。虽然不够优雅,但确实管用。
代码见:https://github.com/karpathy/nanochat/blob/8892470f2975d80e6ef8c2f25d72d890beb50398/tasks/spellingbee.py