Ajuste un modelo Granite en Python usando watsonx

Autor

Anna Gutowska

AI Engineer, Developer Advocate

IBM

¿Qué es el ajuste de instrucciones?

En este tutorial, ajustaremos un modelo IBM® Granite mediante un conjunto de datos sintéticos que contiene reseñas de clientes de una empresa de peluquería canina.

El ajuste de instrucciones es una forma eficiente y económica de adaptar un modelo fundacional de inteligencia artificial (IA) a nuevas tareas posteriores sin volver a entrenar todo el modelo y actualizar sus ponderaciones.

Descripción general de la optimización de LLM

Los modelos fundacionales se basan en modelos de lenguaje de gran tamaño (LLM) y reciben grandes cantidades de datos de entrenamiento. Los casos de uso comunes de los modelos fundacionales son los chatbots y los asistentes virtuales.

Hay varias formas de mejorar la interpretación de la entrada de un modelo fundacional y la calidad de sus respuestas. Para comprender mejor estos matices, comparemos algunos de los métodos.

  • Prompt engineering es la optimización de las respuestas de un modelo preentrenado proporcionando una instrucción bien diseñada. No se introducen nuevos datos con esta técnica y el modelo permanece tal cual. Con este método, el modelo recibe una entrada y una instrucción diseñada delante de ella. Por ejemplo, puede utilizar la instrucción: "Traducir de inglés a español", con la entrada "Buenos días". Este método requiere más trabajo por parte del usuario. Sin embargo, este esfuerzo humano manual para formular instrucciones efectivas ayuda a los modelos de IA generativa a producir respuestas específicas para tareas sin volver a entrenar todo el modelo fundacional.
  • La afinación  de modelos de lenguaje de gran tamaño implica ajustar el mismo modelo proporcionando un gran número de conjuntos de datos etiquetados. La afinación altera las ponderaciones del modelo y se vuelve difícil de gestionar a medida que se diversifican las tareas. Esto requiere una cantidad significativa de recursos computacionales. A su vez, este método tiende a tener la mejor precisión, ya que el modelo puede entrenarse para casos de uso muy específicos.
  • A diferencia de la afinación, el ajuste de instrucciones no altera las ponderaciones preentrenadas del modelo. En cambio, esta técnica es eficiente en cuanto a parámetros al ajustar los parámetros de instrucción para guiar las respuestas del modelo en la dirección preferida. El modelo cuenta con una entrada y una instrucción ajustable generada por la propia IA. Este contexto específico de la tarea guía al modelo masivo para adaptar sus respuestas a una tarea específica, incluso con datos limitados.
  • De forma similar al ajuste de instrucciones, el ajuste de prefijosimplica que el modelo reciba varios ejemplos de resultados preferidos. La diferencia aquí es que también se incluye un prefijo, una serie de vectores específicos de la tarea. El ajuste de prefijos implica tanto instrucciones suaves como instrucciones inyectadas en capas del modelo de deep learning. Estos llamados "tokens" permiten al modelo ajustado la flexibilidad necesaria para admitir una variedad de tareas nuevas a la vez. Este método logra un rendimiento similar al ajuste fino de todas las capas y solo entrena alrededor del 0,1 % de los parámetros. El ajuste de prefijos supera incluso a la afinación en entornos con pocos datos.

Instrucciones suaves versus instrucciones estrictas

Las instrucciones estrictas están orientadas al usuario y requieren la acción del usuario. Una instrucción estricta puede considerarse como una plantilla o instrucciones para que el LLM genere respuestas. A continuación se presenta un ejemplo de una instrucción estricta. Le recomendamos que consulte la página de documentación de IBM para obtener más información sobre este tipo de instrucción y otras muchas.

###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:
"""

Con esta plantilla de instrucciones, se puede proporcionar a un LLM instrucciones específicas sobre la estructura y el estilo de resultado preferidos. A través de esta instrucción explícita, el LLM tendría más probabilidades de producir respuestas deseables de mayor calidad.

Las instrucciones suaves, a diferencia de las instrucciones estrictas, no están escritas en lenguaje natural. En su lugar, las instrucciones se inicializan como vectores numéricos generados por IA que se añaden al inicio de cada embedding de entrada que destila conocimiento del modelo más grande. Esta falta de interpretabilidad se extiende a la IA que elige instrucciones optimizadas para una tarea determinada. A menudo, la IA no puede explicar por qué eligió esas incrustaciones. En comparación con otros métodos de prompting, estos tokens son menos costosos desde el punto de vista informático que la afinación, ya que el propio modelo permanece congelado con ponderaciones fijas. Las instrucciones suaves también tienden a superar a las instrucciones duras creadas por humanos.

En este tutorial trabajaremos con instrucciones suaves para ajustar las instrucciones.

Requisitos previos

Necesita una cuenta de IBM® Cloud para crear un proyecto watsonx.ai .

Pasos

Paso 1. Configure su entorno

Aunque puede elegir entre varias herramientas, este tutorial le muestra cómo configurar una cuenta de IBM para utilizar un Jupyter Notebook.

  1. Inicie sesión en watsonx.ai utilizando su cuenta de IBM Cloud.

  2. Cree un proyecto watsonx.ai.

    Puede obtener el ID de su proyecto desde dentro del propio proyecto. Haga clic en la pestaña Administrar. A continuación, copie el ID del proyecto de la sección Detalles de la página General. Necesita este ID para este tutorial.

  3. Cree un Jupyter Notebook.

    Este paso abrirá un entorno de Notebook donde podrá copiar el código de este tutorial para implementar el ajuste de instrucciones por su cuenta. También puede descargar este notebook en su sistema local y subirlo a su proyecto watsonx.ai como activo. Este Jupyter Notebook junto con los conjuntos de datos utilizados se pueden encontrar en GitHub.

Paso 2. Configure una instancia de watsonx.ai de tiempo de ejecución y una clave de API

  1. Cree una instancia de servicio de watsonx.ai Runtime (seleccione la región adecuada y elija el plan Lite, que es una instancia sin coste).

  2. Genere una clave API.

  3. Asocie la instancia del servicio watsonx.ai Runtime al proyecto que ha creado en watsonx.ai.

Paso 3. Instale e importe las bibliotecas relevantes y configure sus credenciales

Necesitaremos algunas bibliotecas y módulos para este tutorial. Asegúrese de importar los siguientes; si no están instalados, puede resolverlo con una instalación rápida de 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

Configure sus credenciales. Introduzca su clave API y el ID del proyecto.

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

project_id = "YOUR_PROJECT_ID_HERE"

Paso 4. Establezca el entorno e importe el conjunto de datos

Como primer paso para establecer el entorno, cree una instancia de APIClient con sus detalles de autenticación y establezca su project_id .

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

Resultado

"ÉXITO"

Para este tutorial, utilizaremos un conjunto de datos sintéticos que consiste en reseñas de empresas de peluquería canina. Mediante el uso de la URL adecuada, podemos conectar el conjunto de datos al cliente API.

Puede utilizar cualquier conjunto de datos de su elección. Varios conjuntos de datos de código abierto están disponibles en plataformas como 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)

Resultado:

Creando activo de datos...

ÉXITO

print(asset_id)

Resultado

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

Para obtener conocimiento sobre el formato de estas reseñas de clientes, carguemos los datos en un marco de datos de Pandas e imprimamos algunas filas que muestren reseñas tanto positivas como negativas. Un resultado de "1" denota reseñas positivas y "0" se utiliza para reseñas negativas.

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

Resultado:

captura de pantalla de un conjunto de datos de entrenamiento con ejemplos de comentarios y valores asociados 1 y 0, siendo 1 un comentario positivo y 0 uno negativo Conjunto de datos de entrenamiento

Paso 5. Ajuste el modelo.

La clase TuneExperiment se utiliza para crear experimentos y programar ajustes. Usémoslo para inicializar nuestro experimento y establecer nuestro modelo fundacional, datos de entrenamiento y parámetros. El objetivo de este ejercicio de ajuste de instrucciones es que el LLM adapte sus respuestas de acuerdo con las calificaciones de satisfacción del cliente extraídas de nuestro conjunto de datos. Se trata de una tarea de clasificación, ya que las reseñas pueden clasificarse como positivas ("1") o negativas ("0").

Para este tutorial, sugerimos utilizar un modelo de IBM® Granite como modelo de lenguaje de gran tamaño para lograr resultados similares.

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
)

Ahora que tenemos configurado nuestro experimento de ajuste, necesitamos conectarlo a nuestro conjunto de datos. Para esto, usemos la clase DataConnection . Esto requiere el asset_id que producimos anteriormente al iniciar el activo de datos con nuestro cliente API.

data_conn = DataConnection(data_asset_id=asset_id)

Puede utilizar cualquier modelo de IA de su elección. Los modelos fundacionales disponibles para ajustar a través de watsonx se pueden encontrar aquí o ejecutando el siguiente comando.

client.foundation_models.PromptTunableModels.show()

Resultado:

{'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)

Resultado:

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

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

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


pending......
running....................................................................................................................................
completed
Training of '20671f17-ff53-470b-9bfe-04318ecb91d9' finished successfully.

Paso 6. Evalúe los resultados del ajuste.

Para asegurarnos de que nuestra instrucción ha concluido, podemos comprobar el estado. Si el estado que se imprime no es "completado", espere a que finalice el ajuste antes de continuar.

status = prompt_tuner.get_run_status()
print(status)

Resultado

completado

Ahora podemos recuperar el resumen de instrucción. En este resumen, verá un valor de pérdida. Para cada ejecución de entrenamiento, la función de pérdida mide la diferencia entre los resultados previstos y los reales. Por lo tanto, se prefiere un valor de pérdida más bajo.

prompt_tuner.summary()

También podemos trazar la curva de aprendizaje del ajuste de nuestro modelo utilizando la función plot_learning_curve() . Una curva con pendiente negativa que se nivela cerca de cero indica que el modelo está mejorando su generación de resultado esperada. Para obtener más información sobre la interpretación de los gráficos de función de pérdida, consulte la documentación relevante de IBM watsonx.

prompt_tuner.plot_learning_curve()

Resultado:

Gráficos de curvas de aprendizaje Gráficos de curvas de aprendizaje

Paso 7. Implemente el modelo ajustado.

Este paso de implementar el modelo ajustado es crítico para completar el siguiente paso de comparar el rendimiento del modelo ajustado con el modelo preajustado.

Nota: SERVING_NAME se establece en la fecha y hora actuales, ya que debe ser un valor único.

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)

Resultado

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

Synchronous deployment creation for id: '6aa5dd5c-0cc4-44e0-9730-18303e88e14a' started

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


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

-----------------------------------------------------------------------------------------------
Successfully finished deployment creation, deployment_id='24a97b84-47d0-4490-9f5f-21ed2376fdd6'
-----------------------------------------------------------------------------------------------

Paso 8. Pruebe el modelo ajustado.

Ahora, probemos el rendimiento tanto del modelo ajustado como del modelo fundacional original para ver los impactos de nuestro proceso de ajuste. Primero, carguemos el conjunto de datos de prueba. Este conjunto de datos debe ser un subconjunto de datos que no estaba presente durante el ajuste. A menudo, el conjunto de prueba también es más pequeño que el conjunto de entrenamiento. Además, cada entrada del conjunto de datos tiene la instrucción como prefijo del comentario del usuario.

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)

Vamos a mostrar una pequeña parte del conjunto de datos para comprender mejor su estructura.

data.head()

Resultado:

captura de pantalla de un conjunto de datos de entrenamiento con ejemplos de comentarios y valores asociados 1 y 0, siendo 1 un comentario positivo y 0 uno negativo Conjunto de datos de prueba

Al cargar el conjunto de datos, extraigamos las entradas y los resultados.

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

También podemos imprimir una entrada de muestra y un resultado de muestra para comprender mejor cómo hemos extraído el contenido del conjunto de datos.

prompts[0]

Resultado:

"Extrae la satisfacción del comentario. Devuelve 1 simple para un cliente satisfecho o 0 para un cliente insatisfecho.\n Comentario: Largos tiempos de espera.\n Satisfacción:\n'

En este ejemplo, se introduce la instrucción, seguida de la reseña del cliente sobre los largos tiempos de espera y, por último, la satisfacción es 0 para indicar una opinión negativa.

satisfaction[0]

Resultado

0

Ahora que tenemos el conjunto de datos de prueba, probemos la precisión y la puntuación F1 de nuestro modelo ajustado. La puntuación F1 es la media de la precisión y la recuperación del modelo. Necesitaremos el deployment_id para hacer esto. Tenga en cuenta que concurrency_limit se establece en 2 para evitar alcanzar el límite de velocidad de la API. Este es el número de solicitudes que se enviarán en paralelo.

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])}')

Resultado:

accuracy_score: 0.9827586206896551, f1_score: 0.9827586206896551

Dada la alta precisión de nuestro modelo y la puntuación F1, probemos el rendimiento del mismo modelo Granite sin ningún ajuste.

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])}')

Resultado:

base model accuracy_score: 0.9310344827586207, base model f1_score: 0.9298245614035088

Nuestro modelo ajustado supera al modelo fundacional preajustado. Dado que el modelo ajustado se especializa en extraer puntuaciones de satisfacción, puede utilizarse para otras tareas de extracción de satisfacción. ¡Buen trabajo!

Resumen

En este tutorial, ha realizado un ajuste de instrucciones en un modelo de IBM Granite utilizando la API de watsonx. Su modelo ajustado e implementado superó con éxito al modelo fundacional con una precisión aproximadamente un 5 % mayor.

Soluciones relacionadas
IBM watsonx.ai

Entrene, valide, ajuste e implemente IA generativa, modelos fundacionales y capacidades de machine learning con IBM watsonx.ai, un estudio empresarial de nueva generación para desarrolladores de IA. Cree aplicaciones de IA en menos tiempo y con menos datos.

Explore watsonx.ai
Soluciones de inteligencia artificial

Ponga la IA al servicio de su negocio con la experiencia líder del sector y el portfolio de soluciones de IA de IBM.

Explore las soluciones de IA
Servicios y consultoría de inteligencia artificial (IA)

Los servicios de IA de IBM Consulting ayudan a reinventar la forma de trabajar de las empresas usando IA para la transformación.

Explore los servicios de IA
Dé el siguiente paso

Gracias a la IA, IBM Concert descubre información crucial sobre sus operaciones y ofrece recomendaciones de mejora personalizadas para cada aplicación. Descubra cómo Concert puede hacer avanzar su negocio.

Explorar el concierto Explore las soluciones de automatización de procesos empresariales