Ricerca
Misurato, con i dati per verificarlo.
Il ragionamento anticipato non è esatto, quindi è stato misurato su risposte verificabili. Ogni tabella qui sotto ha il suo script e il suo JSON nel repository, e il diario di ricerca conserva le note di lavoro, le più recenti per prime.
Metodo
Problemi con una risposta numerica nota, scritti in italiano in tempo reale: 5-8 caratteri al secondo, qualche pausa naturale, Invio subito dopo l'ultimo carattere, senza rileggere. Lo script è research/thinking_ahead.py; scrive ogni problema con e senza ragionamento anticipato e registra l'attesa per la prima parola della risposta, i token di ragionamento in totale e quelli rimasti dopo Invio, e se la risposta è giusta.
I modelli sono Qwen3 Q4_K_M in thinking mode su llama.cpp (b11747). La macchina di riferimento è una RTX 2060 con 6 GB di VRAM (i5-10400, 16 GB DDR4, Windows 11): Qwen3-4B sta nella VRAM a circa 83 tok/s, Qwen3-14B no (38% sulla GPU, circa 5 tok/s). La seconda macchina è un MacBook Pro M2 Pro, 16 GB, con Metal. Due esecuzioni degli stessi 24 problemi differiscono fino a un secondo nella media: confronta righe misurate una dopo l'altra.
Risultati
| Modello · macchina | Problemi | Corrette | Attesa media, senza | Attesa media, MAFDET | Mediana, senza → MAFDET |
|---|---|---|---|---|---|
| Qwen3-4B RTX 2060 · 6 GB | 24 | 24/24 in entrambi i casi | 12.2 s | 3.2 s | 10.7 s → 2.9 s |
| Qwen3-14B RTX 2060 · 6 GB | 6 | 6/6 in entrambi i casi | 108 s | 47 s | — |
| Qwen3-4B MacBook Pro M2 Pro · 16 GB | 24 | 24/24 in entrambi i casi | 18.1 s | 5.6 s | 16.7 s → 4.1 s |
| Qwen3-14B MacBook Pro M2 Pro · 16 GB | 6 | 6/6 in entrambi i casi | 32.7 s | 12.1 s | 26.5 s → 11.7 s |
Ragionamento anticipato, Qwen3-4B sulla RTX 2060, 24 problemi (research/thinking_ahead.py, dati thinking_ahead_4b.json):
| Senza ragionamento anticipato | mafdet strike | |
|---|---|---|
| Risposte corrette | 24/24 | 24/24 |
| Attesa mediana per la prima parola | 10.7 s | 2.9 s |
| Attesa media | 12.2 s | 3.2 s |
| Più veloce | in 24 problemi su 24 | |
| Ragionamento in totale | 944 token | 662 token |
| Ragionamento rimasto dopo Invio | 944 token | 244 token |
Stessa accuratezza, meno ragionamento in totale (il materiale raccolto durante la digitazione evita al modello di ricominciare da capo), e quasi due terzi di esso fatti prima di Invio. La cornice degli appunti conta: una cornice generica ha dato 22/24 e una mediana di 4.4 s; nessuna cornice ha dato 22/24, 6.9 s e il 70% di ragionamento in più. Con la cornice a lista, la riga di esempio e un logit bias contro parole come user, incomplete, typing durante il ragionamento anticipato, la quota di frasi negli appunti che parlano del messaggio in sé invece del suo contenuto è passata dall'86% al 17-26%.
Risposta esatta in anticipo
Qwen3-4B, senza ragionamento, pausa prima di Invio con il testo invariato: la risposta stessa viene scritta in anticipo, e quella parte è esatta (con decoding greedy, identica token per token a quella avviata dopo Invio; verificato).
| Risposta | Scritta prima di Invio | Risposta completa sullo schermo dopo Invio, strike | Senza strike |
|---|---|---|---|
| 300 token | 200 | 1.2 s | 3.5 s |
| 168 token | 168 (tutta) | istantanea | 1.9 s |
Modelli più grandi
Quello che il modello può fare prima di Invio è limitato dal tempo di digitazione × la sua velocità di scrittura:
| Modello | Sta in 6 GB? | Scrive | Ragionamento scritto durante un messaggio di 30 s |
|---|---|---|---|
| Qwen3-4B | sì | 83 tok/s | quasi tutto |
| Qwen3-8B | no, in parte sulla CPU | 13-16 tok/s | 130-280 token |
| Qwen3-14B | no, in parte sulla CPU | 5 tok/s | circa 160 token |
Anche così, sul 14B (6 problemi, 6/6 corrette in entrambi i casi) il ragionamento anticipato dimezza l'attesa media dopo Invio: 108 s → 47 s, con 164 token di ragionamento scritti prima di Invio in media. Le singole esecuzioni variano molto (lo stesso problema ha impiegato 106 s una volta e 154 s un'altra), quindi 6 problemi danno l'ordine di grandezza. La lettura anticipata guadagna tanto più quanto più grande è il modello: il 14B legge un documento incollato da 3.000 token in circa 10 s, tutti nascosti mentre scrivi.
Indovinare il finale (--branches, sperimentale). Il ragionamento rimasto dopo Invio riguarda per lo più la fine del messaggio, che arriva per ultima. Con --branches 1 il modello indovina anche come finirai e ragiona sull'ipotesi in uno slot tutto suo. Stessi 24 problemi, due esecuzioni ciascuno: 48/48 corrette, attesa media 4.17 s → 3.51 s, decimo più lento 7.9 s → 5.3 s, 14 messaggi su 48 indovinati esattamente. Un guadagno modesto, soprattutto sulle risposte più lente, su 24 problemi non ancora significativo (sign test p = 0.15). Sul 14B nessun ramo ha mai iniziato a ragionare prima di Invio: nell'app un ramo è dato solo ai modelli che stanno nella VRAM.
Un modello piccolo che raccoglie per uno grande (--gatherer, sperimentale). Un Qwen3-0.6B veloce, anche fine-tuned per questo, che scrive materiale mentre digiti perché il 14B lo legga a Invio. Sulla RTX 2060 non batte il 14B che ragiona in anticipo da solo: 47 s contro 60 s senza addestramento e 79-86 s con fine-tuning; perfino materiale ideale scritto a mano dà 62 s, o 49 s se presentato come ragionamento del modello stesso. Il 14B lo legge, poi rifà i calcoli. Le domande aperte per chi vuole portare avanti la cosa sono nel README.
Su un Mac
MacBook Pro M2 Pro, 16 GB, macOS 26.2, llama.cpp con Metal; gli stessi script e gli stessi problemi.
| M2 Pro | Senza ragionamento anticipato | mafdet strike |
|---|---|---|
| Qwen3-4B, 24 problemi: corrette | 24/24 | 24/24 |
| Attesa mediana | 16.7 s | 4.1 s |
| Attesa media | 18.1 s | 5.6 s |
| Ragionamento in totale / rimasto dopo Invio | 966 / 966 | 773 / 248 |
| Qwen3-14B, 6 problemi: corrette | 6/6 | 6/6 |
| Attesa mediana | 26.5 s | 11.7 s |
| Attesa media | 32.7 s | 12.1 s |
Il 4B scrive a 54 tok/s sull'M2 Pro (83-87 sulla RTX 2060), quindi entrambe le attese sono più lunghe che sul PC, e il ragionamento anticipato ne toglie circa la stessa quota. Il 14B è dove il Mac fa la differenza: Metal può usare 12 GB della memoria unificata, quindi l'intero modello è sulla GPU e scrive a 18 tok/s. Durante le esecuzioni il Mac ha raggiunto la pressione termica Heavy per qualche minuto. Dati: thinking_ahead_4b_m2pro.json, thinking_ahead_4b_m2pro_fixed.json, thinking_ahead_14b_m2pro.json.
Provato, e perché no
--recycle(le risposte alle versioni precedenti del messaggio come bozze n-gram): +4% di velocità di decode con digitazione naturale, +20% sul codice, primo token leggermente più tardi.--draft(Qwen3-0.6B che abbozza per il 14B): sulla GPU toglie VRAM al 14B, che quindi esegue più layer sulla CPU (4.8 → 3.5 tok/s); sulla CPU guadagna l'8% con bozze da 4 token e dimezza la velocità di lettura.- Il ragionamento anticipato come bozza per lo speculative decoding dopo Invio: non più veloce sul 4B (73 tok/s in entrambi i casi) e più lento sul 14B (5.0 → 3.1 tok/s), perché i layer sulla CPU calcolano ogni token della bozza e solo l'11% dei token abbozzati era giusto. Script:
research/notes_as_draft.py. - IQ4_XS al posto di Q4_K_M sul 4B (RTX 4070 SUPER): 4% più veloce, una risposta peggiore su 28. Non vale la pena sul 4B; sul 14B, dove è il 31% più veloce con le stesse risposte, è in valutazione.
Fatto chiave imparato: su un modello diviso tra GPU e CPU, i layer sulla CPU calcolano ogni token che ricevono. Qualsiasi cosa elabori più token insieme costa al 14B quasi in proporzione. Per velocizzare il 14B, togli lavoro alla CPU.
Cercasi aiuto: Radeon
MAFDET gira sulle schede Radeon con la build Vulkan di llama.cpp, ma nessuno l'ha ancora misurato su una. Il percorso Vulkan in sé è verificato, sulla RTX 2060 (Qwen3-4B legge 2.103 token/s e ne scrive 83, più o meno come con CUDA). Se hai una scheda dedicata, RX 5000 o successiva, 8 GB o più è l'ideale, circa mezz'ora colmerebbe questo vuoto:
- Installa MAFDET e aprilo una volta: dovrebbe trovare la tua scheda, installare llama.cpp Vulkan e scaricare Qwen3-4B.
mafdet doctormostra cosa ha trovato. - Nell'app, Modelli, Misura Qwen3-4B.
- Dalla cartella di MAFDET, con il suo ambiente attivo:
python research/thinking_ahead.py radeon_4b.json. Circa 20 minuti; lascia la macchina altrimenti inattiva. - Apri una issue con l'output di
mafdet doctor, i numeri di Misura eradeon_4b.json.