Avanzato 11 minQuantization

Qwen3 GGUF: correggere tokenizer e chat template

Risposta diretta

Gli errori del tokenizer e del chat template nei GGUF Qwen3 si manifestano con tre sintomi: un tag di ragionamento che non viene mai chiuso, una generazione che non si arresta o risposte fuori tema. La causa è quasi sempre un chat template applicato in modo errato. Aggiungi --jinja per utilizzare il template incorporato nel GGUF, verifica la provenienza del file e, come ultima risorsa, passa un template personalizzato.

Un GGUF Qwen3 che « risponde a caso » non è quasi mai un problema di qualità del modello: è un problema di formattazione del prompt prima che raggiunga il modello. Questa guida tratta esclusivamente gli errori di tokenizer e di chat template dei GGUF Qwen3: riconoscere il sintomo, verificare l'origine del file, e correggere o sostituire il template.

Di Mohamed Meguedmi·Agg. 2026-09-28·Testato su Windows, macOS e Linux

#I tre sintomi da riconoscere

Tre segnali indicano un problema di tokenizer o di chat template piuttosto che un problema del modello: un tag di ragionamento (solitamente « think ») che si apre senza mai chiudersi nella risposta, una generazione che continua indefinitamente senza fermarsi alla fine logica della risposta, o un modello che risponde fuori tema come se non avesse capito che gli era stata posta una domanda. In tutti e tre i casi, il problema non è il modello stesso: è la struttura del testo che riceve in ingresso a essere malformata.

i
Perché accade specificamente su Qwen3
Il chat template di Qwen3 gestisce una struttura più complessa rispetto alla maggior parte dei modelli precedenti: passaggio tra modalità di ragionamento e modalità diretta, chiamate a strumenti e una sintassi Jinja con costrutti (come lo slicing delle liste) che non erano tutti supportati dalle prime versioni del motore di template di llama.cpp.

#La causa di fondo: il template della chat

Il kit IA Locale

Il tuo ChatGPT privato e gratuito sulla tua macchina in 1 ora — LM Studio, Ollama, Open WebUI, i tuoi documenti, senza cloud.

  • Spazio online a vita
  • PDF + file
  • Aggiornamenti a vita

Un modello linguistico non riceve mai direttamente i tuoi messaggi: un template di chat li formatta (tag dei turni di parola, prompt di sistema, marcatori di inizio/fine) prima di trasformarli in token. Se questo template è assente, scelto male o interpretato male dal motore di inferenza, il modello riceve un testo che non assomiglia a quello su cui è stato addestrato e produce risultati di qualità inferiore, anche se i pesi del modello e il tokenizer stessi sono corretti.

#L'opzione --jinja: la prima cosa da verificare

La documentazione ufficiale Qwen consiglia esplicitamente di aggiungere --jinja al lancio di un GGUF Qwen3 con llama.cpp: questa opzione indica l'uso del template di chat integrato nel file GGUF, presentato come metodo da preferire piuttosto che un template generico scelto per impostazione predefinita dal motore.

Comando di riferimento documentato da 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

Se il tuo comando di avvio non contiene --jinja, è la prima correzione da provare prima di qualsiasi altra ipotesi. Molti script e interfacce creati prima della diffusione di questa opzione la omettono ancora, il che spiega buona parte delle segnalazioni di «risposte rotte» con GGUF Qwen3 che sono invece validi.

#Un bug di parsing noto e corretto

Un errore specifico ha interessato llama.cpp nel template di chat di Qwen3: il motore dei template non riusciva ad analizzare una sintassi Jinja per lo slicing delle liste (messages[::-1]), usata per scorrere la cronologia della conversazione in ordine inverso nella logica di chiamata degli strumenti. L'errore segnalato era un errore di parsing che indicava precisamente questa riga del template.

!
Messaggio d'errore da riconoscere
« Expected value expression at row 18, column 30 » seguito da una riga contenente messages[::-1] nel template: è il segno distintivo esatto di questo bug di parsing. È stato corretto con una pull request successiva nel repository llama.cpp; se lo incontri ancora, la prima cosa da verificare è la versione del tuo binario llama.cpp, probabilmente precedente alla correzione.
  1. 01
    Identificare la versione di llama.cpp utilizzata
    Una versione precedente potrebbe non includere la correzione del parsing per la sintassi di slicing utilizzata dal template Qwen3.
  2. 02
    Aggiornare a una versione recente
    Ricompilare o scaricare nuovamente un binario aggiornato di llama.cpp risolve questo caso specifico, senza dover modificare il GGUF stesso.
  3. 03
    Se l'aggiornamento non è possibile
    Fornire un template personalizzato semplificato tramite --chat-template-file, evitando il costrutto Jinja responsabile del problema.

#llama-server e llama-cli non si comportano allo stesso modo

Un comportamento segnalato nel repository llama.cpp: attivare --jinja con llama-server può far scomparire dalla risposta il blocco di ragionamento (il contenuto tra i tag di pensiero), mentre lo stesso blocco resta visibile usando llama-cli con la stessa opzione e lo stesso modello. Se la tua integrazione dipende dalla presenza del contenuto di ragionamento nell'output (per l'osservabilità o il debug), non si tratta di un problema del tokenizer, ma di una differenza nel trattamento tra i due binari: verificare quale dei due si sta utilizzando prima di approfondire.

Questa distinzione ha una conseguenza pratica per chi costruisce un'integrazione basata su llama.cpp anziché limitarsi a una semplice sessione interattiva: una pipeline di test che verifica il formato di output con llama-cli e viene poi distribuita in produzione dietro llama-server può manifestare una regressione silenziosa su questo punto specifico senza che alcun parametro lato applicazione sia cambiato. Documentare esplicitamente quale binario viene usato in produzione e testare proprio quel binario, anziché quello usato nello sviluppo locale, evita questa trappola.

#Disattivare forzatamente la modalità di ragionamento

Qwen3 offre un meccanismo per passare dalla modalità di ragionamento alla modalità diretta e viceversa a livello del template della chat. La documentazione ufficiale Qwen indica tuttavia che questo meccanismo di disattivazione forzata (hard switch) non è esposto nativamente in llama.cpp: l'impostazione di enable_thinking a false tramite le opzioni della riga di comando può essere ignorata a seconda della versione, come mostrano diverse segnalazioni recenti relative a varianti di Qwen3.5.

La soluzione alternativa documentata da Qwen consiste nel fornire un template personalizzato tramite --chat-template-file, in cui enable_thinking è impostato esplicitamente a false nel template stesso anziché essere passato come parametro al momento della richiesta. È più affidabile di un parametro di esecuzione che dipende dal supporto effettivamente offerto dalla tua versione di llama.cpp.

Un punto da precisare per evitare generalizzazioni errate: la segnalazione #20182 (« enable_thinking param cannot turn off thinking ») riguarda precisamente Qwen3.5-9B nella build 8215, resta contrassegnata come « bug-unconfirmed » nel repository di llama.cpp ed è stata chiusa senza risoluzione (« not planned »). Nulla dimostra che lo stesso comportamento interessi un GGUF del Qwen3 originale (anziché di Qwen3.5): se riscontri questo sintomo su un Qwen3 classico, trattalo come un caso da isolare e segnalare separatamente, anziché come una conferma automatica di questo ticket.

#Controlla la provenienza di un GGUF di terze parti

Una parte dei problemi del tokenizer nei GGUF Qwen3 non dipende da llama.cpp, ma dal file GGUF stesso: una conversione effettuata con una vecchia versione degli strumenti di conversione, oppure un file il cui tokenizer è stato esportato male, produce sintomi simili (mancata fine della generazione, token speciali riconosciuti in modo errato). Prima di cercare un bug nel motore di inferenza, confrontare la dimensione e la data di pubblicazione del tuo file GGUF con quelle riportate in un repository riconosciuto (quello ufficiale di Qwen o uno con nuove quantizzazioni documentate) permette di escludere questa ipotesi.

Un criterio semplice per distinguere rapidamente tra un problema di file e un problema di configurazione: se lo stesso GGUF funziona correttamente su un'altra macchina o con un'altra versione di llama.cpp, il file stesso probabilmente non è la causa. Al contrario, se scaricare nuovamente più volte dallo stesso repository sulla stessa macchina riproduce sistematicamente il sintomo, l'ipotesi più probabile si sposta verso la configurazione locale (versione del binario, opzioni di avvio) piuttosto che verso il file.

→
Suggerimento utile
Se un GGUF scaricato di recente presenta errori del tokenizer che un GGUF più vecchio dello stesso modello non presentava, scaricare nuovamente il file dalla sua fonte originale prima di sospettare un bug di llama.cpp: un download corrotto o una conversione non completata correttamente sono cause frequenti e facili da escludere.

#Quantizzazione troppo bassa: chiamate di tool malformate

Un ultimo sintomo, distinto dai primi tre, riguarda specificamente l'uso di Qwen3 come agente con chiamate a strumenti: anziché un problema di formattazione del testo, è la chiamata allo strumento stessa ad arrivare troncata, con argomenti vuoti o mal strutturati (JSON non valido). Una guida della comunità alla risoluzione dei problemi di llama.cpp documenta che la struttura delle chiamate a strumenti è sensibile al livello di quantizzazione: le quantizzazioni sotto i 4 bit (Q3, Q2, IQ) producono chiamate a strumenti malformate anche quando il template della chat è applicato correttamente con --jinja.

!
Da verificare prima di dare la colpa al template
Se le tue chiamate agli strumenti sono corrette con un GGUF Q5_K_M o Q6_K ma falliscono con lo stesso modello in Q3 o Q2, la causa non è il template della chat ma la quantizzazione stessa: la precisione ridotta dei pesi influisce sulla generazione di strutture rigorose (JSON, tag) più che sulla qualità generale del testo. La soluzione documentata è passare a una quantizzazione con maggiore precisione, non ritoccare il template.

Questo punto può facilmente sfuggire perché, a prima vista, sembra un classico problema di tokenizer: una risposta troncata fa immediatamente pensare a un template di chat chiuso male. La distinzione pratica sta nel contesto in cui compare il sintomo: un problema di template riguarda tutte le risposte, compreso il semplice testo senza chiamate a strumenti, mentre un problema di quantizzazione nelle chiamate a strumenti generalmente non influisce sulle risposte in testo libero e si manifesta solo nella struttura JSON rigorosa richiesta dal protocollo di chiamata a strumenti.

#Tabella rapida per la risoluzione dei problemi

Sintomo osservato, causa più probabile, correzione da provare per prima
SintomoCausa più probabileCorrezione da provare per prima
Tag « think » mai chiusoTemplate di chat non applicatoAggiungere --jinja all'avvio
Generazione che non si ferma maiTemplate mal interpretato o mancanteVerificare --jinja, altrimenti aggiornare llama.cpp
Errore « Expected value expression » all'avvioBug di parsing dello slicing Jinja (corretto con la PR #13573)Aggiornare a una versione recente di llama.cpp
Blocco di riflessione assente con llama-server ma visibile con llama-cliDifferenza di trattamento documentata tra i due binariTestare con llama-cli per confermare, poi seguire il ticket #14894
enable_thinking=false ignoratoHard switch non esposto nativamente in llama.cppImpostare enable_thinking=false in un template tramite --chat-template-file
Chiamate a strumenti troncate o JSON non validoQuantizzazione troppo bassa (Q3, Q2, IQ)Passare almeno a Q4_K_M, idealmente a Q5_K_M o Q6_K
GGUF recente con più bug di uno precedente dello stesso modelloFile mal convertito o download corrottoScaricare di nuovo dalla fonte originale (Qwen ufficiale o repository riconosciuto)
Domande frequenti
Perché il mio GGUF Qwen3 non chiude mai il tag « think »?+
È il sintomo più comune di un template di chat applicato male. Verifica innanzitutto che il tuo comando includa --jinja per utilizzare il template incorporato nel GGUF anziché un template generico predefinito, assente in buona parte degli script e delle interfacce creati prima della diffusione di questa opzione.
L'opzione --jinja risolve tutti i problemi di template Qwen3?+
Risolve la maggior parte dei casi, ma non tutti: un bug di parsing nella sintassi di slicing delle liste ha interessato alcune versioni di llama.cpp (nel frattempo corretto), il comportamento a volte differisce tra llama-server e llama-cli nella visualizzazione del blocco di riflessione, e una quantizzazione troppo bassa può compromettere le chiamate agli strumenti anche con un template corretto.
Come disattivare definitivamente la modalità di ragionamento di Qwen3 con llama.cpp?+
Il parametro enable_thinking passato dalla riga di comando può essere ignorato a seconda della versione. Il metodo documentato da Qwen consiste nel fornire un template personalizzato tramite --chat-template-file, in cui enable_thinking è impostato a false direttamente nel template, anziché trasmetterlo come parametro della richiesta, il cui supporto dipende dalla specifica build che usi.
Un GGUF Qwen3 scaricato di recente si comporta diversamente da uno vecchio: perché?+
Verifica innanzitutto la provenienza e l'integrità del file (scaricandolo nuovamente dalla fonte ufficiale Qwen o da un repository riconosciuto) prima di sospettare un bug di llama.cpp: una conversione GGUF non completata correttamente o un download corrotto producono sintomi legati al tokenizer molto simili a quelli di un bug del template, ma si risolvono scaricando nuovamente il file.
Perché le mie chiamate agli strumenti di Qwen3 vengono troncate anche con --jinja?+
Una guida della comunità alla risoluzione dei problemi documenta che la struttura delle chiamate agli strumenti è sensibile alla quantizzazione: le quantizzazioni inferiori a 4 bit (Q3, Q2, IQ) producono JSON malformati anche con il template corretto. Passare a Q4_K_M o a una quantizzazione più alta (Q5_K_M, Q6_K) è la prima correzione da provare.
Il bug per cui enable_thinking viene ignorato riguarda anche Qwen3, non solo Qwen3.5?+
Le segnalazioni più documentate (issue #20182, #20409) riguardano esplicitamente varianti Qwen3.5 e restano nello stato «bug-unconfirmed», chiuse senza risoluzione. Nulla conferma lo stesso comportamento su un GGUF Qwen3 originale: va verificato caso per caso, anziché presumere che sia identico.
Questa guida ti è stata utile?

Un feedback, un errore, una precisazione? Facci sapere, così la guida migliora per tutti.