GUIDA Come creare un Chatbot con LLama

Pubblicità

Skills07

Head of Development
Staff Forum
Utente Èlite
Messaggi
39,578
Reazioni
13,425
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)​


  1. Concetti base — che cos'è LLaMA, tokenizer, pesi, inferenza
  2. Requisiti e ambiente di lavoro (Windows/macOS/Linux)
  3. Modalità d'esecuzione: llama.cpp vs transformers (pro/contro)
  4. Preparare l'ambiente passo-passo (virtualenv, dipendenze)
  5. Ottenere e preparare i pesi (avvisi, conversione in ggml)
  6. Script minimo per inferenza (llama-cpp-python)
  7. Inferenza con transformers (GPU) — esempio semplice
  8. Capire i prompt e progettare bot che rispettino regole e tono
  9. Personalizzazione: Few-shot, Instruction tuning, LoRA (PEFT)
  10. Backend: API REST con Flask (codice completo)
  11. Frontend: pagina HTML + Tailwind, miglioramenti UX
  12. WebSocket per chat in tempo reale (Flask-SocketIO)
  13. Docker e docker-compose per distribuire il servizio
  14. Sicurezza, privacy e considerazioni legali
  15. Debugging e risoluzione problemi comuni
  16. Checklist finale e suggerimenti per il post sul forum
  17. 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​


  1. Registrati (se richiesto) sulla pagina ufficiale di Meta/LLaMA e accetta la licenza.
  2. Scarica i pesi (spesso in formato safetensors o PyTorch).
  3. 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>

  1. 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:
&lt;!doctype html&gt;<br>&lt;html&gt;<br>&lt;head&gt;<br>  &lt;meta charset="utf-8"&gt;<br>  &lt;meta name="viewport" content="width=device-width,initial-scale=1"&gt;<br>  &lt;script src="https://cdn.tailwindcss.com"&gt;&lt;/script&gt;<br>  &lt;title&gt;Chatbot LLaMA&lt;/title&gt;<br>&lt;/head&gt;<br>&lt;body class="bg-gray-100 p-6"&gt;<br>  &lt;div class="max-w-3xl mx-auto bg-white rounded-2xl shadow p-6"&gt;<br>    &lt;h1 class="text-2xl font-bold mb-4"&gt;Chatbot LLaMA&lt;/h1&gt;<br>    &lt;div id="chat" class="h-96 overflow-y-auto border p-3 mb-3 rounded"&gt;&lt;/div&gt;<br>    &lt;div class="flex"&gt;<br>      &lt;input id="prompt" class="flex-1 border rounded p-2 mr-2" placeholder="Scrivi qui..."&gt;<br>      &lt;button id="send" class="px-4 py-2 bg-blue-600 text-white rounded"&gt;Invia&lt;/button&gt;<br>    &lt;/div&gt;<br>  &lt;/div&gt;<br>  &lt;script&gt;<br>    const chatEl = document.getElementById('chat')<br>    document.getElementById('send').onclick = async ()=&gt;{<br>      const prompt = document.getElementById('prompt').value<br>      if(!prompt) return<br>      chatEl.innerHTML += `&lt;div class='text-sm text-gray-700 mb-2'&gt;&lt;strong&gt;Tu:&lt;/strong&gt; ${prompt}&lt;/div&gt;`<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 += `&lt;div class='text-sm text-gray-900 mb-4'&gt;&lt;strong&gt;Bot:&lt;/strong&gt; ${j.reply}&lt;/div&gt;`<br>      chatEl.scrollTop = chatEl.scrollHeight<br>    }<br>  &lt;/script&gt;<br>&lt;/body&gt;<br>&lt;/html&gt;<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:
Ottima guida come sempre👍
Non c'entra niente, ma io uso Ollama con Open WebUi. Recentemente ho creato un workflow in n8n e accedo alla chat sulla mia istanza di n8n pubblica.
Cosa ne pensi di questo approccio?
 
Ultima modifica:
è un approccio alternativo, che funziona bene.
Io ho provato giusto per dirla tutta dando informazioni migliori con:

- windows 11
- 16gb ram ddr3
- i7 4790
- gtx 970

E gira bene il modello, è un modello leggero che usa al massimo 8gb di ram.
Sicuramente se provassi su quello con l'i5 14600kf + 32gb di ram e la 5060 con i cuda core avrei ancora piu benefici.

Bello comunque che ne stiamo facendo una bella discussione
 
è un approccio alternativo, che funziona bene.
Io ho provato giusto per dirla tutta dando informazioni migliori con:

- windows 11
- 16gb ram ddr3
- i7 4790
- gtx 970

E gira bene il modello, è un modello leggero che usa al massimo 8gb di ram.
Sicuramente se provassi su quello con l'i5 14600kf + 32gb di ram e la 5060 con i cuda core avrei ancora piu benefici.
Sicuramente, io faccio girare tutto sulla 5070Ti, preferisco stare tutto sulla gpu. Uso docker desktop in win11 (che usa wsl comunque). Gli ho dato 6 cpu e 24 Gb di Ram.
Screenshot 2025-12-05 181728.webp
Ollama per gli LLM, open webUi per usarli (in realtà lo uso pochissimo ultimamente), piper per TTS e whisper per speech-to-text, questi due mi servono in home assistant per far parlare Home Assistant voice preview.

I modelli che ho attualmente
Screenshot 2025-12-05 181904.webp
Llama3.1 distillato lo uso proprio in home assistant. Da ieri però sto provando anche qwen3 con ottimi risultati perchè è thinking.
Bello comunque che ne stiamo facendo una bella discussione
Si finalmente qualcuno con cui parlarne seriamente, sono più di 6 mesi che smanetto e sono ancora alle basi, c'è tutto un mondo da scoprire.
 
Ottimo, bellissimo il fatto che hai dockerizzato tutto, in maniera tale da avere ambienti isolati e contenerizzati, questo implica il non installare librerie esterne.

Fondamentale se ti stai cimentando in python, usare sempre il Virtual Environement (venv) cosi col pip installi sempre librerie in un ambiente isolato e non in mezzo a windows.

Allego file con le dipendenze che sto usando io su windows 11 senza WSL.

Python:
flask
flask-cors
llama-cpp-python>=0.2.90
sentencepiece
pdfplumber
python-docx
pypdf
docx2txt
imapclient
requests
python-dotenv
datasets
pandas
numpy
scikit-learn
huggingface-hub

intanto mostro la mia demo in lavorazione che già funziona
Screenshot 2025-12-06 090620.webp

L’intento del mio bot è renderlo disponibile a solo richieste di un argomento e fargli fare analisi documentale
 
Si tramite prompt ad esempio ho scritto questo:
Python:
@app.route("/start_stream", methods=["POST"])
def start_stream():
    data = request.json or {}
    conv_id = data.get("conv_id") or create_conversation()
    convs = load_conversations()
    history = convs.get(conv_id, {}).get("messages", [])

    # Prompt system aggiornato per ambito informatico
    SYSTEM_PROMPT = """
<<SYS>>
Sei un assistente specializzato **solo ed esclusivamente in argomenti di informatica**.

Puoi rispondere SOLO se la domanda riguarda:
- programmazione
- linguaggi di programmazione
- sviluppo software
- architetture software
- informatica generale
- server, reti, protocolli
- hardware, sistemi operativi
- cybersecurity
- database
- strumenti informatici
- troubleshooting tecnico
- AI / machine learning / modelli LLM
- cloud computing
- DevOps, Docker, Kubernetes

SE LA DOMANDA NON È DI NATURA INFORMATICA:
- NON devi rispondere alla domanda
- NON devi inventare nulla
- NON devi divagare

Devi rispondere esattamente con questo messaggio:

"Mi dispiace, posso rispondere solo a domande di ambito informatico."

Il messaggio deve essere IDENTICO senza variazioni.
<</SYS>>
"""

Questo vuol dire che ignora qualsiasi altra richiesta

Poi ho abbellito la UI

1765024554822.webp

E come vedi risponde solo con del codice

Facciamo cosi, vi mostro un affinamento appena fatto

Screenshot 2025-12-06 135709.webp

Screenshot 2025-12-06 135722.webp

Inoltre vi regalo la repository GITHUB con dentro tutto il progetto https://github.com/Chry1911/LLamaChatbot vi chiedo solo, nel caso in cui la scarichiate di dirmelo. Lasciare un commento o altro mi farebbe solo che piacere
 
Ultima modifica da un moderatore:
Si tramite prompt ad esempio ho scritto questo:
Python:
@app.route("/start_stream", methods=["POST"])
def start_stream():
    data = request.json or {}
    conv_id = data.get("conv_id") or create_conversation()
    convs = load_conversations()
    history = convs.get(conv_id, {}).get("messages", [])

    # Prompt system aggiornato per ambito informatico
    SYSTEM_PROMPT = """
<<SYS>>
Sei un assistente specializzato **solo ed esclusivamente in argomenti di informatica**.

Puoi rispondere SOLO se la domanda riguarda:
- programmazione
- linguaggi di programmazione
- sviluppo software
- architetture software
- informatica generale
- server, reti, protocolli
- hardware, sistemi operativi
- cybersecurity
- database
- strumenti informatici
- troubleshooting tecnico
- AI / machine learning / modelli LLM
- cloud computing
- DevOps, Docker, Kubernetes

SE LA DOMANDA NON È DI NATURA INFORMATICA:
- NON devi rispondere alla domanda
- NON devi inventare nulla
- NON devi divagare

Devi rispondere esattamente con questo messaggio:

"Mi dispiace, posso rispondere solo a domande di ambito informatico."

Il messaggio deve essere IDENTICO senza variazioni.
<</SYS>>
"""

Questo vuol dire che ignora qualsiasi altra richiesta

Poi ho abbellito la UI

Visualizza allegato 501283

E come vedi risponde solo con del codice
Ottimo veramente. Infatti quello che voglio imparare bene io e il prompt engineering, scrivere il giusto prompt è la cosa più difficile secondo me
 
Buongiorno, grazie per la guida. Non sono un esperto e vorrei capire qual'è la differenza/vantaggio rispetto ad utilizzare un agente come Copilot. Ho visto che microsoft permette di addestrare copilot e creare un chatbot personalizzato da usare anche in ambiente business.
Inoltre è possibile gestire la privacy dei dati?? Ad esempio negare l'accesso a determinate informazioni ad una parte di utenti ed autorizzare solo un gruppo definito?
 
Questo puoi decidere di installarlo dove vuoi tu, ed istruirlo come vuoi tu, rispetto a copilot che è dentro windows.
Certo il codice è personalizzabile per fare tutto quello che richiedi, essendo codice puoi aggiungere tutte le funzioni che vuoi
 
è proprio della tua conoscenza in quella determinata materia che sono invidioso ma nel senso buono non fraintendere
Sì questo è un argomento nuovo mi ci sto cimentando ora in quanto il primo febbraio cambio azienda e andrò a lavorare nel mondo dell’Ai!

Python lo conosco da un po’ come linguaggio l’ho usato per fare il nostro bot delle offerte Amazon e che però non ci hanno mai fatto lanciare pubblicamente (ne avrebbe guadagnato tutto il forum) in quanto sarebbe stato curato da noi mod

Allora Ragazzi ho lavorato sulla repository che vi ho regalato e ho cambiato completamente il bot, migliorandone l'estetica e aggiungendo funzionalità potentissime. Vi elenco quanto fatto qui sotto:

- aggiunta la funzione di fargli riassumere un pdf
- aggiunta la funzione per fargli leggere una email
- redesign grafico
 

Allegati

  • Screenshot 2025-12-31 160007.webp
    Screenshot 2025-12-31 160007.webp
    29.1 KB · Visualizzazioni: 5
  • Screenshot 2025-12-31 160200.webp
    Screenshot 2025-12-31 160200.webp
    23.9 KB · Visualizzazioni: 5
  • Screenshot 2025-12-31 160244.webp
    Screenshot 2025-12-31 160244.webp
    25.2 KB · Visualizzazioni: 5
  • Screenshot 2025-12-31 160313.webp
    Screenshot 2025-12-31 160313.webp
    21.8 KB · Visualizzazioni: 5
Pubblicità
Pubblicità
Indietro
Top