Skip to content

Speculative decoding diverges from non-speculative output at temperature 0 (should be identical) #1423

Description

@trevorgordon981

Bug

At temperature 0 (greedy), mlx_lm.generate with --draft-model (speculative decoding) produces different output than the same call without a draft model. Greedy speculative decoding should be lossless — the target verifies every drafted token and accepts only its own argmax, so the output must equal plain greedy decoding. Instead the two diverge, reproducibly.

Versions

  • mlx 0.31.2
  • mlx-lm 0.31.3
  • Apple M3 Ultra (512 GB), macOS 26.2 (arm64)

Reproduce

Public models — 8-bit target, 4-bit draft, byte-identical tokenizer (both vocab 262144):

# (A) no speculative decoding
mlx_lm.generate --model mlx-community/gemma-4-31b-it-8bit \
  --temp 0 --max-tokens 500 \
  --prompt "Write a detailed essay (multiple paragraphs) explaining how a transformer neural network processes a sentence, from tokenization through attention to output."

# (B) with speculative decoding (same prompt)
mlx_lm.generate --model mlx-community/gemma-4-31b-it-8bit \
  --draft-model mlx-community/gemma-4-e2b-it-4bit --num-draft-tokens 2 \
  --temp 0 --max-tokens 500 \
  --prompt "Write a detailed essay (multiple paragraphs) explaining how a transformer neural network processes a sentence, from tokenization through attention to output."

Expected

(A) and (B) identical (greedy spec-decode is exact).

Actual

They diverge. Same prompt, temp 0:

(A) no draft: …its significance (replacing RNNs/LSTMs), and the general flow (Encoder-Decoder or Decoder-only).

(B) with draft: …its departure from RNNs/LSTMs (parallelism), and the general goal (mapping input sequences to output sequences).

Observations:

  • Reproducible & deterministic across repeated isolated runs (not a flaky startup artifact).
  • The divergence appears/accumulates with longer generations; short generations — or runs where an early stop sequence truncates output before the divergence point — can look identical, which makes it easy to miss.
  • Not a tokenizer mismatch — draft and target tokenizer.json are byte-identical (vocab 262144).
  • Also reproduces via mlx_lm.server /v1/chat/completions with the same model pair: spec-decode responses can drop the entire post-reasoning content on longer generations, consistent with the same underlying divergence.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions