huggingface / huggingface/candle
CPU quantized matmul has no batch path: prefill runs at token-at-a-time speed
- Dominant language
- Rust
- Stars
- 21k
- Forks
- 1.8k
- Avg merge
- 16h 42m
- Merged PRs (30d)
- 25
Description
Finding from embedding candle's quantized GGUF models in a long-running CPU server process, verified against the 0.11 sources.
Measured on a Ryzen 5 4600H (Qwen2.5-0.5B/3B Q4_K_M, `quantized_qwen2`, built with `-C target-cpu=native` so the AVX2 `vec_dot` kernels are active): prompt processing throughput is flat at ~35 tok/s (0.5B) regardless of prompt length — a 512-token prompt ≈ 15s, 1024 ≈ 35s, 2048 ≈ 70s, scaling linearly. Processing the whole prompt in one `forward` costs roughly N× the cost of decoding one token, i.e. the quantized matmul gets no GEMM-like benefit from `seq_len > 1` (llama.cpp on the same hardware processes prompts at several hundred tok/s by dequantizing/blocking into a real batched GEMM).
For interactive use this makes prefill the dominant cost on CPU: at ~35 tok/s a 1000-token prompt takes ~30s before the first generated token.
A secondary note for CPU users: the quantized `vec_dot` kernel selection is `#[cfg(target_feature = "avx2")]` — compile-time — while the f32 path (`gemm`/`pulp`) dispatches at runtime via `feature_detected!`. A default `x86_64` build silently runs the scalar quantized kernels (~3× slower prefill measured on the same machine). Worth a docs mention, or a runtime dispatch like the f32 path.
Contributor guide
No contributing guide indexed for this repository
Research direction
Start by locating the quantized matmul and AVX2 `vec_dot` implementations in the 0.11 sources, then compare their prompt-processing path with the f32 `gemm`/`pulp` path and runtime feature dispatch. Benchmark prompt lengths greater than one token and default versus `target-cpu=native` builds; done means batched prefill no longer scales as token-at-a-time, with the CPU dispatch behavior documented or addressed.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- machine-learning, performance
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100