Skip to content

Native CPU expert results depend on verifier width (plain/MTP divergence) #152

Closed

Description

@clapbr

Affected: Engine 0.1.24 (3ce2523), native i-quant expert packs. This is in the CPU expert path, so it is not specific to CUDA or HIP.

In native_expert.cpp, singleton expert groups use ggml vec_dot, while groups with nt >= 2 use custom AVX gate/up or IQ4_NL down kernels. These reductions produce slightly different FP32 results. The group size changes with verifier width, so the same weights and token activations can produce different expert outputs in plain and MTP runs. PR #43 documents the speed reason for the switch and its small AVX-versus-ggml error, but does not test equality across verifier widths.

Reproduction: Using one existing GSQ-RCO IQ3_S GGUF shard, take layer 0, expert 7 (IQ3_XXS gate/up, IQ4_NL down) and four fixed activations. Run the same native expert rows as four singleton calls, two calls of width 2, and one call of width 4; compare the FP32 outputs bitwise. Replaying the current mixed dispatch produced 9,566 differing cells against the singleton reference. With ggml vec_dot selected at every width, gate/up and down outputs matched bitwise for widths 1, 2 and 4. On a fixed 21,999-token prompt, the patched plain and MTP paths also generated the same 150 greedy token IDs; MTP accepted 93/130 drafts.

Expected: Changing the verifier or speculative width should not change target-model expert arithmetic for identical inputs.

Suggested fix: Select one arithmetic path independent of nt, and add a width 1/2/4 regression test. Using ggml vec_dot at every width is a conservative fix; retaining the multi-token AVX speed would require its result to be made width-invariant and validated separately.

Activity

  1. Niko1221 commented on Sep 29, 2026

    @Niko1221
    Owner

    Thanks @clapbr, confirmed: native_expert.cpp picks the AVX multi-token kernels only for groups of 2 or more, so the verify width changes the rounding. For now STRATA_NO_IQ512=1 STRATA_NO_IQ256=1 STRATA_NO_IQ4NL=1 gives width-invariant results (at some CPU speed). We'll choose one path for all widths, add your 1/2/4 test, and gate it.

  2. added 2 commits that reference this issue on Sep 30, 2026
  3. Niko1221 commented on Sep 30, 2026

    @Niko1221
    Owner

    0.1.30 adds STRATA_IQ_MT_MIN=1 (in the config's env): the CPU experts use the multi-token kernels for every group, so a token's expert rows round the same whatever the verify window held, and greedy output no longer depends on the drafting (checked bit for bit by native_expert_parity). It costs 1-3% decode on IQ3_S with AVX-512 (IQ3_XXS +3%, the others within noise), so the default stays 0.1.29's rule. Thanks for the precise report!

  4. added a commit that references this issue on Oct 1, 2026
  5. 29 remaining items

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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