Repository navigation
Freeze the 0.2.3.post2 MQA logits as _legacy APIs and keep 0.2.3 callers working - #128
Merged
Merged
Conversation
0.2.5 made the SM100 MQA logits kernel MX-only. sglang keeps FP32 index-K scales as its default, so it still needs the 0.2.3 SM100 kernel, which accepts FP32 or MX scales, FP32 or BF16 weights/logits, and cleaning. Add SM100-only `fp8_fp4_mqa_logits_legacy`, `fp8_fp4_paged_mqa_logits_legacy`, `get_mqa_logits_metadata_legacy` and `get_paged_mqa_logits_metadata_legacy` with the 0.2.3 signatures. The kernel, schedulers, layout and clean-logits code are copied unchanged from 3cca390^1 into `legacy/` directories under the `deep_gemm::legacy` namespace. The current APIs are untouched. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…3 calls to it The `_legacy` APIs now carry 0.2.3.post2's MQA logits for every architecture: the host entry points and the SM90, SM100 (including the BF16 contiguous kernel from release sgl-project#117) and SM120 kernels, copied under `deep_gemm::legacy` with `legacy_`-prefixed JIT names. Callers written against 0.2.3 run unchanged: - `fp8_mqa_logits` / `fp8_paged_mqa_logits` are restored on top of the `_legacy` functions. - `fp8_fp4_mqa_logits` / `fp8_fp4_paged_mqa_logits` take the `_legacy` path when called with a bool `clean_logits` after the fixed arguments, or with `clean_logits` / `logits_dtype` keywords (and the dense call without `max_seqlen_k`). - `get_paged_mqa_logits_metadata` without `indices` returns the 0.2.3 schedule on SM100. `test_attention_legacy.py` runs on all architectures and checks the 0.2.3 call shapes bitwise against the `_legacy` calls. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
_legacy APIs_legacy APIs and keep 0.2.3 callers working
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Purpose
DeepGEMM 0.2.5 (#103) changed the MQA logits APIs and, on SM100, made the kernel accept only MX scales: packed UE8M0, four per 128-element token. sglang main is pinned to 0.2.3.post2 and calls the 0.2.3 APIs on SM90, SM100 and SM120, with FP32 index-K scales by default. With this PR, sglang main can move to the new wheel without code changes and run exactly the MQA logits code it runs today. The 0.2.5 APIs and kernels are unchanged.
What 0.2.3 callers get
fp8_mqa_logits/fp8_paged_mqa_logits(removed in 0.2.5) are restored on top of the_legacyfunctions.fp8_fp4_mqa_logits/fp8_fp4_paged_mqa_logitstake the_legacypath when the call uses the 0.2.3 signature: a boolclean_logitsright after the fixed arguments, or aclean_logits=/logits_dtype=keyword. A dense call withoutmax_seqlen_kalso counts, since 0.2.5 requires it. The 0.2.5 signatures never match these.get_paged_mqa_logits_metadatawithoutindicesreturns the 0.2.3 schedule on SM100, where the 0.2.5 metadata requiresindices. On SM90 and SM120 it keeps returning the 0.2.5 metadata. For every SM with work, it is the same as 0.2.3's; it differs only in the end-of-schedule entries for idle SMs, which both kernels skip. The legacy test checks this bitwise.Ambiguous by construction: a 0.2.3-style paged call with only the seven fixed arguments, or a dense call passing just
max_seqlen_k=, uses the 0.2.5 path. sglang main never makes either call._legacyAPIs (0.2.3.post2 signatures, SM90 / SM100 / SM120)fp8_fp4_mqa_logits_legacy(q, kv, weights, ks, ke, clean_logits=False, max_seqlen_k=0, logits_dtype=torch.float, schedule_meta=None)fp8_fp4_mqa_logitsfp8_fp4_paged_mqa_logits_legacy(q, kv_cache, weights, context_lens, block_table, schedule_meta, max_context_len, clean_logits=False, logits_dtype=torch.float, indices=None)fp8_fp4_paged_mqa_logitsget_mqa_logits_metadata_legacy(ks, ke, num_kv_tokens, num_heads)get_mqa_logits_metadataget_paged_mqa_logits_metadata_legacy(context_lens, block_kv, num_sms, indices=None)get_paged_mqa_logits_metadataThese stay available for callers that want to choose explicitly, e.g. FP32 index-K pools after sgl-project/sglang#44350.
Implementation
deep_gemm/include/deep_gemm/legacy/andcsrc/jit_kernels/impls/legacy/hold 0.2.3.post2's MQA logits code for all three architectures. That covers SM90 dense and paged, SM120 FP8/FP4 dense and paged, and SM100 including the BF16 contiguous kernel from release [SM100] mqa_logits: faster bf16-weight paths, including the dev contiguous kernel for MX scales (release/v0.2.3) #117. The only changes are include paths, thedeep_gemm::legacynamespace and alegacy_prefix on JIT kernel names. SM90 and SM120 files are byte-identical between 0.2.3.post2 and3cca390^1; only SM100 carried release-only changes.csrc/apis/attention.hpp: the four_legacyentry points are 0.2.3.post2's host functions for all architectures, calling thelegacy::kernels.tma::copyas a wrapper overcopy_nd, and every other symbol they use is unchanged.legacy/directories,test_attention_legacy.pyand the wiring.Size: about +7,900 lines, almost all copied 0.2.3.post2 code.
Test
4x B300 (SM103), CUDA 13.0, torch 2.14.1+cu130,
DG_TEST_PROFILE=release:test_attention_legacy.py: pass. Each case is also run through the 0.2.3 call shapes (fp8_mqa_logits, positionalclean_logits, the shared metadata name) and must match the_legacycall bitwise. The JIT cache showslegacy_sm100_bf16_mqa_logitsbuilt, so the [SM100] mqa_logits: faster bf16-weight paths, including the dev contiguous kernel for MX scales (release/v0.2.3) #117 fast path runs.test_attention.py(0.2.5 APIs): pass, and it builds nolegacy_*kernels.sglang main (38d9e4a3fe) DeepGEMM-related suites under 0.2.3.post2 and under this wheel: identical results in all 16 files. That covers 192
test_deepgemm_paged_mqa_logits, 192 CuteDSL paged, 95 FP4 indexer, DSA/DSV4 indexers, mega-MoE, FP8 linear and mHC. The 14test_paged_mqa_metadatafailures and 1test_dsafailure fail identically on 0.2.3.post2.E2E, sglang main 38d9e4a3fe on 4x B300 (TP4), 0.2.3.post2 vs this wheel. Each run does GSM8K (
few_shot_gsm8k, 1319 questions, run twice) andbench_serving(random 8192 in / 256 out, 256 prompts, concurrency 32):sm100_paged_mqa_logitslegacy_sm100_paged_mqa_logitssm100_mqa_logits,sm100_paged_mqa_logits_metadatalegacy_sm100_mqa_logits,legacy_sm100_paged_mqa_logits_metadataV4-Flash:
flashinfer_mxfp4MoE, EAGLE 3/1/4, chunked prefill 4096, reasoning effort pinned tolow. No server errors in either run. With this wheel, sglang main ran onlylegacy_*MQA kernels.Not run here: SM90 and SM120 (no box available; the release workflow's test job covers H200).
🤖 Generated with Claude Code