- Messaggi
- 39,219
- Reazioni
- 13,231
- Punteggio
- 253
Guida completa: costruire un chatbot LLaMA in Python e servire un'interfaccia web con Flask
Scopo: questa guida è pensata per un lettore neofita che si avvicina per la prima volta ai modelli di linguaggio (LLM). Ti guiderò passo-passo: dai concetti base fino a un’app funzionante (backend Flask + frontend semplice), includendo istruzioni pratiche, script, Docker, e suggerimenti per addestrare e personalizzare il modello.
Nota importante sulle licenze
I pesi dei modelli LLaMA sono soggetti a licenze ufficiali di Meta. Prima di scaricarli o distribuirli assicurati di leggere e accettare i termini. Alcuni pesi non possono essere ridistribuiti pubblicamente.
Indice (rapido)
- Concetti base — che cos'è LLaMA, tokenizer, pesi, inferenza
- Requisiti e ambiente di lavoro (Windows/macOS/Linux)
- Modalità d'esecuzione: llama.cpp vs transformers (pro/contro)
- Preparare l'ambiente passo-passo (virtualenv, dipendenze)
- Ottenere e preparare i pesi (avvisi, conversione in ggml)
- Script minimo per inferenza (llama-cpp-python)
- Inferenza con transformers (GPU) — esempio semplice
- Capire i prompt e progettare bot che rispettino regole e tono
- Personalizzazione: Few-shot, Instruction tuning, LoRA (PEFT)
- Backend: API REST con Flask (codice completo)
- Frontend: pagina HTML + Tailwind, miglioramenti UX
- WebSocket per chat in tempo reale (Flask-SocketIO)
- Docker e docker-compose per distribuire il servizio
- Sicurezza, privacy e considerazioni legali
- Debugging e risoluzione problemi comuni
- Checklist finale e suggerimenti per il post sul forum
- Risorse e link utili (cosa leggere dopo)
1) Concetti base (breve)
- LLM (Large Language Model): modello di deep learning addestrato su grandi quantità di testo. Genera testo predicendo la parola successiva.
- LLaMA: famiglia di modelli rilasciata da Meta (es. LLaMA 2/3). Ha diversi formati e pesi.
- Tokenizer: converte testo in numeri (token) che il modello elabora.
- Pesi: i file che contengono i parametri del modello.
- Inferenza: generare testo usando il modello già addestrato.
Per un principiante: pensa al modello come a una grande funzione che trasforma un prompt in una risposta; il tokenizer traduce il testo in input numerici che la funzione comprende.
2) Requisiti e ambiente di lavoro
Requisiti minimi
- Python 3.10+ (consigliato 3.11)
- 8+ GB RAM (per modelli piccoli/quantizzati con llama.cpp)
- Per modelli grandi e training: GPU con CUDA (16GB+ consigliati)
- Spazio su disco: 10–50 GB (a seconda dei pesi)
Sistema operativo
- Linux è più semplice per tool di ML; macOS va bene; Windows funziona ma alcune dipendenze (compilazione di llama.cpp) possono richiedere WSL.
Consigli pratici
- Usa un ambiente virtuale (venv) o Conda.
- Lavora su una macchina dedicata se sperimenti con pesi grandi.
3) Modalità d'esecuzione: pro e contro
llama.cpp
- Pro: esecuzione su CPU, supporto a modelli quantizzati (ggml), basso uso di memoria, ottimo per laptop/desktop senza GPU.
- Contro: performance inferiore rispetto a GPU; conversione pesi richiesta.
transformers
- Pro: sfrutta GPU per inferenza veloce e training; ecosistema ricco (PEFT, Accelerate).
- Contro: richiede GPU, più complesso da configurare.
Servizi gestiti (Hugging Face Inference, AWS, Replicate)
- Pro: zero setup hardware, produzione più semplice.
- Contro: costi, dipendenza da servizi esterni.
Scelta per un neofita: cominciare con llama.cpp per sperimentare localmente, poi passare a GPU/transformers se necessario.
4) Preparare l'ambiente passo-passo
Esempio su Linux / macOS.
Codice:
# crea e attiva venv<br>python -m venv venv<br>source venv/bin/activate<br>pip install --upgrade pip<br>
Installazioni principali (versione di base per llama-cpp-python):
Codice:
pip install flask flask-socketio llama-cpp-python<br>
Se prevedi GPU e transformers:
Codice:
pip install transformers accelerate peft datasets safetensors bitsandbytes torch<br>
Nota: l'installazione di torch dipende dalla tua versione di CUDA; segui la guida ufficiale di PyTorch.
5) Ottenere e preparare i pesi
- Registrati (se richiesto) sulla pagina ufficiale di Meta/LLaMA e accetta la licenza.
- Scarica i pesi (spesso in formato safetensors o PyTorch).
- Per llama.cpp: è necessario convertire i pesi in formato ggml (quantizzato). I repository llama.cpp forniscono script di conversione. Tipicamente il comando è qualcosa del genere (semplificato):
Codice:
# clonare llama.cpp e usare script di conversione (esempio generico)<br>git clone https://github.com/ggerganov/llama.cpp<br>cd llama.cpp<br># copia i pesi in una cartella e segui il README per convertire a ggml<br>python convert.py --input model.safetensors --output model.ggml<br>
- Metti il file model.ggml in ./models/.
Attenzione: i nomi dei comandi e script cambiano col tempo; segui sempre il README del repo llama.cpp che hai clonato.
6) Script minimo per inferenza con
File infer_llama.py:
Codice:
from llama_cpp import Llama<br><br># percorso al modello ggml<br>MODEL_PATH = "./models/llama-7b.ggml"<br>llm = Llama(model_path=MODEL_PATH)<br><br>prompt = "Scrivi una breve guida introduttiva su Flask in italiano."<br>res = llm.create(prompt=prompt, max_tokens=200, temperature=0.2)<br>print(res.choices[0].text)<br>
Esegui:
Codice:
python infer_llama.py<br>
Parametri utili:
- max_tokens: lunghezza massima generata
- temperature: casualità (0.0 = deterministico)
- top_p: nucleus sampling
- stop: lista di token per fermare la generazione
7) Inferenza con transformers (GPU)
Installare le dipendenze necessarie (PyTorch compatibile con la tua GPU).
Esempio semplificato:
Codice:
from transformers import AutoTokenizer, AutoModelForCausalLM<br>import torch<br><br>model_name = "meta-llama/your-model-name"<br>tokenizer = AutoTokenizer.from_pretrained(model_name)<br>model = AutoModelForCausalLM.from_pretrained(model_name, torch_dtype=torch.float16, device_map='auto')<br><br>inputs = tokenizer("Ciao! Spiegami cosa è Flask.", return_tensors='pt').to(model.device)<br>outputs = model.generate(**inputs, max_new_tokens=150)<br>print(tokenizer.decode(outputs[0], skip_special_tokens=True))<br>
Questo approccio va bene se hai accesso ai pesi e una GPU.
8) Progettare prompt efficaci (prompt engineering)
Concetti chiave
- System prompt: istruzioni a inizio prompt che definiscono comportamento (es. tono, lingua, formato).
- Few-shot: includere alcuni esempi di domanda/risposta per indirizzare il modello.
- Temperature e max_tokens determinano creatività e lunghezza.
Esempio di system prompt
Codice:
Sei un assistente tecnico che risponde in italiano in modo chiaro e conciso. Fornisci esempi di codice quando necessario e non inventare fatti.<br>
Best practices
- Fornisci formato di output se necessario (JSON, elenco puntato).
- Se il modello tende a inventare, abbassa temperature e aggiungi prompt che richiedano "se non sei sicuro, ammettilo".
9) Personalizzazione: Few-shot, Instruction-tuning, LoRA
Few-shot
- Facile: inserisci esempi nel prompt. Non richiede training.
- Limite: prompt più lungo, inferenza più costosa.
Instruction-tuning / Fine-tuning
- Addestrare il modello su coppie (prompt -> risposta) per ottenere comportamento persistente.
- Richiede risorse (GPU, tempo).
LoRA (PEFT)
- Metodo efficiente che modifica pochi parametri.
- Vantaggio: richiede poca memoria e salva solo i pesi adattati.
Esempio schematico per LoRA (concettuale):
Codice:
# librerie: transformers, accelerate, peft<br># carica modello in 4-bit o fp16<br># prepara dataset (JSONL con campi prompt, response)<br># configura LoraConfig e trainer<br># trainer.train()<br># salva i pesi LoRA<br>
Per un neofita: comincia con few-shot; passa a LoRA quando vuoi che le personalizzazioni siano persistenti senza dover mantenere grandi training runs.
10) Backend Flask: API REST completa
Crea app.py con una API REST minima che serve il modello.
Codice:
# app.py<br>from flask import Flask, request, jsonify<br>from llama_cpp import Llama<br>import os<br><br>app = Flask(__name__)<br>MODEL_PATH = os.environ.get('MODEL_PATH','./models/llama-7b.ggml')<br>llm = Llama(model_path=MODEL_PATH)<br><br>@app.route('/api/chat', methods=['POST'])<br>def chat():<br> data = request.json or {}<br> prompt = data.get('prompt','')<br> if not prompt:<br> return jsonify({'error':'prompt mancante'}), 400<br> # potresti costruire qui un prompt system integrando istruzioni persistenti<br> resp = llm.create(prompt=prompt, max_tokens=256, temperature=0.2)<br> text = resp.choices[0].text<br> return jsonify({'reply': text})<br><br>if __name__ == '__main__':<br> app.run(host='0.0.0.0', port=5000)<br>
Eseguire in sviluppo
Codice:
export MODEL_PATH=./models/llama-7b.ggml<br>python app.py<br>
Migliorie consigliate
- Aggiungi gestione errori e timeout.
- Aggiungi rate-limiting (es. flask-limiter).
- Log delle richieste (evita di registrare dati sensibili).
11) Frontend semplice (HTML + Tailwind)
File templates/index.html (Flask serve la cartella templates automaticamente):
Codice:
<!doctype html><br><html><br><head><br> <meta charset="utf-8"><br> <meta name="viewport" content="width=device-width,initial-scale=1"><br> <script src="https://cdn.tailwindcss.com"></script><br> <title>Chatbot LLaMA</title><br></head><br><body class="bg-gray-100 p-6"><br> <div class="max-w-3xl mx-auto bg-white rounded-2xl shadow p-6"><br> <h1 class="text-2xl font-bold mb-4">Chatbot LLaMA</h1><br> <div id="chat" class="h-96 overflow-y-auto border p-3 mb-3 rounded"></div><br> <div class="flex"><br> <input id="prompt" class="flex-1 border rounded p-2 mr-2" placeholder="Scrivi qui..."><br> <button id="send" class="px-4 py-2 bg-blue-600 text-white rounded">Invia</button><br> </div><br> </div><br> <script><br> const chatEl = document.getElementById('chat')<br> document.getElementById('send').onclick = async ()=>{<br> const prompt = document.getElementById('prompt').value<br> if(!prompt) return<br> chatEl.innerHTML += `<div class='text-sm text-gray-700 mb-2'><strong>Tu:</strong> ${prompt}</div>`<br> document.getElementById('prompt').value = ''<br> const res = await fetch('/api/chat', {method:'POST', headers:{'Content-Type':'application/json'}, body:JSON.stringify({prompt})})<br> const j = await res.json()<br> chatEl.innerHTML += `<div class='text-sm text-gray-900 mb-4'><strong>Bot:</strong> ${j.reply}</div>`<br> chatEl.scrollTop = chatEl.scrollHeight<br> }<br> </script><br></body><br></html><br>
Miglioramenti UX:
- visualizzare indicatori di "sta scrivendo..."
- timestamp per i messaggi
- supporto per prompt predefiniti
12) Chat in tempo reale con Flask-SocketIO
File app_socket.py:
Codice:
from flask import Flask, render_template<br>from flask_socketio import SocketIO, emit<br>from llama_cpp import Llama<br><br>app = Flask(__name__)<br>socketio = SocketIO(app, cors_allowed_origins='*')<br>llm = Llama(model_path='./models/llama-7b.ggml')<br><br>@app.route('/')<br>def index():<br> return render_template('index.html')<br><br>@socketio.on('user_message')<br>def handle_message(data):<br> prompt = data.get('prompt','')<br> emit('bot_typing', {'status': True})<br> resp = llm.create(prompt=prompt, max_tokens=256)<br> emit('bot_reply', {'reply': resp.choices[0].text})<br><br>if __name__ == '__main__':<br> socketio.run(app, host='0.0.0.0', port=5000)<br>
Lato client usa socket.io per inviare messaggi e ricevere risposte in tempo reale.
13) Docker e docker-compose
Dockerfile (esempio semplice)
FROM python:3.11-slim<br>WORKDIR /app<br>COPY requirements.txt ./<br>RUN pip install --no-cache-dir -r requirements.txt<br>COPY . /app<br>ENV MODEL_PATH=/app/models/llama-7b.ggml<br>EXPOSE 5000<br>CMD ["python","app.py"]<br>
docker-compose.yml di esempio (per sviluppo locale):
Codice:
version: '3.8'<br>services:<br> web:<br> build: .<br> volumes:<br> - ./models:/app/models:ro<br> ports:<br> - "5000:5000"<br>
Costruisci e avvia:
Codice:
docker compose up --build<br>
Note: i file dei pesi sono molto grandi: montali come volume e non includerli nell'immagine.
14) Sicurezza, privacy e considerazioni legali
- Proteggi l'API: usa autenticazione (API key), HTTPS e rate-limiting.
- Dati sensibili: evita di loggare informazioni personali; se necessario, anonimizza i log.
- Licenze dei pesi: rispetta i termini di Meta e dei dataset usati per il fine-tuning.
- Moderazione: implementa filtri per contenuti offensivi o pericolosi (prima di mostrare la risposta all'utente).
15) Debugging e problemi comuni
- Errore memoria GPU: riduci batch size, usa 4-bit quantization, o passa a llama.cpp.
- Installazione difficile su Windows: prova WSL2 con Ubuntu.
- Performance lente su CPU: usa modello quantizzato con llama.cpp.
- Risposte inventate (hallucinations): specifica nel prompt di "ammettere se non si è sicuri", riduci temperature, fornisci fonti in prompt.
16) Checklist per il post sul forum
- Fornisci istruzioni chiare su come ottenere i pesi (link ufficiale e nota licenza).
- Includi file essenziali: app.py, requirements.txt, templates/index.html, Dockerfile, docker-compose.yml.
- Includi screenshot della UI e output di esempio.
- Spiega limitazioni e possibili upgrade (GPU, LoRA, deploy su cloud).
17) Risorse e link utili (da aggiungere al post)
- Documentazione ufficiale LLaMA (Meta) — come ottenere i pesi e licenza
- Repository llama.cpp — conversione ggml ed esecuzione CPU
- llama-cpp-python — binding Python per llama.cpp
- Hugging Face: transformers, accelerate, peft, datasets — per inferenza GPU e LoRA
- Flask e Flask-SocketIO — guide ufficiali
- TailwindCSS — guida rapida per styling
- PyTorch — installazione corretta per la tua GPU
REPOSITORY GITHUB: https://github.com/Chry1911/LLamaChatbot
Ultima modifica:




