La personalización de los LLM se puede lograr de diferentes maneras: desde la creación cuidadosa de prompts y la gestión del contexto hasta el fine-tuning con tus propios conjuntos de datos. El fine-tuning permite consolidar el estilo, la terminología y el formato de las respuestas, además de mejorar la precisión en tareas específicas de un dominio. Sin embargo, este enfoque tiene límites y requiere datos de alta calidad; de lo contrario, los resultados pueden ser peores que con el modelo base.
1. Cómo LLM «recuerda» y «se adapta»: La ilusión del contexto
Antes de hablar sobre el ajuste fino, es importante entender cómo LLM logra crear una sensación de personalización.
Esto es importante para no apresurarse a un ajuste fino costoso si la tarea se puede resolver con métodos más simples:
- A través de la Ventana de Contexto (Memoria a Corto Plazo): Dentro de un solo diálogo, envías al modelo no solo una nueva pregunta, sino también toda o parte de la correspondencia anterior. El modelo procesa todo este texto como un único «contexto». Es gracias a esto que «recuerda» las observaciones anteriores y continúa el pensamiento. La limitación aquí es la longitud de la ventana de contexto (número de tokens).
- Componiendo Instrucciones del Sistema (System Prompt): Puedes establecer el rol, el tono y las reglas de comportamiento del modelo al comienzo de cada diálogo. Por ejemplo: «Eres un experto en Python, responde brevemente».
- Incluyendo varios ejemplos del comportamiento deseado en la solicitud Aprendizaje de Pocos Disparos (Few-Shot Learning): (pares de entrada/salida) permite que el modelo «aprenda» este patrón directamente dentro de la solicitud actual.
- Gestión de estado del lado de la aplicación: La forma más poderosa. La aplicación (que accede a la API) puede almacenar información del usuario (preferencias, historial, datos de perfil) y agregarla dinámicamente al prompt antes de enviarla al modelo.
2. Por qué y cuándo es necesario el ajuste fino (Fine-tuning) de un modelo.
El ajuste fino es el proceso de entrenar aún más un LLM base ya preparado en tu propio conjunto de datos específico. Esto permite que el modelo:
- Adapte el estilo y el tono: El modelo hablará «tu idioma», ya sea científico estricto, marketing amigable o la jerga de una comunidad específica.
- Siga instrucciones y formatos específicos: Si necesitas respuestas en una estructura JSON estrictamente definida, o siempre con un conjunto específico de campos.
- Comprenda el lenguaje específico del dominio: El entrenamiento con tu documentación interna o textos de la industria ayudará al modelo a manejar mejor la terminología de tu nicho.
- Mejore el rendimiento en tareas específicas: Para ciertos tipos de consultas (por ejemplo, clasificación de sentimientos, generación de código en un marco específico), el ajuste fino puede proporcionar respuestas más precisas y relevantes que el modelo base.
- Reduzca la longitud de los prompts: Si el modelo ya «conoce» el comportamiento deseado gracias al ajuste, no necesitas recordárselo cada vez en el prompt, lo que ahorra tokens y reduce la latencia.
3. Cuándo el ajuste fino no es la mejor solución.
El ajuste fino es una herramienta poderosa pero no universal. No debes usarla si:
- El modelo necesita acceder a nuevos conocimientos: El ajuste fino cambia los pesos del modelo, pero no «carga» nuevos hechos en él en tiempo real. Si tu tarea es responder preguntas basadas en una base de conocimientos en constante cambio (documentos de la empresa, últimas noticias), es mejor usar Generación Aumentada por Recuperación (RAG). Aquí, el modelo base obtiene el contexto de tu base de datos durante la ejecución de la consulta.
- Una tarea simple se puede resolver con ingeniería de prompts: Siempre comienza con la ingeniería de prompts más efectiva. Si la tarea se puede resolver con instrucciones simples y ejemplos de pocos disparos, el ajuste fino es redundante y más costoso.
- No tienes suficientes datos de alta calidad: Datos malos = modelo mal ajustado.
4. Preparación de datos.
La calidad y cantidad de tus datos son de vital importancia. El modelo aprende de tus ejemplos, por lo que deben ser precisos, diversos y consistentes.
- Formato: La mayoría de las veces JSON Lines (
.jsonl) o CSV (.csv). - Estructura de datos: Depende de la tarea.
- Ajuste de Instrucciones (Instruction Tuning – Instrucción-Respuesta): Adecuado para tareas generalizadas como preguntas y respuestas, reformulación, resumen.
json{"input_text": "Reformula la frase: 'La tecnología de IA se está desarrollando rápidamente.'", "output_text": "La inteligencia artificial está demostrando un rápido progreso."}{"input_text": "Nombra la capital de Francia.", "output_text": "La capital de Francia es París."} - Ajuste de Chat (Chat Tuning – Chat): Ideal para entrenar al modelo para mantener un diálogo en un rol o estilo específico.
json{"messages": [
{"author": "user", "content": "¡Hola! ¿Qué me recomiendas para cenar?"},
{"author": "model", "content": "¡Buenas noches! Hoy es un gran día para pasta Carbonara, o, si prefieres algo ligero, ensalada César."}]}{"messages": [
{"author": "user", "content": "Háblame de las nuevas características de Python 3.12."},
{"author": "model", "content": "En Python 3.12 se introdujeron f-strings con sangría, nueva sintaxis para genéricos universales y un manejo mejorado de errores Unicode."}]}
- Ajuste de Instrucciones (Instruction Tuning – Instrucción-Respuesta): Adecuado para tareas generalizadas como preguntas y respuestas, reformulación, resumen.
- Cantidad: Mínimo 100-200 ejemplos de alta calidad, pero cuanto más, mejor (miles para tareas serias).
- Calidad: Precisión, consistencia de estilo, tono y formato en todo el conjunto de datos.
5. Modelos y plataformas
5.1. OpenAI
OpenAI proporciona una API bastante simple e intuitiva para el ajuste fino.
Proceso:
- Prepara los datos en formato JSONL, donde cada línea es un objeto con una matriz de
messages(como en la API de Chat Completions). - Sube el archivo de datos a través de la API.
- Crea un trabajo de ajuste fino, especificando el archivo subido y el modelo base.
- Supervisa el progreso.
- Usa el nuevo modelo ajustado por su ID.
Ejemplo de datos (archivo training_data.jsonl):
{"messages": [
{"role": "system", "content": "Eres un asistente amigable para el soporte al cliente de una empresa de TI."},
{"role": "user", "content": "Mi internet no funciona."},
{"role": "assistant", "content": "¡Oh, disculpe las molestias! Intentemos resolverlo. ¿Cómo está conectado a internet, por Wi-Fi o por cable?"}]}
{"messages": [
{"role": "system", "content": "Eres un asistente amigable para el soporte al cliente de una empresa de TI."},
{"role": "user", "content": "¿Cómo puedo restablecer mi contraseña?"},
{"role": "assistant", "content": "¡Claro! Para restablecer su contraseña, por favor, vaya a la página de inicio de sesión y haga clic en '¿Olvidó su contraseña?' debajo del campo de entrada. Luego siga las instrucciones en pantalla."}
]}
Ejemplo de código Python:
Instala previamente: pip install openai
import openai
from openai import OpenAI
import os
# Establece tu clave API de OpenAI. Se recomienda usar una variable de entorno.
# os.environ["OPENAI_API_KEY"] = "sk-..."
client = OpenAI()
# 1. Subir archivo de datos
try:
file_response = client.files.create(
file=open("training_data.jsonl", "rb"),
purpose="fine-tune"
)
file_id = file_response.id
print(f"Archivo subido exitosamente. ID del archivo: {file_id}")
except openai.APIStatusError as e:
print(f"Error al subir el archivo: {e.status_code} - {e.response}")
exit()
# 2. Crear trabajo de ajuste fino
try:
ft_job_response = client.fine_tuning.jobs.create(
training_file=file_id,
model="gpt-3.5-turbo" # Puedes especificar una versión específica, por ejemplo, "gpt-3.5-turbo-0125"
)
job_id = ft_job_response.id
print(f"Trabajo de ajuste fino creado. ID del trabajo: {job_id}")
print("Supervisa el estado del trabajo a través de la API o en OpenAI Playground.")
except openai.APIStatusError as e:
print(f"Error al crear el trabajo: {e.status_code} - {e.response}")
exit()
# Ejemplo de supervisión de estado y obtención del nombre del modelo (ejecutar después de la creación del trabajo):
# # job_id = "ftjob-..." # Reemplaza con el ID de tu trabajo
# # job_status = client.fine_tuning.jobs.retrieve(job_id)
# # print(f"Estado actual del trabajo: {job_status.status}")
# # if job_status.status == "succeeded":
# # fine_tuned_model_name = job_status.fine_tuned_model
# # print(f"Nombre del modelo ajustado: {fine_tuned_model_name}")
# 3. Usar el modelo ajustado (una vez que esté listo)
# # Reemplaza con el nombre real de tu modelo, obtenido después del ajuste fino exitoso
# # fine_tuned_model_name = "ft:gpt-3.5-turbo-0125:my-org::abcd123"
# # if 'fine_tuned_model_name' in locals() and fine_tuned_model_name:
# # try:
# # response = client.chat.completions.create(
# # model=fine_tuned_model_name,
# # messages=[
# # {"role": "user", "content": "Tengo un problema de inicio de sesión."}
# # ]
# # )
# # print("\nRespuesta del modelo ajustado:")
# # print(response.choices[0].message.content)
# # except openai.APIStatusError as e:
# # print(f"Error al usar el modelo: {e.status_code} - {e.response}")
5.2. Anthropic
Anthropic no proporciona una API pública para el ajuste fino de sus modelos Claude 3 (Opus, Sonnet, Haiku) en el mismo sentido que OpenAI o Google.
Anthropic se enfoca en crear modelos base muy potentes que, según afirman, funcionan excelentemente con ingeniería de prompts avanzada y patrones RAG, minimizando la necesidad de ajuste fino en la mayoría de los casos. Para grandes clientes empresariales o socios, puede haber programas para crear «custom» modelos o integraciones especializadas, pero esta no es una función de ajuste fino disponible públicamente a través de la API.
If you are working with Claude 3, your primary focus should be on:
- High-quality prompt engineering: Experiment with system instructions, few-shot examples, clear request formatting. Claude is known for its ability to strictly follow instructions, especially in XML tags.
- RAG systems: Use external knowledge bases to provide the model with relevant context.
5.3. Google (Gemini)
Google está desarrollando activamente capacidades de ajuste fino a través de su plataforma Google Cloud Vertex AI. This is a full-fledged ML platform that provides tools for data preparation, running training jobs, and deploying models. Fine-tuning is available for the Gemini family of models.
Process:
- Prepare data (JSONL or CSV) in
input_text/output_textformat (for instruction tuning) ormessages(for chat tuning). - Upload data to Google Cloud Storage (GCS).
- Create and run a fine-tuning job via the Vertex AI Console or SDK.
- Deploy the fine-tuned model to an Endpoint.
- Use the fine-tuned model via this Endpoint.
Example data (file gemini_tuning_data.jsonl):
{"input_text": "Resume las ideas principales de este libro: 'El libro trata sobre el viaje de un héroe que supera obstáculos y se encuentra a sí mismo.'", "output_text": "El personaje principal del libro se embarca en un viaje transformador, enfrentando desafíos y logrando el autodescubrimiento."}
{"input_text": "Explica el principio de un reactor termonuclear en términos sencillos.", "output_text": "Un reactor termonuclear intenta reproducir el proceso que ocurre en el Sol: la fusión de núcleos atómicos ligeros a temperaturas muy altas, liberando enormes cantidades de energía."}
Example Python code (requires google-cloud-aiplatform):
Install beforehand: pip install google-cloud-aiplatform and pip install google-cloud-storage
import os
from google.cloud import aiplatform
from google.cloud import storage
# --- Configuración ---
# REEMPLAZA con tus valores:
PROJECT_ID = "your-gcp-project-id"
REGION = "us-central1" # Elige una región que admita Gemini y Vertex AI
BUCKET_NAME = "your-gcs-bucket-for-tuning" # Nombre de tu bucket de GCS (debe crearse previamente)
DATA_FILE_LOCAL_PATH = "gemini_tuning_data.jsonl"
GCS_DATA_URI = f"gs://{BUCKET_NAME}/{DATA_FILE_LOCAL_PATH}"
TUNED_MODEL_DISPLAY_NAME = "my-tuned-gemini-model"
# --- Fin de la configuración ---
# Inicializar Vertex AI
aiplatform.init(project=PROJECT_ID, location=REGION)
# 1. Crear archivo de datos (si no existe)
with open(DATA_FILE_LOCAL_PATH, "w", encoding="utf-8") as f:
f.write('{"input_text": "Resume las ideas principales de este libro: \'El libro trata sobre el viaje de un héroe que supera obstáculos y se encuentra a sí mismo.\'", "output_text": "El personaje principal del libro se embarca en un viaje transformador, enfrentando desafíos y logrando el autodescubrimiento."}\n')
f.write('{"input_text": "Explica el principio de un reactor termonuclear en términos sencillos.", "output_text": "Un reactor termonuclear intenta reproducir el proceso que ocurre en el Sol: la fusión de núcleos atómicos ligeros a temperaturas muy altas, liberando enormes cantidades de energía."}\n')
print(f"Archivo de datos '{DATA_FILE_LOCAL_PATH}' creado.")
# 2. Subir datos a Google Cloud Storage
def upload_blob(bucket_name, source_file_name, destination_blob_name):
"""Sube un archivo a un bucket de GCS."""
storage_client = storage.Client(project=PROJECT_ID)
bucket = storage_client.bucket(bucket_name)
blob = bucket.blob(destination_blob_name)
blob.upload_from_filename(source_file_name)
print(f"Archivo '{source_file_name}' subido a 'gs://{bucket_name}/{destination_blob_name}'.")
try:
upload_blob(BUCKET_NAME, DATA_FILE_LOCAL_PATH, DATA_FILE_LOCAL_PATH)
except Exception as e:
print(f"Error al subir el archivo a GCS. Asegúrate de que el bucket exista y tengas permisos: {e}")
exit()
# 3. Crear y ejecutar trabajo de ajuste fino
print(f"\nIniciando ajuste fino del modelo '{TUNED_MODEL_DISPLAY_NAME}'...")
try:
# `tune_model` inicia el trabajo y devuelve el modelo ajustado al finalizar
tuned_model = aiplatform.Model.tune_model(
model_display_name=TUNED_MODEL_DISPLAY_NAME,
source_model_name="gemini-1.0-pro-001", # Modelo base Gemini Pro
training_data_path=GCS_DATA_URI,
tuning_method="SUPERVISED_TUNING",
train_steps=100, # Número de pasos de entrenamiento. El valor óptimo depende del tamaño de los datos.
# batch_size=16, # Se puede especificar
# learning_rate_multiplier=1.0 # Se puede especificar
)
print(f"Modelo '{TUNED_MODEL_DISPLAY_NAME}' ajustado con éxito. ID del modelo: {tuned_model.name}")
print("El proceso de ajuste fino puede llevar un tiempo considerable.")
except Exception as e:
print(f"Error de ajuste fino. Revisa los registros en la Consola de Vertex AI: {e}")
exit()
# 4. Implementar modelo ajustado (para usar)
print(f"\nImplementando modelo ajustado '{TUNED_MODEL_DISPLAY_NAME}' en el endpoint...")
try:
endpoint = tuned_model.deploy(
machine_type="n1-standard-4", # Tipo de máquina para el endpoint. Elige el adecuado.
min_replica_count=1,
max_replica_count=1
)
print(f"Modelo implementado en el endpoint: {endpoint.name}")
print("La implementación también puede llevar varios minutos.")
except Exception as e:
print(f"Error al implementar el modelo: {e}")
exit()
# 5. Usar modelo ajustado
print("\nProbando modelo ajustado...")
prompt = "Háblame de tus capacidades después del entrenamiento."
instances = [{"prompt": prompt}] # Para ajuste de instrucciones. Si es ajuste de chat, entonces {"messages": [...]}
try:
response = endpoint.predict(instances=instances)
print("\nRespuesta del modelo ajustado:")
print(response.predictions[0])
except Exception as e:
print(f"Error al usar el modelo ajustado: {e}")
# Después de terminar, no olvides eliminar el endpoint y el modelo para evitar costos innecesarios:
# endpoint.delete()
# tuned_model.delete()
6. Recomendaciones generales
- Empieza poco a poco: No intentes entrenar el modelo con miles de ejemplos de inmediato. Empieza con un conjunto de datos pequeño pero de alta calidad.
- Itera: El ajuste fino es un proceso iterativo. Entrena, evalúa, ajusta los datos o los hiperparámetros, repite.
- Monitoreo: Supervisa cuidadosamente las métricas de entrenamiento (pérdida) y utiliza un conjunto de datos de validación para evitar el sobreajuste.
- Evaluación: Siempre prueba el modelo ajustado con datos que *nunca haya visto* durante el entrenamiento para evaluar su capacidad de generalización.
- Costo: Recuerda que el ajuste fino y la implementación de endpoints son de pago. Tenlo en cuenta en tu presupuesto.
- Documentación: Consulta siempre la documentación oficial del proveedor de LLM. Las API y las capacidades están en constante evolución.