Skip to content

Optimize flashmask sm90#165

Open
baoqiwen wants to merge 11 commits into
PaddlePaddle:mainfrom
baoqiwen:bqw_perf
Open

Optimize flashmask sm90#165
baoqiwen wants to merge 11 commits into
PaddlePaddle:mainfrom
baoqiwen:bqw_perf

Conversation

@baoqiwen

@baoqiwen baoqiwen commented Jul 20, 2026

Copy link
Copy Markdown

针对 flashmask v4 cutedsl sm90 做优化

27661bd:Optimize flashmask bwd: O1 m-block segments + full/partial mask split

  1. O1 m-block 分段跳转(取代逐块跳过),直接用预算好的边界标量(LTS/LTE/UTS/UTE_nblock_max/min)几次整数除法算出最多 3 段连续可见区间,与 cpp 的分段跳转一致。
  2. full/partial mask 拆分,新增 partially_masked 参数,与 cpp 对齐。

8c2e847:Optimize flashmask fwd: build block lists in a cute kernel instead of paddle ops

  1. 把 fwd 每次调用前构建 block list 的 host 前处理从几十个 paddle op 换成一个 cutedsl kernel

d4fa1ab:Optimize flashmask fwd: drop per-call output zero-fill and skip SM90 reduce_block_count

  1. fwd 去掉 per-call 输出清零,每个被调度的 (m_block, head, batch) tile 在 epilogue 都会无条件写满整块 O(全 mask 的行由 kernel 写 O=0 / LSE=-inf),所以未初始化缓冲是安全的。
  2. SM90 跳过 valid_block_count 分配 + reduce_block_count kernel,这两处 sm100 才使用

f09d963:Encode flashmask partial flag into mask index for SM90 fwd

  1. 把"这个 mask-list 块到底需不需要逐元素 flashmask"这一分类预先算好、塞进索引的空闲 bit,从而在 fwd 热路径上省掉逐块的 gmem 判定。

122faf4:Optimize flashmask cutedsl d256/dv256 bwd via atomicAdd dQaccum

  1. 非 deterministic 的 d256 走 atomicAdd 路径——直接用 v4.f32 原子加把 dQ 寄存器写回 gmem,去掉 sdQaccum 与 warp-1 store 循环,省出 smem 开 num_stages_Q=2 并启用 dKV_swapAB/dQ_swapAB;deterministic 仍保留有序的 TMA 路径。

631ba7f:Optimize flashmask cutedsl d256/dv256 bwd: slice dQKV MMA + larger KV tile

  1. d256 atomic 路径把 dV/dQ/dK 拆成两个 M-half 交错执行,让前半 dQ 的 atomicAdd 与后半 MMA 重叠。实测:d256/dv256 Full bwd 2087ms → 1844ms。
  2. n_block_size 从 64 tuner 到 80。实测:d256/dv256 Full bwd 1844ms → 1523ms。

24e5363:skip causal mask on fully-visible blocks in SM90 fwd
SM90 前向 causal 注意力里,对角线以下那些"全部可见、不需要掩码"的 K/V 块之前还在逐元素跑一遍无用的 causal mask,现在直接跳过(仅在有 FlexAttention mask_mod 时才保留),从而砍掉约一半块的冗余整型比较,把 d128 causal 前向从 15.7ms 降到 14.2ms。(对齐cpp实现)

@baoqiwen baoqiwen changed the title Optimize flashmask bwd: O1 m-block segments + full/partial mask split Optimize flashmask sm90 Jul 21, 2026
# the KV block index and forward it so mma skips the per-element
# flashmask apply on causal/seqlen-only mask blocks.
mask_raw = curr_mask_block_idx[curr_mask_block_cnt - 1]
mask_n_block = mask_raw & 0x3FFFFFFF

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cpp 描述:单开一个 bool 数组存 partial flag,放在 smem,会引发 4-way bank conflict。把 partial flag 编进 n_block 这个 int 里,既省 smem 又消除 bank conflict。

cutedsl 设计:
bit 0–29(30 位): block 下标, 范围 0 ~ 2³⁰-1。
bit 30(1 位):fm_partial 标志(1=部分被 mask, 需逐元素 apply; 0=全可见, skip)。
bit 31(符号位):特意不用,保持为 0,让整个值恒为非负。

cpp 用符号位存 flag,(索引占 31 位);
DSL 用 bit30 (索引占 30 位, 符号位留空换取全程非负、无移位陷阱,更加安全)。
block idx 不可能超过 2**30 的,不然早 oom 了。用 30 bit 也十分安全。

_postprocess_run(
dq_accum_tensor, dq_tensor, softmax_scale,
head_dim_rounded, m_block_size, AtomLayoutMdQ, dQ_swapAB,
head_dim, m_block_size, AtomLayoutMdQ, dQ_swapAB,

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这地方其实无所谓,反正如果这里是非 pad,进了 bwd post 之后也会统一 pad。
看 overlap pr 合入后,统一一下写法。保持外部全部非 pad,由 bwd post pad。

@baoqiwen
baoqiwen force-pushed the bqw_perf branch 2 times, most recently from 3508785 to 0426f1d Compare July 24, 2026 19:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant