onnxruntime
c933d07a - Add the ORT-side FlashMLA launcher (still no call site)

Commit
72 days ago
Add the ORT-side FlashMLA launcher (still no call site) Second of three steps. The previous commit got FlashMLA compiling; this one adapts it to ORT's parameters and workspace conventions. Nothing calls it yet, so behaviour is unchanged; wiring it into LaunchPagedLatentAttention behind an env switch and measuring it in-model is the next commit. flash_mla_latent.h deliberately does not include flash_mla.h. Those symbols only exist when the sm90a object library is built, so the include stays inside the .cu and callers see plain parameters. Mapping notes, all cross-checked against the standalone benchmark (dev/scripts/h200_3/flash_mla_bench.cu) that was already validated against an fp32 reference: - ORT's query heads become FlashMLA's `ngroups`, and `h` (its KV head count) is 1, so its flattened `seqlen_q` is seqlen_q * num_heads. ORT's query layout (token, head, head_size) already matches its q_row_stride = head_size. - k_ptr == v_ptr: the value is the leading 512 channels of the same 576-wide latent row. This is the assumption that makes it MLA rather than ordinary paged attention, and it is exactly what the ORT latent cache already stores. - k_batch_stride is the PER-PAGE stride, not a per-sequence one, because the cache is indexed through block_table. - params.cu_seqlens_k is misnamed upstream: it is read as a per-sequence total KV length, not a cumulative offset. ORT carries the length as of the start of the step, so BuildSeqlensKKernel adds seqlen_q. It is a device kernel rather than a host computation because the value must be right under CUDA graph replay, where the host cannot see it. - num_sm_parts follows the benchmark's formula (SMs / query tiles). Upstream's own getFlashMlaNumSmParts ignores the KV length and returns the SM count (132 here) regardless, which is far too many for a short context. FlashMlaLatentSupported() is deliberately strict. Every condition it screens -- bf16, unquantized cache, head_size 576, v_head_size 512, page size 64, one KV head, no head sink, no kv_indices, no softcap, no sliding window, uniform query length across the batch -- is something the kernel assumes rather than checks, so a false positive would be silent corruption rather than a failure. Verified to compile standalone at sm_90a with the same flags and include paths the CUDA EP uses.
Author
Committer
Parents
Loading