Il fine-tuning di un modello linguistico parte da un modello già addestrato e lo adatta ai propri dati: uno stile di risposta, un argomento, un formato. Con LoRA e QLoRA il modello non si riaddestra da capo. I pesi originali restano congelati e si addestra solo un piccolo adattatore che vi si aggiunge, per cui basta una GPU di casa.
Questa guida usa Soup (pacchetto soup-cli), uno strumento open source con licenza Apache-2.0 che governa l’addestramento con un file YAML e pochi comandi. Si parte dall’installazione e si arriva a un file GGUF da usare in Ollama o in LM Studio. I comandi sono quelli della documentazione ufficiale, elencata in fondo.
Cosa serve
I requisiti vengono dalla sezione Requirements del README di Soup:
- Python 3.10, 3.11 o 3.12. Sono le versioni provate dalla CI del progetto. Python 3.13 e successivi non sono ancora supportati, perché lo stack di PyTorch non è stato validato su quelle versioni.
- Una GPU con CUDA, cioè NVIDIA, che è la scelta consigliata. Soup gira anche su Apple Silicon (MPS). La CPU è sperimentale e molto lenta e va bene solo per le prove. In quel caso la quantizzazione si disattiva da sola.
- Almeno 8 GB di VRAM per addestrare con QLoRA un modello da 7 miliardi di parametri.
- Un compilatore C++ e CMake, che servono più avanti per l’esportazione GGUF quantizzata.
La tabella ufficiale indica la taglia massima di modello per ogni quantità di VRAM, con QLoRA a 4 bit:
| VRAM | Modello massimo (QLoRA 4 bit) | Esempi |
|---|---|---|
| 8 GB | ~7B | Llama-3.1-8B, Mistral-7B |
| 16 GB | ~14B | Phi-4-14B, Qwen2.5-14B |
| 24 GB | ~34B | CodeLlama-34B, Yi-1.5-34B |
| 48 GB | ~70B | Llama-3.3-70B |
| 80 GB e oltre | 70B+ (completo) o MoE | Mixtral-8x22B, DeepSeek-V3 |
Il progetto parla anche di un modello da 8B addestrato su una GPU da portatile con 4 GB. Quel risultato richiede il layer streaming, una funzione opzionale ancora in BETA. Le misure sono state fatte sulla v0.72.2, prima della correzione arrivata con la v0.73.0, e il README dice che vanno ripetute (issue #361). Questa guida segue il percorso standard e il layer streaming non lo usa.
Creare un ambiente virtuale e installare Soup
Per l’installazione più pulita il README indica pipx o uv tool, che danno a Soup un ambiente tutto suo. pip è la strada per chi lavora già dentro un ambiente virtuale, un notebook Colab o un’immagine Docker. Qui si usa pip, quindi l’ambiente va creato prima.
Su Debian 12, Ubuntu 23.04 e versioni successive pip non può scrivere nel Python di sistema (regola PEP 668) e si ferma con l’errore externally-managed-environment. Il README lo risolve con python3 -m venv .venv && source .venv/bin/activate, da lanciare nella cartella di lavoro su Linux o macOS. La prima parte crea l’ambiente nella sottocartella .venv, la seconda lo attiva. L’attivazione dura quanto il terminale aperto: in ogni nuova sessione va rifatta dalla stessa cartella. Il python3 usato deve essere una delle versioni supportate.
Con l’ambiente attivo si installa Soup. Il pacchetto base soup-cli contiene solo la CLI leggera, con gli strumenti per la configurazione e i dati. Per addestrare serve l’extra [train], che aggiunge PyTorch, transformers, peft, trl e le altre librerie.
pip install "soup-cli[train]"Le virgolette devono essere doppie, perché è l’unica forma che funziona in tutte le shell (bash, zsh, PowerShell e cmd.exe). Se l’installazione si chiude senza errori, nel terminale c’è il comando soup.
Controllare GPU e dipendenze con soup doctor
Prima di scaricare un modello conviene controllare che Soup veda la GPU e che le librerie siano a posto. soup doctor riunisce in un solo report la GPU, le risorse del sistema, le dipendenze e la versione di Soup.
soup doctorSe usate una GPU NVIDIA, verificate che Soup possa utilizzarla tramite CUDA. Su Apple Silicon il dispositivo previsto è MPS; la CPU è supportata per prove sperimentali, molto lente e senza quantizzazione. Il Command reference spiega che il comando esce con codice 1 se manca una dipendenza essenziale o se un pacchetto installato supera la versione massima prevista. In quel caso l’ambiente va sistemato prima di proseguire.
Creare la configurazione dal template chat
Soup legge tutto da un file soup.yaml: modello di partenza, dataset, parametri di addestramento e cartella di output. Il template chat è il punto di partenza per un modello conversazionale.

soup init --template chatAlla fine nella cartella di lavoro c’è il file soup.yaml. Nell’esempio completo del README le voci principali sono queste:
base: il modello di partenza su Hugging Face, per esempiometa-llama/Llama-3.1-8B-Instruct. Per usarlo dovete prima richiedere e ottenere l’accesso dalla sua pagina, accettando la Llama 3.1 Community License e le condizioni d’uso, quindi autenticarvi nel terminale conhf auth loginusando lo stesso account. La licenza Apache-2.0 di Soup non si estende al modello;task: sft: l’addestramento supervisionato;training: epoche, learning rate,batch_size: auto, i parametri dilora(realpha) equantization: 4bit, cioè QLoRA;output: ./output: la cartella dove finisce l’adattatore.
Dalla v0.75 Soup rifiuta le chiavi che non riconosce. Basta un errore di battitura come quantizaton e la configurazione non si carica. Il messaggio d’errore indica il nome del campo che probabilmente si voleva scrivere.
Preparare il dataset
Soup riconosce da solo diversi formati di dati, tra cui Alpaca, ShareGPT e ChatML, in file JSONL, JSON, CSV, Parquet o TXT. Nella maggior parte dei casi basta indicare il file. Per un modello chat la cosa più semplice è un file JSONL, con un esempio per riga, in formato alpaca o sharegpt.
Il README non riporta i campi di ogni formato. Lo schema, con un esempio svolto per ciascun formato, si trova nella pagina docs/data.md del repository di Soup, a cui il README rimanda. In alternativa il Command reference elenca soup data demo alpaca_demo --output ./d.jsonl, che copia nella cartella corrente un file JSONL d’esempio in formato alpaca. Aprite quel file e usatelo come modello per le vostre righe, con la stessa struttura.
Salvate i vostri esempi in un file JSONL, per esempio ./data/train.jsonl come nella configurazione ufficiale. Poi controllatene il formato con soup data validate <percorso>, anche questo nel Command reference: al posto di <percorso> va il percorso del vostro file, cioè ./data/train.jsonl se avete seguito l’esempio. Il formato viene riconosciuto in automatico.
Nel soup.yaml il dataset si configura nel blocco data:
train: il percorso del file con i vostri dati, per esempio./data/train.jsonl(non il file d’esempio./d.jsonl, a meno che non vogliate fare solo una prova);format: il formato, per esempioalpaca;val_split: facoltativo, è la quota di esempi tenuta da parte per la validazione. Nell’esempio ufficiale vale0.1, cioè il 10%.
Avviare il fine-tuning LoRA/QLoRA
Con configurazione e dataset pronti si avvia l’addestramento. Quantizzazione a 4 bit, adattatore LoRA e dimensione del batch li gestisce Soup sulla base del file di configurazione.
soup train --config soup.yamlQuando l’addestramento finisce, l’adattatore sta nella cartella indicata da output, cioè ./output con la configurazione d’esempio. Dalla v0.75 Soup registra e mostra anche la loss di validazione, che prima veniva calcolata e poi scartata.
Provare il modello in chat
Prima di esportare il modello conviene provarlo. soup chat apre nel terminale una chat interattiva con il modello appena addestrato.
soup chat --model ./outputFate domande simili a quelle del dataset e confrontate le risposte con quelle che vi aspettate. La documentazione non dice come si chiude la sessione.
Unire l’adattatore al modello di base
L’unione (merge) produce un modello unico e indipendente, con i pesi LoRA fusi in quelli del modello di base. Soup ricava il modello di base dal file adapter_config.json dell’adattatore. Il passaggio è facoltativo: come spiega la pagina Serving & export, quando si esporta in GGUF un adattatore il merge avviene da sé.
soup merge --adapter ./output --output ./mergedIl modello unito finisce nella cartella ./merged.
Compilare llama.cpp ed esportare in GGUF
GGUF è il formato di file che usano Ollama, llama.cpp e LM Studio. Per la conversione Soup si appoggia a llama.cpp. Al primo utilizzo lo clona da internet (tag b5270) nella cartella ~/.soup/llama.cpp della vostra home, ma non lo compila. La conversione in f16 o f32 funziona con il solo script Python. Le versioni quantizzate richiedono invece il programma llama-quantize, da compilare una volta.
Se la cartella ~/.soup/llama.cpp non esiste ancora, lanciate prima dalla cartella del progetto l’esportazione non quantizzata soup export --model ./output --format gguf --quant f16, che compare nella pagina Serving & export. Non ha bisogno di llama-quantize e al primo utilizzo fa scaricare llama.cpp. Il risultato è un GGUF in f16, non quantizzato.
A quel punto si compila. Su Linux e macOS bastano un compilatore C++ e CMake. Su Windows il progetto ha validato Visual Studio 2022 Build Tools con il carico di lavoro «Desktop development with C++» e CMake 3.14 o successivo. La compilazione indicata è solo per CPU: le build CUDA di llama.cpp il progetto non le ha provate.
cd ~/.soup/llama.cppcmake -B build -DGGML_NATIVE=OFF -DLLAMA_CURL=OFF -DCMAKE_BUILD_TYPE=Releasecmake --build build --config Release --target llama-quantize -j 4Soup cerca il programma compilato in build/bin/llama-quantize, in build/bin/Release/llama-quantize.exe con MSVC e nel PATH. Non installate con pip il file requirements.txt di llama.cpp: fissa torch a una versione solo CPU, che sostituisce quella CUDA e rompe l’addestramento. Le poche dipendenze dello script di conversione le installa già Soup.
Tornate nella cartella del progetto, quella con soup.yaml e ./output, ed esportate in versione quantizzata. L’esempio ufficiale usa q4_k_m. Le altre quantizzazioni supportate sono q4_0, q5_k_m, q8_0, f16 e f32.
soup export --model ./output --format gguf --quant q4_k_mIl risultato è un file con estensione .gguf. La pagina non dice esattamente dove viene salvato, ma nei suoi esempi il file quantizzato compare come ./output/model.q4_k_m.gguf. Prendete nota del percorso completo, perché serve nei prossimi passaggi.
Caricare il GGUF in Ollama
Secondo la documentazione di Ollama sull’importazione, per un GGUF composto da un solo file si crea un file di testo chiamato Modelfile che contiene questa riga:
FROM /path/to/file.ggufAl posto di /path/to/file.gguf scrivete il percorso completo del file .gguf prodotto da soup export. Ollama non quantizza i GGUF durante l’importazione, ma il vostro è già stato quantizzato in q4_k_m.
Dalla cartella che contiene il Modelfile si crea il modello. my-model è un nome d’esempio, quello con cui il modello comparirà in Ollama. Potete sceglierne un altro, purché sia lo stesso in ollama create e in ollama run.
ollama create my-modelPoi lo si avvia per provarlo:
ollama run my-modelUsare il GGUF in LM Studio e LM Studio Bionic
In LM Studio basta mettere il file nella struttura di cartelle che l’app si aspetta. Dentro ~/.lmstudio/models/ si crea una cartella per l’editore, dentro questa una per il modello, e lì si mette il file GGUF. Per esempio ~/.lmstudio/models/io/mio-modello/mio-modello-q4_k_m.gguf, con nomi di cartella scelti da voi.

Per LM Studio Bionic la documentazione dice di scegliere nel selettore dei modelli un modello Local, che deve essere già scaricato e adatto all’hardware disponibile. Non descrive però una procedura per importare un GGUF creato in proprio, quindi qui non ne riportiamo una.
Se qualcosa va storto
- error: externally-managed-environment durante
pip install: è la regola PEP 668 di Debian 12, Ubuntu 23.04 e successive. Create e attivate l’ambiente virtuale come nella sezione sull’installazione e ripetetepip install, oppure usate pipx ouv tool. - pip rifiuta il nome del pacchetto: probabilmente avete usato le virgolette singole (
'soup-cli[train]'). Servono quelle doppie. - Crash nativi di PyTorch prima ancora che Soup parta: controllate la versione di Python. Con la 3.13 e successive pip sceglieva pacchetti di PyTorch non testati, che andavano in crash. Usate la 3.10, la 3.11 o la 3.12.
- La configurazione non si carica: dalla v0.75 una chiave sconosciuta o scritta male blocca il caricamento, con codice di uscita 1. Correggete o eliminate la chiave segnalata.
Restano fuori da questa guida Docker, l’addestramento su più GPU, DeepSpeed, il backend MLX, i metodi DPO, GRPO e RLHF, la Web UI, autopilot e la pubblicazione su Hugging Face: sono tutti descritti nella documentazione del progetto. Per disinstallare Soup non c’è un comando documentato.
Documentazione di riferimento
Pagine consultate il 6 ottobre 2026. La guida si basa sulla documentazione della v0.75.
- Soup, repository ufficiale su GitHub
- Soup, README
- Soup, Serving & export (merge, GGUF, compilazione di llama.cpp)
- Soup, Command reference
- Ollama, Importing a model
- LM Studio, Import Models
- LM Studio Bionic, Choose a Cloud, Local, or Remote Model