Ce qui se passe
Hugging Face ajoute à transformers l'exécution efficace des fichiers
GGUF, le format de llama.cpp. On choisit un GGUF sur le Hub, on le charge
avec from_pretrained, et les poids restent quantifiés en mémoire.
transformers savait déjà lire un GGUF, mais en le déquantifiant — c'est encore
le repli quand aucun noyau compatible n'est disponible, avec la mémoire que cela
coûte.
Premier périmètre : les Mac Apple Silicon et l'architecture Qwen3.5, dense et MoE, ainsi que les checkpoints Qwen3.8 compatibles.
Le mécanisme
Plutôt que de réécrire des noyaux, transformers reprend ceux de ggml pour
Metal, distribués sur le Hub par la bibliothèque kernels :
| Noyau | Rôle |
|---|---|
ggml-quantization |
lit les poids quantifiés sans décompresser la matrice, experts MoE compris |
ggml-norm |
normalisation fusionnée, dont la RMSNorm centrée de Qwen3.5 et 3.8 |
ggml-attn |
flash attention Metal, pour le prompt comme pour le décodage |
ggml-gated-delta-net |
couches d'attention linéaire des architectures hybrides Qwen |
topk |
routage des experts MoE, écrit par Hugging Face |
S'y ajoutent deux retouches de generate qui profitent à tous les modèles :
le masque d'attention inutile est supprimé d'emblée quand l'entrée n'a pas de
remplissage (#48814), et le test d'arrêt est lu avec un pas de décalage, pour
que le CPU continue d'alimenter le GPU au lieu de l'attendre (#47975).
Comment s'y prendre
Il faut un Mac Apple Silicon, une version de PyTorch couverte par les builds de
ggml-quantization (en général les deux dernières), et transformers depuis
main en attendant la prochaine version :
pip install -U "git+https://github.com/huggingface/transformers.git" kernelsfrom transformers import AutoModelForCausalLM, AutoTokenizer
repo, fichier = "unsloth/Qwen3.5-4B-GGUF", "Qwen3.5-4B-Q4_K_M.gguf"
tokenizer = AutoTokenizer.from_pretrained(repo, gguf_file=fichier)
model = AutoModelForCausalLM.from_pretrained(repo, gguf_file=fichier)Tout le reste est l'API habituelle. Pour brancher un client comme Jan ou Pi sur
une API compatible OpenAI, installer l'extra serving puis :
transformers serve "unsloth/Qwen3.5-4B-GGUF:Qwen3.5-4B-Q4_K_M.gguf"
# URL de base : http://localhost:8000/v1 — options --reasoning on | off | autoPour le choix de quantification, les tailles du Qwen3.5-4B d'Unsloth parlent d'elles-mêmes : BF16 8,42 Go, Q6_K 3,53 Go, Q5_K_M 3,14 Go, Q4_K_M 2,74 Go, le point de départ conseillé. Monter ensuite si la mémoire le permet, et juger sur ses propres tâches.
Ce que valent les chiffres
Sur un MacBook Pro M2 Max (32 Go, macOS 26.6, PyTorch 2.12.1, kernels 0.17.0),
le débit de transformers est proche de celui de llama.cpp (build b10200)
sur trois checkpoints : un petit dense, un grand dense, un MoE. Les deux mesures
ne se comparent pas strictement — llama-bench ne compte que le décodage, la
mesure transformers inclut le traitement du prompt — et le billet ne donne les
valeurs que sous forme de graphique.
Les limites
- Chemin quantifié MPS uniquement ; ailleurs, retour à la déquantification.
- Remplissage et lots encore lents ;
generate_batchsur MPS est prévu. - Couverture limitée à Qwen3.5, élargie progressivement.
- Hugging Face le dit lui-même : pour de l'inférence locale pure, llama.cpp reste le moteur recommandé.
Ce que ça change
L'intérêt n'est pas de remplacer llama.cpp mais de faire entrer le même fichier
dans l'outillage PyTorch : poser des hooks sur les activations, évaluer un
checkpoint quantifié avec ses scripts existants, vérifier qu'une conversion GGUF
n'a pas abîmé les poids, essayer un logits processor maison, ou repartir d'un
GGUF pour un fine-tuning avec GgufConfig(dequantize=True). À terme, les
noyaux ggml pourraient accélérer des architectures que llama.cpp ne prend pas en
charge.
Source : Transformers now runs llama.cpp quants, blog Hugging Face, 22 septembre 2026.