Inicio/Blog/Fine-Tuning de LLMs: Cómo Entrenar tu Propio Modelo [Tutorial 2026]
Volver al Blog
Tutoriales IA2 de febrero de 202620 min

Fine-Tuning de LLMs: Cómo Entrenar tu Propio Modelo [Tutorial 2026]

Aprende a hacer fine-tuning de LLMs paso a paso. Tutorial con código Python, datasets, y cómo crear un modelo personalizado para tu negocio.

Fine-Tuning de LLMs: Cómo Entrenar tu Propio Modelo [Tutorial 2026]

El fine-tuning te permite especializar un LLM en tu dominio específico. En lugar de depender de prompts complejos, entrenas el modelo para que entienda tu vocabulario, estilo y casos de uso particulares.

¿Cuándo Hacer Fine-Tuning?

Sí Hacer Fine-Tuning Si:

  • Tienes un dominio muy específico (legal, médico, técnico)
  • Necesitas un estilo o tono consistente
  • El modelo debe seguir un formato específico siempre
  • Tienes miles de ejemplos de interacciones ideales
  • Los prompts están demasiado largos y costosos

No Hacer Fine-Tuning Si:

  • Puedes lograr el resultado con buenos prompts
  • Tienes menos de 100 ejemplos
  • El conocimiento que necesitas es público y actual
  • Necesitas que el modelo acceda a datos en tiempo real

Alternativas al Fine-Tuning

MétodoCuándo Usarlo
Prompt engineeringPrimero siempre
Few-shot promptingEjemplos en el prompt
RAGDatos que cambian frecuentemente
Fine-tuningComportamiento/estilo consistente

Opciones de Fine-Tuning en 2026

1. OpenAI Fine-Tuning (GPT-4o, GPT-4o-mini)

AspectoDetalle
Modelo baseGPT-4o-mini, GPT-4o
Mínimo ejemplos10 (recomendado: 50-100)
FormatoJSONL con messages
Precio training$25/M tokens (4o-mini)
Precio inference2x modelo base

2. Anthropic Fine-Tuning (Claude)

AspectoDetalle
DisponibilidadSolo Enterprise
ProcesoContactar ventas
Mínimo ejemplos1000+ recomendado

3. Open Source (Llama, Mistral)

AspectoDetalle
ModelosLlama 3.2, Mistral, Qwen
HerramientasHugging Face, Axolotl
HardwareGPU 24GB+ (A100, 4090)
TécnicasLoRA, QLoRA, Full fine-tune

Tutorial: Fine-Tuning con OpenAI

Paso 1: Preparar Dataset

El formato JSONL requiere conversaciones completas:

jsonl
1{"messages": [{"role": "system", "content": "Eres un asistente de soporte técnico de SoftwareCorp."}, {"role": "user", "content": "No puedo iniciar sesión"}, {"role": "assistant", "content": "Entiendo que tienes problemas para acceder. Vamos a solucionarlo:\n\n1. Verifica que usas el email correcto\n2. Prueba 'Olvidé contraseña'\n3. Limpia cookies del navegador\n\n¿Cuál de estos pasos has intentado?"}]}
2{"messages": [{"role": "system", "content": "Eres un asistente de soporte técnico de SoftwareCorp."}, {"role": "user", "content": "La app va muy lenta"}, {"role": "assistant", "content": "Vamos a optimizar el rendimiento:\n\n1. Cierra otras aplicaciones\n2. Actualiza a la última versión\n3. Reinicia el dispositivo\n\n¿Qué versión de la app tienes instalada?"}]}

Paso 2: Validar Dataset

python
1import json
2 
3def validate_jsonl(file_path):
4 errors = []
5 with open(file_path, 'r') as f:
6 for i, line in enumerate(f, 1):
7 try:
8 data = json.loads(line)
9 if 'messages' not in data:
10 errors.append(f"Línea {i}: Falta 'messages'")
11 for msg in data['messages']:
12 if 'role' not in msg or 'content' not in msg:
13 errors.append(f"Línea {i}: Mensaje mal formado")
14 except json.JSONDecodeError:
15 errors.append(f"Línea {i}: JSON inválido")
16 return errors
17 
18errors = validate_jsonl('training_data.jsonl')
19if errors:
20 print("Errores encontrados:")
21 for e in errors:
22 print(e)
23else:
24 print("Dataset válido!")

Paso 3: Subir Dataset

python
1from openai import OpenAI
2 
3client = OpenAI()
4 
5# Subir archivo
6file = client.files.create(
7 file=open("training_data.jsonl", "rb"),
8 purpose="fine-tune"
9)
10 
11print(f"Archivo subido: {file.id}")

Paso 4: Crear Fine-Tuning Job

python
1job = client.fine_tuning.jobs.create(
2 training_file=file.id,
3 model="gpt-4o-mini-2024-07-18",
4 hyperparameters={
5 "n_epochs": 3,
6 "batch_size": 1,
7 "learning_rate_multiplier": 1.8
8 }
9)
10 
11print(f"Job creado: {job.id}")

Paso 5: Monitorear Progreso

python
1import time
2 
3while True:
4 job_status = client.fine_tuning.jobs.retrieve(job.id)
5 print(f"Status: {job_status.status}")
6 
7 if job_status.status in ['succeeded', 'failed']:
8 break
9 
10 time.sleep(60)
11 
12if job_status.status == 'succeeded':
13 print(f"Modelo listo: {job_status.fine_tuned_model}")

Paso 6: Usar el Modelo

python
1response = client.chat.completions.create(
2 model=job_status.fine_tuned_model, # ft:gpt-4o-mini-2024-07-18:org:custom:id
3 messages=[
4 {"role": "system", "content": "Eres un asistente de soporte técnico de SoftwareCorp."},
5 {"role": "user", "content": "Mi cuenta está bloqueada"}
6 ]
7)
8 
9print(response.choices[0].message.content)

Tutorial: Fine-Tuning Open Source con LoRA

¿Qué es LoRA?

LoRA (Low-Rank Adaptation) entrena solo una pequeña parte del modelo, reduciendo:

  • Memoria necesaria: 4-8GB en vez de 80GB
  • Tiempo de entrenamiento: horas en vez de días
  • Costo: GPU consumer vs cluster

Setup del Entorno

bash
1# Crear entorno
2python -m venv llm-finetune
3source llm-finetune/bin/activate
4 
5# Instalar dependencias
6pip install torch transformers datasets peft accelerate bitsandbytes
7pip install trl wandb

Código de Fine-Tuning con Llama

python
1import torch
2from datasets import load_dataset
3from transformers import (
4 AutoModelForCausalLM,
5 AutoTokenizer,
6 BitsAndBytesConfig,
7 TrainingArguments
8)
9from peft import LoraConfig, get_peft_model
10from trl import SFTTrainer
11 
12# Configuración de cuantización (4-bit para ahorrar memoria)
13bnb_config = BitsAndBytesConfig(
14 load_in_4bit=True,
15 bnb_4bit_quant_type="nf4",
16 bnb_4bit_compute_dtype=torch.float16
17)
18 
19# Cargar modelo base
20model_name = "meta-llama/Llama-3.2-8B-Instruct"
21model = AutoModelForCausalLM.from_pretrained(
22 model_name,
23 quantization_config=bnb_config,
24 device_map="auto"
25)
26 
27tokenizer = AutoTokenizer.from_pretrained(model_name)
28tokenizer.pad_token = tokenizer.eos_token
29 
30# Configuración LoRA
31lora_config = LoraConfig(
32 r=16, # Rank
33 lora_alpha=32,
34 target_modules=["q_proj", "v_proj", "k_proj", "o_proj"],
35 lora_dropout=0.05,
36 bias="none",
37 task_type="CAUSAL_LM"
38)
39 
40model = get_peft_model(model, lora_config)
41 
42# Cargar dataset (formato: {"text": "### User: pregunta\n### Assistant: respuesta"})
43dataset = load_dataset("json", data_files="training_data.json")
44 
45# Argumentos de entrenamiento
46training_args = TrainingArguments(
47 output_dir="./llama-finetuned",
48 num_train_epochs=3,
49 per_device_train_batch_size=4,
50 gradient_accumulation_steps=4,
51 learning_rate=2e-4,
52 fp16=True,
53 logging_steps=10,
54 save_strategy="epoch"
55)
56 
57# Trainer
58trainer = SFTTrainer(
59 model=model,
60 train_dataset=dataset["train"],
61 tokenizer=tokenizer,
62 args=training_args,
63 max_seq_length=2048
64)
65 
66# Entrenar
67trainer.train()
68 
69# Guardar modelo
70trainer.save_model("./llama-finetuned-final")

Usar el Modelo Fine-Tuned

python
1from peft import PeftModel
2 
3# Cargar modelo base + adaptador LoRA
4base_model = AutoModelForCausalLM.from_pretrained(
5 "meta-llama/Llama-3.2-8B-Instruct",
6 device_map="auto",
7 torch_dtype=torch.float16
8)
9 
10model = PeftModel.from_pretrained(base_model, "./llama-finetuned-final")
11 
12# Generar respuesta
13prompt = "### User: ¿Cómo reseteo mi contraseña?\n### Assistant:"
14inputs = tokenizer(prompt, return_tensors="pt").to("cuda")
15 
16outputs = model.generate(**inputs, max_new_tokens=200)
17print(tokenizer.decode(outputs[0], skip_special_tokens=True))

Preparar Datasets de Calidad

Estructura de Datos Ideal

json
1{
2 "instruction": "Responde como agente de soporte de SoftwareCorp",
3 "input": "Mi factura tiene un error",
4 "output": "Lamento el inconveniente con tu factura. Para corregirlo necesito:\n\n1. Número de factura\n2. Descripción del error\n3. Datos correctos\n\n¿Puedes proporcionarme estos datos?"
5}

Fuentes de Datos

  1. Conversaciones reales de tu equipo de soporte
  2. FAQs convertidas a formato conversacional
  3. Documentación adaptada a Q&A
  4. Datos sintéticos generados con GPT-4

Generar Datos Sintéticos

python
1from openai import OpenAI
2 
3client = OpenAI()
4 
5def generate_training_example(topic):
6 response = client.chat.completions.create(
7 model="gpt-4o",
8 messages=[
9 {"role": "system", "content": """Genera un ejemplo de conversación
10 de soporte técnico para SoftwareCorp sobre el tema dado.
11 Formato JSON: {"user": "...", "assistant": "..."}"""},
12 {"role": "user", "content": f"Tema: {topic}"}
13 ]
14 )
15 return response.choices[0].message.content
16 
17topics = [
18 "problema de login",
19 "facturación incorrecta",
20 "app lenta",
21 "cancelar suscripción",
22 "actualizar plan"
23]
24 
25examples = [generate_training_example(t) for t in topics]

Mejores Prácticas

1. Calidad > Cantidad

  • 100 ejemplos excelentes > 1000 ejemplos mediocres
  • Revisa manualmente cada ejemplo
  • Elimina duplicados y contradicciones

2. Diversidad de Ejemplos

  • Cubre todos los casos de uso
  • Incluye variaciones de la misma pregunta
  • Añade casos edge

3. Consistencia de Formato

  • Mismo tono en todas las respuestas
  • Estructura similar (saludo, pasos, cierre)
  • Longitud consistente

4. Hiperparámetros

ParámetroValor RecomendadoEfecto
Epochs2-4Más = overfitting
Learning rate1e-5 a 2e-4Más alto = inestable
Batch size4-16Depende de GPU
LoRA rank8-64Más = más capacidad

5. Evaluación

python
1# Métricas a evaluar
2test_cases = [
3 {"input": "No puedo acceder", "expected_topics": ["login", "contraseña"]},
4 {"input": "Cobro incorrecto", "expected_topics": ["factura", "reembolso"]}
5]
6 
7def evaluate_model(model, test_cases):
8 results = []
9 for case in test_cases:
10 response = model.generate(case["input"])
11 # Evaluar si cubre los temas esperados
12 coverage = sum(1 for t in case["expected_topics"] if t in response.lower())
13 results.append(coverage / len(case["expected_topics"]))
14 return sum(results) / len(results)

Costos Estimados

OpenAI Fine-Tuning

ConceptoGPT-4o-miniGPT-4o
Training$25/M tokens$100/M tokens
Inference$0.60/M input$6/M input
1000 ejemplos (~500K tokens)~$12.50~$50

Open Source (Cloud GPU)

ProveedorGPUPrecio/horaPara 8B model
RunPodA100 40GB$1.69~$5-10 total
Lambda LabsA100 80GB$1.29~$4-8 total
Vast.ai4090$0.40~$2-5 total

Conclusión

El fine-tuning es poderoso pero no siempre necesario. Antes de invertir tiempo y dinero:

  1. Prueba prompt engineering - A menudo es suficiente
  2. Considera RAG - Para datos que cambian
  3. Evalúa el ROI - ¿Justifica el costo?

Si decides hacer fine-tuning:

  • Empieza con OpenAI (más fácil)
  • Prepara datos de calidad
  • Itera basándote en evaluaciones
  • Considera open source para escalar

Recursos relacionados:

Posts Relacionados

JS

Javier Santos Criado

Consultor de IA y Automatización | Fundador de Javadex

Experto en implementación de soluciones de Inteligencia Artificial para empresas. Especializado en automatización con n8n, integración de LLMs, y desarrollo de agentes IA.

¿Quieres más contenido de IA?

Explora nuestras comparativas y guías