Avancé 11 minQuantization

Qwen3 GGUF : corriger tokenizer et chat template

Réponse directe

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.

Par Mohamed Meguedmi·Màj 2026-09-28·Testé sur Windows, macOS, Linux

#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.

i
Pourquoi ça arrive spécifiquement sur Qwen3
Le chat template de Qwen3 gère une structure plus complexe que la plupart des modèles précédents : bascule entre mode réflexion et mode direct, appels d'outils, et une syntaxe Jinja avec des constructions (comme le slicing de liste) qui n'étaient pas toutes prises en charge par les premières versions du moteur de template de llama.cpp.

#La cause racine : le chat template

Le kit IA Locale

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.

Commande de référence documentée par Qwen
./llama-cli -hf Qwen/Qwen3-8B-GGUF:Q8_0 --jinja --color -ngl 99 -fa -sm row --temp 0.6 --top-k 20 --top-p 0.95 --min-p 0 -c 40960 -n 32768 --no-context-shift

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.

!
Message d'erreur à reconnaître
« Expected value expression at row 18, column 30 » suivi d'une ligne contenant messages[::-1] dans le template : c'est la signature exacte de ce bug de parsing. Il a été corrigé par une pull request ultérieure dans le dépôt llama.cpp ; si vous le rencontrez encore, la première chose à vérifier est la version de votre binaire llama.cpp, probablement antérieure au correctif.
  1. 01
    Identifier la version de llama.cpp utilisée
    Une version ancienne peut ne pas inclure le correctif de parsing pour la syntaxe de slicing utilisée par le template Qwen3.
  2. 02
    Mettre à jour vers une version récente
    Recompiler 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.
  3. 03
    Si la mise à jour n'est pas possible
    Passer 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.

→
Réflexe utile
Si un GGUF téléchargé récemment présente des erreurs de tokenizer qu'un GGUF plus ancien du même modèle ne présentait pas, retélécharger le fichier depuis sa source d'origine avant de suspecter un bug de llama.cpp : un téléchargement corrompu ou une conversion mal terminée sont des causes fréquentes et faciles à écarter.

#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.

!
À vérifier avant d'incriminer le template
Si vos appels d'outils sont corrects sur un GGUF Q5_K_M ou Q6_K mais cassent sur le même modèle en Q3 ou Q2, la cause n'est pas le chat template mais la quantification elle-même : la précision réduite sur les poids affecte davantage la génération de structures strictes (JSON, balises) que la qualité générale du texte. La correction documentée est de remonter la quantification, pas de retoucher le template.

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 observé, cause la plus probable, correction à essayer en premier
SymptômeCause la plus probableCorrection en premier
Balise « think » jamais ferméeChat template non appliquéAjouter --jinja au lancement
Génération qui ne s'arrête jamaisTemplate mal interprété ou absentVérifier --jinja, sinon mettre à jour llama.cpp
Erreur « Expected value expression » au lancementBug 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-cliDifférence de traitement documentée entre les deux binairesTester avec llama-cli pour confirmer, puis suivre le ticket #14894
enable_thinking=false ignoréHard switch non exposé nativement dans llama.cppFixer enable_thinking=false dans un template via --chat-template-file
Appels d'outils tronqués ou JSON invalideQuantification 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èleFichier mal converti ou téléchargement corrompuRetélécharger depuis la source d'origine (Qwen officiel ou dépôt reconnu)
Questions fréquentes
Pourquoi mon GGUF Qwen3 ne ferme jamais la balise « think » ?+
C'est le symptôme le plus courant d'un chat template mal appliqué. Vérifiez d'abord que votre commande inclut --jinja pour utiliser le template embarqué dans le GGUF plutôt qu'un template générique par défaut, absent d'une bonne partie des scripts et interfaces construits avant la généralisation de cette option.
L'option --jinja règle-t-elle tous les problèmes de template Qwen3 ?+
Elle règle la majorité des cas, mais pas tous : un bug de parsing sur la syntaxe de slicing de liste a affecté certaines versions de llama.cpp (corrigé depuis), le comportement diffère parfois entre llama-server et llama-cli sur l'affichage du bloc de réflexion, et une quantification trop basse peut casser les appels d'outils malgré un template correct.
Comment désactiver définitivement le mode réflexion de Qwen3 avec llama.cpp ?+
Le paramètre enable_thinking passé en ligne de commande peut être ignoré selon la version. La méthode documentée par Qwen consiste à fournir un template personnalisé via --chat-template-file où enable_thinking est fixé à false directement dans le template, plutôt que transmis comme paramètre de requête dépendant du support exact de votre build.
Un GGUF Qwen3 téléchargé récemment se comporte différemment d'un ancien : pourquoi ?+
Vérifiez d'abord la provenance et l'intégrité du fichier (retéléchargement depuis la source officielle Qwen ou un dépôt reconnu) avant de suspecter un bug de llama.cpp : une conversion GGUF mal terminée ou un téléchargement corrompu produisent des symptômes de tokenizer très proches d'un bug de template, mais se corrigent en retéléchargeant le fichier.
Pourquoi mes appels d'outils Qwen3 sont-ils tronqués même avec --jinja ?+
Un guide de dépannage communautaire documente que la structure des appels d'outils est sensible à la quantification : les quantifications sous 4 bits (Q3, Q2, IQ) produisent des JSON malformés même avec le bon template. Remonter à Q4_K_M ou une quantification plus haute (Q5_K_M, Q6_K) est la correction à tester en premier.
Le bug enable_thinking ignoré touche-t-il aussi Qwen3, pas seulement Qwen3.5 ?+
Les signalements les plus documentés (issues #20182, #20409) portent explicitement sur des variantes Qwen3.5 et restent au statut « bug-unconfirmed », fermés sans résolution. Rien ne confirme le même comportement sur un GGUF Qwen3 d'origine : à vérifier au cas par cas plutôt qu'à supposer identique.
Ce guide vous a aidé ?

Un retour, une erreur, une précision ? Faites-nous signe, ça améliore le guide pour tout le monde.