深度学习与生成式AI理论
本文是《人工智能训练师基础》系列的第三章独立扩展版。原系列把数据结构、算法、人工智能基础、机器学习、深度学习、生成式AI、伦理安全七大模块挤在一篇里,理论细节常常只能点到为止。本章单独拆出来讲透——深度学习与生成式AI是整个理论体系的核心内容,也是后续实操模块(模型微调、训练任务)的理论根基,所以这一章得啃下来。原文只讲了思路的部分,这次我会用具体数字带你一步步算一遍,把”听懂了”变成”真正会算”。
第三章 深度学习与生成式人工智能理论:从神经网络到大模型
深度学习与生成式AI是核心重点内容,虽然原清单只把”人工智能基础”列为重点模块,但DL和生成式AI的理论部分会和其它模块交叉,且是后续实操模块的理论根基,必须讲清核心。
激活函数:给网络加非线性
没有激活函数,多层网络无论堆多深都等价于一个线性变换,等于白搭。激活函数就是把线性结果”掰弯”的非线性函数。
Sigmoid 把任意实数压到 (0,1) 区间,输出可以解释成概率,所以二分类输出层常用它。但它有两个臭名昭著的毛病:一是梯度消失,当输入很大或很小时导数接近0,反向传播时梯度一层层衰减下去;二是输出非零中心,会让下一层梯度总往一个方向走,收敛慢。现在基本只在输出层用,隐藏层早就不用了。
ReLU 是当前隐藏层的绝对主力,公式就是 max(0, x),正区间导数恒为1,彻底解决了正区间的梯度消失问题,计算还特别快。它为什么能缓解梯度消失?因为只要神经元活着(输入大于0),梯度就能一路畅通地传回去,不会被层层相乘稀释掉。ReLU 的缺点是”神经元死亡”——如果某个神经元输入长期小于0,它的梯度永远是0。补救办法是 LeakyReLU,负区间给一个很小的斜率,让神经元还有一线生机。
Softmax 不是单值激活,而是把一个向量”归一化”成概率分布,所有分量之和为1,多分类输出层标配。
记住一句话:隐藏层默认 ReLU,二分类输出用 Sigmoid,多分类输出用 Softmax。
动手算一算:三种激活函数的输出和梯度
光记公式容易混,咱们拿一个具体输入走一遍。设输入 x = 2.0。
1 | import math |
几个关键观察你跟着对一遍:
- ReLU 输出 2.0、梯度 1.0——梯度原封不动传回去,这就是”只要活着梯度就畅通”。
- Sigmoid 输出 0.8808、梯度只有 0.1050,已经损失近九成。再看 x = -3.0 时 Sigmoid 输出 ≈ 0.0474、梯度 ≈ 0.0452,离 0 已经很近了——这就是”输入很大或很小时梯度趋零”。
- Tanh 在 x=2.0 时输出 0.9640、梯度 0.0707,比 Sigmoid 略好但仍衰减明显。
记住一个数字感觉:Sigmoid 导数最大值在 x=0 处,刚好是 0.25。也就是说哪怕在最理想情况下,每经过一层 Sigmoid,梯度最多只剩四分之一,连乘十层就只剩 0.25 的 10 次方。这就是下一节梯度消失的根骨。
损失函数与优化器:网络怎么学
损失函数衡量”预测值离真实值有多远”。回归问题用 MSE 均方误差,分类问题用交叉熵,它衡量两个概率分布的差异,配合 Softmax 时梯度形式非常简洁(预测概率减真实概率),收敛快。
反向传播是训练的核心机制,本质是用链式法则从输出层往输入层逐层算梯度。算出梯度后,优化器决定怎么用这些梯度更新参数。
最基础的是 SGD 随机梯度下降,参数往梯度的反方向走一步,步长由学习率控制。Momentum 加了”动量”,把历史梯度做指数加权平均,相当于给小球加了惯性,能冲过小坑、减少震荡。RMSprop 给每个参数单独维护一个学习率,按梯度平方的滑动平均自适应缩放。Adam 是 Momentum 和 RMSprop 的结合体,同时维护梯度的一阶矩和二阶矩的滑动平均并做偏差修正,是目前最常用的”默认选择”,收敛快、调参少。实际应用中如果遇到”哪个优化器对稀疏梯度友好、自适应学习率”的问题,重点候选就是 Adam 和 RMSprop。
学习率不是越小越好——太小收敛慢,太大会在最优点附近震荡甚至发散。实战中常用学习率调度,比如余弦退火、Warmup。
动手算一算:反向传播的链式法则
光说”链式法则从输出往输入逐层算梯度”很抽象,咱们建一个最小网络手算一遍。
网络结构:输入 x → 隐层 z1 = w1·x + b1,激活 a1 = σ(z1) → 输出层 z2 = w2·a1 + b2,激活 y = σ(z2) → 损失 L = 0.5·(y - t)²。设 x=1.0, w1=0.5, b1=0, w2=0.5, b2=0, 真实标签 t=1.0。
1 | import math |
观察一下两个梯度的大小:w2 拿到 -0.0643,w1 拿到 -0.0121。浅层 w1 的梯度只有输出层的五分之一左右——这就是梯度在反向过程中被层层稀释的直观体现。如果再用 Sigmoid 把导数压到 0.25,连个十层八层,浅层梯度直接归零。
如果用学习率 η=0.1 更新:w2_new ≈ 0.5 - 0.1×(-0.0643) = 0.5064;w1_new ≈ 0.5 - 0.1×(-0.0121) = 0.5012。这就是一次梯度下降的完整闭环。
动手算一算:Sigmoid 导数连乘如何让梯度归零
接着上面的观察,咱们专门演示梯度消失。Sigmoid 导数最大值是 0.25(出现在 x=0 处),其他位置更小。假设一个 10 层网络,每层都用 Sigmoid,反向传播时梯度连乘:
1 | # 假设每层都恰好工作在 Sigmoid 导数最大处 0.25 |
10 层之后梯度只剩 0.00000095,参数几乎不动了。这就是为什么深层网络早期训不动。把激活换成 ReLU 后,正区间导数恒为 1:
1 | relu_grad = 1.0 |
对比一目了然:ReLU 让梯度能原封不动地传回浅层,这就是它成为隐藏层默认选择的根骨。
CNN:卷积如何”看”图
CNN 解决了 MLP 参数爆炸的问题,靠的是两个核心思想:局部连接和权值共享。
卷积层用一个小小的卷积核(比如3×3)在整张图上滑动,每次只看局部一块,这就是局部连接。更妙的是,同一个卷积核在滑动过程中权重不变——这就是”权值共享”,可以形象理解为”用同一个滤镜扫整张图”。一张图里无论猫耳朵在左上角还是右下角,同一个滤镜都能识别出来,这叫平移不变性。这样一来,3×3 的核只有9个参数,远比全连接层省。
卷积层有几个关键超参数:卷积核大小、步长 stride、填充 padding。输出尺寸公式记一下:输出边长 = (输入边长 - 卷积核大小 + 2×填充) / 步长 + 1,向下取整。当步长为2、不填充时,输出尺寸会减半,相当于做了下采样。
池化层就是降采样,最常用的是最大池化 MaxPool,在窗口里取最大值,作用是缩小特征图、降低计算量、增加平移鲁棒性,没有参数。
批归一化 BatchNorm 是个里程碑式技巧:给每一层的输入做标准化,减去均值除以标准差,再用两个可学习参数缩放和偏移。好处是让每层输入分布稳定、允许用更大学习率、加速收敛。一句话总结:BatchNorm 就是给每层输入做标准化。注意它在训练和推理时行为不同——训练用 batch 统计量,推理用全量滑动平均。它和 LayerNorm 别混——BatchNorm 沿 batch 维度归一化(适合 CV),LayerNorm 沿特征维度归一化(适合 NLP/Transformer)。
经典架构发展脉络必须记清楚。LeNet 是 LeCun 在1998年搞的,第一个成功的 CNN,识别手写数字。AlexNet 在2012年 ImageNet 比赛一战成名,首次用 ReLU、Dropout、GPU 训练【需网络查询确认:AlexNet 具体年份与作者】。VGG 探索了”用堆叠小卷积核代替大卷积核”的思想,两个3×3卷积的感受野等于一个5×5,但参数更少、非线性更多。ResNet 是何恺明的代表作,提出了残差连接,让网络可以堆到152层甚至更深而不退化——核心是让输入直接跳过几层加到输出上,网络学的是”残差”而非”恒等映射”,解决了深层网络退化问题。Inception 走的是”多尺度并行卷积”路线。
动手算一算:一次卷积操作的全过程
光说”卷积核在图上滑动”不直观,咱们手动跑一遍。设输入是 3×3 矩阵,卷积核 2×2,步长 stride=1,不填充 padding=0:
1 | import numpy as np |
逐个位置给你看:
- 左上角 (0,0) 看到子矩阵 [[1,2],[4,5]],跟核 [[1,0],[0,1]] 对应相乘再求和:1×1 + 2×0 + 4×0 + 5×1 = 6。
- 右上角 (0,1) 子矩阵 [[2,3],[5,6]]:2×1 + 3×0 + 5×0 + 6×1 = 8。
- 左下角 (1,0) 子矩阵 [[4,5],[7,8]]:4 + 8 = 12。
- 右下角 (1,1) 子矩阵 [[5,6],[8,9]]:5 + 9 = 14。
输出就是 [[6, 8], [12, 14]]。这个核的效果相当于”取对角线元素之和”——你滑动它扫过整张图,效果就像用同一块滤镜扫整张图,这就是”权值共享”的直观含义。如果换成步长 stride=2,输出尺寸变成 (3-2)//2 + 1 = 1,只剩一个值,相当于做了一次下采样。
动手算一算:MaxPool 池化操作
池化比卷积还简单。设输入 4×4 矩阵,MaxPool 窗口 2×2,步长 2:
1 | import numpy as np |
四个窗口逐个看:左上 [[1,3],[5,6]] 取最大 6;右上 [[2,4],[7,8]] 取最大 8;左下 [[9,4],[1,2]] 取最大 9;右下 [[3,2],[5,6]] 取最大 6。整个过程没有可学习参数,纯粹是”挑最大的那个”——作用是缩小特征图、降低计算量,还能让特征对小幅度平移更鲁棒(移动一两格最大值往往不变)。
动手算一算:BatchNorm 标准化、缩放、偏移
BatchNorm 听起来玄乎,其实就三步:减均值、除标准差、再做缩放和偏移。设一个 batch 有 4 个样本的某个特征值:x = [2.0, 4.0, 6.0, 8.0],可学习参数 γ=2.0、β=1.0:
1 | import numpy as np |
走一遍数字感觉:
- 原始数据 [2,4,6,8] 分布在 2 到 8 之间。
- 减均值 5.0 后变成 [-3,-1,1,3],再除以标准差 2.2361 变成 [-1.34,-0.45,0.45,1.34]——这就是”标准正态分布”的形状,均值 0、方差 1。
- 最后乘 γ=2 加 β=1,输出 [-1.68, 0.11, 1.89, 3.68]——分布形状不变,但被拉伸和平移了。
γ 和 β 是网络自己学的:如果它发现”原始分布其实更好”,可以把 γ 学成 1、β 学成 0,等于跳过 BatchNorm;如果发现”标准化后丢掉了某些尺度信息”,可以用 γ 拉回来。所以 BatchNorm 不是死板的归一化,而是”先归一化再让模型自己决定要不要复原”——这就是它的精妙之处。
动手算一算:残差连接让梯度直达浅层
ResNet 的残差连接 y = x + F(x) 看着就一行公式,但它解决了一个大问题。咱们看一个对比,假设有 3 层网络,每层梯度衰减因子是 0.1:
1 | # 不用残差:梯度逐层连乘 |
不用残差时浅层梯度只有 0.001,参数几乎不动;加上残差后梯度至少是 1,浅层照样能更新——这就是”让网络可以堆到 152 层还不退化”的核心机制。
再用一个具体的前向数值感受一下”学残差”和”学恒等映射”的区别。设输入 x=1.0,浅层 F(x) 初始输出 0.01(接近 0):
- 不用残差:y = F(x) = 0.01,模型要直接学出”输出 1.0”,难度大。
- 用残差:y = x + F(x) = 1.0 + 0.01 = 1.01,模型只要让 F(x) 趋近 0 就等于恒等映射,学习目标变成”学残差”,难度大幅降低。
这就是 ResNet 的双重好处:前向上”学恒等映射很容易”,后向上”梯度能直达浅层”。
RNN与LSTM:处理序列的记忆机器
RNN 专门处理序列数据(文本、语音、时序),核心思想是”当前输出不仅依赖当前输入,还依赖上一时刻的隐状态”。隐状态就像网络的短期记忆。但原始 RNN 有个致命问题:长程依赖,序列一长,反向传播时梯度要么消失要么爆炸。
LSTM 用精巧的”门控”机制解决了这个问题。它有三个门:遗忘门、输入门、输出门,外加一个细胞状态 cell state。可以用”记忆的写/读/遗忘”来类比:遗忘门决定从长期记忆里忘掉什么,输入门决定把新信息写进长期记忆多少,输出门决定基于当前记忆输出什么。细胞状态是一条贯穿全程的”传送带”,信息可以几乎无损地流过去,梯度也能顺畅回流,这就解决了长程依赖。
GRU 是 LSTM 的简化版,把三个门简化成两个(更新门和重置门),参数更少、训练更快,效果在很多任务上和 LSTM 接近。
双向 RNN 让序列的每个位置都能看到前后文信息,适合离线任务。序列到序列 Seq2Seq 是”编码器-解码器”结构,典型应用是机器翻译,后来有了注意力机制来缓解定长向量的信息损失瓶颈,再后来注意力机制演化成了 Transformer。
动手算一算:LSTM 三个门怎么开门
LSTM 公式背起来很烦,咱们用一个最小数字示例把流程走通。设当前输入 x_t = 0.5,上一时刻隐状态 h_{t-1} = 0.3,上一时刻细胞状态 C_{t-1} = 0.7。为了聚焦在”门怎么开”这件事上,假设 W·[h_{t-1}, x_t] + b 已经被算好成一个标量(实际是向量,原理一样)。
1 | import math |
跟着数字走一遍你就能看清门控的本质:
- 遗忘门开 0.73,意味着旧细胞状态 0.7 被保留了约 73%(贡献 0.5118)。
- 输入门只开 0.38,意味着新候选内容 0.4621 只写入了 38%(贡献 0.1744)。
- 两者相加得到新细胞状态 0.6862——和旧的 0.7 接近,因为遗忘门开得大、输入门开得小,”短期记忆基本没换”。
- 输出门开 0.69,把细胞状态过 tanh 压一下再放出去 69%,得到新隐状态 0.4109。
关键直觉:细胞状态 C_t 是一条”传送带”,门只是在控制”留多少、写多少、说多少”。反向传播时梯度沿 C_t 这条传送带回流,门控只起”乘上一个 0~1 的系数”的作用,不会像 RNN 那样反复乘权重导致爆炸或消失——这就是 LSTM 解决长程依赖的根骨。
正则化与优化策略
Dropout 是隐藏层正则化的经典做法:训练时随机让一部分神经元”掉线”(输出置0),推理时全部启用但权重缩放。直观理解是每次训练的是不同子网络,相当于模型集成,强迫网络不要过度依赖个别神经元。BatchNorm 除了稳定分布本身也有正则化效果。L1 正则化产生稀疏权重做特征选择,L2 正则化让权重整体变小更平滑。早停 Early Stopping 是性价比最高的正则化:在验证集损失不再下降反而上升时停止训练。数据增强对图像特别有用——翻转、旋转、裁剪等。
优化策略这边还有权重初始化:不能全置0,也不能随机太大。Xavier 初始化适合 Sigmoid 和 Tanh,He 初始化(何恺明)适合 ReLU 族。迁移学习是”站在巨人肩膀上”——拿一个在大数据集上预训练好的模型,冻结底层或用小学习率微调顶层,在自己小数据集上往往能拿到不错的效果。
强化学习速览
核心框架是马尔可夫决策过程 MDP,由状态 S、动作 A、奖励 R、转移概率 P、折扣因子 γ 组成。”马尔可夫”的含义是”未来只依赖当前状态,与历史无关”。
Q-Learning 是值函数方法,维护一个 Q 表 Q(s,a),更新公式是经典的贝尔曼方程。问题是 Q 表只能处理离散小状态空间。DQN 用神经网络逼近 Q 函数,引入经验回放和目标网络两个技巧【需网络查询确认:DQN 论文年份】。策略梯度 Policy Gradient 直接参数化策略,适合连续动作空间但方差大。Actor-Critic 把值函数和策略函数结合起来,是现代强化学习的主流框架。PPO(近端策略优化)是 OpenAI 力推的算法,对策略更新幅度做裁剪限制,是 RLHF 里最常用的对齐算法之一,必须记住它和 RLHF 的关系。
生成模型家族:AE/VAE/GAN/扩散
生成模型的目标是”学数据分布,然后能采样生成新样本”。这家族有四大主流。
自编码器 AE 是个”压缩-还原”网络,编码器把输入压成低维向量,解码器再还原回去,学到的低维向量叫潜在表示。但 AE 本身不能直接生成新样本——因为潜在空间没有结构。
VAE 补上了这个缺口,它不学确定的潜在向量而是学一个分布,损失除了重建项还有 KL 散度项,这样潜在空间是连续平滑的,随便采点都能生成合理样本。VAE 生成相对模糊但训练稳定。
GAN 走的是完全不同的路子:生成器与判别器对抗博弈。经典比喻就是”造假者 vs 警察”——生成器造假钞试图骗过判别器,判别器努力分辨真假,两者在博弈中一起变强。GAN 生成的图比 VAE 锐利,但训练难、容易模式崩溃(只生成少数几种样本)。
扩散模型 Diffusion 是这两年图像生成的王者,Stable Diffusion、DALL-E 2 都是它的徒子徒孙。核心思想简单到让人意外:加噪再去噪。前向过程逐步给原图加高斯噪声加到纯噪声,反向过程训练一个网络学会从噪声逐步去噪还原成图。训练时网络预测每一步要去除的噪声,推理时从纯噪声开始迭代去噪生成图。优点是训练稳定、生成质量高,缺点是采样慢。Stable Diffusion 还把扩散过程搬到潜在空间(用 VAE 先压缩),大幅降低计算量。
动手算一算:扩散模型前向加噪与反向去噪
扩散模型公式背起来头疼,咱们用 3 步加噪走一遍。设原图 x_0 = 1.0(一个像素值,简化为一维),每步的”保留系数” α_t 和”噪声系数” √(1-α_t) 都是预设好的:
1 | import math |
三步之后原图 1.0 被噪声搅成了 1.1542,已经看不出原来的样子。再多加几步,就趋近于纯高斯噪声了——这就是前向过程”加噪到纯噪声”。
反向去噪是训练的核心目标。网络 ε_θ 接收当前的 x_t 和步数 t,预测”这一步加进去的噪声是什么”。看一个反向单步的简化计算:
1 | # 反向过程:已知 x_3,假设网络预测出第 3 步噪声 ε_θ = 0.7(真实是 0.8) |
网络预测的噪声 0.7 跟真实的 0.8 有点偏差,所以预测出来的 x_2 = 0.9213 和真实的 0.8557 也不完全一样。训练的目标就是让 ε_θ 的预测越来越准,这样从纯噪声开始一步步反推,就能还原出清晰的图。推理时从 x_T(纯噪声)开始,反复执行这个反向步骤 T 次,最后得到生成的图——所以扩散模型推理慢是因为要迭代很多次。
Transformer:大模型的基石
Transformer 是 2017 年 Google 论文《Attention is All You Need》提出的,彻底颠覆了 RNN 统治 NLP 的格局【需网络查询确认:论文具体年份与作者】。它的核心是自注意力机制,让序列中每个位置都能直接和所有位置交互,可以高度并行。
自注意力怎么算?用一句话概括:每个词跟所有词算相关性。具体来说,对每个词的 embedding 做三次线性变换得到 Query、Key、Value 三个向量,然后用 Query 和所有 Key 做点积得到相关性分数,除以根号 dk 缩放,过 Softmax 归一化成权重,再用这些权重对 Value 加权求和。整个过程就是”我用 Query 去问所有人,谁的 Key 和我匹配度高就多取谁的 Value”。
多头注意力是自注意力的升级版:把 Q/K/V 分成多组,每组独立做注意力,最后拼起来再投影。好处是不同头可以关注不同子空间的关系——有的头关注语法、有的关注语义、有的关注长距离依赖。
位置编码是因为 Transformer 本身没有位置感知能力(注意力是顺序无关的),需要额外把位置信息加进去。原始论文用正弦余弦函数生成固定编码,也有可学习位置编码(BERT 用)、相对位置编码(T5 用)。后来有 ALiBi、RoPE 旋转位置编码等改进。
Transformer 整体结构是编码器-解码器堆叠。后来 GPT 只取解码器部分,BERT 只取编码器部分,T5 保留完整结构,这就引出了三条路线。
动手算一算:自注意力的完整计算流程
自注意力公式 Attention(Q, K, V) = softmax(Q·K^T / √dk)·V。咱们用 3 个词、每个词 2 维向量走完整流程。为了聚焦在注意力机制本身,假设 Q=K=V 都等于输入 embedding(实际中会有 W_Q、W_K、W_V 三个权重矩阵做线性变换):
1 | import numpy as np |
四个步骤都给你串起来了,几个直觉点你跟着对一遍:
- 第 1 步 Q·K^T 是”两两算相关性”。词3 跟自己点积是 2(最大),因为它向量最长;词1 和词2 互不相关(点积 0)。
- 第 2 步除以 √dk=√2≈1.414。为什么要缩放?因为 dk 越大,点积本身数值越大,softmax 会进入”几乎 one-hot”的饱和区,梯度趋零。除一下把数值压回合理范围。
- 第 3 步 softmax 把每行归一成”注意力权重”,所有权重和为 1,可以理解为”我把注意力按这个比例分给每个词”。
- 第 4 步加权求和。词1 的输出 [0.8026, 0.5991] 基本上是”自己 + 词3”,因为权重 0.4013 给自己、0.4013 给词3——这就是”谁的 Key 跟我匹配就多取谁的 Value”。
这就是自注意力的全部家底,多头注意力就是”把这个过程重复 h 次,每次用不同的 W_Q/W_K/W_V,最后拼起来再投影”。
GPT与BERT:两条路线
虽然都基于 Transformer,但 GPT 和 BERT 的设计哲学完全相反,必须分清。
GPT 走的是自回归路线:用 Transformer 解码器,从左到右逐词预测下一个词,训练目标就是”语言建模”。它生成时一个词一个词往外蹦,天然适合生成任务。优点是生成流畅、能做零样本少样本,缺点是只能看到左边的上下文。
BERT 走的是双向编码路线:用 Transformer 编码器,训练时用掩码语言建模 MLM——随机遮住一些词,让模型基于上下文(左右双向)预测被遮的词。BERT 能看到完整上下文,理解能力强,做分类、问答效果很好,但天生不擅长生成。
简单记忆:GPT 自回归、单向、擅长生成;BERT 双向编码、擅长理解。T5 走中间路线,用编码器-解码器统一所有任务为”文本到文本”格式。LLaMA 是 Meta 开源的一系列大模型,结构上基本沿用 GPT 的解码器路线,是开源大模型的标杆【需网络查询确认:LLaMA 各版本发布时间和参数规模】。
多模态模型
CLIP 是 OpenAI 提出的,思想很优雅:用两个编码器分别编码图像和文本,让”匹配的图文对”在向量空间里靠近,”不匹配的”远离。CLIP 的图像编码器后来被无数多模态模型当”眼睛”用。BLIP 和 BLIP-2 引入 Q-Former 这个小网络,把冻结的图像编码器和冻结的大语言模型连起来【需网络查询确认:BLIP-2 发布年份】。LLaVA 是把 CLIP 图像编码器的输出通过一个投影层接到 LLaMA 上,让大模型能”看图说话”。GPT-4V 是 OpenAI 在 GPT-4 基础上加的多模态版本。
高效微调技术:LoRA为何这么火
大模型动辄几十亿几百亿参数,全量微调显存和算力都吃不消。于是诞生了一系列”参数高效微调”PEFT 方法。
LoRA 是当下最火的方法,核心思想:冻结原模型,只训练低秩小矩阵。原模型某层权重 W 是 d×d 的大矩阵,LoRA 不直接动 W,而是学两个小矩阵 A(d×r) 和 B(r×d) 的乘积加到 W 上,r 远小于 d(比如8或16)。这样可训练参数从 d² 降到 2dr。推理时可以把 BA 合并到 W 里,零额外开销。为什么有效?因为微调时权重更新 ΔW 本身就是低秩的。LoRA 的优势是参数少、效果接近全量、可以插拔复用。
Adapter Tuning 是在 Transformer 每层里插入小瓶颈模块,只训练这些小模块,参数量小但会增加推理延迟。Prefix Tuning 是在每个注意力层的 KV 前面拼上一些可学习的”虚拟前缀” token,只训练这些前缀。Prompt Tuning 更轻量,只在输入 embedding 层加可学习的 prompt token,参数最少但小模型上效果一般。P-Tuning v2 是 Prefix Tuning 的改进版,把可学习 prompt 加到每一层,对中小模型也有效。
实际应用中如果遇到”哪个方法推理无额外开销”的问题,答案是 LoRA(可合并权重);遇到”哪个最轻量只动输入”,是 Prompt Tuning;遇到”为什么 LoRA 火”,因为它参数少、效果好、可插拔、推理零开销。
动手算一算:LoRA 低秩分解省了多少参数
LoRA 的精髓在 d² → 2dr 这个参数缩减。先用一个小矩阵把”乘积加到 W 上”这件事走通,再单独看大模型场景下的参数节省比例。
1 | import numpy as np |
看清楚乘法过程之后,咱们再算一下参数节省比例。这个例子 d=4、r=2,原参数 16 个,LoRA 参数 8+8=16 个,反而没省——这告诉你”低秩分解只有在 d 远大于 r 时才划算”。换个真实规模:
1 | # 大模型实际场景:d=4096, r=8 |
1677 万参数被压到 6.5 万,节省 99.6%。这就是 LoRA 让普通消费级显卡也能微调大模型的根骨。
再看”推理零开销”这件事:训练时 W 和 ΔW=BA 是分开存的,但推理前可以把 ΔW 直接加到 W 里得到 W’,之后只用 W’ 做前向,跟原来完全一样快——这就是”推理零额外开销”的来源。Adapter 就做不到这点,因为它在每一层都插了额外的小网络,前向计算量永久增加。
训练方法:SFT、RLHF与DPO
把一个预训练基座模型变成好用的对话助手,要经过几个阶段的训练。
预训练阶段是大规模无监督地学语言知识,用海量文本做下一个词预测,得到基座模型。这一步烧钱烧卡,但模型还不会”听指令”。
SFT 监督微调是第一步对齐:用”指令-回答”对的高质量数据微调模型,让它学会按指令格式回答。SFT 是几乎所有对齐流程的起点。
RLHF 基于人类反馈的强化学习是 OpenAI 在 InstructGPT/ChatGPT 里发扬光大的方法【需网络查询确认:InstructGPT 论文年份】。流程分三步:先 SFT 得到初始策略,再训练一个奖励模型 RM(用人类对多个回答的偏好排序数据),最后用 RM 的打分当奖励,用 PPO 算法优化策略模型让回答得分更高。RLHF 效果惊艳但流程复杂、训练不稳定、要同时维护四个模型(策略、参考、奖励、价值)。
DPO 直接偏好优化是后来居上的简化方案,核心洞察是:在特定数学假设下,可以直接用偏好数据(A比B好)通过一个简洁的损失函数优化策略模型,省掉了显式的奖励模型和 RL 训练循环。DPO 训练更稳定、更简单,效果接近甚至超过 RLHF。
三者关系一句话总结:SFT 是基础对齐,RLHF 用强化学习+奖励模型做偏好优化,DPO 用监督学习方式直接做偏好优化、绕开 RL 的复杂性。一般流程是 SFT 先做,再用 RLHF 或 DPO 二选一做偏好对齐。
提示工程与RAG
提示工程不训练模型,靠设计输入提示来激发模型能力。零样本 Zero-shot 是直接给模型任务不加示例。少样本 Few-shot 是在提示里给几个”输入-输出”示例,让模型模仿模式。链式思维 CoT 是让模型”一步步思考”再给答案的技巧,提示里加”Let’s think step by step”或给带推理过程的示例,能显著提升数学、逻辑等复杂推理任务的准确率。
RAG 检索增强生成是把外部知识检索和大模型生成结合的范式。流程是:用户提问→把问题编码成向量→在知识库(向量数据库)里检索相关文档片段→把检索结果拼进提示→大模型基于检索内容生成答案。它解决的是大模型”知识过期”和”幻觉”问题。RAG 比微调更适合知识频繁更新的场景,成本也低。关键区别:RAG vs 微调——知识频繁更新选 RAG(不用重训),需要改变模型行为风格选微调。RAG 不能让模型学会新技能,只能让它查到新知识。
评估指标与工具库
评估指标按任务分要记清楚。文本生成用 BLEU 和 ROUGE。BLEU 看生成文本里 n-gram 有多少出现在参考文本里,侧重精确率,机器翻译常用。ROUGE 反过来,看参考文本里 n-gram 有多少被生成文本覆盖,侧重召回率,文本摘要常用。别记反。多模态对齐用 CLIP Score,衡量图像和文本匹配程度。大语言模型综合能力有 MMLU(英文多任务理解基准,覆盖57个学科)和 C-Eval(中文综合评估基准)。
工具库这块要认识这几个名字和它们的分工。Hugging Face Transformers 是事实上的模型库标准,提供几千个预训练模型的加载、推理、微调 API。PEFT 是 Hugging Face 出的参数高效微调库,封装了 LoRA、Adapter、Prefix Tuning 等方法。DeepSpeed 是微软的大模型训练加速库,提供 ZeRO 优化(把优化器状态、梯度、参数分片到多卡)。Accelerate 也是 Hugging Face 的,简化多卡、混合精度、分布式训练的样板代码。TRL 是 Transformers Reinforcement Learning 库,专门做 RLHF、DPO 等对齐训练。别把 DeepSpeed 和 Accelerate 混,也别把 PEFT 和 TRL 混。
动手算一算:BLEU 与 ROUGE 的 n-gram 匹配
BLEU 和 ROUGE 容易记反,咱们用同一个例子把两个都算一遍。设参考文本 R = “我 喜欢 吃 苹果”,生成文本 G = “我 喜欢 苹果”。
1 | from collections import Counter |
跟着数字对一遍:
- 1-gram 层面:生成的 [“我”,”喜欢”,”苹果”] 三个词都在参考里出现,匹配 3 个。
- BLEU-1 = 匹配数 / 生成总数 = 3/3 = 1.0(”生成里有多少命中参考”——精确率视角,翻译常用)。
- ROUGE-1 = 匹配数 / 参考总数 = 3/4 = 0.75(”参考里有多少被生成覆盖”——召回率视角,摘要常用)。
- 2-gram 层面:生成的 2-gram 是 [“我 喜欢”, “喜欢 苹果”],参考的 2-gram 是 [“我 喜欢”, “喜欢 吃”, “吃 苹果”]。只有 “我 喜欢” 命中,匹配 1 个。
- BLEU-2 = 1/2 = 0.5。
- ROUGE-2 = 1/3 ≈ 0.333。
关键直觉就一句话:BLEU 用”生成文本做分母”(精确率),ROUGE 用”参考文本做分母”(召回率)。翻译用 BLEU,摘要用 ROUGE,就这两个对应关系。
深度学习与生成式AI重点回顾
激活函数:隐藏层默认 ReLU 不是 Sigmoid,ReLU 缓解梯度消失是因为正区间梯度恒为1;Softmax 只用于多分类输出层。卷积:权值共享是”同一个滤镜扫整张图”;池化没有参数;输出尺寸公式别忘了加2倍 padding。BatchNorm:给每层输入做标准化,训练用 batch 统计、推理用滑动平均;它和 LayerNorm 别混。ResNet:残差连接学的是”残差”不是”恒等映射”,解决的是退化问题。LSTM 三个门:遗忘门忘、输入门写、输出门读,细胞状态是传送带;GRU 是简化版三个门变两个。GAN:生成器和判别器对抗博弈不是合作;模式崩溃是只生成少数样本。扩散模型:加噪再去噪,训练预测噪声、推理从纯噪声迭代去噪;Stable Diffusion 在潜在空间扩散才省算力。Transformer:自注意力是每个词跟所有词算相关性,用 Q/K/V;多头是分多组并行算;位置编码是因为注意力本身无位置感知。GPT vs BERT:自回归单向生成 vs 双向编码理解,这个对比很重要。LoRA:冻结原模型只训练低秩小矩阵,可合并权重所以推理零开销;Adapter 会增加推理延迟;Prompt Tuning 最轻量只动输入。SFT/RLHF/DPO:SFT 是监督微调打基础,RLHF 用奖励模型+PPO 做偏好优化(复杂不稳定),DPO 直接用偏好数据做监督式优化(简单稳定),一般先 SFT 再二选一对齐。PPO 是 RLHF 里最常用的对齐算法。提示工程:零样本无示例、少样本有示例、CoT 让模型逐步推理;RAG 是检索+生成解决幻觉,不是微调。评估指标:BLEU 重精确率用于翻译,ROUGE 重召回率用于摘要,别记反;CLIP Score 评图文匹配;MMLU 是英文综合、C-Eval 是中文综合。