Skip to content

JAX/XLA 原语分析

MaxText 是配置驱动的引擎:模型代码在 trace 期被组装成 jaxpr,最终落成一张 XLA 程序,在 TPU pod 上以 SPMD 方式执行。读懂这台引擎,本质上就是读懂它用了哪些 JAX 原语、每个原语在追踪期与编译/运行期分别做了什么。

本系列不是 API 手册,而是**「原语在真实场景下的行为分析」**。对每个原语,结合 MaxText 中实际调用它的场景(训练主循环 / 分区 / Decoder 堆叠 / 注意力 / MoE / 流水线 / 上下文并行 / 量化),讲清三件事:

  1. JAX 追踪期语义 —— trace 出什么、引入什么副作用;
  2. XLA 落地形态 —— 编译成什么 HLO(collective、While、Conditional、Dot、Mosaic kernel)、如何参与 GSPMD 分区、是否触发重计算/offload;
  3. MaxText 为什么这样用 —— 性能(MFU)、显存、还是数值对齐的动机。

通用背景(全系列共识)

后续各场景页都建立在下面这套共识之上。

  • jit → trace → jaxpr → HLO:一次 jit 调用把 Python 函数 trace 成 jaxpr 并编译成一张 XLA 可执行程序;Python 控制流只在 trace 期执行一次,运行期跑的是编译后的 HLO。
  • SPMD / GSPMD:单程序、多设备。张量带 sharding 标注,XLA 的 GSPMD partitioner 自动传播 sharding 并在需要处插入集合通信(all-gather / reduce-scatter / all-reduce)。
  • 两套分区世界
    • GSPMD 自动分区 —— 用 with_sharding_constraint / 逻辑轴约束给张量贴 sharding,编译器决定何时通信;
    • shard_map 手动分区 —— 切换到 per-shard 视角,显式写集合通信,通信直接成为 HLO。
  • 逻辑轴 → 物理轴:MaxText 用 Flax 逻辑轴名(如 embed / mlp / heads)标注激活,再由 logical_axis_rules 映射到 mesh 的物理轴,把「模型代码」与「并行策略」解耦。
  • Pallas / Mosaic:用 Python 写 TPU kernel,经 Mosaic 编译成自定义 HLO,绕开 XLA 的默认 codegen(splash attention、megablox GMM、KDA 等)。
  • remat / checkpoint policy:用重计算换显存。policy 决定哪些中间值在前向存下、哪些反向重算、哪些 offload 到 host。
  • custom_vjp:手写反向,绕开自动微分——用于 Pallas kernel 反向、数值稳定、节省显存。

原语速查表

按类别速查;「页」列指向对应场景深入页。

并行 / 分区

原语JAX 追踪期语义XLA 落地形态主要场景(页)
shard_map在子函数内切换到 per-shard 手动分区视角,axis 名进入 manual mesh不走 GSPMD 自动通信,内部显式 collective 直接成 HLOMoE / 注意力 / 流水线(04,05,06)
with_sharding_constraint给中间张量贴物理 sharding(NamedSharding约束 GSPMD 传播,必要处插入 reshard分区(02)
nn.with_logical_constraint(Flax)给激活贴逻辑轴名logical_axis_rules 解析为物理 sharding 后再约束 GSPMD激活分区主力(02)
PartitionSpec / NamedSharding描述张量在 mesh 上如何切分喂给 GSPMD partitioner全局(02)
logical_axis_rules逻辑轴名 → mesh 物理轴名的映射规则决定上述约束的物理含义configs/types.pyutils/sharding.py(02)
pjit带 in/out sharding 的 jitGSPMD 分区编译少量显式使用(02)

编译变换

原语JAX 追踪期语义XLA 落地形态主要场景(页)
jittrace 函数→jaxpr,缓存编译产物一张 XLA 可执行程序全局(01)
eval_shape只 trace 形状/dtype,不做实际计算不产生执行 HLO,仅抽象推导初始化 / AOT(01)
ShapeDtypeStruct抽象张量占位(shape + dtype + sharding)AOT lower 的输入规格01
lower() + compile()(AOT)提前 trace 并编译,不执行把编译从 step 0 提前,产出可复用可执行体trainers/pre_train/train_compile.py(01)
make_jaxpr导出 jaxpr不执行调试用(01 附注)

控制流

原语JAX 追踪期语义XLA 落地形态主要场景(页)
lax.scan循环体 trace 一次,带 carry编译成 While HLO,循环体不展开(缩小程序体积与编译时间)层堆叠 / microbatch(03,06)
lax.cond两个分支都 traceConditional HLO,运行期择一执行MoE 路由分支等(05)
lax.fori_loop固定/动态次数循环While HLO 或展开流水线(06)
lax.while_loop条件循环While HLO流水线(06)
lax.select逐元素择一Select HLO(无分支,两路都算)注意力 mask 等(04)

集合通信(多在 shard_map / 流水线内)

原语JAX 追踪期语义XLA 落地形态主要场景(页)
lax.all_gather沿 axis 收集各 shardAllGather HLOFSDP 权重收集 / CP 环(05,06,07)
lax.ppermute按 perm 在设备间点对点轮转CollectivePermute HLO流水线 ring / CP 环(06,07)
lax.psum跨 axis 求和AllReduce HLOMoE / 梯度(05)
lax.psum_scatter求和并 scatter(reduce-scatter)ReduceScatter HLOmegablox GMM(05)
lax.axis_index取当前设备在 axis 上的下标设备 id 相关 HLO路由 / mask(05,06)

自定义梯度

原语JAX 追踪期语义XLA 落地形态主要场景(页)
custom_vjp指定前向 + 自定义反向反向不由 autodiff 生成,接入你给的 HLO/kernelPallas 反向 / 注意力 / token 排序(04,05,07)
stop_gradient反向梯度截断为 0反向图剪枝全局
value_and_grad同时求值与反向前向 + 反向 HLO训练 loss(01)

算子内核(Pallas / 底层)

原语JAX 追踪期语义XLA 落地形态主要场景(页)
pallas_call调用 Pallas kernel(grid / BlockSpecMosaic 编出自定义 TPU HLOsplash / megablox / KDA(04,05,07)
dot_general通用张量收缩Dot HLO(matmul),量化在此插入量化 / GMM(05,08)

显存 / remat

原语JAX 追踪期语义XLA 落地形态主要场景(页)
rematjax.checkpoint标记重计算边界反向时重算而非物化激活03
nn.remat(Flax)作用于带参 module 的 remat同上,作用于 module03
jax.checkpoint_policies.*选择 存 / 算 / offload 的命名集合(save_only_these_namessave_and_offload_only_these_names控制 remat 物化策略与 host offload03

Flax lifted 变换

原语JAX 追踪期语义XLA 落地形态主要场景(页)
nn.scan在带参 module 上 scan(层堆叠/共享)底层 lax.scan → While HLODecoder 堆叠(03)
nn.vmapmodule 上批量化新增向量化维度03 / 05(按用到处)

阅读导航

主题串起的原语
01训练主循环与 AOT 编译jit / value_and_grad / lower+compile / eval_shape / ShapeDtypeStruct
02分区:逻辑轴 → 物理 meshwith_logical_constraint + logical_axis_rules / with_sharding_constraint / PartitionSpec·NamedSharding / pjit
03Decoder 堆叠与重计算 / Offloadnn.scan / nn.remat / remat_policy / checkpoint_policies
04注意力shard_map / pallas_call(splash) / custom_vjp / cond·select
05MoE / 专家并行shard_map / all_gather·psum·psum_scatter·axis_index / custom_vjp / megablox GMM pallas_call / dot_general
06流水线并行ppermute / scan / all_gather / fori_loop·while_loop
07上下文并行 / KDA 线性注意力ring all_gather·ppermute / GLA scan kernel / custom_vjp
08量化dot_general / AQT·Qwix 拦截 / sub-channel