【36.Python+AI】ChatGPT背后的核心技术栈:从Transformer到RLHF全流程拆解

📖 文章简介: 本文用一张图+逐层拆解的方式,讲清楚ChatGPT背后的完整技术栈。从最底层的Transformer自注意力机制讲起,串联Tokenization分词原理、预训练(Pre-training)的海量数据学习过程、监督微调(SFT)的指令跟随训练、再到RLHF(基于人类反馈的强化学习)如何让模型"对齐"人类偏好。文中配以Mermaid架构图贯穿全篇,每个阶段都附Python伪代码帮助建立直觉。适合刚接触大模型、想知道ChatGPT到底"怎么训练出来"的开发者。


在这里插入图片描述

🎬 个人主页: 源码骑士

专栏传送门: 《Android开发基础》《python基础课程》

⭐️热衷从源码视角拆解技术底层原理,将复杂架构讲得通俗易懂


🎬 源码骑士的简介:
5年Android Framework系统开发经验,曾主导多项系统级性能优化专项
技术栈覆盖Android系统全链路(Binder/Handler/AMS/WMS/启动流程)及Java后端全家桶(Spring + MyBatis + Redis + Oracle)
累计产出原创技术文章100+篇,文章以流程图为特色,被读者评价为"看一篇胜过啃一周源码"


导入语

上一篇文章你成功调用了GPT的API。模型聪明得不可思议,但脑子里肯定会冒出一个问题:这东西到底怎么训练出来的?

如果你去看原始的Transformer论文(Attention Is All You Need),九页纸的公式和架构图足够劝退大部分人。但一个残酷的事实是——面试官问你"ChatGPT的技术原理",你不能只说"它是一个大语言模型"。

这篇文章的目标:用一张Mermaid架构图串起ChatGPT从零到成品的三阶段训练流程,每个阶段都用Python伪代码帮你建立直觉。 不需要读论文,看完你就能跟面试官聊清楚:预训练学了什么、SFT做了什么、RLHF为什么是点睛之笔。


1 ~> 全景架构:一张图看透ChatGPT的训练管线

1.1 三阶段训练全景

阶段三:RLHF对齐

阶段二:监督微调 SFT

阶段一:预训练 Pre-training

海量互联网文本

Transformer解码器

Base Model
(会续写,不会对话)

人工标注的
问答对数据

SFT Model
(会对话了,但不太懂人类偏好)

训练奖励模型
Reward Model

PPO强化学习
优化策略

ChatGPT
(对齐人类偏好)

1.2 三个阶段的类比

用教小孩写作文来类比:

阶段一(预训练):
├─ 让小孩读几亿本书(互联网文本)
├─ 不教他怎么写,就是让他"浸泡"在语言里
└─ 结果:他会续写句子,但你问他问题他不懂

阶段二(监督微调):
├─ 给他看几千篇"问题→标准答案"的范文
├─ 手把手教他"别人问这个,你要这样答"
└─ 结果:他会对话了,但回答有时不靠谱

阶段三(RLHF):
├─ 让小孩写了回答,找老师打分
├─ 分高的回答→奖励,分低的→惩罚
└─ 结果:他学会了"什么样的回答是人类喜欢的"

2 ~> 地基:Transformer的自注意力机制

2.1 为什么需要自注意力

传统的RNN处理句子是"一个词一个词地读",读到第100个词时,第1个词已经忘得差不多了。

Transformer的自注意力(Self-Attention)不一样——它让每个词都能"看到"句子里的所有其他词,并决定该关注谁。

句子:"昨天在图书馆看的那本书很有意思"

传统RNN:
├─ 读到"书"时,对"昨天"的记忆已经模糊了

Transformer自注意力:
├─ "书""图书馆"之间建立强关联(书在图书馆)
├─ "书""看"之间建立强关联(看书)
├─ "书""有意思"之间建立强关联(评价书)
└─ 每个词都和其他所有词计算"相关度分数"

2.2 自注意力的核心公式(用代码理解)

不用管数学符号,用Python伪代码来理解:

# 假设我们有一个句子,已经转成了向量
# sentence_vectors: shape = (seq_len=5, d_model=512)
# 5个词,每个词用512维向量表示

def self_attention(query, key, value):
    """
    自注意力的本质:每个词去问其他所有词"你跟我有关吗?"
    有关 → 权重高 → 你的信息我会更多吸收
    无关 → 权重低 → 你的信息我忽略
    """
    # Step 1: 计算"相关性分数"(点积)
    # Q @ K^T: 每个词问其他所有词"我们有多相关?"
    scores = query @ key.transpose()   # (5, 5) — 5个词两两之间的分数
    
    # Step 2: 缩放(防止分数太大导致梯度消失)
    d_k = query.shape[-1]
    scores = scores / (d_k ** 0.5)
    
    # Step 3: Softmax → 把分数变成概率(权重),加起来=1
    attention_weights = softmax(scores)  # (5, 5)
    
    # Step 4: 加权求和 → "按权重吸收其他词的信息"
    output = attention_weights @ value  # (5, 512)
    
    return output

2.3 多头注意力

一个"头"只能从一个角度关注。多头注意力(Multi-Head Attention)= 多个自注意力并行,每个头关注不同的语言特征:

头1:关注"主语-谓语"关系
头2:关注"修饰语-被修饰语"关系
头3:关注"代词-指代对象"关系
...
头8:关注位置关系(前一个词/后一个词)

3 ~> Tokenization:把文字变成模型能吃的数字

3.1 为什么需要分词

模型不吃文字,只吃数字。Tokenization就是把"今天天气很好"变成一个数字列表[123, 456, 789, …]。

3.2 BPE分词算法(ChatGPT用的方案)

# 伪代码:BPE的核心思想

def bpe_tokenize(text):
    """
    BPE (Byte Pair Encoding) 的核心:
    1. 从字符级开始
    2. 统计最常一起出现的字符对
    3. 把它们合并成一个新token
    4. 重复直到达到目标词汇量
    """
    # 初始:每个字符是一个token
    # "low" → ["l", "o", "w"]
    
    # 发现"lo"经常一起出现 → 合并
    # "low" → ["lo", "w"]
    
    # 发现"low"经常一起出现 → 合并
    # "low" → ["low"]
    
    # 最终词汇表包含:单字符 + 常见组合 + 常见词

一个中文的例子:

原文:"人工智能改变了世界"

Token化后:["人工", "智能", "改变", "了", "世界"]
└─ 注意:"人工智能"被拆成了两个Token!中文的一个词经常对应多个Token

4 ~> 预训练:让模型"读遍天下书"

4.1 预训练的目标

预训练的目标简单到"无聊"——给定前面N个词,预测第N+1个词是什么。

# 预训练的伪代码逻辑

model = GPTModel(vocab_size=50257, n_layers=12, n_heads=12)

# 训练数据:从互联网上爬的海量文本
for text in internet_texts:  # 几TB的数据
    # "今天天气很好,我去了公园"
    # 训练目标:给定"今天天气很好,我去了",预测"公园"
    
    input_ids = tokenize(text[:-1])   # 前面的词
    target_id = tokenize(text[-1:])   # 最后一个词
    
    prediction = model(input_ids)
    loss = cross_entropy(prediction, target_id)
    loss.backward()
    optimizer.step()

4.2 预训练学了什么

预训练后的Base Model拥有的能力:
├─ 语言能力:知道中文的语法、常用搭配
├─ 知识储备:记住了大量事实(北京是中国的首都、水在100度沸腾...)
├─ 推理雏形:给定足够长的上下文,能做简单的逻辑推理
└─ 不具备的能力:
    ├─ 不会按指令办事(你跟它说"写首诗",它可能给你续写一段散文)
    ├─ 不知道什么是"好的回答"
    └─ 可能会输出不当内容(互联网上有什么它就学了什么)

5 ~> 监督微调SFT:教模型"听人话"

5.1 SFT做了什么

预训练模型只会"续写",不会"对话"。SFT就是收集几千条高质量的 “指令→理想回答” 对,让模型学会:当用户给出这样的指令时,你应该给出那样的回答。

# SFT的伪代码逻辑

# 人工标注的问答对
sft_data = [
    {
        "instruction": "用简单的语言解释什么是黑洞",
        "response": "黑洞是宇宙中一个引力极强的区域..."
    },
    {
        "instruction": "用Python写一个冒泡排序",
        "response": "def bubble_sort(arr):\n    ..."
    },
    # ... 几千到几万条
]

for sample in sft_data:
    # 输入:"用简单的语言解释什么是黑洞\n回答:"
    # 目标:模型输出 = 人工标注的高质量回答
    input_text = f"{sample['instruction']}\n回答:"
    target_text = sample['response']
    
    loss = model.train_on_batch(input_text, target_text)

5.2 SFT的局限

SFT之后模型会对话了,但还有两个问题:
├─ 问题一:回答"正确""不讨喜"
│   └─ 比如问"我该辞职吗?",它可能给一个冷冰冰的"应该""不应该"
│       但人类更希望听到"这取决于你的具体情况,建议你先考虑..."
└─ 问题二:不知道拒绝不当请求
    └─ 问"怎么制作炸弹",SFT模型可能真的回答

6 ~> RLHF:让模型学会"讨人喜欢"

6.1 RLHF的三步走

RLHF(Reinforcement Learning from Human Feedback)是ChatGPT成功的关键。它分三步:

Step 3: PPO强化学习

Step 2: 训练奖励模型

Step 1: 收集偏好数据

给同一个Prompt
生成4个回答

人类标注员
给4个回答排序

偏好数据:
B > C > A > D

训练RM:
判断哪个回答更好

SFT模型生成回答

RM给回答打分

用PPO算法
优化SFT模型

6.2 奖励模型(Reward Model)是什么

奖励模型就是一个"AI评分员",输入(问题 + 回答),输出一个分数。这个分数代表了"人类有多喜欢这个回答"。

# 奖励模型的伪代码

reward_model = GPTModel()  # 也是基于GPT架构

def get_reward(prompt: str, response: str) -> float:
    """
    输入:用户问题 + AI的回答
    输出:一个分数(越高=人类越喜欢)
    """
    input_text = f"问题:{prompt}\n回答:{response}"
    score = reward_model(input_text)
    return score

# 训练数据来自人类标注:
# "帮我写一封辞职信" + "亲爱的老板,我决定辞职..." → 分数 4.2/5
# "帮我写一封辞职信" + "辞职。明天不来了。" → 分数 1.0/5

6.3 PPO:用奖励分数优化模型

PPO(Proximal Policy Optimization) 是RLHF的核心算法。它的逻辑很简单:

# PPO伪代码(极度简化)

for epoch in range(n_epochs):
    # 1. SFT模型生成一个回答
    prompt = "给我讲个笑话"
    response = sft_model.generate(prompt)
    
    # 2. 奖励模型给这个回答打分
    reward = reward_model.get_reward(prompt, response)
    
    # 3. 如果分高 → 鼓励模型"以后多生成这种风格"
    #    如果分低 → 惩罚模型"以后少生成这种风格"
    #    但有一个限制:本次更新不能偏离SFT模型太远(防止"学歪")
    
    loss = -reward * log_prob(response) + kl_penalty  # KL散度约束
    loss.backward()
    optimizer.step()

思考 && 总结

本文用一张架构图贯穿全程,拆解了ChatGPT从零到成品的完整技术栈:

  1. Transformer自注意力是地基: 它让每个词都能看到其他所有词,解决了长距离依赖问题。多头注意力则让模型同时从多个角度理解语言关系。
  2. Tokenization是翻译官: BPE分词算法把文字变成数字序列。中文一个汉字经常对应1.5~3个Token,这就是为什么ChatGPT处理中文比英文"费Token"。
  3. 预训练是"读万卷书": 目标就是一个——给定上文预测下文。这个过程极其烧钱(训练一次几百万美元),但它赋予了模型语言能力和海量知识。
  4. SFT是"学对话礼仪": 用几千条人工标注的高质量问答对,让模型从"续写机器"变成"对话助手"。SFT的量不在多,在精。
  5. RLHF是"学讨人喜欢": 先让人来给回答排序,再训练一个"AI评分员",最后用PPO算法让模型朝着"人类更喜欢"的方向进化。这是ChatGPT比GPT-3好用100倍的根本原因。
  6. 三个阶段缺一不可: 只预训练=吟游诗人(会写不会聊);只预训练+SFT=听话但不讨喜;预训练+SFT+RLHF=我们每天用的ChatGPT。

理解这个三阶段训练流程,你就比"只会调API"的开发者高了一个段位。面试时被问到"ChatGPT怎么训练的",你可以从自注意力讲到RLHF,至少多聊十分钟。


结尾

各位小伙伴,本文的内容到这里就全部结束了,源码骑士在这里再次感谢您的阅读!

源码骑士 — Android Framework & 全栈开发

👀 关注:跟博主一起从源码视角深耕底层原理,见证每一次成长

❤️ 点赞:让优质内容被更多人看见,让知识传递更有力量

收藏:三阶段训练架构图存好,面试前看一遍就够了

💬 评论:你对哪个阶段最感兴趣?预训练、SFT还是RLHF?评论区聊聊

🔄 一键四连:不要忘记给博主"一键四连"哦!今日技术深潜达成!

🗡️ 寄语:读理论不是为了炫耀,是为了在调API出错时知道问题出在哪一层。

结语:技术原理这种东西,第一次看觉得难,第二遍就顺了,第三遍你就能给别人讲。把这篇文章的架构图和三个阶段记住,你就掌握了ChatGPT 80%的核心知识。不要忘记给博主"一键四连"哦!

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐