eager
JAX 没有「先算出数、再在张量上调 backward」这种写法:不 jit 的 jax.grad 也是一个函数变换,只是逐个算子执行。tenferro 两种都有。traced 模式是 JAX 式的,见上一部分变换;eager 模式是 PyTorch 式的:variable_from 建叶子,运算在 with_eager_session 里立即执行并记录,loss.backward(&mut engine) 把梯度写进叶子的槽位。这一部分先拿 torch.autograd 对照 eager 的每个接口,再把 eager 和 traced 放在同一个函数、同一个 TRG 上比较结果和时间。eager 的内部机制(trace、残差、梯度槽、缓存)见 tenferro 卷的 eager AD。
- backward:
variable_from/backward/grad()对应requires_grad=True/backward()/.grad,同一个梯度和 PyTorch 逐位相同;不同在边上:第二次backward不需要retain_graph,函数式grad的结果总能再求导,在no_grad里算的结果调backward静默返回空梯度,没有原地运算。 - eager 还是 traced:两种模式的梯度逐位相同(JAX 的 jit 和不 jit 反而不同);eager 每次反向约 58 µs 起步,图越深越贵,400 层时是 traced 的 39 倍;整图 eager 的 TRG 4 步就要 7 秒一次,按步分段后 20 步 0.64 s,比分段的 traced 快,因为反向不重算前向。
flowchart TB leaf["variable_from"] --> sess["with_eager_session"] sess --> run["立即执行"] sess --> rec["记 trace 留残差"] run --> val["value 可读"] rec --> bw["backward"] bw --> slot["累加进 grad 槽"] bw --> same["同一套语义 VJP"] same --> trc["traced grad"]
💬 关联讨论
发起讨论加载中...