-
Notifications
You must be signed in to change notification settings - Fork 2.7k
[None][feat] Support the masked DSA indexer k-cache pool in the Python cache transceiver #17283
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
e954b0f
f40804d
25b5f9b
0b3d7fa
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1912,25 +1912,17 @@ def get_preferred_transceiver_runtime( | |
| cls, | ||
| pretrained_config: Any = None | ||
| ) -> Optional[Literal["CPP", "PYTHON"]]: | ||
| """Preferred KV-cache transceiver runtime, differentiated per checkpoint. | ||
|
|
||
| ``DeepseekV3ForCausalLM`` / ``DeepseekV32ForCausalLM`` use MLA attention, which transfers | ||
| a large latent KV that the Python (v2) transceiver handles better in disaggregated | ||
| serving, so they prefer the Python transceiver. GLM 5.2 (``GlmMoeDsaForCausalLM`` / | ||
| ``glm_moe_dsa``) uses a per-layer masked DSA indexer k-cache pool (cross-layer indexer | ||
| sharing) that the Python transceiver does not support, so GLM checkpoints must use the | ||
| C++ transceiver, which handles both the masked pool and dense indexer layouts. Applied | ||
| only when ``cache_transceiver_config.transceiver_runtime`` is 'auto'; an explicit runtime | ||
| """Preferred KV-cache transceiver runtime. | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I feel like this is the 3rd or 4th PR I reviewed recently that touched this. I'm beginning to wonder if it would make more sense to have ? That way we keep this particular part independent for every model "flavor". Ofc if you're confident this should be done for every model, then I guess this is better, but I'm not sure if it holds up in the future.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
|
|
||
| ``DeepseekV3ForCausalLM`` / ``DeepseekV32ForCausalLM`` / ``GlmMoeDsaForCausalLM`` | ||
| (GLM 5.2) use MLA attention, which transfers a large latent KV that the Python | ||
| (v2) transceiver handles better in disaggregated serving. The Python transceiver | ||
| also supports GLM 5.2's per-layer masked DSA indexer k-cache pool (cross-layer | ||
| indexer sharing), so every checkpoint sharing this implementation prefers the | ||
| Python transceiver. Applied only when | ||
| ``cache_transceiver_config.transceiver_runtime`` is 'auto'; an explicit runtime | ||
| is always respected. | ||
| """ | ||
| if pretrained_config is not None: | ||
| architectures = getattr(pretrained_config, 'architectures', | ||
| None) or [] | ||
| # model_type is checked as a fallback: it is 'glm_moe_dsa' on GLM | ||
| # checkpoints until __init__ rewrites it to 'deepseek_v32'. | ||
| if ("GlmMoeDsaForCausalLM" in architectures or getattr( | ||
| pretrained_config, 'model_type', None) == 'glm_moe_dsa'): | ||
| return "CPP" | ||
| return "PYTHON" | ||
|
|
||
| def __init__(self, model_config: ModelConfig[PretrainedConfig]): | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Non-blocking hardening note. Skipping the indexer view for a fully-masked stage is correct for the transfer itself, but it opens a narrow hole in the fan-in bounce gate:
_fanin_bounce_safe(transfer.py:1590) refuses multi-writer bounce by scanning the peer's page table for REPLICATED views, and that page table comes from the singlectx_info_endpointrank. If that rank's stage is fully masked, its page table advertises no REPLICATED view even though other writer stages do own indexer rows — the gate passes,reserve()splits the region astotal // num_writers, and the stage that does own indexer rows writes more than its equal share, overrunning into the neighboring sub-region. Dense layouts are immune (every rank advertises the view), so this is specific to the masked case. Requires ctx-PP > gen-PP fan-in plus opt-in bounce, so it's rare — but the fix is cheap: also scan the receiver's own page table (self._registrar.self_extractor.page_table, already in hand forextra_bytes) for REPLICATED views, which is populated whenever the receiver has any indexer rows to receive into. Fine as a follow-up.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel the same, does this work for ctx pp != gen pp?