← 返回书架人工智能 · 交互式 Wiki
模型工程/整层反向传播资料与边界
训练目标与优化进阶计算演示

EXACT MECHANICS / BACKPROPAGATION

整层反传:从 loss 回到每个矩阵

沿一层带 RMSNorm、因果 Attention、残差和 SwiGLU 的小型 Transformer,逐项查看局部导数、分支汇合与权重梯度。每个数字都可以用有限差分复核。

01 / LOCAL RULES

反传需要的是局部规则与上游梯度

令 G 为 loss 对某个算子输出的梯度。反传把 G 与该算子的局部导数组合,得到输入和参数的梯度;这就是向量-雅可比积的作用。实现通常不显式存下整张雅可比矩阵。一个张量有多条使用路径时,各路径贡献相加。

Y=XW:∇XL=GW⊤,∇WL=X⊤G,Y=A+B:∇AL=G,  ∇BL=G,Y=A⊙B:∇AL=G⊙B,∇BL=G⊙A.\begin{aligned}Y&=XW:\quad\nabla_X L=GW^\top,\\&\hspace{3.4em}\nabla_W L=X^\top G,\\Y&=A+B:\quad\nabla_A L=G,\;\nabla_B L=G,\\Y&=A\odot B:\quad\nabla_A L=G\odot B,\\&\hspace{4.7em}\nabla_B L=G\odot A.\end{aligned}
使用行向量 batch 约定:X∈ℝⁿˣᵈ、W∈ℝᵈˣᵏ、G∈ℝⁿˣᵏ。广播参数的梯度需要沿被广播轴求和;共享权重也需要汇总所有使用位置。

残差 Y=X+F(X) 给 X 两条路径:恒等分支的 G,以及 F 的反传贡献。它保留了直接通路,但实际梯度仍由分支和后续计算共同决定。冻结参数意味着不更新这部分参数;仍可通过该算子对其他输入求导。

02 / ONE BLOCK

沿着损失走回输入

01 / ATTENTION

Norm → Q/K/V

因果 softmax 后加权 V,经过 O 投影,与原始 X 相加。

02 / FFN

Norm → SwiGLU

gate 与 up 分支逐元素相乘,down 投影后再次残差相加。

03 / LOSS

Hidden → logits

投到三个候选类别,仅第二个位置的目标参与交叉熵。

04 / BACKWARD

局部求导并汇总

每一分支反向传递,在共享输入、残差和参数处相加。

前向数值与当前反向节点

固定小矩阵 · JavaScript 双精度

输入 X=[[0.5,−0.2],[0.1,0.7]]。权重固定;这里计算 loss 与梯度,推进按钮只切换观察位置。

Loss
反向节点
张量形状

坐标前向值对该值的梯度

全部参数和输入梯度的范数
对象形状梯度 Frobenius 范数

X 是可微输入,不是本例的权重;若来自 embedding lookup,其梯度继续累加回对应词表行。范数只能概括大小,梯度方向与各元素仍需单独看。

03 / ATTENTION VJP

softmax 与 Q/K/V 怎样分别接收梯度?

S=QK⊤/d,P=softmax⁡row(S+M),H=PV,GP=GHV⊤,GV=P⊤GH,(GS)ij=Pij((GP)ij−∑kPik(GP)ik),GQ=GSK/d,GK=GS⊤Q/d.\begin{aligned}S&=QK^\top/\sqrt d,\\P&=\operatorname{softmax}_{row}(S+M),\quad H=PV,\\G_P&=G_HV^\top,\quad G_V=P^\top G_H,\\(G_S)_{ij}&=P_{ij}\left((G_P)_{ij}-\sum_kP_{ik}(G_P)_{ik}\right),\\G_Q&=G_SK/\sqrt d,\quad G_K=G_S^\top Q/\sqrt d.\end{aligned}
M 是固定因果 mask。被屏蔽位置 P=0,相应分数梯度为零。本例每行至少有一个可见位置;全被屏蔽的行需要实现额外定义。

虽然前位置的输出 logits 没有 loss,后位置仍可以读取前位置的 K/V,因此前位置输入仍会收到梯度。反过来,改变未来位置不会影响更早位置的前向结果。这两件事分别由 loss 位置与因果可见性决定。

04 / NORM & GATE

归一化与门控的局部导数

r=(d−1∑jxj2+ϵ)−1/2,y=x⊙γ r,v=Gy⊙γ,Gx=rv−r3dx∑jvjxj,Gγ=∑位置Gy⊙x r.\begin{aligned}r&=(d^{-1}\sum_jx_j^2+\epsilon)^{-1/2},\\y&=x\odot\gamma\,r,\quad v=G_y\odot\gamma,\\G_x&=rv-\frac{r^3}{d}x\sum_jv_jx_j,\\G_\gamma&=\sum_{\text{位置}}G_y\odot x\,r.\end{aligned}
RMSNorm 在每行上归一化,γ 跨位置共享。本例 ε=10⁻⁵。第二项来自 r 对输入的依赖;把 r 当常量会漏掉梯度。
SiLU⁡(a)=aσ(a),SiLU⁡′(a)=σ(a)+aσ(a)(1−σ(a)),z=SiLU⁡(a)⊙b,Ga=Gz⊙b⊙SiLU⁡′(a),Gb=Gz⊙SiLU⁡(a).\begin{aligned}\operatorname{SiLU}(a)&=a\sigma(a),\\\operatorname{SiLU}'(a)&=\sigma(a)+a\sigma(a)(1-\sigma(a)),\\z&=\operatorname{SiLU}(a)\odot b,\\G_a&=G_z\odot b\odot\operatorname{SiLU}'(a),\\G_b&=G_z\odot\operatorname{SiLU}(a).\end{aligned}
a、b 分别来自 gate/up 线性层。得到两支梯度后,继续用矩阵乘的局部规则返回共享 Norm 输出。
05 / CHECK

直接扰动一个参数,验证反传结果

∂L∂θj≈L(θj+h)−L(θj−h)2h\frac{\partial L}{\partial\theta_j}\approx\frac{L(\theta_j+h)-L(\theta_j-h)}{2h}
h=10⁻⁵,其他输入和参数保持不变。有限差分存在截断与浮点误差;步长过大或过小都可能影响比较。

解析梯度与数值梯度

解析梯度
有限差分
绝对误差
06 / INDEPENDENT FRAMEWORK REFERENCE

用 PyTorch 再实现一次,结果是否对应?

项目提供独立 Python 实现,固定 PyTorch 2.9.0、CPU 与 float64。Node 侧导出输入、权重和参考结果;Python 使用张量算子与自动微分重新计算,不读取手写梯度来构造结果。三个新增实验和本页小型 block 使用各自明确的模型配置。

python3.12 -m venv .venv-framework
.venv-framework/bin/python -m pip install -r scripts/framework-requirements.txt
npm run lab:framework
对照项实际执行与核验
整层小模型三个目标类别的前向与全部输入/参数梯度;八步 AdamW 轨迹;第三步保存后由新进程恢复。
Packing独立序列、真实 padding batch、块隔离 packing 的前向、梯度与一次更新;截断、末轮监督、零标签、跨样本可见与重复 shift。
LoRAA/B 初始化与梯度、输入梯度、切断分支、SGD、同底座合并以及重新量化误差。
对比学习全局参考与两个 CPU Gloo 进程;可微 gather、远端 detach、单样本 microbatch,以及 DDP 参数平均后的更新。

命令写入新的 artifacts/framework-lab-<timestamp>/,保留配置、参考值、逐项误差、checkpoint 和报告。默认数值比较使用绝对容差 10⁻⁹、相对容差 10⁻⁸;同进程环境的新进程完整恢复要求与 PyTorch 连续基线逐值一致。版本、设备和实际结果以该次报告为准。

框架实验不下载预训练模型,不运行 CUDA、NCCL 或模型质量评测。CPU 通信检查确认本实验的梯度与缩放协议;GPU 混合精度、其他 gather backward、真实 tokenizer 和生产 kernel 需要在对应环境继续验证。

适用范围与一手资料

两位置、hidden=2、FFN=3、词表=3 的单头双残差 block,包含两个 RMSNorm。无位置编码、bias、dropout 和最终 Norm,仅末位置监督。解析梯度用中心差分和固定 PyTorch 2.9.0 CPU 双精度独立实现核对;框架实验另含更新、恢复与双进程对比学习。

公式与机制的原始依据 · 7 项
知识目录
搜索知识库