上一章 · 返回首页 · 内容清单 · 下一章

课程锚点:Lecture01 Slides12–20;GPUs Slides6–8;week2 PyTorch notebook Cells5–8。以下推导补足课件默认的数学基础。

1.1 Tensor、shape 和乘法

Tensor 在这里先理解为多维数组。[B,T,D] 的三个轴分别是 batch 中序列数、每条序列位置数、每个位置的特征数。例如 [2,4,8] 有 64 个数,FP32 数据本体 256 bytes,BF16 本体 128 bytes;尚未算对象、梯度与显存分配开销。

同为三维,不代表意义相同:[B,T,V] 最后一维是词表 logits;[B,H,T] 则可能表示每个头的统计。轴的名字比轴的数量更重要。 本讲义用 T 表示序列长、N 表示层数,避免课件中 L 同时表示 length/layers。

X:[B,T,D]、W:[D,F] 时,X@W:[B,T,F]。batch 和位置轴保留,对每个 token 用同一组参数。PyTorch nn.Linear(D,F).weight 实际存 [F,D],forward 是 X @ weight.T + bias;数学符号和存储约定不要混为一谈。

逐元素乘 * 要满足广播:[B,T,F]*[B,T,1]→[B,T,F]。它不是 [B,T,F]@[B,T,1]。注意力加权的 A@V 是矩阵乘法;SwiGLU 两分支的 gate*up 是逐元素乘。

reshape 改形状;transpose 交换轴并常返回非连续视图。多头合并常用 x.transpose(1,2).contiguous().view(B,T,D)。只把 [B,T,H,d] 直接 view 成 [B,H,T,d],并没有正确交换 head 与 time。

1.2 线性层为什么不够

h=W1 x+b1; y=W2 h+b2 可合并成 y=(W2W1)x+(W2b1+b2)。不论叠多少层,只要都仿射,整体仍仿射。XOR 等非线性可分问题需要非线性结构。激活函数、attention 中依赖输入的 softmax、门控乘法等会引入非线性。

ReLU max(0,x):x>0 导数 1,x<0 导数 0,0 点使用约定的次梯度。一个单元若长期落在负半轴,更新路径可能失活。SiLU xσ(x) 保留平滑的负区响应;它并不保证任何位置梯度都为正或不会消失。SwiGLU 见 04。

参数是训练需要学习的 W、b 等;hidden state 是给定输入下临时算出的表示。模型规模说“8B parameters”,不是“8B tokens”,也不是“某次 forward 的 hidden state 大小”。

1.3 loss、梯度、反向传播、优化器各做什么

设 a=wx+b、h=ReLU(a)、ŷ=vh+c,loss L=1/2(ŷ-y)^2。链式法则:

∂vL=(y^−y)h,∂cL=y^−y,\partial_vL=(\hat y-y)h,\quad \partial_cL=\hat y-y, ∂wL=(y^−y)v1a>0x,∂bL=(y^−y)v1a>0.\partial_wL=(\hat y-y)v\mathbf1_{a>0}x,\quad \partial_bL=(\hat y-y)v\mathbf1_{a>0}.

取 x=2、y=1、w=0.5、b=0、v=2、c=0:a=1、h=1、ŷ=2、L=0.5。梯度 (∂w,∂b,∂v,∂c)=(4,2,1,1)。学习率 η=0.1,一次 SGD 同时更新到 (w,b,v,c)=(0.1,-0.2,1.9,-0.1)。所有梯度由更新前参数计算;不能更新 v 后再用新 v 计算 w 的旧梯度。

反向传播是高效计算梯度的方法,优化器是利用梯度更新参数的方法。 SGD、AdamW 可以共用同一次 backprop;loss.backward() 通常不负责修改参数。

链式法则使反向传播把上游导数逐层传递。计算图保存 forward 中需要的值;共享参数的多条使用路径会把梯度相加。理解这一点才能解释为什么同一个 FFN 对所有 token 都处理,其权重梯度来自所有有效 token。

1.4 从 logits 到交叉熵

模型最后给 V 个实数 z,称 logits,不要求非负或和为 1。softmax:

pi=ezi∑jezj,L=−log⁡py=−zy+log⁡∑jezj.p_i={e^{z_i}\over\sum_j e^{z_j}},\qquad L=-\log p_y=-z_y+\log\sum_j e^{z_j}.

数值稳定形式先减最大值 m:softmax(z)=softmax(z-m)。这不改变概率,因为分子分母同时乘 e^-m;却能避免正数指数溢出。不能把 softmax 后概率当 logits 再送入期待 logits 的交叉熵接口,否则做了第二次 softmax。

求导:∂L/∂z_i=p_i-1[i=y]。正确类的概率不足时,梯度下降提高其 logit;其余类被压低。若用软标签 q:L=-Σq_i log p_i,梯度为 p_i-q_i。蒸馏会直接用到这个结论。

例:正确 token 的概率 0.25,该位置 NLL=-ln .25=1.386294。另一个位置正确概率 0.5,平均 NLL=1.039721,PPL=exp(1.039721)=2.828427。不是把两个正确率算术平均后再取倒数。

1.5 一个真实训练 step

  1. 从训练集取 batch;文本分词、padding,准备 attention mask 与 loss mask。
  2. optimizer.zero_grad() 清掉上次梯度;若做梯度累积,应只在一组 microbatch 开始前清。
  3. forward 得 logits;对齐 next-token 目标,计算有效位置的平均 loss。
  4. backward 建立各参数梯度;必要时做梯度缩放/还原与 clipping。
  5. optimizer.step() 更新参数;按规定时机 scheduler.step()。
  6. 独立验证集评估,不更新参数,记录 loss、token 数与性能。

model.eval() 控制 dropout 等模块行为;no_grad()/inference_mode() 控制 autograd。二者不是同一开关,eval 并不自动禁止求梯度。

batch 是一次处理的数据组;microbatch 是累积中的小组;step 通常指一次 optimizer 更新;epoch 是数据集遍历一遍。若每卡 microbatch=2、数据并行卡数=4、累积8次,则全局每 step 64 条序列。长度不同时,有效 token 数也不同。

1.6 最容易丢分的细节

  • 梯度为负意味着增加该参数在局部会降低 loss;更新是 θ←θ-ηg,不是“负梯度就一定减参数”。
  • 训练 loss 下降不保证泛化;应使用验证集选超参,测试集用于最终评估。
  • 大 batch 不保证更快到达相同质量,也不等于 epoch 更少。
  • 整数 token ID 不直接接受普通实数梯度;embedding 表中被查询的向量可以学习。
  • attention mask 控制能看到哪些输入;loss mask 控制哪些预测贡献训练目标。二者互不替代。

闭卷检验:把本章标量网络中 x 改为 -2,重新算 forward/梯度;再解释为何某些参数梯度会归零,而 c 的梯度仍可非零。


上一章 · 返回首页 · 内容清单 · 下一章

Built with LogoFlowershow