To estimate the total prefill latency, assemble the components (DSA, MoE, and Communication) into a serial layer and multiply by the number of layers.
Assembly Pattern:
- DSA:
dsa = ContextDSAModule.get_cp_dsa(b, isl, cp, db, dims) - MoE:
moe = MoEOp.get(num_tokens=isl, moe_tp=cp, moe_ep=ep, distribution=dist) (Note: MoE uses the full isl, not per-card). - Comm:
comm = db.ag_latency(isl*hidden*2, cp) + db.rs_latency(isl*hidden*2, cp) - Layer:
layer = dsa + moe + comm (These are treated as serial operations). - Total Prefill:
prefill = layer * num_layers (Note: The first k dense layers may not have MoE/DSA-MoE communication).
Critical Invariants:
- Base Row: Must be
bf16-KV (even if KV is stored in fp8, the FMHA kernel is bf16). - MoE Parallelism: Communication primitives must follow the MoE parallel mode (e.g., TP+SP $\rightarrow$
AG_hidden+RS; EP $\rightarrow$ all-to-all). - RS (Reduce-Scatter): There is one RS per layer after MoE, performing TP-reduce+SP-scatter. Exclude
cross_device_reduce (allreduce) as it is for decode/post-processing.
dsa = ContextDSAModule.get_cp_dsa(b, isl, cp, db, dims)
moe = MoEOp.get(num_tokens=isl, moe_tp=cp, moe_ep=ep, distribution=dist) # full tokens
comm = db.ag_latency(isl*hidden*2, cp) + db.rs_latency(isl*hidden*2, cp) # AG_hidden + RS
layer = dsa + moe + comm # serial
prefill = layer * num_layers # (first_k_dense_replace layers have no MoE/DSA-MoE comm)