Skip to content

MODEL-MM-QWEN4-EXP W1: resolve and validate the qwen4_exp config, register the architecture, and refuse by name until the forward exists #1981

Description

@localai-bot

W1 of #1978, whose spec landed in
#1980 as
.agents/specs/qwen4-exp-flash-next.md.
That issue deliberately carries no product code. This one is the first slice that does.

Scope

Config resolution and registration for Qwen4ExpForConditionalGeneration /
model_type: qwen4_exp, reachable through the loader, plus a refusal that names what is
not implemented yet rather than dying somewhere downstream.

Concretely:

  1. The full_attention rewrite. Upstream's __post_init__ rewrites every
    full_attention entry in layer_types to qwen_sparse_attention, because the
    published checkpoint's layer_types says full_attention for layers that actually
    run the QSA indexer. A reader that takes the checkpoint at face value will wire dense
    attention on 12 of 48 layers and be wrong without saying so.
  2. layer_types synthesis from full_attention_interval when the key is absent:
    linear_attention unless (i + 1) % interval == 0, interval defaulting to 4. For
    this checkpoint that reproduces the published 48-entry list exactly, which is the
    test.
  3. Every validate_architecture rejection, mirrored: unsupported layer types;
    output_gate_type outside {sigmoid, silu}; hc_count <= 1; num_experts <= 0;
    num_experts_per_tok outside [1, num_experts]; non-positive
    moe_intermediate_size / shared_expert_intermediate_size; the QSA all-or-nothing
    field group; indexer_kv_heads != 1; and rotary_dim > indexer_head_dim where
    rotary_dim = int(head_dim * partial_rotary_factor).
  4. ple_layer_ids is one-indexed. The lookup is index(layer_idx + 1), so [2]
    selects 0-based layer 1. This is documented upstream as one-indexed and pinned by
    test_ple_layers_must_use_linear_attention; it is not an off-by-one to be corrected.
    Validation must also reject a PLE id whose layer is not linear_attention.
  5. number_of_conv_states = 3 when ple_layer_ids is non-empty, else 1.
  6. A refusal naming the missing parts. The forward does not exist yet, so loading
    this architecture must fail with a message naming QSA, the n-gram embedding, the PLE
    layer and the gated residual — not with a shape or dtype error from a lower layer.
    AGENTS.md requires an unimplemented arm to refuse by name.

Out of scope

The forward, the weight loader, and the GGUF arm. Those are W2 onward in the spec.

Reachability

The slice enters through the loader's architecture dispatch, so the smallest failing
test drives it from there rather than constructing the config type by hand. Per AGENTS.md
"Nothing lands dead", a unit test that builds the struct directly does not discharge
this, and the fresh reviewer should delete the production call site in a scratch copy and
confirm the focused gate goes red.

Oracle

transformers 5.16.0, the lane pin accepted for this row and recorded in
.agents/oracles/transformers.md.
vLLM does not implement qwen4_exp at any revision, so there is nothing to mirror for
the config shape; the ops it does supply are W2 onward. Values are checked against the
published Qwen/Qwen3.8-Flash-Next config.json.

Done when

Every rejection above has a red-first case, the 48-entry layer_types synthesis matches
the published list, the full_attention rewrite is asserted, and an attempted load
refuses by name. No token claim and no speed claim; neither is reachable at this wave.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions