Prove e risultati
Tutte le misure sono fatte sul mio PC, un Intel Core i5-4570 con 7,9 GiB di RAM e Windows 10. Sotto ogni risultato c'è scritto cosa dimostra e cosa no.
Prova del 27 ottobre 2026, ore 17:46; ripetuta il 28 ottobre alle 14:19
Determinismo: stessi numeri su ogni macchina
L'idea: se due persone eseguono lo stesso modello con lo stesso prompt, devono ottenere gli stessi numeri, bit per bit. Non di solito: sempre. Per controllarlo VELA-G ha un comando, --hash, che stampa tre impronte SHA-256: quella dei valori in uscita (logit) per 24 parole fisse a ogni posizione, quella di 64 token generati, quella dei token del tokenizzatore.
Ho preso quattro modelli piccoli con pesi casuali, calcolato le impronte su Linux (compilatore gcc, processore Xeon) e le ho confrontate con quelle calcolate sul mio PC, con quattro modi di calcolo diversi.
| Modello | 1 thread | 4 thread | 3 thread, senza AVX2 | 1 thread, senza AVX2 |
|---|---|---|---|---|
| llama Q3_K_M | Identico | Identico | Identico | Identico |
| llama Q6_K | Identico | Identico | Identico | Identico |
| qwen2 Q4_0 | Identico | Identico | Identico | Identico |
| qwen3 Q4_K_M | Identico | Identico | Identico | Identico |
16 prove su 16 identiche. Il risultato è rimasto lo stesso dopo una nuova compilazione e dopo le ottimizzazioni di velocità del 28 ottobre (ripetuta alle 14:19: 16 su 16). Una versione compilata senza le istruzioni AVX2 ha dato 16 su 16 anche su Linux x86.
Come si ottiene
- Le somme di numeri interi sono esatte, quindi non c'è nulla da fissare.
- Per i numeri decimali l'ordine delle somme è sempre lo stesso: 8 corsie, 4 posizioni consecutive per corsia, moltiplicazione e somma fuse con
fmaf, somma finale(t0+t2)+(t1+t3). La versione scalare (senza AVX2) segue lo stesso ordine. - exp, sin, cos e pow sono riscritte in precisione doppia, in un file mio, per non dipendere dalla libreria del sistema.
- Il compilatore non può fondere moltiplicazioni e addizioni da solo (
-ffp-contract=off). - Elaborare n token insieme dà gli stessi numeri che elaborarli uno alla volta, e il numero di thread non cambia nulla.
Cosa non dimostra. I quattro modelli sono piccoli e con pesi casuali: provano che il calcolo è identico, non dicono niente sulla qualità del testo. Ho provato solo processori x86-64 (il riferimento è un Xeon, il mio PC è un i5 Haswell). ARM e macOS non li ho eseguiti. Un confronto fra due macchine diverse su un modello vero, per esempio Qwen3-0.6B Q4_K_M, non l'ho ancora fatto.
Due serie: 27 ottobre ore 07:58 e 28 ottobre ore 14:19, 4 thread
Velocità contro llama.cpp
Stesso file GGUF, stesso PC, stesso numero di thread. Le barre mostrano i token al secondo (più lunga vuol dire più veloce). Nella lettura del prompt la barra vuota è VELA-G il 27 ottobre, prima delle ottimizzazioni; quella piena è VELA-G il 28 ottobre.
Qwen3-0.6B Q4_K_M (378 MB)
Scrittura della risposta (28 ottobre)
Lettura del prompt
Il 28 ottobre VELA-G arriva al 77% di llama.cpp nella risposta e al 65% nella lettura del prompt. Il 27 ottobre nella lettura era al 23%.
Qwen3-4B Q4_K_M (2382 MB)
Scrittura della risposta (28 ottobre)
Lettura del prompt
Il 28 ottobre VELA-G arriva al 96% di llama.cpp nella risposta e al 79% nella lettura del prompt. Il 27 ottobre nella lettura era al 45%.
Qwen2 1,8B (1840 MB)
Scrittura della risposta (28 ottobre)
Lettura del prompt
Il 28 ottobre VELA-G arriva al 102% di llama.cpp nella risposta e al 85% nella lettura del prompt. Il 27 ottobre nella lettura era al 41%.
Come leggerlo. Nella risposta, che dipende soprattutto dalla velocità della memoria, VELA-G è alla pari con llama.cpp sui due modelli più grandi. Sul più piccolo risulta dietro: il 28 ottobre mattina la stessa prova dava 91%, quindi quel numero è da ripetere. Nella lettura del prompt, che dipende dal calcolo, è ancora dietro, dal 65% all'85%, ma è molto migliorata rispetto al giorno prima. Una prova su un solo PC, con prompt brevi, e llama.cpp cambia anche di un 10-20% da una serie all'altra.
Cosa è cambiato tra il 27 e il 28 ottobre
- Seno e coseno di RoPE si calcolavano per ogni testa e per ogni livello: ora una volta per posizione.
- Q, K e V (e gate e up) leggono lo stesso vettore, che veniva quantizzato più volte: ora una sola.
- Normalizzazioni, RoPE e attivazioni giravano su un solo core: ora usano tutti i core.
- Il kernel Q4_K/Q5_K decodifica i pesi una volta ogni 8 token invece di ogni 4, con attivazioni allineate a 32 byte e prefetch dei pesi.
Ho confrontato le varianti del kernel direttamente sul mio i5-4570: su una CPU più recente nessuna batteva quella esistente, sul mio la migliore era il 23% più veloce. Dopo ogni modifica ho rifatto le 16 prove di determinismo: tutte identiche.
Stessa prova, 6 casi
Il testo è lo stesso di llama.cpp?
Con temperatura 0 ho dato a VELA-G e a llama.cpp due prompt (The capital of France is e def fibonacci(n):) su tre modelli, 40 token ciascuno. In 5 casi su 6 il testo è identico.
Nel sesto (Qwen2 1,8B, prima frase) le risposte si separano al secondo token: la differenza tra i due candidati è di 0,045 nei logit, e al quarto token di 0,058. Su 40 scelte, 2 sono diverse. È una quasi parità, in cui differenze minime di calcolo bastano a cambiare la scelta. Con VELA-G la scelta resta la stessa su ogni macchina.
Mediana di 3 ripetizioni, temperatura 0, 28 ottobre
Decodifica speculativa
Un modello piccolo (Qwen3-0.6B) propone alcuni token, il modello grande li verifica in un solo passaggio e tiene quelli giusti. Il testo finale non cambia: in tutte le prove era identico (24 richieste su 24 nell'ultima serie).
| Modello | Tipo di testo | Senza bozza | Con bozza | Variazione |
|---|---|---|---|---|
| Qwen2 1,8B | prosa | 9,60 | 10,05 | +5% |
| Qwen2 1,8B | codice | 9,52 | 14,76 | +55% |
| Qwen3-4B | prosa | 7,42 | 8,75 | +18% |
| Qwen3-4B | codice | 7,45 | 10,39 | +39% |
Nell'uso reale non conviene (misura del 27 ottobre, da rifare con il motore più veloce). In NEXUS, con temperatura 0,7 e prompt che includono pagine web, il guadagno netto è sparito: da +2% a −13%, perché leggere un prompt lungo con due modelli costa circa 10 secondi. Per questo la funzione è spenta per impostazione predefinita e si attiva a mano. Funziona bene dove il testo è prevedibile, come il codice, e con prompt brevi.
Con temperatura sopra 0 e un valore di K che si adatta ai tempi, due esecuzioni con lo stesso seme possono dare testi diversi. A temperatura 0 e con --hash il risultato è sempre uguale.
Dal dossier tecnico VELA
MOSAICO: 80 miliardi di parametri in 8 GB di RAM
Qwen3-Next da 80 miliardi di parametri, nel mio formato .jns (48 GB su disco), eseguito con VELA. La RAM usata in più è circa 3,3 GiB. «Token principali identici» è la quota di passi in cui il token più probabile di VELA coincide con quello del modello a precisione piena.
| Lingua | Token al secondo | Token principali identici |
|---|---|---|
| Italiano | 1,39 | 91-96% |
| Inglese | 0,92 | 100% |
| Codice | 0,97 | 100% |
Contro llama.cpp con il GGUF ufficiale dello stesso modello: 384 confronti su 384 identici.
Limiti. Un solo PC, prompt brevi, 32 token generati per prova. Sui modelli piccoli che stanno in RAM un programma come Ollama è più veloce: MOSAICO serve quando il modello non ci starebbe.
Ricerca del 27 ottobre 2026, non esaustiva
Cosa c'era già
Per quanto ho trovato, nessuno ha pubblicato un motore per veri modelli GGUF quantizzati su CPU comuni che dia risultati identici bit per bit fra Windows e Linux e fra compilatori diversi, con una velocità vicina a quella di llama.cpp. Può darsi che esista e non l'abbia trovato. Questi sono i lavori più vicini:
- Cankaya (arXiv 2606.00279): un emulatore per verificare i calcoli su GPU bit per bit.
- Liu e Tsai (arXiv 2610.19498): riproducibilità del quantizzatore GGUF. Mostrano che
-ffp-contract=offelimina le differenze tra x86 e arm64, come faccio anch'io. - Chen (arXiv 2609.00363): kernel INT8 su GPU.
- Xyntetik Runner: LoRA tramite GGUF su x86 Linux; segnala differenze di
expftra librerie. - nmicic/int-llm: un piccolo modello GPT da 14 mila parametri, tutto intero, identico fra piattaforme.
- llama.cpp, richiesta 16016: determinismo su CUDA, non ancora integrata.
- Altri lavori sul determinismo dell'inferenza, per lo più su GPU (Thinking Machines, Yuan e altri a NeurIPS 2025, HEAL).
Il pacchetto è pronto, ma nessun altro l'ha ancora eseguito.
Come ripetere le prove
Il pacchetto contiene il programma per Windows e per Linux x86-64, i quattro modelli, i valori di riferimento, i sorgenti e un file con le impronte di tutto.
Su Windows (10 o 11, 64 bit): estrai lo zip e fai doppio clic su PROVA_WINDOWS.cmd. Il risultato è nel file RISULTATI\RISULTATO_DETERMINISMO.txt e finisce con «16 prove su 16 identiche al riferimento», oppure con l'elenco di quelle diverse.
Su Linux x86-64:
unzip VELA-G_verifica_determinismo.zip
cd VELA-G_verifica
sha256sum -c SHA256SUMS.txt
bash prova_determinismo.sh
Su ARM, Raspberry Pi o macOS: bash compila.sh compila il motore (serve gcc o clang), poi bash prova_determinismo.sh. È la prova che io non ho potuto fare e che mi interessa di più.
Con un modello vero (se hai scaricato Qwen3-0.6B Q4_K_M) puoi confrontare le tre impronte con quelle di un'altra persona:
vela-g.exe Qwen3-0.6B-Q4_K_M.gguf --hash --ctx=256
Se due macchine stampano le stesse tre righe, il risultato è identico. Se qualcuna è diversa, mi interessa saperlo: è esattamente il tipo di errore che cerco.
Laboratorio NEXUS · 28 ottobre 2026. Dati, verifiche e limiti sono descritti nelle singole pagine.
Contatti: sradraven@sradraven.com · Tutti i progetti tecnologia & IA
