Skip to content

Support per-layer DSA indexer schedule (GLM-5.2) - #1412

Open
davidrhodus wants to merge 1 commit into
ml-explore:mainfrom
davidrhodus:glm-moe-dsa-indexer-types
Open

Support per-layer DSA indexer schedule (GLM-5.2)#1412
davidrhodus wants to merge 1 commit into
ml-explore:mainfrom
davidrhodus:glm-moe-dsa-indexer-types

Conversation

@davidrhodus

Copy link
Copy Markdown

Summary

GLM-5.2 (model_type: glm_moe_dsa) reuses the DeepSeek-V3.2 backbone but enables the DSA "lightning indexer" on only a subset of layers, declared per-layer via an indexer_types list ("full" = that layer has its own indexer weights; otherwise it has none). The shared deepseek_v32 attention builds an Indexer on every layer unconditionally, so loading GLM-5.2 fails:

ValueError: Missing N parameters:
  model.layers.*.self_attn.indexer.{wq_b,wk,weights_proj,k_norm}.weight ...

(GLM-5.2 declares "full" on layers 0,1,2 then every 4th — 22 of 78 layers.)

Changes

  • deepseek_v32.py
    • DeepseekV32Attention takes layer_idx and builds the Indexer only when indexer_types[layer_idx] == "full" — or when indexer_types is absent, in which case the indexer is built on every layer (DeepSeek-V3.2 behaviour is unchanged).
    • forward guards the indexer/sparse-mask block behind self.indexer is not None.
    • make_cache gives indexer-less layers a single-slot CacheList(KVCache()) — a second, never-written KVCache otherwise crashes CacheList.state on its empty keys.
  • glm_moe_dsa.py — add the optional indexer_types config field.
  • tests/test_models.pyglm_moe_dsa config with mixed ["full","shared",...] indexer_types, exercising both the conditional indexer build and the mixed-cache decode path.

Testing

  • New test passes the standard model_test_runner checks (fp32/fp16 forward, KV-cache decode, batch > 1, deepcopy); confirmed indexer is built only on "full" layers and the single-slot cache decodes correctly.
  • End-to-end: converted the full GLM-5.2 (glm_moe_dsa, 256 experts) to MLX and verified coherent generation (it failed with "Missing parameters" before this change).

DeepSeek-V3.2 / other glm_moe_dsa checkpoints without indexer_types are unaffected (indexer still built on every layer, 2-slot cache).

🤖 Generated with Claude Code

GLM-5.2 (glm_moe_dsa) enables the DeepSeek-V3.2-style lightning indexer on
only a subset of layers, declared via a per-layer `indexer_types` list
("full" = own indexer weights, otherwise none). The shared deepseek_v32
attention unconditionally builds an Indexer on every layer, so loading
GLM-5.2 failed with "Missing N parameters" for the indexer-less layers.

- deepseek_v32: build the Indexer only when `indexer_types[layer_idx]` is
  "full" (or when the field is absent -> every layer, unchanged for
  DeepSeek-V3.2); guard the indexer use in forward; give indexer-less layers
  a single-slot cache in make_cache (a second, never-written KVCache crashes
  CacheList.state).
- glm_moe_dsa: add the optional `indexer_types` config field.
- tests: glm_moe_dsa config with mixed "full"/"shared" indexer_types.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants