大语言模型(LLM)入门:从Transformer到ChatGPT

前言

前面我们用C语言实现了Transformer的核心结构。但你可能想问:ChatGPT和我们的简化版Transformer之间,到底差了什么?

今天,我们从工程视角拆解大语言模型(LLM)的关键技术:

· 预训练 + 微调:为什么GPT需要"海量数据预训练"

· 生成策略:贪心搜索、束搜索、温度采样

· 上下文窗口:为什么ChatGPT能记住之前的对话

· RLHF:如何让模型更"听话"

不写完整代码(动辄万行),但讲清楚核心原理。


一、从GPT到ChatGPT:进化路线

```

年份 模型 参数量 训练数据

2018 GPT-1 1.17亿 BooksCorpus

2019 GPT-2 15亿 40GB网页

2020 GPT-3 1750亿 570GB

2022 InstructGPT ~GPT-3 +人类反馈

2022 ChatGPT ~GPT-3.5 +对话微调

2023 GPT-4 估计万亿级 更大更多

```

核心思想:越大越好 + 越多越好

维度 小模型(我们实现的) 大模型(GPT)

参数量 ~10万 1750亿

训练数据 几KB 几百GB

训练时间 秒级 数月

硬件 CPU 万卡GPU集群


二、预训练:让模型学会"说话"

2.1 什么是预训练?

把海量互联网文本(维基百科、书籍、网页)喂给模型,让它学会:

· 语法:主语+谓语+宾语

· 常识:太阳从东边升起

· 推理:如果A=B且B=C,那么A=C

· 知识:北京是中国的首都

2.2 预训练任务:预测下一个词

```

训练样本:

输入: "中国的首都是"

目标: "北京"

输入: "1 + 1 ="

目标: "2"

输入: "人工智能的英文是"

目标: "AI"

```

损失函数:交叉熵损失

```

Loss = -log P(目标词 | 输入)

```

2.3 规模法则(Scaling Law)

OpenAI发现:模型越大、数据越多、算力越强,性能就越好

参数规模 10³ 10⁶ 10⁹ 10¹²

性能 差 一般 好 惊艳

这就是为什么GPT-3(1750亿)比GPT-2(15亿)强那么多。


三、生成策略:如何让模型"输出文字"

训练好的模型只是知道每个词的概率,但如何产生一段连贯的文字?

3.1 贪心搜索(Greedy Search)

每次都选概率最大的词:

```

输入: "今天天气"

Step1: P("很")=0.5, P("不")=0.3, P("真")=0.2 → 选"很"

Step2: 输入"今天天气很",P("好")=0.6, P("热")=0.4 → 选"好"

输出: "今天天气很好"

```

优点:简单快速

缺点:容易重复、缺乏创造性

```python

def greedy_search(model, input_tokens, max_len):

for _ in range(max_len):

next_token = argmax(model.predict(input_tokens))

input_tokens.append(next_token)

return input_tokens

```

3.2 束搜索(Beam Search)

保留k个最优候选,拓宽搜索空间:

```

k=2 (束宽度=2)

Step1: [("很", 0.5), ("不", 0.3)] # 保留2个

Step2: 从"很"扩展: "很好"(0.5*0.6=0.3), "很热"(0.5*0.4=0.2)

从"不"扩展: "不好"(0.3*0.7=0.21), "不错"(0.3*0.2=0.06)

保留top2: ("很好",0.3), ("不好",0.21)

输出: "很好" 或 "不好"

```

优点:质量更高

缺点:计算量大

```python

def beam_search(model, input_tokens, beam_width, max_len):

sequences = [(input_tokens, 1.0)]

for _ in range(max_len):

all_candidates = []

for seq, score in sequences:

probs = model.predict(seq)

for i, p in enumerate(top_k(probs, beam_width)):

all_candidates.append((seq + [i], score * p))

sequences = sorted(all_candidates, key=lambda x: -x[1])[:beam_width]

return sequences[0][0]

```

3.3 温度采样(Temperature Sampling)

添加"随机性",让模型更有创造性:

```python

def temperature_sample(logits, temperature):

temperature=0 → 贪心(确定)

temperature=1 → 原始概率

temperature>1 → 更随机

probs = softmax(logits / temperature)

return random_choice(probs)

```

温度 效果 适用场景

0.1 几乎确定 代码生成、翻译

0.7 平衡 对话、写作

1.0 随机 创意写作

3.4 Top-K + Top-P 采样

现代LLM的组合策略:

```

Top-K: 只保留概率最高的K个词

Top-P: 保留累积概率达到P的词(核采样)

例: 概率分布 [0.4, 0.3, 0.1, 0.05, 0.05, 0.03, 0.02, 0.02, 0.02, 0.01]

Top-K=3 → [0.4, 0.3, 0.1] # 只保留前3个

Top-P=0.7 → [0.4, 0.3] # 累积到0.7

```


四、上下文窗口:如何"记住"对话

4.1 什么是上下文窗口?

模型一次能处理的最大token数量。

模型 上下文窗口

GPT-3 2048

GPT-3.5 4096

GPT-4 8192 / 32768

Claude 2 100000

4.2 为什么窗口很重要?

```

用户: 我叫张三

AI: 你好,张三!

用户: 我叫什么名字? ← 需要记住之前的对话

AI: 你叫张三

```

如果窗口不够长,模型会"忘记"前面的内容。

4.3 长窗口的技术挑战

· 注意力复杂度O(n²):窗口100k时,计算量巨大

· 内存占用:需要存储100k×100k的注意力矩阵

· 位置编码:需要支持超长序列的位置编码

解决方案:

· 稀疏注意力(如Longformer)

· 滑动窗口注意力

· 线性注意力(如RWKV)


五、指令微调:让模型"听话"

5.1 预训练模型的问题

预训练模型学会了"预测下一个词",但它不一定理解用户的意图:

```

用户: "给我讲个笑话"

预训练模型: "给我讲个笑话"是用户的要求,我应该..." ← 在解释,没讲笑话

```

5.2 指令微调(Instruct Fine-tuning)

用问答对继续训练:

输入 输出

"讲个笑话" "为什么程序员总是混淆万圣节和圣诞节?因为Oct 31 == Dec 25!"

"解释什么是AI" "AI是人工智能的缩写..."

经过微调,模型学会:用户问什么,我就答什么。

5.3 对话微调(Chat Fine-tuning)

用多轮对话数据训练:

```

{"role": "user", "content": "你好"}, {"role": "assistant", "content": "你好!有什么我可以帮你的?"}, {"role": "user", "content": "我叫张三"}, {"role": "assistant", "content": "你好张三!很高兴认识你"}

```

ChatGPT就是经过对话微调的GPT-3.5。


六、RLHF:让模型"对齐人类偏好"

6.1 为什么还需要RLHF?

即使经过指令微调,模型还是会:

· 输出有害内容

· 编造事实(幻觉)

· 不遵循复杂指令

6.2 RLHF三步走

Step 1:收集人类偏好数据

让人类标注员对模型输出进行排序:

```

输出A: "我不确定..."

输出B: "根据资料,答案是..."

人类偏好: B > A

```

Step 2:训练奖励模型(Reward Model)

奖励模型学会:给"好"的输出打高分,给"差"的输出打低分。

Step 3:用强化学习优化模型(PPO算法)

让模型生成内容 → 奖励模型打分 → 高分鼓励,低分惩罚 → 模型自我改进

6.3 效果对比

模型 有用性 无害性 诚实性

GPT-3(预训练) 差 差 差

+指令微调 中 中 中

+RLHF 好 好 好

ChatGPT = GPT-3 + 指令微调 + RLHF


七、部署推理:如何用起来

7.1 推理优化技术

技术 原理 加速比

KV Cache 缓存已计算的K/V,避免重复计算 10x

量化(INT8/INT4) 用更少位数表示权重 4x

Flash Attention 优化注意力计算 2x

批处理 同时处理多个请求 按需

7.2 硬件需求

模型规模 内存(FP16) 推荐显卡

1B 2GB 任意GPU

7B (LLaMA) 14GB RTX 3090/4090

13B 26GB A100(40G)

70B 140GB 多卡A100

175B (GPT-3) 350GB 多卡集群

7.3 开源模型推荐

模型 参数量 特点

LLaMA 3 8B/70B Meta出品,性能强

Mistral 7B 速度快,效果好

Qwen 2.5 7B/72B 阿里出品,中文强

DeepSeek 67B 性价比高

Phi-3 3.8B 微软出品,小体量


八、总结:从我们的C语言模型到ChatGPT

层级 我们的实现 ChatGPT

模型 简化Transformer 优化的GPT架构

参数 约10万 1750亿

训练数据 几KB 几百GB

训练方式 无 预训练+微调+RLHF

生成 简单前向 束搜索+温度采样

对话 不支持 多轮对话

硬件 CPU 万卡集群

核心洞见:

  1. 原理不复杂,工程很复杂

  2. 数据比算法重要(质量 > 创新)

  3. 规模产生奇迹(量变引起质变)


下一篇预告:《从零实现一个推荐系统:协同过滤与矩阵分解》


评论区分享一下你最想用LLM做什么~

相关推荐
金创想3 小时前
积木移动题目分析及解题思路——木块问题(1)
c++·算法·字符串·c·刷题·信息学奥赛·积木
MY_TEUCK3 小时前
【Java 后端 | 微服务远程调用实战】Nacos + OpenFeign 从入门到公共模块抽取
java·开发语言·微服务
love_muming3 小时前
Java编程核心技巧全解析
java·开发语言·idea
『昊纸』℃3 小时前
一篇读懂C语言
c语言·编程语言·嵌入式系统·系统编程·历史发展
wjm0410063 小时前
简单谈谈ios开发中的UI
开发语言·ios·swift
slandarer3 小时前
MATLAB | 土地利用变化桑基图及状态转移桑基图绘制
开发语言·数学建模·matlab·桑基图
BestOrNothing_20153 小时前
C++零基础到工程实战(5.2.4):指针与引用在函数传参、返回值与效率优化中的应用
c++·指针·引用·const·函数参数
L_09073 小时前
【C++】面向对象三大特性之多态
开发语言·c++
threelab3 小时前
Three.js 银河星系效果 | 三维可视化 / AI 提示词
开发语言·javascript·人工智能