常见坑
每一章对着一个 PyTorch 习惯:先写出 PyTorch 里的写法和输出,再把它照搬到 burn,给出现象(报错原文或静默的错误结果),然后到 0.22.1 的源码里找原因,最后给出改法和检查办法。机制在前面几部分讲过的,这里只链过去;burn 卷常见坑从 burn 自身出发,和这里互补。
复现环境都是 M2 Max、macOS 27、rustc 1.99.0、PyTorch 2.15.0、burn 0.22.1;没有特别说明时 burn 用 Flex 设备,PyTorch 用 CPU。
flowchart TB habit["PyTorch 的写法"] --> port["照搬到 burn"] port --> ce["编译不过"] port --> pn["运行时 panic"] port --> silent["静默得到错的数"] ce --> fix["改法"] pn --> fix silent --> chk["怎么检查"] chk --> fix
整数与 dtype
- Int 的 / 向零截断,不是 //:负数的商差 1,取余却跟除数同号。
- I32 求和静默回绕:PyTorch 提升成 int64,burn 不提升。
- Int + 0.5 还是 Int,小数被截掉:浮点标量先截成整数,
idx * 0.5全是 0。 - binary_op: dtype mismatch:没有类型提升,F32 和 F64 混算 panic。
维度与索引
- argmax 是 [B, 1],准确率算成 0.4375:归约保留维度,补维补错了静默广播。
Tensor<1>: ElementConversionis not satisfied:秩不同的张量相加,报错不提秩。s![.., -1]不降秩,s![5]越界不报错:整数下标不去掉维度,越界得到空张量。- mask_where 照搬 torch.where,结果正好互补:参数的含义不同。
所有权
- use of moved value:
x:残差连接、循环、forward(&self)里的 E0382、E0507、E0369。
自动求导
- detach() 之后还在记图:EMA 每步越来越慢,目标网络第二步 panic。
- 验证循环里内存一直涨:autodiff 模型上的前向把图留到下一次 backward。
- loss 忘了 mean,梯度大了 batch 倍:非标量 backward 不报错,按求和处理。
- linalg::svd: gradients are not implemented:精简分解,不能求导,autodiff 设备上直接 panic。
模型与参数
- Param::map 改值后参数不再训练:要么第二步 panic,要么参数静默冻结。
HashMap<String, Linear>: Moduleis not satisfied:照提示加#[module(skip)],参数个数变成 0。- BatchNorm 推理结果和 PyTorch 对不上:有偏的运行方差、共享的快照、过期的统计量。
优化器
- optim.step 之后 loss 不变:没接住返回的新模型,照编译器建议 clone 后更新丢了。
- 优化器默认值和 PyTorch 不同:RMSprop 带动量,ε、权重衰减、dampening、梯度裁剪都不一样。
- 续训之后 Adam 从头开始:状态按 ParamId 存,参数重建后状态对不上。
GPU 与数据加载
- Metal 上越界的下标不报错,读出 0:GPU 内核不查下标。
- 加载器一直交出同一个 Err:记日志再 continue 的循环永远不结束。
- 没有 drop_last,多 worker 打乱不完整:最后一批照样送出,打乱只在 worker 自己的分片里。
- CPU 上的 matmul 慢了 27 倍:关了默认 feature,Flex 只用一个线程。
存取与部署
- matmul: dtype mismatch:float64 / 半精度权重加载成功,前向才报错。
- File already exists 与 Sequential 键名:默认不覆盖,Sequential 的下标要映射。
- Failed to load burnpack file:burn-onnx 生成的代码记住了构建目录的绝对路径。
💬 关联讨论
发起讨论加载中...