← Todo el material
Curso Básico 23 de agosto de 2026

Fine-tuning — Módulo 4: elegir el modelo base y el hardware

Cuarto módulo del Curso de Fine-tuning práctico y cierre del bloque básico: base vs instruct y cuándo cada uno, qué tamaño pide tu tarea, licencias de Llama, Qwen, Mistral y Gemma, la cuenta completa de VRAM paso a paso (pesos, gradientes, optimizador y activaciones), la tabla de qué cabe con full FT, LoRA y QLoRA, y dónde entrenar con costos por hora.

☰ Índice del contenido

Con el módulo 3 ya sabes qué secuencia de tokens va a ver el modelo y sobre cuáles se calcula el gradiente. Falta la pregunta material: qué modelo y dónde lo entrenas. Y es la pregunta donde más gente se estrella contra un CUDA out of memory a los cuarenta minutos de haber empezado, porque las cuentas de VRAM del fine-tuning no se parecen a las de la inferencia. En inferencia dimensionas pesos más caché; en entrenamiento hay tres pasajeros más — gradientes, estados del optimizador y activaciones — y entre los tres suelen pesar más que el modelo. Este módulo cierra el bloque básico con esa cuenta explícita, la tabla de qué cabe en qué, y el mapa de dónde arrendar el fierro.

La tesis del módulo

En fine-tuning, la VRAM no la define el modelo: la define el método. El mismo 8B necesita más de 100 GB con full fine-tuning, cabe en 24 GB con LoRA y cabe en 12 GB con QLoRA. Elegir el método es una decisión de arquitectura con consecuencias de presupuesto de un orden de magnitud, y se toma antes de arrendar nada.

Base vs instruct

Todo modelo abierto se publica en dos sabores, y elegir mal el punto de partida es un error caro porque se descubre tarde.

Un modelo base (glosar: el modelo tal como salió del pre-entrenamiento; sabe muchísimo del mundo pero solo hace una cosa: continuar texto — no obedece instrucciones ni tiene formato de conversación) es materia prima. Un modelo instruct (glosar: el mismo modelo después de instruction tuning y alineamiento; ya sabe conversar, seguir instrucciones y negarse a cosas dañinas) ya trae comportamiento de asistente. El recorrido completo entre uno y otro está en los módulos 7 y 8 del Curso de Transformers.

Modelo baseModelo instruct
Sabe conversarNoSí
Chat templatePuede no traerSí, definido
Ejemplos que necesitasMilesCientos
Comportamiento de seguridadNingunoYa alineado
Riesgo de conflicto de estiloNulo: es hoja en blancoReal: peleas con su alineamiento
Cuándo elegirloFormato muy propio, dataset grandeCasi siempre, sobre todo el primero

La recomendación práctica es partir por el instruct. El razonamiento: ya trae gratis la mayor parte del comportamiento que tú tendrías que enseñar (formato de conversación, seguir instrucciones, no responder cualquier cosa), así que tu dataset de 800 ejemplos rinde mucho más. El escenario en que el base gana es cuando tu formato de salida es tan particular que el alineamiento del instruct se convierte en un estorbo — el modelo insiste en agregar advertencias, en explicar lo que hizo o en suavizar el tono — y tienes suficientes ejemplos para enseñar todo desde cero.

Ojo: los modelos base con frecuencia no traen chat_template en su tokenizer. Si eliges base, tienes que definir tú una plantilla y usarla idéntica en entrenamiento y en inferencia. Es exactamente el punto del módulo 3 y una fuente clásica de “el modelo entrenó bien y en producción responde raro”.

Tamaño: qué pide realmente tu tarea

La intuición de “más grande siempre mejor” es cara y con frecuencia falsa en fine-tuning, porque un modelo chico afinado en una tarea estrecha compite bien con uno grande genérico.

TareaTamaño razonablePor qué
Clasificación en N categorías fijas0.5B – 3BLa tarea no necesita razonar
Extracción de campos estructurados1B – 8BNecesita entender el texto, no razonar
Reescritura, estilo y tono3B – 8BFluidez importa; razonamiento no tanto
Asistente de dominio conversacional7B – 14BNecesita conocimiento y coherencia
Razonamiento multi-paso, código14B – 70BAquí el tamaño sí compra capacidad
Agente con uso de herramientas14B+Planificar es lo que más pide tamaño

La regla operativa: empieza con el modelo más chico que podría funcionar, mide, y sube solo si el número lo pide. Es más rápido de iterar (un ciclo de entrenamiento de 20 minutos en vez de 6 horas), más barato de servir en producción, y si el chico ya cumple el umbral, el grande solo agrega costo por token para siempre.

Licencias: la parte aburrida que decide el proyecto

Que un modelo esté en Hugging Face y se descargue con un comando no significa que puedas usarlo comercialmente. Las licencias de los pesos varían y hay que leerlas antes de construir un producto encima.

FamiliaLicenciaUso comercialLetra chica relevante
Llama (Meta)Licencia comunitaria propiaSíLímite de usuarios activos mensuales; obligación de atribución y de nombrar el modelo derivado con el prefijo de la familia
Qwen (Alibaba)Apache 2.0 en la mayoría de tamañosSíAlgunos tamaños puntuales han usado licencias distintas: verifica el modelo exacto
Mistral (los abiertos)Apache 2.0SíLos modelos “grandes” son de licencia comercial cerrada, no confundir
Gemma (Google)Términos de uso de GemmaSíPolítica de uso prohibido que se hereda a los derivados
DeepSeekLicencia propia / MIT según modeloSíVaría por versión: revisar el repositorio

Tres reglas que ahorran problemas:

  1. Lee la licencia del modelo exacto, no de la familia. Dentro de una misma familia conviven licencias distintas por tamaño y por versión.
  2. La licencia se hereda a tu adaptador. Un LoRA entrenado sobre un modelo con restricciones queda sujeto a esas restricciones, y también el modelo fusionado.
  3. Los datos con que entrenaste también tienen licencia. Es el punto de la destilación del módulo 1: si generaste el dataset con las salidas de un modelo comercial, los términos de ese proveedor pueden prohibir usarlo para entrenar.

Cuidado: las licencias cambian con cada release y las tablas de internet envejecen rápido. Lo que está arriba es un mapa de orientación, no asesoría legal. Antes de comprometer un producto, abre el archivo LICENSE del repositorio del modelo que vas a usar y léelo. Toma cinco minutos.

La cuenta de VRAM, completa y explícita

Esta es la sección que evita el CUDA out of memory. En GPU módulo 2 vimos la cuenta de inferencia: pesos más KV cache. Entrenar suma tres pasajeros que en inferencia no existen.

   LOS CUATRO PASAJEROS DE LA VRAM AL ENTRENAR (full FT)

 ┌──────────────────┬───────────────────┬───────────┐
 │ pesos            │ ████              │ P x 2 B   │
 ├──────────────────┼───────────────────┼───────────┤
 │ gradientes       │ ████              │ E x 2 B   │
 ├──────────────────┼───────────────────┼───────────┤
 │ optimizador Adam │ ████████████████  │ E x 8 B   │
 ├──────────────────┼───────────────────┼───────────┤
 │ activaciones     │ ██                │ batch,seq │
 └──────────────────┴───────────────────┴───────────┘

  P = parámetros totales. E = parámetros ENTRENABLES.
  Full FT: E = P y el optimizador pesa 4x los pesos.
  LoRA:    E es una fracción minúscula de P.

Vamos pieza por pieza. P es el número de parámetros del modelo.

1. Pesos. En BF16 (glosar: bfloat16, formato de 16 bits usado como estándar en entrenamiento moderno — mismo tamaño que FP16 pero con más rango de exponente, que lo hace más estable; ver el módulo 4 de GPU), cada parámetro son 2 bytes.

pesos = P × 2 bytes

2. Gradientes. Cada parámetro entrenable necesita guardar su gradiente, del mismo tamaño que el parámetro. Aquí E es el número de parámetros entrenables, que en full fine-tuning es P y en LoRA es una fracción minúscula.

gradientes = E × 2 bytes

3. Estados del optimizador. Adam (glosar: el optimizador estándar en deep learning; además del gradiente actual mantiene dos promedios móviles por parámetro — el primer momento, que es la dirección suavizada, y el segundo momento, que es la magnitud — para ajustar el paso de cada peso individualmente) guarda dos estados por parámetro entrenable, y por estabilidad numérica los guarda en FP32, es decir 4 bytes cada uno.

optimizador Adam = E × 2 estados × 4 bytes = E × 8 bytes

Este es el pasajero que sorprende: en full fine-tuning, el optimizador ocupa el cuádruple de lo que ocupan los pesos en BF16. Es la razón principal de que full fine-tuning sea tan caro.

4. Activaciones. Los resultados intermedios de cada capa que hay que conservar para el paso hacia atrás. Dependen del batch_size, del largo de secuencia, del número de capas y del tamaño oculto — no del método de fine-tuning. Es el único término que puedes bajar con perillas: batch más chico, secuencia más corta, o gradient checkpointing (glosar: técnica que descarta las activaciones intermedias y las recalcula durante el paso hacia atrás; baja mucho la memoria a cambio de aproximadamente un 30% más de tiempo de cómputo).

El ejemplo numérico, paso a paso

Modelo de 8.000 millones de parámetros (P = 8e9), BF16, Adam.

Full fine-tuning (E = P = 8e9):

pesos            8e9 x 2 bytes  =  16 GB
gradientes       8e9 x 2 bytes  =  16 GB
optimizador      8e9 x 8 bytes  =  64 GB
──────────────────────────────────────────
subtotal estático               =  96 GB
activaciones (batch 4, 2k tok)  ~   8 GB
overhead CUDA y fragmentación   ~   4 GB
──────────────────────────────────────────
TOTAL                           ~ 108 GB

Ciento ocho gigabytes. Eso no cabe en una H100 de 80 GB: necesitas varias GPUs y una estrategia de repartición del estado del optimizador entre ellas.

LoRA sobre el mismo modelo, con r=16 sobre atención y MLP (all-linear, el default que recomienda el módulo 5). Los parámetros entrenables quedan alrededor del 0.5% de P, digamos E ≈ 42 millones:

pesos (congelados)  8e9 x 2 bytes  =  16 GB
gradientes         42e6 x 2 bytes  ~ 0.08 GB
optimizador        42e6 x 8 bytes  ~ 0.34 GB
──────────────────────────────────────────────
subtotal estático                  ~ 16.4 GB
activaciones (batch 2, 2k tok)     ~  4 GB
overhead                           ~  2 GB
──────────────────────────────────────────────
TOTAL                              ~ 22 GB

De 108 GB a 22 GB. Y fíjate dónde está ahora el gasto: los pesos congelados son más del 70% del total. Gradientes y optimizador se volvieron ruido estadístico. Eso es lo que hace a LoRA una idea tan buena, y por eso el siguiente paso obvio es atacar el término que quedó dominando.

QLoRA, que es exactamente eso: cargar los pesos base en 4 bits (0.5 bytes por parámetro) y entrenar el LoRA encima:

pesos en 4 bits    8e9 x 0.5 bytes ~  4 GB
gradientes         42e6 x 2 bytes  ~ 0.08 GB
optimizador        42e6 x 8 bytes  ~ 0.34 GB
──────────────────────────────────────────────
subtotal estático                  ~  4.4 GB
activaciones (batch 2, 2k tok)     ~  4 GB
overhead                           ~  2 GB
──────────────────────────────────────────────
TOTAL                              ~ 10.4 GB

Poco más de diez gigabytes. Un 8B afinándose en una tarjeta de consumidor. Ese salto — de necesitar un clúster a necesitar una RTX — es la razón de que el fine-tuning haya dejado de ser cosa de laboratorios.

"""Estimador de VRAM para fine-tuning. Órdenes de magnitud, no exacto.

La estimación de activaciones es aproximada por diseño: depende de la
arquitectura, de la implementación de atención y de si hay gradient
checkpointing. Úsala para dimensionar, no para prometer.
"""

def estimar_vram(
    parametros_b: float,          # en miles de millones (8 = 8B)
    metodo: str = "qlora",        # "full" | "lora" | "qlora"
    frac_entrenable: float = 0.005,  # LoRA r=16 all-linear ~0.5%
    batch_size: int = 2,
    seq_len: int = 2048,
    capas: int = 32,
    hidden: int = 4096,
    gradient_checkpointing: bool = True,
) -> dict:
    P = parametros_b * 1e9
    GB = 1e9                          # GB decimales, como en el texto

    # 1) Pesos: 2 bytes en BF16, 0.5 bytes cuantizados a 4 bits.
    bytes_peso = 0.5 if metodo == "qlora" else 2
    pesos = P * bytes_peso / GB

    # 2) y 3) Gradientes y Adam solo sobre lo ENTRENABLE.
    E = P if metodo == "full" else P * frac_entrenable
    gradientes = E * 2 / GB
    optimizador = E * 8 / GB          # 2 estados x 4 bytes (FP32)

    # 4) Activaciones. Con checkpointing se guardan ~1 tensor por capa
    # en vez de la decena de intermedios del bloque Transformer.
    factor = 2 if gradient_checkpointing else 16
    activaciones = batch_size * seq_len * hidden * capas * 2 * factor / GB

    overhead = 2.0                    # contexto CUDA, fragmentación
    total = pesos + gradientes + optimizador + activaciones + overhead

    return {
        "pesos_gb": round(pesos, 2),
        "gradientes_gb": round(gradientes, 2),
        "optimizador_gb": round(optimizador, 2),
        "activaciones_gb": round(activaciones, 2),
        "overhead_gb": overhead,
        "TOTAL_gb": round(total, 1),
        # Margen de seguridad: nunca dimensiones al 100% de la tarjeta.
        "gpu_minima_gb": round(total * 1.2, 1),
    }


if __name__ == "__main__":
    for metodo in ("full", "lora", "qlora"):
        print(metodo.ljust(6), estimar_vram(8, metodo=metodo))
    # full   TOTAL ~ 100+ GB  -> multi-GPU
    # lora   TOTAL ~  22 GB   -> A6000 / A100 40GB
    # qlora  TOTAL ~  10 GB   -> RTX 3090 / 4090 / A10

Qué cabe en qué

Con la fórmula anterior, la tabla de referencia. Los valores suponen BF16, Adam, seq_len 2048, batch chico y gradient checkpointing activado. Son órdenes de magnitud para dimensionar, no garantías.

ModeloFull FTLoRA (r=16)QLoRA (4 bits)
1B – 3B~24 – 40 GB~8 – 12 GB~5 – 8 GB
7B – 8B~100 – 120 GB~20 – 24 GB~10 – 14 GB
13B – 14B~180 – 200 GB~34 – 40 GB~16 – 20 GB
32B – 34B~430 – 470 GB~75 – 85 GB~28 – 36 GB
70B~900 GB+~160 – 180 GB~48 – 60 GB

Traducido a tarjetas concretas:

GPUVRAMQué alcanza con QLoRAQué alcanza con LoRA
RTX 3060 12GB12 GBHasta 7B – 8B, justoHasta 3B
RTX 3090 / 409024 GBHasta 14B cómodo, 32B apretadoHasta 8B
A10G / L424 GBIgual que arriba, más lentoHasta 8B
A100 40GB40 GBHasta 32BHasta 14B
A100 / H100 80GB80 GB70B apretadoHasta 32B
2 × H100 80GB160 GB70B cómodo70B

Ojo: las activaciones crecen linealmente con el largo de secuencia, y el largo lo definiste en el módulo 3 con el p99 de tus longitudes. Pasar de seq_len 2048 a 8192 cuadruplica ese término, y en QLoRA — donde los pesos ya son chicos — las activaciones pasan a ser el gasto dominante. Si tu dataset tiene ejemplos largos, la tabla de arriba se corre un escalón.

Las tres perillas cuando no cabe

Cuando el CUDA out of memory aparece, este es el orden de intervención, de menos a más costoso en calidad:

  1. Gradient checkpointing. Baja muchísimo las activaciones a cambio de ~30% más de tiempo. Cuesta tiempo, no calidad. Enciéndelo casi siempre.
  2. Bajar el batch y subir gradient_accumulation_steps. Acumular gradientes de varios micro-batches antes de actualizar (glosar: procesar 4 batches de 2 acumulando el gradiente y actualizar una vez, lo que es matemáticamente casi equivalente a un batch de 8 pero con la memoria de uno de 2). Es la perilla más segura: el batch efectivo se mantiene.
  3. Bajar max_seq_length. Solo hasta donde no truncar respuestas. Más allá, estás degradando el dataset, que es lo que el módulo 3 advirtió que no hay que hacer.

Recién si nada de eso alcanza: bajar de LoRA a QLoRA, o bajar de tamaño de modelo.

Dónde entrenar

Cinco opciones, con la que conviene en cada caso. Los precios son órdenes de magnitud a la fecha de escritura y varían mucho por región, disponibilidad y tipo de contrato — trátalos como referencia para comparar entre opciones, no como cotización.

OpciónCosto aprox./horaVentajaDesventaja
Tu GPUSolo electricidadSin límite de tiempo, datos en casaTecho de VRAM fijo, cero elasticidad
Google ColabGratis a ~10 USD/mesCero fricción para empezarSesiones que se cortan, GPU variable
RunPod / Vast.ai~0.3 – 3 USDLo más barato por GPU-horaSin garantías, hay que administrar
Lambda / Paperspace~1 – 3 USDMás estable, buen soporteDisponibilidad intermitente
Vertex AI / SageMaker~3 – 12 USDAuditoría, IAM, VPC, cumplimientoEl más caro; complejidad de setup

La recomendación por etapa:

  • Aprendiendo y prototipando: Colab con un modelo de 1B a 3B en QLoRA. Cero costo, ciclo de iteración corto, y todo lo que aprendes se traslada igual a modelos grandes.
  • Entrenamiento serio de un proyecto: RunPod o Vast con una 4090 o una A100. Es donde está la mejor relación precio-rendimiento por lejos, y para un entrenamiento de 3 horas la falta de garantías importa poco.
  • Empresa con datos sensibles o requisitos de auditoría: Vertex AI o SageMaker. Pagas varias veces más por GPU-hora y estás comprando control de acceso, registro de auditoría, red privada y un contrato. Si tus datos no pueden salir de un perímetro, no hay alternativa barata.
  • Uso continuo y predecible: comprar la tarjeta. Una 4090 se paga contra el arriendo en algunos meses de uso intensivo, y además queda para inferencia local.

Cuidado: cuando arriendes por hora, el primer gasto real no es entrenar sino descargar el modelo y subir el dataset. Un 14B en BF16 son unos 28 GB que hay que bajar cada vez que levantas una instancia nueva. Usa el almacenamiento persistente del proveedor o una caché de Hugging Face montada, o vas a pagar veinte minutos de GPU ociosa en cada corrida. Y apaga la instancia: la GPU se cobra encendida, no ocupada.

Errores comunes

  • Dimensionar la VRAM con la cuenta de inferencia. Entrenar suma gradientes, estados del optimizador y activaciones. Con full fine-tuning, Adam solo pesa el cuádruple de los pesos en BF16.
  • Olvidar que Adam guarda dos estados en FP32. Son 8 bytes por parámetro entrenable, el ítem más grande del presupuesto en full fine-tuning y la razón principal de que sea inviable en una sola GPU.
  • Elegir el modelo más grande que cabe. Cabe para entrenar y después hay que servirlo en producción, todos los días, pagando cada token. Empieza por el más chico que podría funcionar y sube solo si la métrica lo exige.
  • Partir de un modelo base cuando el instruct servía. El instruct ya trae la mayor parte del comportamiento gratis, así que tus 800 ejemplos rinden mucho más. El base es para casos donde el alineamiento estorba.
  • Usar un modelo base sin definir el chat template. Muchos no traen uno, y armar la plantilla al vuelo distinto en entrenamiento y en inferencia produce un modelo que entrenó bien y responde mal.
  • Asumir que “está en Hugging Face” es “puedo usarlo comercialmente”. Las licencias varían por familia, por tamaño y por versión, y se heredan al adaptador y al modelo fusionado. Lee el LICENSE del modelo exacto.
  • No activar gradient checkpointing. Es la perilla que más memoria libera y solo cuesta tiempo de cómputo. Debería estar encendida por defecto en casi todo entrenamiento.
  • Bajar max_seq_length para que quepa, sin mirar el p99. Estás truncando respuestas y enseñándole al modelo a cortarse. Baja el batch y acumula gradientes antes de tocar la longitud.
  • Dejar la instancia arrendada encendida. Se cobra por hora encendida, no por hora útil. La factura del fin de semana olvidado es la anécdota más repetida del rubro.

Cierre del bloque básico

Con estos cuatro módulos ya tienes el marco completo antes de entrenar nada: cuándo corresponde hacer fine-tuning y cuándo la respuesta es prompt o RAG (M1), cómo se construye el dataset que es la mayor parte del resultado (M2), cómo se convierte ese dataset en tokens y máscaras que el modelo pueda aprovechar (M3), y qué modelo y qué fierro hacen falta para ejecutarlo (M4). Ninguna de estas cuatro decisiones se arregla después con hiperparámetros. Todo lo que viene en el bloque intermedio se apoya en que estas estén bien tomadas.

La frase para llevarse

“La GPU que necesitas no la define el modelo, la define el método: el mismo 8B pide 108 GB con full fine-tuning y 10 con QLoRA. Aprende a hacer la cuenta y dejas de arrendar de más.”

Qué viene

Módulo 5: LoRA y QLoRA a fondo, y con esto arranca el bloque intermedio. Hasta ahora LoRA fue una caja negra que baja la VRAM; toca abrirla. Vamos a ver la descomposición de bajo rango que hay detrás — por qué dos matrices flacas pueden reemplazar el ajuste de una gigante —, qué significan de verdad r y lora_alpha y cómo se eligen, en qué módulos conviene enchufar los adaptadores (q_proj, v_proj, o todas las lineales, y qué cambia), el dropout, y la mecánica interna de QLoRA: la cuantización NF4, el doble cuantizado y los optimizadores paginados. Con la configuración de peft explicada línea por línea y el criterio para saber cuándo r=8 alcanza y cuándo tu tarea de verdad pide r=64.

Material relacionado

Fine-tuningLoRAQLoRAVRAMGPU

Preguntas sobre este curso

Regístrate gratis para hacer preguntas y guardar tu progreso.

✉ Entérate de lo nuevo

Recibe un aviso cuando publique nuevos cursos, workshops o investigaciones. Sin spam.