Rust in Everything
基于 burn 0.22.1

常见坑

每一章对着一个 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

  1. Int 的 / 向零截断,不是 //:负数的商差 1,取余却跟除数同号。
  2. I32 求和静默回绕:PyTorch 提升成 int64,burn 不提升。
  3. Int + 0.5 还是 Int,小数被截掉:浮点标量先截成整数,idx * 0.5 全是 0。
  4. binary_op: dtype mismatch:没有类型提升,F32 和 F64 混算 panic。

维度与索引

  1. argmax 是 [B, 1],准确率算成 0.4375:归约保留维度,补维补错了静默广播。
  2. Tensor<1>: ElementConversion is not satisfied:秩不同的张量相加,报错不提秩。
  3. s![.., -1] 不降秩,s![5] 越界不报错:整数下标不去掉维度,越界得到空张量。
  4. mask_where 照搬 torch.where,结果正好互补:参数的含义不同。

所有权

  1. use of moved value: x:残差连接、循环、forward(&self) 里的 E0382、E0507、E0369。

自动求导

  1. detach() 之后还在记图:EMA 每步越来越慢,目标网络第二步 panic。
  2. 验证循环里内存一直涨:autodiff 模型上的前向把图留到下一次 backward。
  3. loss 忘了 mean,梯度大了 batch 倍:非标量 backward 不报错,按求和处理。
  4. linalg::svd: gradients are not implemented:精简分解,不能求导,autodiff 设备上直接 panic。

模型与参数

  1. Param::map 改值后参数不再训练:要么第二步 panic,要么参数静默冻结。
  2. HashMap<String, Linear>: Module is not satisfied:照提示加 #[module(skip)],参数个数变成 0。
  3. BatchNorm 推理结果和 PyTorch 对不上:有偏的运行方差、共享的快照、过期的统计量。

优化器

  1. optim.step 之后 loss 不变:没接住返回的新模型,照编译器建议 clone 后更新丢了。
  2. 优化器默认值和 PyTorch 不同:RMSprop 带动量,ε、权重衰减、dampening、梯度裁剪都不一样。
  3. 续训之后 Adam 从头开始:状态按 ParamId 存,参数重建后状态对不上。

GPU 与数据加载

  1. Metal 上越界的下标不报错,读出 0:GPU 内核不查下标。
  2. 加载器一直交出同一个 Err:记日志再 continue 的循环永远不结束。
  3. 没有 drop_last,多 worker 打乱不完整:最后一批照样送出,打乱只在 worker 自己的分片里。
  4. CPU 上的 matmul 慢了 27 倍:关了默认 feature,Flex 只用一个线程。

存取与部署

  1. matmul: dtype mismatch:float64 / 半精度权重加载成功,前向才报错。
  2. File already exists 与 Sequential 键名:默认不覆盖,Sequential 的下标要映射。
  3. Failed to load burnpack file:burn-onnx 生成的代码记住了构建目录的绝对路径。

💬 关联讨论

发起讨论
加载中...