
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_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_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 三个阶段的关键参数、数据规模、训练目标整理成一份可以直接对照使用的配置表。你可以把它当成一个速查手册做微调或者读论文时随时翻。先看整体对照表阶段数据规模数据形态训练目标典型算法输出模型SFT1万–10万条prompt response 对最大化目标回答的似然监督微调SFT 模型奖励建模10万–100万条prompt 多个回答 排序二分类/回归打分奖励模型训练RM 模型RLHF依赖 RMprompt 采样回答最大化奖励同时约束偏离PPORLHF 模型SFT 阶段的数据是人工标注的问答对。标注员拿到一个 prompt写一个符合 helpful、truthful、harmless 的回答。这个阶段本质上是让模型学会“指令跟随”的格式知道别人问问题时要给答案而不是继续接龙。奖励建模阶段的数据是对比数据。同一个 promptSFT 模型生成多个回答标注员对这些回答排序。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: fBearer {API_KEY} } data { model: model, messages: [{role: user, content: prompt}], temperature: 0.7 } resp requests.post(API_URL, headersheaders, jsondata) 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 在演讲里给了一个很实用的建议提示词工程做到头之后可以尝试 SFTRLHF 难度大但理论上能比 SFT 再好一点。这个建议对开发者很有参考价值。如果你在做垂直领域的应用先做好提示词工程再考虑用少量数据做 SFT最后才考虑 RLHF。另外Karpathy 提到判别比生成容易这个思路可以迁移到很多场景。比如你做数据标注与其让标注员从零写答案不如让模型生成候选让标注员排序。这样效率更高质量也更稳定。如果你想把这条链路用到自己的项目里建议先从 SFT 入手。SFT 相对容易数据量要求也不高1 万条左右就能看到效果。奖励建模和 RLHF 对工程能力要求更高训练不稳定是常态不建议一上来就做。最后给一个实用技巧在做对比实验时固定其他变量只改一个阶段。比如固定 prompt 和 temperature只换模型观察输出差异。这样你才能清楚每个阶段到底带来了什么变化。如果你在配置或调用过程中遇到问题可以先去控制台确认 Key 状态再对照接入文档检查配置。需要验证模型输出时可以直接用模型对话功能快速测试。长期做编码或 Agent 相关开发的话Coding Plan 会更合适。把环境搭好剩下的就是动手跑起来。