Metti a punto i prompt del modello Granite in Python utilizzando watsonx

Autore

Anna Gutowska

AI Engineer, Developer Advocate

IBM

Che cos'è il prompt tuning?

In questo tutorial, effettueremo il prompt tune di un modello IBM® Granite utilizzando un set di dati sintetico contenente recensioni dei clienti su un'azienda di toelettatura per cani.

Il prompt tuning è un modo efficiente ed economico per adattare un foundation model di intelligenza artificiale (AI) a nuove attività a valle senza riqualificare l'intero modello e aggiornarne i pesi.

Panoramica dell'ottimizzazione LLM

I foundation model sono basati su modelli linguistici di grandi dimensioni (LLM) e ricevono grandi quantità di dati di addestramento. I casi d'uso più comuni dei foundation model sono i chatbot e gli assistenti virtuali.

Esistono diversi modi per migliorare l'interpretazione dell'input e la qualità delle risposte da parte di un foundation model. Per comprendere meglio queste sfumature, confrontiamo alcuni metodi.

  • Il prompt engineering è l'ottimizzazione delle risposte di un modello preaddestrato fornendo un prompt ben progettato. Non vengono introdotti nuovi dati utilizzando questa tecnica e il modello rimane così com'è. Utilizzando questo metodo, il modello riceve un input e un prompt ingegnerizzato davanti ad esso. Ad esempio, può utilizzare il prompt: "traduci dall'inglese allo spagnolo" con l'input: "buongiorno." Questo metodo richiede più lavoro da parte dell'utente, ma questo sforzo manuale per formulare suggerimenti efficaci aiuta i modelli di AI generativa a produrre risposte specifiche per le attività senza riqualificare l'intero foundation model.
  • L'ottimizzazione dei modelli linguistici di grandi dimensioni comporta l'ottimizzazione dello stesso modello fornendo un numero elevato di set di dati etichettati. La messa a punto altera i pesi del modello e diventa difficile da gestire man mano che le attività si diversificano, richiedendo una notevole quantità di risorse di calcolo. A sua volta, questo metodo tende ad avere la migliore accuratezza poiché può essere addestrato per casi d'uso molto specifici.
  • A differenza dell'ottimizzazione,  il tuning dei prompt  non modifica i pesi del modello pre-addestrato. Al contrario, questa tecnica è efficiente in termini di parametri, dato che regola i parametri dei prompt per guidare le risposte del modello nella direzione preferita. Il modello è dotato di input e soft prompt regolabili generati dall'AI stessa. Questo contesto specifico dell'attività guida il modello di massa ad adattare le sue risposte a un'attività ristretta anche con dati limitati.
  • Analogamente al prompt tuning, il prefix-tuning comporta che il modello riceva diversi esempi di output preferito. La differenza in questo caso è che viene incluso anche un prefisso, cioè una serie di vettori specifici per il compito. Il prefix-tuning coinvolge sia i soft prompt che i prompt inseriti nei livelli del modello di deep learning. Questi cosiddetti "token virtuali" danno al modello ottimizzato la flessibilità necessaria per supportare diverse nuove attività contemporaneamente. Questo metodo raggiunge prestazioni simili alla messa a punto di tutti i livelli e addestra solo lo 0,1% dei parametri circa. Il prefix-tuning è addirittura più efficace della messa a punto in contesti con pochi dati.

Soft prompt e hard prompt

Gli hard prompt sono rivolti all'utente e richiedono un'azione da parte sua. Un hard prompt può essere pensato come un modello o come le istruzioni per l'LLM al fine di generare risposte. Di seguito viene presentato un esempio di hard prompt. Ti invitiamo a consultare la pagina della documentazione IBM per maggiori informazioni su questo tipo di prompt e su molti altri.

###For demonstration purposes only. It is not necessary to run this code block.
hard_prompt_template = """Generate a summary of the context that answers the question. Explain the answer in multiple steps if possible.
Answer style should match the context. Ideal Answer length is 2-3 sentences.\n\n{context}\nQuestion: {question}\nAnswer:
"""

Utilizzando questo modello di hard prompt, è possibile fornire a un LLM istruzioni specifiche sulla struttura e sullo stile degli output preferiti. Attraverso questo prompt esplicito, l'LLM avrebbe maggiori probabilità di produrre risposte desiderabili di qualità superiore.

I soft prompt, a differenza degli hard prompt, non sono scritti in linguaggio naturale. In questo caso, i prompt vengono inizializzati come vettori numerici generati dall'AI aggiunti all'inizio di ogni embedding di input che estrae la conoscenza dal modello più ampio. Questa mancanza di interpretabilità si estende all'AI che sceglie prompt ottimizzati per una determinata attività. Spesso l'AI non è in grado di spiegare perché ha scelto quegli embedding. Rispetto ad altri metodi di richiesta, questi token virtuali sono meno dispendiosi dal punto di vista computazionale rispetto alla messa a punto, poiché il modello stesso rimane bloccato con pesi fissi. I soft prompt tendono a superare anche i prompt rigidi progettati dall'uomo.

In questo tutorial lavoreremo con i soft prompt per il tuning dei prompt.

Prerequisiti

Per creare un progetto watsonx.ai è necessario un account IBM Cloud .

Passaggi

Passaggio 1: configura il tuo ambiente

Sebbene sia possibile scegliere tra diversi strumenti, questo tutorial illustra come configurare un account IBM per l'utilizzo di un Jupyter Notebook.

  1. Accedi a watsonx.ai usando il tuo account IBM Cloud.

  2. Crea un progetto watsonx.ai.

    Puoi ottenere l'ID del tuo progetto dall'interno del tuo progetto. Clicca sulla scheda Gestisci. Quindi, copia l'ID del progetto dalla sezione Dettagli della pagina Generali. Per questo tutorial ti serve questo ID.

  3. Crea un Jupyter Notebook.

    Questo passaggio aprirà un ambiente Notebook in cui potrai copiare il codice da questo tutorial per implementare autonomamente il tuning del prompt. In alternativa, puoi scaricare questo notebook sul tuo sistema locale e caricarlo nel tuo progetto watsonx.ai come asset. Questo Jupyter Notebook, insieme ai set di dati utilizzati, è disponibile su GitHub.

Passaggio 2: configura un'istanza di runtime di watsonx.ai e una chiave API

  1. Crea un'istanza di servizio watsonx.ai Runtime (seleziona l'area geografica appropriata e scegli il piano Lite, che è un'istanza gratuita).

  2. Genera una chiave API.

  3. Associa l'istanza del servizio watsonx.ai Runtime al progetto che hai creato in watsonx.ai.

Passaggio 3. Installare e importare le librerie pertinenti e configurare le tue credenziali

Abbiamo bisogno di alcune librerie e moduli per questo tutorial. Assicurati di importare le seguenti e, se non sono installate, puoi risolvere il problema con una rapida installazione pip.

#installations
%pip install ibm-watsonx-ai | tail -n 1
%pip install pandas | tail -n 1
%pip install wget | tail -n 1
%pip install scikit-learn | tail -n 1
%pip install matplotlib | tail -n 1 #imports
import wget
import pandas as pd

from ibm_watsonx_ai import APIClient
from ibm_watsonx_ai.foundation_models.utils.enums import ModelTypes
from ibm_watsonx_ai.experiment import TuneExperiment
from ibm_watsonx_ai.helpers import DataConnection
from ibm_watsonx_ai.foundation_models import ModelInference
from sklearn.metrics import accuracy_score, f1_score
from datetime import datetime

Configura le tue credenziali. Inserisci la tua chiave API e l'ID del progetto.

credentials = {
    "url": "https://us-south.ml.cloud.ibm.com",
    "apikey": "YOUR_API_KEY_HERE"
}

project_id = "YOUR_PROJECT_ID_HERE"

Passaggio 4: stabilisci l'ambiente e importa il set di dati

Come primo passo per stabilire l'ambiente, crea un'istanza di APIClient con i suoi dati di autenticazione e imposti il suo project_id.

client = APIClient(credentials)
client.set.default_project(project_id)

Output

'SUCCESS'

Per questo tutorial utilizzeremo un set di dati sintetico costituito da recensioni di attività di toelettatura per cani. Utilizzando l'URL appropriato, possiamo collegare il set di dati al client API.

Puoi utilizzare qualsiasi set di dati tu preferisca. Diversi set di dati open source sono disponibili su piattaforme come HuggingFace.

train_filename = 'dog_grooming_reviews_train_data.json'

url = "https://raw.githubusercontent.com/AnnaGutowska/think/main/tutorials/prompt-tuning-tutorial/" + train_filename
wget.download(url)

asset_details = client.data_assets.create(name=train_filename, file_path=train_filename)
asset_id = client.data_assets.get_id(asset_details)

Output

Creazione degli asset di dati...

SUCCESS

print(asset_id)

Output

3b1db894-8d9e-428d-8fee-d96f328c7726

Per ottenere degli insight nella formattazione di queste recensioni dei clienti, carichiamo i dati in un dataframe Pandas e stampiamo alcune righe che mostrano sia le recensioni positive che quelle negative. Un output di "1" indica recensioni positive mentre "0" viene utilizzato per recensioni negative.

pd.set_option('display.max_colwidth', None)
df = pd.read_json(train_filename)
df[5:10]

Output

schermata di un set di dati di addestramento con esempi di commenti e valori associati 1 e 0, di cui 1 un commento positivo e 0 un commento negativo Set di dati di addestramento

Passaggio 5. Adattare il modello.

La classe TuneExperiment viene utilizzata per creare esperimenti e pianificare il tuning. Usiamola per inizializzare il nostro esperimento e impostare il nostro foundation model, i dati di addestramento e i parametri. L'obiettivo di questo rapido esercizio di tuning del prompt è che l'LLM personalizzi le sue risposte in base alle valutazioni di soddisfazione dei clienti estratte dal nostro set di dati. Si tratta di un'attività di classificazione, poiché le recensioni possono essere classificate come positive ("1") o negative ("0").

Per questo tutorial, suggeriamo di utilizzare un modello IBM® Granite come modello linguistico di grandi dimensioni per ottenere risultati simili.

experiment = TuneExperiment(credentials,
    project_id=project_id
)

prompt_tuner = experiment.prompt_tuner(name="prompt tuning tutorial",
    task_id=experiment.Tasks.CLASSIFICATION,
    base_model="ibm/granite-3-8b-instruct",
    accumulate_steps=16,
    batch_size=8,
    learning_rate=0.001,
    max_input_tokens=128,
    max_output_tokens=2,
    num_epochs=12,
    tuning_type=experiment.PromptTuningTypes.PT,
    init_text="Extract the satisfaction from the comment. Return simple '1' for satisfied customer or '0' for unsatisfied. Comment:",
    init_method="text",
    verbalizer="classify {0, 1} {{input}}",
    auto_update_model=True
)

Ora che abbiamo impostato il nostro esperimento di ottimizzazione, dobbiamo collegarlo al nostro set di dati. Per farlo, utilizziamo la classe DataConnection. Ciò richiede l'asset_id prodotto in precedenza all'avvio dell'asset di dati con il nostro client API.

data_conn = DataConnection(data_asset_id=asset_id)

Puoi utilizzare il modello AI che preferisci. I foundation model disponibili per l'adattamento tramite watsonx possono essere trovati qui o eseguendo il seguente comando.

client.foundation_models.PromptTunableModels.show()

Output

{'FLAN_T5_XL': 'google/flan-t5-xl', 'GRANITE_13B_INSTRUCT_V2': 'ibm/granite-13b-instruct-v2', 'LLAMA_2_13B_CHAT': 'meta-llama/llama-2-13b-chat'}

tuning_details = prompt_tuner.run(
    training_data_references=[data_conn],
    background_mode=False)

Output

##############################################

Running '20671f17-ff53-470b-9bfe-04318ecb91d9'

##############################################


pending......
running....................................................................................................................................
completed
Addestramento di '20671f17-ff53-470b-9bfe-04318ecb91d9' completato con successo.

Passaggio 6. Valutare i risultati dell'ottimizzazione.

Per assicurarci che la nostra messa a punto dei prompt sia terminata, possiamo controllarne lo stato. Se lo stato stampato è diverso da "completato", attendi che la messa a punto sia terminata prima di continuare.

status = prompt_tuner.get_run_status()
print(status)

Output

completato

Ora possiamo recuperare il riepilogo della messa a punto del prompt. In questo riepilogo vedrai un valore di perdita. Per ogni sessione di addestramento, la funzione di perdita misura la differenza tra i risultati previsti e quelli effettivi. Pertanto, è preferibile un valore di perdita inferiore.

prompt_tuner.summary()

Possiamo anche tracciare la curva di apprendimento del nostro modello di messa a punto utilizzando la funzione plot_learning_curve(). Una curva verso il basso che si livella vicino allo zero indica che il modello sta migliorando la generazione di output prevista. Per saperne di più sull'interpretazione dei grafici delle funzioni di perdita, consulta la documentazione pertinente di IBM® watsonx.

prompt_tuner.plot_learning_curve()

Output

Grafici della curva di apprendimento Grafici della curva di apprendimento

Passaggio 7. Implementare il modello ottimizzato.

Questa fase di implementazione del modello messo a punto è critica per completare i passaggi successivi di confronto delle prestazioni del modello messo a punto con quello pre-ottimizzato.

Nota: il SERVING_NAME è impostato sulla data e l'ora correnti, poiché deve essere un valore univoco.

model_id = prompt_tuner.get_model_id()

meta_props = {
    client.deployments.ConfigurationMetaNames.NAME: "PROMP TUNE DEPLOYMENT",
    client.deployments.ConfigurationMetaNames.ONLINE: {},
    client.deployments.ConfigurationMetaNames.SERVING_NAME : datetime.now().strftime('%Y_%m_%d_%H%M%S')
}

deployment_details = client.deployments.create(model_id, meta_props)

Output

######################################################################################

Creazione dell'implementazione sincrona per l'id: '6aa5dd5c-0cc4-44e0-9730-18303e88e14a' started

######################################################################################


initializing.......................
ready

-----------------------------------------------------------------------------------------------
Creazione dell'implementazione conclusa con successo, deployment_id='24a97b84-47d0-4490-9f5f-21ed2376fdd6'
-----------------------------------------------------------------------------------------------

Passaggio 8: testa il modello messo a punto.

Ora, testiamo le prestazioni sia del modello messo a punto che del foundation model originale per vedere l'impatto del nostro processo di tuning. Innanzitutto, carichiamo il set di dati di test. Questo set di dati dovrebbe essere un sottoinsieme di dati che non erano presenti durante l'ottimizzazione. Spesso, il set di test è anche più piccolo del set di addestramento. Inoltre, ogni input nel set di dati di test ha il prompt come prefisso del commento dell'utente.

test_filename = 'dog_grooming_reviews_test_data.json'
url = "https://raw.githubusercontent.com/AnnaGutowska/think/main/tutorials/prompt-tuning-tutorial/" + test_filename
wget.download(url)
data = pd.read_json(test_filename)

Ecco una piccola parte del set di dati per comprenderne meglio la struttura.

data.head()

Output

schermata di un set di dati di addestramento con esempi di commenti e valori associati 1 e 0, di cui 1 un commento positivo e 0 un commento negativo Set di dati di prova

Dopo aver caricato il set di dati di prova, estraiamo gli input e gli output.

prompts = list(data.input)
satisfaction = list(data.output)
prompts_batch = ["\n".join([prompt]) for prompt in prompts]

Possiamo anche stampare un esempio di input e output di test per capire meglio come abbiamo estratto il contenuto del set di dati.

prompts[0]

Output

'Extract the satisfaction from the comment. Return simple 1 for satisfied customer or 0 for unsatisfied.\nComment: Long wait times.\nSatisfaction:\n'

In questo esempio, viene introdotto il prompt, seguito dalla recensione del cliente sui lunghi tempi di attesa e infine una soddisfazione pari a 0, a indicare una recensione negativa.

satisfaction[0]

Output

0

Ora che abbiamo il set di dati di test, testiamo la precisione e il punteggio F1 del nostro modello ottimizzato. Il punteggio F1 è la media della precisione e del richiamo del modello. Per fare ciò avremo bisogno di deployment_id. Tieni presente che il concurrency_limit è impostato su 2 per evitare di raggiungere il limite di velocità dell'API. Questo è il numero di richieste che verranno inviate in parallelo.

deployment_id = deployment_details['metadata']['id']

tuned_model = ModelInference(
    deployment_id=deployment_id,
    api_client=client
)

tuned_model_results = tuned_model.generate_text(prompt=prompts_batch, concurrency_limit=2)
print(f'accuracy_score: {accuracy_score(satisfaction, [int(float(x)) for x in tuned_model_results])}, f1_score: {f1_score(satisfaction, [int(float(x)) for x in tuned_model_results])}')

Output

accuracy_score: 0.9827586206896551, f1_score: 0.9827586206896551

Data l'elevata precisione e il punteggio F1 del nostro modello, testiamo le prestazioni dello stesso modello Granite senza alcuna messa a punto.

base_model = ModelInference(
    model_id="ibm/granite-3-8b-instruct",
    api_client=client
)

base_model_results = base_model.generate_text(prompt=prompts_batch, concurrency_limit=2)

print(f'base model accuracy_score: {accuracy_score(satisfaction, [int(x) for x in base_model_results])}, base model f1_score: {f1_score(satisfaction, [int(x) for x in base_model_results])}')

Output

base model accuracy_score: 0.9310344827586207, base model f1_score: 0.9298245614035088

Il nostro modello con messa a punto supera le prestazioni del foundation model pre-ottimizzato. Poiché il modello con messa a punto è specializzato nell'estrazione dei punteggi di soddisfazione, può essere utilizzato per altri compiti uguali. Ottimo lavoro!

Riepilogo

In questo tutorial, hai eseguito il tuning dei prompt su un modello IBM Granite utilizzando l'API watsonx. Il modello ottimizzato e distribuito ha superato con successo il foundation model con una precisione superiore di circa il 5%.

Soluzioni correlate
IBM® watsonx.ai

Addestra, convalida, adatta e implementa le funzionalità di AI generativa, foundation model e machine learning con IBM watsonx.ai, uno studio aziendale di nuova generazione per builder AI. Crea applicazioni AI in tempi ridotti e una minima quantità di dati.

Esplora watsonx.ai
Soluzioni di intelligenza artificiale

Metti l'AI al servizio della tua azienda con l'esperienza leader di settore e il portfolio di soluzioni di IBM nel campo dell'AI.

Esplora le soluzioni AI
Consulenza e servizi per l'intelligenza artificiale (AI)

I servizi di AI di IBM Consulting aiutano a reinventare il modo in cui le aziende lavorano con l'AI per la trasformazione.

Esplora i servizi AI
Prossimi passi

Attraverso l'AI, IBM Concert scopre insight di importanza chiave sulle operazioni e fornisce raccomandazioni specifiche per migliorare le applicazioni. Scopri come Concert può migliorare il tuo business.

Esplora Concert Esplora le soluzioni di automazione dei processi aziendali