ChatBot in Python con Gradio e Google Gemma sfruttando Hugging Face

Ciao a tuttə e bentrovatə, quest’oggi vorrei proporvi un piccolo Chatbot basato su Google Gemma e scritto in Python, sfruttando l’ecosistema di Hugging Face; per l’interfaccia grafica del chatbot utilizzeremo Gradio, una bella libreria adatta allo scopo.

Prepariamo l’ambiente

Vorrei avvisarvi che la preparazione sarà lunghetta e che sarà necessario scaricare diversi Gigabyte di robaccia: munitevi di una buona ADSL (o meglio ancora di Fibra Ottica) e di un po’ di pazienza.

Per completezza vi informo anche che questo articolo è stato scritto utilizzando un PC con Windows 11 Pro e non su Ubuntu (attendo impaziente Aprile per provare la 24.04) o sulla mia amata Debian; la precisazione è necessaria in quanto andremo anche a fare il setup delle CUDA (se lavorate su Linux dovrete adattare le parti necessarie di questo tutorial).

Installiamo Python su Windows

Abbiamo due opportunità per avere Python sul nostro PC:

Io ho seguito la prima strada (ma bisogna stare attenti in fase di installazione a flaggare un paio di opzioni) mentre forse, per la maggior parte dei “newbie” (non che io mi consideri un “arrivato”) sarebbe preferibile utilizzare la seconda possibilità.

Installiamo e Configuriamo Visual Studio Code

Per questo esperimento di coding ho deciso di utilizzare l’ottimo VS Code di Microsoft; non credo che abbia bisogno di presentazioni ma, per chi non lo conoscesse, è un ottimo editor, ricchissimo di funzioni e che, con le opportune estensioni (ve ne sono moltissime) non ha nulla da invidiare a IDE più blasonati, come l’ottimo PyCharm (che utilizzo di solito).

Iniziamo installando e scaricando VS Code (se già non lo avete…) a questo punto andrebbe già bene così ma, se pensate di utilizzare Python per un po’, vi consiglio di installare anche l’estensione per sviluppare in questo linguaggio (ma è una cosa che si può fare comodamente anche dopo… nel prosieguo darò i comandi nel caso decideste di saltare questo passaggio).

Al primo avvio vi verrà chiesto se volete l’interfaccia di VS Code in Italiano e altre domande: penso che sia inutile approfondire 🙂

Installiamo le CUDA su Windows

Per scaricare le CUDA basta andare all’apposito indirizzo sul sito ufficiale di NVIDIA e scegliere: piattaforma, architettura, versione di Windows e se vogliamo un installer che scarichi dalla rete le risorse oppure un .exe unico (e bello pesante).

L’installer è un classico installer… mi va di fare giusto due precisazioni:

  • La prima è che al momento in cui scrivo siamo alla versione 12.4 (è importante quando poi installeremo torch con il supporto per queste librerie)
  • La seconda è che, non avendo io installato l’IDE ufficiale di Microsoft (Visual Studio), darà un Warning all’installazione (ma funziona tutto… state sereni 😉 )

Non è necessario riavviare a fine installazione ma io un colpetto di reboot l’ho fatto comunque (per scaramanzia windowsiana 🙂 )

Generiamo il Token di autenticazione per Hugging Face

Dovremo andare su Hugging Face e creare un account; poi andare nei settaggi e generare un Token di autenticazione: dopo la generazione questo Token va incollato nel file .env che viene allegato al repository GitHub.

Chiediamo l’accesso al modello Google Gemma su Hugging Face

Come per Meta LLama 2 anche per Google Gemma è necessario richiedere l’accesso: normalmente basta andare in una delle pagine dei modelli (ne sono presenti diversi) e cliccare sulla richiesta all’inizio della pagina: vogliate perdonarmi ma ho fatto questo passaggio un po’ di tempo fa e mi è sfuggito di mente… 🙁

Due Parole su Gradio.app

Prima di andare avanti col codice (di cui fornirò anche un repository GitHub) vorrei parlarvi di Gradio: il motto che campeggia in Homepage è “Build & Share Delightful Machine Learning Apps” (Crea e condividi deliziose app di machine learning)… ed effettivamente è vero.

Con poco codice si creano delle interfacce veramente carine, la documentazione è ben scritta (un po’ datata, se proprio vogliamo essere puntigliosi) ed è il perfetto strumento per un Data Scientist che non abbia tempo e/o voglia di scrivere codice frontend per le app aziendali interne.

Se volete approfondire vi conviene iniziare da questa ottima guida sul sito ufficiale dedicata ai Chatbot con Gradio.

Finalmente un po’ di codice

Creiamo l’ambiente virtuale in Python

Per evitare di sporcare l’ambiente principale conviene creare un virtual enviroment (o venv, per accorciare); la procedura da seguire è la seguente:

  1. Andare nel menù Terminale di VS Code e aprire un terminale
  2. Creare una cartella in c: con il comando: mkdir c:\chatbot
  3. Spostarsi nella directory corretta con il comando: cd c:\chatbot
  4. Dare il comando: python -m venv venv (come spiegato nella documentazione ufficiale)
  5. Attivare l’ambiente con il comando: \.venv\Scripts\Activate.ps1

A questo punto vorrei fare notare due cose:

  • È possibile automatizzare la creazione dell’ambiente aggiungendo la cartella c:\chatbot all’ambiente di lavoro direttamente da VS Code e installando l’estensione per Python in VS Code
  • Occhio: se uscite e rientrate in VS Code vi ritroverete dentro la cartella chatbot ma dovrete di nuovo attivare l’ambiente con il comando al punto cinque di cui sopra

Installiamo le dipendenze

Sempre nella finestra del Terminale diamo questi comandi; sono dei pip (l’installer dei pacchetti Python) che servono ad installare le dipendenze necessarie a fare girare il codice (che sta per arrivare 😉 ).

  • pip install python-dotenv
  • pip install https://gradio-builds.s3.amazonaws.com/b9dbcf7aa22fe9a19edbc0c52d46a973d8d57ad4/gradio-4.24.0-py3-none-any.whl
  • pip install transformers
  • pip install torch –index-url https://download.pytorch.org/whl/cu121 (su questo spenderò due parole dopo… occhio che sono più di due Gb)
  • pip install accelerate

Per quanto riguarda torch vorrei fare notare che io ho installato le CUDA alla versione 12.4 mentre il supporto di questa libreria in torch è attualmente alla 12.1… però funziona tutto… di più non so dirvi 🙂

Ma questo codice?

Arriva arriva… 🙂

Ecco a voi il main.py.


# import python-dotenv
import os
from dotenv import load_dotenv

# import from huggingface
from transformers import AutoTokenizer, AutoModelForCausalLM
import torch

# import regex for clean response
import re

# import gradio for gui
import gradio as gr


# take environment variables from .env file.
load_dotenv()
token = os.getenv('TOKEN')

# set some stuffs
model_id = "google/gemma-2b-it"
dtype = torch.bfloat16

# start with chat
def gemma_chat(message, history):
    tokenizer = AutoTokenizer.from_pretrained(model_id, token=token)
    model = AutoModelForCausalLM.from_pretrained(
        model_id,
        token=token,
        hidden_activation="gelu_pytorch_tanh",
        device_map="cuda",
        torch_dtype=dtype,
    )

    chat = [
        { "role": "user", "content": message },
    ]

    prompt = tokenizer.apply_chat_template(chat, tokenize=False, add_generation_prompt=True)
    
    inputs = tokenizer.encode(prompt, add_special_tokens=False, return_tensors="pt")
    outputs = model.generate(input_ids=inputs.to(model.device), max_new_tokens=2048)
    
    response = tokenizer.decode(outputs[0])
    
    
    # clean the response
    response_cleaned = re.split("model", response)   

    # return the response
    return response_cleaned[1]


gr.ChatInterface(gemma_chat).launch()

Vale la pena spendere due parole su questo codice che è molto didattico e anche ripreso quasi integralmente da questa pagina di Hugging Face.

La funzione gemma chat è quasi integralmente ripresa dalla pagina sopraindicata; è possibile cambiare il modello cambiando la variabile model_id (per esempio al posto di google/gemma-2b-it è possibile mettere google/gemma-7b-it (a patto di avere un hardware sufficiente).

È anche possibile cambiare il numero massimo di token che vengono generati cambiando max_new_tokens (attualmente settato a 2048).

Per funzionare questo codice ha bisogno di un token di autenticazione da Hugging Face (di cui abbiamo parlato prima) da un file separato che si chiama .env (occhio… è scritto in UN*X-Style: è un file senza un nome e con estensione env; in un sistema UN*X sarebbe un file nascosto); viene caricato con l’istruzione:

load_dotenv()

Per amore di completezza riporto anche il file .env


TOKEN=<PUT-YOUR-HUGGINGFACE-TOKEN-HERE>

Ma GitHub?

Se qualcuno non avesse troppa voglia di fare copia&incolla del codice? Ho provveduto ad un repo su GitHub da cui clonare il tutto: https://github.com/senzanome75/Chatbot-Gradio-Google-Gemma-Hugging-Face.

Se avete installato il solo Git vI basterà un colpetto di: git clone https://github.com/senzanome75/Chatbot-Gradio-Google-Gemma-Hugging-Face.git altrimenti potreste utilizzare l’ottimo GitHub Desktop (o la sua controparte a linea di comando GitHub CLI) per clonare il repository.

Esplode tutto?

A questo punto, sempre dal terminale di VS Code e sempre con l’ambiente virtuale attivato (il venv di cui sopra), se non avete fatto errori, vi basterà scrivere: python main.py e andare all’indirizzo http://127.0.0.1:7860 (indirizzo che viene comunque scritto nel Terminale di VS Code) per iniziare a chattare con il vostro Chatbot.

Conclusioni

Che dire: spero che anche voi vi divertiate come mi sono divertito io a fare funzionare il tutto 🙂

Certo serve un buon hardware, una scheda grafica NVIDIA “sostenuta” (utilizziamo le CUDA, ma è possibile modificare il codice per utilizzare la CPU invece della GPU) e un po’ di pazienza per scaricare il modello, le dipendenze, etc. ma penso possa valerne la pena considerando che poi, si ottiene un Chatbot a costo zero.

Vi invito a provare e a commentare (specie se avete dei problemi, così vediamo di risolverli 🙂 ).


Commenti

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.