Rust in Everything
基于 burn 0.22.1

执行方式

PyTorch 的代码写下去就按顺序执行,CPU 上调用返回时已经算完,MPS 和 CUDA 上调用返回时内核已经进了队列。burn 在 CPU 后端 Flex 上和它一样;在 Metal 这类 GPU 后端上多了一层 Fusion:op 先记下来,到读回结果或 sync 时才决定怎么合并、怎么执行。写法不用改,变的是「什么时候算」「算不算」「错在哪一行报」和「怎么计时」。

这一部分用 PyTorch 的 CPU、MPS 和 burn 的 Flex、Metal 四种设备对照:

  1. eager 和延迟执行:调用返回时算完了没有;没人读的结果 PyTorch 照算、burn 不算;8 个逐元素 op 在 burn Metal 上自动融合,PyTorch 要 torch.compile;形状错误、显存不够、下标越界分别在哪一行报。
  2. 计时:torch.mps.synchronize() 对 device.sync(),mps.Event 对 profile_with 加 flush;不同步量到的只是调用开销;第一次调用 PyTorch 卡在调用那一行,burn 卡在 sync;CPU 上 matmul 的快慢主要看用了哪个库。
flowchart TB
  code["同一行 a.exp()"] --> tcpu["torch CPU 当场算"]
  code --> flex["burn Flex 当场算"]
  code --> mps["torch MPS 排队"]
  code --> metal["burn Metal 登记"]
  mps --> run["一定执行"]
  metal --> lazy["读回或 sync 才执行"]
  lazy --> fused["可能合并 可能省掉"]

Fusion 内部怎么登记、怎么切块融合、错误怎么挂在张量上,见 burn 卷的 Fusion;GPU 计时的坑见 GPU 上第一次很慢、计时忽快忽慢。

💬 关联讨论

发起讨论
加载中...