Skip to content

VLM embedding-prefill throughput regressed 1.5-2.3x on M1 Ultra since v0.1.0 #299

Description

@inureyes

Summary

The VLM prefill path (language-model prefill over pre-computed image embeddings) regressed 1.5-2.3x on Apple M1 Ultra between v0.1.0 (benchmark sweep 2026-05-19) and v0.2.1 (sweep 2026-06-15). Text prefill is unaffected, so the regression is isolated to the VLM embedding-prefill path. The current binary reproduces the slow v0.2.1 numbers, confirming this is current behavior and not a one-off sweep artifact.

Evidence (M1 Ultra, prompt "What is in this image?", test image, warmup=20, prefill tok/s)

Model mlxcel v0.1.0 mlxcel current mlx-vlm 0.4.4 (0.1.0 ref) mlx-vlm 0.4.4 (today)
llava-interleave-qwen-0.5b-bf16 8589 3746 4186 3937
gemma-4-26b-a4b-it-4bit 476 270 259 261
molmo2-4b 1012 687 730 706

Prompt-token counts are identical across sweeps (754 / 277 / 438), so this is not a prompt or tokenization change.

This is not environmental

Re-running the same mlx-vlm version (0.4.4) on the same host today reproduces its own v0.1.0 prefill numbers (4186->3937, 259->261, 730->706, all within run variance). The host is stable; only mlxcel's VLM prefill dropped. Current mlxcel VLM prefill is therefore roughly at parity with mlx-vlm (~0.95-1.03x), versus the ~1.33x median advantage reported for the v0.1.0 campaign (which was inflated by anomalously fast mlxcel measurements, e.g. llava at 8589 tok/s = 2.05x).

Reproduction

cargo build --release --features metal,accelerate
./target/release/mlxcel-bench-decode \
  -m models/llava-interleave-qwen-0.5b-bf16 \
  -p "What is in this image?" \
  --image tests/fixtures/test_image.png \
  --warmup-tokens 20 --max-tokens 100
# Observe Prefill ~3700 tok/s; the v0.1.0 sweep recorded ~8589 tok/s for the same model.

Scope / where to look

The measured prefill is generate_with_stats_and_embeddings in src/bin/bench_decode.rs (the vision encoder runs separately in prepare_and_compute_vlm_embeddings and is excluded from the prefill stat). So the regression is in the language-model prefill over input embeddings, not in the vision encoder and not in text prefill (text prefill held at ~1.79x).

Suspect window: changes landed between v0.1.0 (2026-05-19) and v0.2.1 (2026-06-15). Candidate causes to bisect:

Acceptance criteria

  • Bisect to the introducing change and root-cause why the embeddings-prefill path slowed on M1 Ultra.
  • Restore VLM embedding-prefill throughput, or document why the slowdown is an intended/unavoidable cost of the new cache/prefill path.
  • Re-measure on M1 Ultra against same-version mlx-vlm to confirm.

Metadata

Metadata

Assignees

Labels

priority:mediumMedium prioritytype:bugBug fixes, error corrections, or issue resolutions

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions