huggingface / huggingface/candle

CPU quantized matmul has no batch path: prefill runs at token-at-a-time speed

Open
#3,707 0 comments 0 reactions 0 assignees View on GitHub
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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.