1. 从 State of GPT 演讲说起:ChatGPT 到底是怎么被“教”出来的
如果你看过 Andrej Karpathy 那场 State of GPT 的演讲,大概率会有一种“原来如此”的感觉:ChatGPT 不是凭空冒出来的魔法,而是一条被反复打磨的训练流水线。这条流水线大致分成四段——Pretraining、SFT、Reward Modeling、RLHF。其中 Pretraining 吃掉了 99% 的算力时间,但真正让模型“会聊天、听得懂指令、答得像人”的,恰恰是后面三段。
这篇内容聚焦的就是后面三段:SFT、奖励建模、RLHF。我会按训练链路拆开讲原理,同时给出一份可复制的训练阶段对照表、关键术语速查配置,以及验证各阶段输出差异的具体操作步骤。适合谁看?适合已经用过 ChatGPT、想搞清楚它背后训练逻辑的开发者;也适合正在做 LLM 微调、想弄明白 SFT 和 RLHF 到底差在哪的工程同学。
先给一个整体印象:预训练模型像一个读遍了互联网的“文本接龙机器”,你给它一句话,它会顺着往下编。SFT 是拿人工写好的问答对去教它“别人问你就答”;奖励建模是训练一个“打分员”,让它学会判断哪个回答更好;RLHF 则是让模型根据打分员的反馈去调整自己,尽量输出人类更喜欢的回答。这三步环环相扣,缺一不可。
Karpathy 在演讲里有个很关键的判断:判别比生成容易。让标注员从零写一个高质量回答很难,但让他在几个候选回答里挑一个更好的,就简单得多。这个洞察直接解释了为什么 RLHF 有效——它把“生成难题”转化成了“判别任务”,再用强化学习把判别信号回传给模型。
下面我会先讲清楚每个阶段在做什么、数据长什么样、模型怎么更新,再给出一份可以直接对照使用的配置表。如果你手头有 API Key,还可以跟着后面的步骤,实际验证一下不同阶段模型输出的差异。
2. TaoToken 前置准备:把调用环境先搭起来
在动手验证各阶段输出差异之前,得先把调用环境准备好。这里我用 TaoToken 作为统一入口,它的好处是 Base URL 和 Key 的管理比较集中,切换模型也方便。官网地址是 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,API 地址是 https://taotoken.net/api 。
你需要先拿到一个 API Key。进入控制台后创建 Key,然后把它保存好——后面所有请求都要用到。如果你用的是 Claude Code 这类编码工具,或者 Cline、Codex 这类支持自定义 Base URL 的客户端,配置方式基本一致:填 Base URL、填 Key、选 Model ID。
这里要特别提醒一句:无论你用哪种客户端,只要涉及自定义接入,Base URL、API Key、Model ID 这三件套必须写全,缺一个都会报错。很多人卡在 401 或者 local proxy failed,往往就是这三项里有一项没填对。
我试过把 TaoToken 的 Key 配到几个不同的工具里,整体流程是通的。下面给出一份通用的配置片段,你可以按自己用的工具调整格式。比如在 Cline 的 MCP 配置里,或者在 Codex 的 auth.json 里,结构会略有不同,但核心字段是一样的。
先看一份 JSON 格式的配置示例,适合大多数支持 OpenAI 兼容接口的客户端:
{ "base_url": "https://taotoken.net/api", "api_key": "sk-你的Key", "model": "gpt-4o" }如果你用的是 Claude Code,配置会写在 settings 里,格式类似这样:
{ "env": { "ANTHROPIC_BASE_URL": "https://taotoken.net/api", "ANTHROPIC_API_KEY": "sk-你的Key", "ANTHROPIC_MODEL": "claude-3-5-sonnet-20241022" } }注意这里的 Base URL 不要带 UTM 参数,直接用 https://taotoken.net/api 就行。Key 要替换成你自己在控制台创建的那一串。Model ID 根据你要验证的模型来填,比如 gpt-4o、gpt-3.5-turbo 等。
配置好之后,建议先用一个最简单的请求测一下连通性。可以用 curl,也可以用 Python 的 requests。下面给一个 curl 示例:
curl https://taotoken.net/api/v1/chat/completions \ -H "Content-Type: application/json" \ -H "Authorization: Bearer sk-你的Key" \ -d '{ "model": "gpt-4o", "messages": [{"role": "user", "content": "你好"}] }'如果返回里有 choices 字段,说明连通没问题。如果报 401,先检查 Key 有没有复制完整;如果报 model not found,检查 Model ID 拼写。这一步过了,后面验证各阶段输出差异就顺了。
3. 可复制配置:SFT、奖励建模、RLHF 三阶段对照表与参数速查
这一节是全文的核心,我会把 SFT、奖励建模、RLHF 三个阶段的关键参数、数据规模、训练目标整理成一份可以直接对照使用的配置表。你可以把它当成一个速查手册,做微调或者读论文时随时翻。
先看整体对照表:
| 阶段 | 数据规模 | 数据形态 | 训练目标 | 典型算法 | 输出模型 |
|---|---|---|---|---|---|
| SFT | 1万–10万条 | prompt + response 对 | 最大化目标回答的似然 | 监督微调 | SFT 模型 |
| 奖励建模 | 10万–100万条 | prompt + 多个回答 + 排序 | 二分类/回归打分 | 奖励模型训练 | RM 模型 |
| RLHF | 依赖 RM | prompt + 采样回答 | 最大化奖励同时约束偏离 | PPO | RLHF 模型 |
SFT 阶段的数据是人工标注的问答对。标注员拿到一个 prompt,写一个符合 helpful、truthful、harmless 的回答。这个阶段本质上是让模型学会“指令跟随”的格式,知道别人问问题时要给答案,而不是继续接龙。
奖励建模阶段的数据是对比数据。同一个 prompt,SFT 模型生成多个回答,标注员对这些回答排序。Karpathy 特别提到,这个排序任务很难,有时候一个 prompt 的答案要花几个小时来标注。训练时,模型学会给更好的回答打更高的分。
RLHF 阶段用 PPO 算法,根据奖励模型的打分来更新策略。奖励高的回答,其 token 被强化的概率更大;奖励低的回答,token 被抑制。这里有个关键点:RLHF 会降低输出的熵,让模型更确定,而 SFT 模型往往更发散。
下面给出一份更细的参数速查配置,用 TOML 格式表示,方便你直接改:
[sft] data_size = "10k-100k" epochs = 3 learning_rate = 2e-5 batch_size = 64 max_length = 2048 [reward_modeling] data_size = "100k-1M" epochs = 1 learning_rate = 1e-5 batch_size = 32 num_candidates = 4 [rlhf] algorithm = "ppo" kl_coef = 0.1 clip_range = 0.2 learning_rate = 1e-6 batch_size = 16这份配置里的数值是常见起点,不是绝对标准。比如 kl_coef 控制模型偏离 SFT 模型的程度,太小会学不到东西,太大会限制更新。clip_range 是 PPO 的裁剪范围,防止单次更新步子太大。
如果你用的是 Codex 的 auth.json,配置结构会不一样,但核心还是 Base URL、Key、Model ID 三件套。下面给一个 auth.json 的示例:
{ "base_url": "https://taotoken.net/api", "api_key": "sk-你的Key", "model": "gpt-4o", "provider": "openai" }注意,这里的 model 字段要和你实际要调用的模型一致。如果你要验证 SFT 和 RLHF 的输出差异,可以分别用不同的 Model ID 去请求,比如一个偏 SFT 风格的模型和一个偏 RLHF 风格的模型。
再补充一个关键术语速查:
- Pretraining:预训练,用海量文本做下一 token 预测。
- SFT:监督微调,用人工问答对教模型指令跟随。
- Reward Modeling:奖励建模,训练打分模型判断回答好坏。
- RLHF:基于人类反馈的强化学习,用奖励信号更新策略。
- PPO:近端策略优化,RLHF 常用的强化学习算法。
- KL 散度:约束 RLHF 模型不要偏离 SFT 模型太远。
这份对照表和速查配置,你可以直接复制到自己的笔记里。做实验时对照着看,能少走很多弯路。
4. 验证请求:实际对比 SFT 与 RLHF 输出差异的操作步骤
光看理论不够,最好实际跑一下,感受 SFT 模型和 RLHF 模型在输出上的差异。下面给出一套可操作的验证步骤。
第一步,准备两个不同的 Model ID。如果你手头有对应资源,可以用一个偏 SFT 风格的模型和一个偏 RLHF 风格的模型。如果没有,也可以用同一个模型的不同版本做对比,重点观察输出风格。
第二步,设计一组测试 prompt。建议选那种“有明确正确答案但模型可能发散”的问题,比如:
- “写一个判断字符串是否是回文的 Python 函数。”
- “解释一下什么是梯度下降。”
- “给我三个提高睡眠质量的建议。”
这些问题既能考察正确性,也能考察回答的确定性和格式。
第三步,用同一组 prompt 分别请求两个模型,记录输出。下面给一个 Python 脚本示例:
import requests API_URL = "https://taotoken.net/api/v1/chat/completions" API_KEY = "sk-你的Key" def query(model, prompt): headers = { "Content-Type": "application/json", "Authorization": f"Bearer {API_KEY}" } data = { "model": model, "messages": [{"role": "user", "content": prompt}], "temperature": 0.7 } resp = requests.post(API_URL, headers=headers, json=data) return resp.json()["choices"][0]["message"]["content"] prompts = [ "写一个判断字符串是否是回文的 Python 函数。", "解释一下什么是梯度下降。", "给我三个提高睡眠质量的建议。" ] for p in prompts: print("Prompt:", p) print("Model A:", query("gpt-4o", p)) print("Model B:", query("gpt-3.5-turbo", p)) print("---")运行后,重点观察几个维度:回答是否直接切题、是否有多余的追问、格式是否稳定、有没有自我纠错。RLHF 模型通常更倾向于给出确定、简洁、符合人类偏好的回答;SFT 模型可能更发散,有时会给出多个方向。
第四步,做多次采样,观察一致性。把 temperature 调高一点,比如 1.0,同一个 prompt 请求多次,看输出波动。RLHF 模型因为熵更低,多次采样的一致性通常更高。
第五步,记录结果,做成对照表。比如:
| Prompt | 模型 | 是否直接回答 | 是否有追问 | 格式稳定性 |
|---|---|---|---|---|
| 回文函数 | A | 是 | 否 | 高 |
| 回文函数 | B | 是 | 偶尔 | 中 |
这样一轮下来,你对 SFT 和 RLHF 的差异会有直观感受。Karpathy 在演讲里提到,RLHF 模型生成的答案更被人类喜欢,这个结论你自己跑一遍就能验证。
如果你还想验证奖励建模的影响,可以构造几个候选回答,自己先排序,然后看模型更倾向于哪个。虽然普通用户拿不到奖励模型的直接接口,但通过对比不同模型的输出偏好,也能间接感受到奖励信号的作用。
5. 常见报错排查:401、local proxy failed、reading choices、OAuth 怎么处理
配置和调用过程中,最容易撞上的就是几类报错。这一节我把常见错误和排查路径整理出来,你遇到时可以直接对照。
401 Unauthorized:这是最常见的。原因通常是 Key 没填、Key 复制不完整、Key 前后有空格,或者 Base URL 写错了。排查顺序:先确认 Authorization 头里的 Bearer 后面跟的是完整 Key;再确认 Base URL 是 https://taotoken.net/api ,不要多加路径;最后确认 Key 没有过期或被禁用。
local proxy failed:这个报错通常出现在客户端配置了本地代理,但代理没启动或者端口不对。排查时先检查客户端里的代理设置,确认是否有多余的 proxy 配置。如果你没有用代理,就把相关配置清空。另外,Base URL 如果被错误地写成了本地地址,也会触发这个错误。
reading choices 报错:这个一般出现在解析响应时,代码期望有 choices 字段但实际没有。原因可能是请求体格式不对,比如 messages 字段拼写错误,或者 model 字段为空。排查时先把原始响应打印出来,看返回的 JSON 结构。如果返回的是 error 字段,就按错误信息处理。
OAuth 相关报错:如果你用的是 Claude Code 这类需要 OAuth 的工具,可能会遇到 token 过期或授权失败。排查时先确认 OAuth 流程是否走完,token 是否写入配置文件。如果用的是 API Key 模式,就检查 ANTHROPIC_API_KEY 和 ANTHROPIC_BASE_URL 是否都填了。注意,OAuth 和 API Key 是两种模式,不要混用。
再补充一个容易忽略的点:Model ID 拼写错误。比如把 gpt-4o 写成 gpt4o,或者把 claude-3-5-sonnet-20241022 写成 claude-3.5-sonnet,都会报 model not found。排查时直接对照官方文档的 Model ID 列表。
如果你用的是 Cline 的 MCP 配置,报错信息可能会更具体。比如 MCP 连接失败,通常是配置文件路径不对,或者 JSON 格式有语法错误。建议用 JSON 校验工具先检查一遍配置文件。
还有一个高频问题:请求超时。如果网络环境不稳定,或者 prompt 太长,可能会超时。排查时先缩短 prompt,再逐步加长。如果确认是网络问题,可以适当增加超时时间。
最后提醒一句:所有报错排查,第一步都是看原始错误信息。不要只看客户端封装的提示,尽量拿到完整的响应体。很多问题在原始信息里写得很清楚。
6. 从原理到实践:把训练链路认知用到日常开发里
把 SFT、奖励建模、RLHF 这条链路搞清楚之后,你会发现很多日常开发里的现象都能解释了。比如为什么 ChatGPT 有时候会“过度礼貌”,为什么它倾向于给出结构化的回答,为什么它在某些问题上会反复确认——这些都能从 RLHF 的奖励信号里找到线索。
Karpathy 在演讲里给了一个很实用的建议:提示词工程做到头之后,可以尝试 SFT;RLHF 难度大,但理论上能比 SFT 再好一点。这个建议对开发者很有参考价值。如果你在做垂直领域的应用,先做好提示词工程,再考虑用少量数据做 SFT,最后才考虑 RLHF。
另外,Karpathy 提到判别比生成容易,这个思路可以迁移到很多场景。比如你做数据标注,与其让标注员从零写答案,不如让模型生成候选,让标注员排序。这样效率更高,质量也更稳定。
如果你想把这条链路用到自己的项目里,建议先从 SFT 入手。SFT 相对容易,数据量要求也不高,1 万条左右就能看到效果。奖励建模和 RLHF 对工程能力要求更高,训练不稳定是常态,不建议一上来就做。
最后给一个实用技巧:在做对比实验时,固定其他变量,只改一个阶段。比如固定 prompt 和 temperature,只换模型,观察输出差异。这样你才能清楚每个阶段到底带来了什么变化。
如果你在配置或调用过程中遇到问题,可以先去控制台确认 Key 状态,再对照接入文档检查配置。需要验证模型输出时,可以直接用模型对话功能快速测试。长期做编码或 Agent 相关开发的话,Coding Plan 会更合适。把环境搭好,剩下的就是动手跑起来。