SFT将下一个词元模型转化为聊天机器人 | AI生成和翻译

首页 2026.07

问题:SFT(监督微调)如何将像 nanoGPT 这样的下一个词元预测模型转变为聊天机器人?我们是直接训练 JSON 格式的对话,还是将其转换为 User: / Assistant: 文本,并训练模型来预测助手的回答?

回答:

是的,这基本上就是这个思路。关键点在于:

即便是聊天模型,本质上仍然是下一个词元预测模型。

神经网络本身并没有发生根本性变化。唯一改变的是训练数据的格式

步骤一:预训练(nanoGPT)

在 nanoGPT 中,你使用的可能是纯文本:

The capital of France is Paris.

模型看到的是

输入: The capital of France is
目标: capital of France is Paris .

或者更准确地说

输入词元:
The capital of France is Paris .

预测:

The -> capital
capital -> of
of -> France
France -> is
is -> Paris
Paris -> .

每个词元都预测下一个词元。


步骤二:SFT 数据集

假设你有如下 JSON 数据:

{
  "messages": [
    {
      "role": "user",
      "content": "2+2 等于多少?"
    },
    {
      "role": "assistant",
      "content": "4。"
    }
  ]
}

模型并非直接基于 JSON 对象进行训练。

相反,JSON 会被转换为文本。

例如,

<|user|>
2+2 等于多少?

<|assistant|>
4。

或者

User: 2+2 等于多少?
Assistant: 4。

或者对于某些模型:

<|im_start|>user
2+2 等于多少?
<|im_end|>

<|im_start|>assistant
4。
<|im_end|>

每个模型家族都有自己特定的聊天模板


步骤三:词元化

格式化之后,

User: 2+2 等于多少?

Assistant: 4。

会变成类似这样的词元:

[User]
[:]
[2]
[+]
[2]
[等于]
[多少]
[?]

[Assistant]
[:]

[4]
[。]

Transformer 并不理解这些词元在语义上是“角色”。它只会看到词元序列。


步骤四:损失掩码(关键部分)

大多数 SFT 训练不会对用户的词元计算损失。

示例:

User: 2+2 等于多少?
Assistant: 4。

内部会变成

输入:

User:
2
+
2
等于
多少
?
Assistant:
4
。

标签会被掩码,变为:

User        -> 忽略
:           -> 忽略
2           -> 忽略
+           -> 忽略
2           -> 忽略
等于        -> 忽略
多少        -> 忽略
?          -> 忽略
Assistant   -> 忽略

4           -> 预测
。          -> 预测

在许多实现中:

labels =
[-100,
 -100,
 -100,
 ...
 -100,
 token("4"),
 token("。")]

其中 -100 告诉损失函数(例如 PyTorch 中的交叉熵损失)忽略这些位置。

这教会模型:

根据已有的对话历史,生成助手的回复。


步骤五:推理

在推理过程中,你输入

User: 给我讲个笑话。

Assistant:

模型会预测出

为什么
鸡
要
过
马路
...

因为在 SFT 阶段,它见过数百万个以

Assistant:

之后紧跟回答的示例。

因此它已经学会了这种模式。


多轮对话

训练数据也可以像这样:

User: 你好

Assistant: 你好!

User: 谁发明了 Python?

Assistant: Guido van Rossum。

损失通常仅对助手的消息进行计算。

概念上:

User: 你好                     忽略

Assistant: 你好!              训练

User: 谁发明了 Python?        忽略

Assistant: Guido van Rossum。  训练

这教会模型如何在多轮对话中维持上下文。


为什么 JSON 仍然有用

JSON 格式主要用于组织数据集:

[
  {"role":"system","content":"你很有帮助。"},
  {"role":"user","content":"你好"},
  {"role":"assistant","content":"你好!"}
]

在训练之前,预处理步骤会应用模型的聊天模板,生成一个单一的文本序列,例如

<System>
你很有帮助。

<User>
你好

<Assistant>
你好!

然后,这段文本会被词元化,并用于下一个词元预测。


与 nanoGPT 的联系

这是关键的联系:

预训练

维基百科文章

↓

预测下一个词元

SFT

User:
问题

Assistant:
回答

↓

预测助手的下一个词元

训练目标仍然完全相同:下一个词元预测。唯一的区别是:

所以你的理解是正确的:对话 JSON 被转换为格式化的文本序列,进行词元化,然后模型再次通过下一个词元预测进行训练。SFT 中主要的附加技术是损失掩码,它确保模型学会生成助手的回答,而不是简单地预测提示中的每一个词元。


AI生成和翻译,但整理分享仍需精力。如果觉得有帮助,欢迎 捐助支持。 微信:@lzwjavaWeChat QR · X: @lzwjava · 打个招呼 👋

返回 捐助