Qwen3 GGUF : corriger tokenizer et chat template
Les erreurs de tokenizer et de chat template sur les GGUF Qwen3 se manifestent par trois symptômes : balise de réflexion jamais fermée, génération qui ne s'arrête pas, ou réponses hors sujet. La cause est presque toujours le chat template mal appliqué. Ajoutez --jinja pour utiliser le template embarqué dans le GGUF, vérifiez la provenance du fichier, et en dernier recours passez un template personnalisé.
Un GGUF Qwen3 qui « répond n'importe quoi » n'est presque jamais un problème de qualité du modèle : c'est un problème de mise en forme du prompt avant qu'il n'atteigne le modèle. Ce guide traite uniquement les erreurs de tokenizer et de chat template des GGUF Qwen3 : reconnaître le symptôme, vérifier la provenance du fichier, et corriger ou remplacer le template.
#Les trois symptômes à reconnaître
Trois signaux indiquent un problème de tokenizer ou de chat template plutôt qu'un problème de modèle : une balise de réflexion (généralement « think ») qui s'ouvre sans jamais se refermer dans la réponse, une génération qui continue indéfiniment sans s'arrêter à la fin logique de la réponse, ou un modèle qui répond hors sujet comme s'il n'avait pas compris qu'une question lui était posée. Dans les trois cas, le modèle lui-même n'est pas en cause : c'est la structure du texte qu'il reçoit en entrée qui est mal formée.
#La cause racine : le chat template
Ton ChatGPT privé et gratuit sur ta machine en 1 heure — LM Studio, Ollama, Open WebUI, tes documents, sans cloud.
- Espace en ligne à vie
- PDF + fichiers
- Mises à jour à vie
Un modèle de langage ne reçoit jamais directement vos messages : un chat template les met en forme (balises de tour de parole, prompt système, marqueurs de début/fin) avant de les transformer en tokens. Si ce template est absent, mal choisi ou mal interprété par le moteur d'inférence, le modèle reçoit un texte qui ne ressemble pas à ce sur quoi il a été entraîné, et produit des sorties dégradées, même si les poids du modèle et le tokenizer eux-mêmes sont corrects.
#L'option --jinja : la première chose à vérifier
La documentation officielle Qwen recommande explicitement d'ajouter --jinja au lancement d'un GGUF Qwen3 avec llama.cpp : cette option indique d'utiliser le chat template embarqué dans le fichier GGUF, présentée comme la méthode à privilégier plutôt qu'un template générique choisi par défaut par le moteur.
Si votre commande de lancement ne contient pas --jinja, c'est la première correction à essayer avant toute autre hypothèse. Beaucoup de scripts et d'interfaces construits avant la généralisation de cette option l'omettent encore, ce qui explique une bonne part des rapports de « réponses cassées » sur des GGUF Qwen3 pourtant valides.
#Un bug de parsing connu et corrigé
Une erreur spécifique a touché llama.cpp sur le chat template Qwen3 : le moteur de template échouait à analyser une syntaxe Jinja de découpage de liste (messages[::-1]), utilisée pour parcourir l'historique de conversation à l'envers dans la logique d'appel d'outils. L'erreur remontée était un échec d'analyse pointant précisément cette ligne du template.
- 01Identifier la version de llama.cpp utiliséeUne version ancienne peut ne pas inclure le correctif de parsing pour la syntaxe de slicing utilisée par le template Qwen3.
- 02Mettre à jour vers une version récenteRecompiler ou retélécharger un binaire llama.cpp à jour résout ce cas précis, sans avoir besoin de modifier le GGUF lui-même.
- 03Si la mise à jour n'est pas possiblePasser un template personnalisé simplifié via --chat-template-file, en évitant la construction Jinja incriminée.
#llama-server et llama-cli ne se comportent pas pareil
Un comportement signalé dans le dépôt llama.cpp : activer --jinja avec llama-server peut faire disparaître le bloc de réflexion (le contenu entre les balises de pensée) de la réponse, alors que ce même bloc reste visible en utilisant llama-cli avec la même option et le même modèle. Si votre intégration dépend de la présence du contenu de réflexion dans la sortie (pour de l'observabilité ou du débogage), ce n'est pas un problème de tokenizer mais une différence de traitement entre les deux binaires — vérifier lequel des deux vous utilisez avant de chercher plus loin.
Cette distinction a une conséquence pratique pour qui construit une intégration au-dessus de llama.cpp plutôt qu'une simple session interactive : un pipeline de test qui valide le format de sortie sur llama-cli, puis qui est déployé en production derrière llama-server, peut voir apparaître une régression silencieuse sur ce point précis sans qu'aucun paramètre du côté applicatif n'ait changé. Documenter explicitement quel binaire sert la production, et tester sur ce binaire précis plutôt que sur celui utilisé en développement local, évite ce piège.
#Désactiver le mode réflexion de force
Qwen3 propose un mécanisme de bascule entre mode réflexion et mode direct au niveau du chat template. La documentation officielle Qwen indique cependant que ce mécanisme de désactivation forcée (hard switch) n'est pas exposé nativement dans llama.cpp : passer enable_thinking à false via les options de ligne de commande peut être ignoré selon la version, comme le montrent plusieurs signalements récents sur des variantes Qwen3.5.
Le contournement documenté par Qwen consiste à fournir un template personnalisé via --chat-template-file, dans lequel enable_thinking est fixé explicitement à false au niveau du template lui-même plutôt que transmis comme paramètre au moment de la requête. C'est plus fiable qu'un paramètre d'exécution qui dépend du support exact de votre version de llama.cpp.
Point à préciser pour ne pas généraliser à tort : le signalement #20182 (« enable_thinking param cannot turn off thinking ») porte précisément sur Qwen3.5-9B en build 8215, reste étiqueté « bug-unconfirmed » sur le dépôt llama.cpp, et a été fermé sans résolution (« not planned »). Rien ne prouve que le même comportement touche un GGUF Qwen3 d'origine (par opposition à Qwen3.5) : si vous rencontrez ce symptôme sur un Qwen3 classique, traitez-le comme un cas à isoler et à signaler séparément plutôt que comme une confirmation automatique de ce ticket.
#Vérifier la provenance d'un GGUF tiers
Une part des problèmes de tokenizer sur les GGUF Qwen3 ne vient pas de llama.cpp mais du fichier GGUF lui-même : une conversion faite avec une version ancienne des outils de conversion, ou un fichier dont le tokenizer a été mal exporté, produit des symptômes similaires (fin de génération absente, tokens spéciaux mal reconnus). Avant de chercher un bug côté moteur d'inférence, comparer la taille et la date de publication de votre fichier GGUF avec un dépôt reconnu (Qwen officiel, ou des re-quantifications documentées) permet d'écarter cette hypothèse.
Un repère simple pour trancher rapidement entre un problème de fichier et un problème de configuration : si le même GGUF fonctionne correctement sur une autre machine, ou avec une autre version de llama.cpp, le fichier lui-même n'est probablement pas en cause. À l'inverse, si plusieurs re-téléchargements du même dépôt sur la même machine reproduisent systématiquement le symptôme, l'hypothèse la plus probable se déplace vers la configuration locale (version du binaire, options de lancement) plutôt que vers le fichier.
#Quantification trop basse : appels d'outils malformés
Un dernier symptôme, distinct des trois premiers, touche spécifiquement l'usage de Qwen3 en agent avec appel d'outils : au lieu d'un problème de mise en forme du texte, l'appel d'outil lui-même arrive tronqué, avec des arguments vides ou mal structurés (JSON invalide). Un guide de dépannage communautaire consacré à llama.cpp documente que la structure des appels d'outils est sensible au niveau de quantification : les quantifications sous 4 bits (Q3, Q2, IQ) produisent des appels d'outils malformés même quand le chat template est correctement appliqué avec --jinja.
Ce point est facile à manquer parce qu'il ressemble, au premier abord, à un problème de tokenizer classique : une réponse tronquée fait immédiatement penser à un chat template mal fermé. La distinction pratique tient dans le contexte d'apparition du symptôme : un problème de template touche toutes les réponses, y compris le texte simple sans appel d'outil, alors qu'un problème de quantification sur les appels d'outils épargne généralement les réponses en texte libre et ne se manifeste que sur la structure JSON stricte attendue par le protocole d'appel d'outils.
#Tableau de dépannage rapide
| Symptôme | Cause la plus probable | Correction en premier |
|---|---|---|
| Balise « think » jamais fermée | Chat template non appliqué | Ajouter --jinja au lancement |
| Génération qui ne s'arrête jamais | Template mal interprété ou absent | Vérifier --jinja, sinon mettre à jour llama.cpp |
| Erreur « Expected value expression » au lancement | Bug de parsing du slicing Jinja (corrigé par la PR #13573) | Mettre à jour vers une version récente de llama.cpp |
| Bloc de réflexion absent avec llama-server mais visible avec llama-cli | Différence de traitement documentée entre les deux binaires | Tester avec llama-cli pour confirmer, puis suivre le ticket #14894 |
| enable_thinking=false ignoré | Hard switch non exposé nativement dans llama.cpp | Fixer enable_thinking=false dans un template via --chat-template-file |
| Appels d'outils tronqués ou JSON invalide | Quantification trop basse (Q3, Q2, IQ) | Remonter au moins en Q4_K_M, idéalement Q5_K_M ou Q6_K |
| GGUF récent plus buggé qu'un ancien du même modèle | Fichier mal converti ou téléchargement corrompu | Retélécharger depuis la source d'origine (Qwen officiel ou dépôt reconnu) |
- Comprendre les formats GGUF et safetensors
- Fiche technique de Qwen3-32B
- llama.cpp : c'est quoi, et faut-il quitter Ollama ?
- Choisir sa quantification (Q4, Q5, Q8, FP16)
- Source : documentation officielle Qwen pour llama.cpp
- Source : bug de parsing du chat template Qwen3 (llama.cpp)
- Source : différence de comportement server/cli sur le bloc de réflexion
- Source : guide de dépannage llama.cpp (quantification et appels d'outils)
Pourquoi mon GGUF Qwen3 ne ferme jamais la balise « think » ?+
L'option --jinja règle-t-elle tous les problèmes de template Qwen3 ?+
Comment désactiver définitivement le mode réflexion de Qwen3 avec llama.cpp ?+
Un GGUF Qwen3 téléchargé récemment se comporte différemment d'un ancien : pourquoi ?+
Pourquoi mes appels d'outils Qwen3 sont-ils tronqués même avec --jinja ?+
Le bug enable_thinking ignoré touche-t-il aussi Qwen3, pas seulement Qwen3.5 ?+
Un retour, une erreur, une précision ? Faites-nous signe, ça améliore le guide pour tout le monde.