La mia chat AI locale con Python e Gemma — Parte 8: esposizione dei parametri LLM

  • Home
  • AI & ChatBot
  • La mia chat AI locale con Python e Gemma — Parte 8: esposizione dei parametri LLM
Image

La mia chat AI locale con Python e Gemma — Parte 8: esposizione dei parametri LLM

Era una domanda da cinque minuti. Volevamo sapere se il modello locale che gira dentro Private Mind (una chat offline con Gemma in formato GGUF) esponesse una manopola per la temperatura, perché certe risposte sembravano più caute del necessario. Cinque minuti dopo la risposta era sì, e insieme alla risposta era arrivato un problema che nessuno aveva cercato.

La funzione che genera ogni risposta accetta ventisei parametri. Ne stavamo passando quattro. Gli altri ventidue non erano assenti: erano decisi da qualcun altro.

Questa distinzione è tutto l’articolo. Un parametro che non passi non sparisce, prende il valore che la libreria ha scelto per te, e quel valore non compare da nessuna parte nel tuo codice. Non c’è una riga da leggere, non c’è una costante da cercare, non c’è un commento che dica perché. C’è solo un comportamento, e quando quel comportamento ti sorprende non hai nessun appiglio per capirlo.

Impostazioni di default

Tre esempi, tutti veri, tutti scoperti quel pomeriggio.

Il primo: un filtro chiamato min_p era attivo al valore 0.05. Ritaglia la coda della distribuzione delle probabilità, il che significa che alzare la temperatura ha un effetto più contenuto di quanto ti aspetteresti. Nessuno l’aveva scelto. Nessuno sapeva che esistesse.

Il secondo, più insidioso: la penalità sulle ripetizioni era a 1.0, che nel gergo di llama.cpp non vuol dire “penalità bassa” ma “penalità disattivata”. La stessa libreria, in una funzione gemella usata per il completamento semplice, la imposta a 1.1. Noi eravamo capitati sulla variante che la spegne. Se una risposta lunga fosse entrata in loop (succede) la leva più diretta per curarla non era collegata a niente.

Il terzo riguarda il modello stesso. Google, per Gemma 3, raccomanda temperatura 1.0, top_k 64, top_p 0.95. Noi giravamo a 0.7 con top_k 40. Non è sbagliato in senso assoluto, è più conservativo di quanto il modello preveda per sé. Ed era il risultato di una riga scritta mesi prima, con un numero plausibile, mai più toccata.

Un problema da CTO e non da sviluppatore

Niente di tutto questo produce un errore. Nessun test rosso, nessun alert, nessuna eccezione in un log. Il sistema funziona esattamente come il giorno prima.

Il danno è un altro, ed è di attribuzione. Quando l’utente nota che le risposte sono più piatte del previsto, la colpa finisce sul modello. Si valuta di cambiare quantizzazione, si guarda un modello più grande, si mette a bilancio della GPU. In un’azienda quella catena di ragionamenti arriva a costare davvero, e parte tutta da una domanda che nessuno ha pensato di fare: siamo sicuri di sapere con che impostazioni stiamo girando?

La generalizzazione è immediata e non riguarda solo gli LLM. Ogni dipendenza che integrate ha dei default. Il vostro client HTTP ha un timeout che qualcuno ha scelto, il vostro pool di connessioni ha una dimensione massima, il vostro ORM ha un livello di isolamento delle transazioni. Nessuno di questi è documentato nel vostro repository, perché tecnicamente non è codice vostro. Ma è comportamento vostro, e quando un cliente vi chiede perché il sistema si comporta in un certo modo, “è il default della libreria” non è una risposta che potete dare due volte.

La domanda utile non è “il nostro sistema è configurabile”. Quasi sempre lo è. La domanda è: sappiamo dire, senza aprire il codice sorgente di una dipendenza, com’è configurato adesso?

La disciplina che è costata più della funzionalità

Qui arriva la parte che vale la pena raccontare a chi decide, perché è controintuitiva.

Avendo scoperto che la penalità sulle ripetizioni era disattivata, e avendo davanti la raccomandazione ufficiale di Google, la cosa ovvia era sistemare tutto mentre eravamo lì. Abbiamo deciso di non farlo.

I valori scritti nel codice sono la copia esatta di quelli che subivamo prima. Identici, deliberatamente. Rendere esplicito un default non doveva cambiare il comportamento di un singolo token, e c’è un test automatico il cui unico scopo è verificare che non sia cambiato.

Il motivo è che due modifiche impacchettate insieme sono indistinguibili. Se avessimo alzato la penalità nella stessa sessione intitolata “rendere leggibili le impostazioni”, e nelle settimane successive qualcuno avesse notato risposte diverse, non avrebbe avuto nessun modo di collegare le due cose. Avremmo trasformato un problema di visibilità in un problema di visibilità più una regressione difficile da tracciare.

I valori diversi (compresi quelli consigliati da Google) sono finiti altrove: in tre preset selezionabili, dove sono una scelta che si vede e si può disfare.

Il taglio conta quanto l’aggiunta

Esposti nell’interfaccia: temperatura, top_p, top_k, penalità ripetizione, seed. Cinque leve su ventisei.

L’esclusione più interessante è una famiglia di parametri chiamata mirostat. Fa una cosa legittima e utile, ma quando è attiva scavalca top_k e top_p. Un pannello che li mostrasse tutti insieme si contraddirebbe da solo: l’utente sposterebbe due cursori che non hanno più alcun effetto, senza nessun segnale che glielo dica. Abbiamo preferito una scatola degli attrezzi più piccola e onesta a una completa e bugiarda.

Stesso ragionamento sulla forma. Non cinque cursori nudi, ma quattro scelte con nome (Segui l’agente, Preciso, Bilanciato, Creativo) e i cursori nascosti dietro un pannello avanzato. Cinque numeri crudi in un’interfaccia producono configurazioni rotte che poi sembrano, di nuovo, colpa del modello.

Quello che resta

Il lavoro è durato un pomeriggio e ha prodotto tre moduli, un pannello e cinquantacinque test in più. Ma se dovessi indicare la cosa che ha cambiato davvero il progetto, non è nessuna di queste. È che adesso esiste un posto dove andare a leggere con che impostazioni gira il modello, e quel posto risponde senza che si debba aprire il sorgente di una dipendenza.

Se l’articolo ti è piaciuto restiamo in contatto su linkedin a: https://www.linkedin.com/in/andreatonin/

#defaultimpliciti #debitotecnico #configurabilità #llmlocali #osservabilità #decisionidiprodotto #errorediattribuzione #designdellescelte #configurazioneesterna #manutenibilità

Releated Posts

Private Vision: i LoRA e la matematica della personalizzazione — Parte 4

La cartella loras/ di Private Vision era piena di roba fatta da altri. Funzionava, per carità: Private Vision…

DiByAndrea Tonin Set 9, 2026

Dalla Skill all’Agente AI: automatizzare le note spese con ChatGPT e Google Workspace

Prima abbiamo distinto Progetti, GPT e Skill. Un Progetto è uno spazio di lavoro, un GPT è un…

DiByAndrea Tonin Ago 23, 2026

Anatomia di una Skill di ChatGPT: quando il prompt diventa una procedura

Negli ultimi mesi abbiamo imparato a scrivere prompt sempre più strutturati. Non più il classico “fammi un testo…

DiByAndrea Tonin Ago 23, 2026

Progetti, GPT e Skill: la differenza spiegata bene

Negli ultimi anni ChatGPT è passato dall’essere “una chat intelligente” a diventare un piccolo ecosistema di strumenti: Progetti,…

DiByAndrea Tonin Ago 23, 2026