# Ajuste fino 2x más rápido con Unsloth

Unsloth reescribe las partes críticas para el rendimiento de HuggingFace Transformers con kernels Triton optimizados a mano, ofreciendo **2x de velocidad de entrenamiento** y **70% de reducción de VRAM** sin pérdida de precisión. Es un reemplazo de fácil integración: tus scripts TRL/PEFT existentes funcionan sin cambios después de intercambiar la importación.

{% hint style="success" %}
Todos los ejemplos se ejecutan en servidores GPU alquilados a través de [CLORE.AI Marketplace](https://clore.ai/marketplace).
{% endhint %}

## Características clave

* **Entrenamiento 2x más rápido** — kernels Triton personalizados para attention, RoPE, cross-entropy y RMS norm
* **70% menos VRAM** — checkpointing de gradientes inteligente y pesos mapeados en memoria
* **Reemplazo de HuggingFace listo para usar** — un cambio de importación, nada más
* **QLoRA / LoRA / ajuste fino completo** — todos los modos soportados de serie
* **Exportación nativa** — guarda directamente en GGUF (todos los tipos de cuantización), adaptadores LoRA o modelo fusionado en 16 bits
* **Amplia cobertura de modelos** — Llama 3.x, Mistral, Qwen 2.5, Gemma 2, DeepSeek-R1, Phi-4 y más
* **Gratis y de código abierto** (Apache 2.0)

## Requisitos

| Componente | Mínimo         | Recomendado    |
| ---------- | -------------- | -------------- |
| GPU        | RTX 3060 12 GB | RTX 4090 24 GB |
| VRAM       | 10 GB          | 24 GB          |
| RAM        | 16 GB          | 32 GB          |
| Disco      | 40 GB          | 80 GB          |
| CUDA       | 11.8           | 12.1+          |
| Python     | 3.10           | 3.11           |

**Precios de Clore.ai:** RTX 4090 ≈ $0.5–2/día · RTX 3090 ≈ $0.3–1/día · RTX 3060 ≈ $0.15–0.3/día

Un modelo 7B con QLoRA de 4 bits cabe en **\~10 GB de VRAM**, haciendo viable incluso una RTX 3060.

## Inicio rápido

### 1. Instalar Unsloth

```bash
# Crear un venv (recomendado)
python -m venv /workspace/unsloth-env
source /workspace/unsloth-env/bin/activate

pip install --upgrade pip
pip install "unsloth[colab-new] @ git+https://github.com/unslothai/unsloth.git"
pip install --no-deps trl peft accelerate bitsandbytes xformers
```

### 2. Cargar un modelo con cuantización de 4 bits

```python
from unsloth import FastLanguageModel
import torch

model, tokenizer = FastLanguageModel.from_pretrained(
    model_name="unsloth/Meta-Llama-3.1-8B-Instruct-bnb-4bit",
    max_seq_length=2048,
    dtype=None,            # detección automática (float16 en Ampere, bfloat16 en Ada)
    load_in_4bit=True,
)
```

### 3. Aplicar adaptadores LoRA

```python
model = FastLanguageModel.get_peft_model(
    model,
    r=16,
    target_modules=["q_proj", "k_proj", "v_proj", "o_proj",
                     "gate_proj", "up_proj", "down_proj"],
    lora_alpha=16,
    lora_dropout=0,
    bias="none",
    use_gradient_checkpointing="unsloth",   # 70% de reducción de VRAM
    random_state=42,
    use_rslora=False,
    loftq_config=None,
)
```

### 4. Preparar datos y entrenar

```python
from datasets import load_dataset
from trl import SFTTrainer
from transformers import TrainingArguments

dataset = load_dataset("yahma/alpaca-cleaned", split="train")

trainer = SFTTrainer(
    model=model,
    tokenizer=tokenizer,
    train_dataset=dataset,
    dataset_text_field="text",
    max_seq_length=2048,
    dataset_num_proc=2,
    packing=True,
    args=TrainingArguments(
        per_device_train_batch_size=2,
        gradient_accumulation_steps=4,
        warmup_steps=10,
        num_train_epochs=1,
        learning_rate=2e-4,
        fp16=not torch.cuda.is_bf16_supported(),
        bf16=torch.cuda.is_bf16_supported(),
        logging_steps=10,
        optim="adamw_8bit",
        weight_decay=0.01,
        lr_scheduler_type="linear",
        seed=42,
        output_dir="/workspace/outputs",
    ),
)

stats = trainer.train()
print(f"Training loss: {stats.training_loss:.4f}")
```

## Exportando el modelo

### Guardar solo el adaptador LoRA

```python
model.save_pretrained("/workspace/lora-adapter")
tokenizer.save_pretrained("/workspace/lora-adapter")
```

### Fusionar y guardar el modelo completo (float16)

```python
model.save_pretrained_merged(
    "/workspace/merged-model",
    tokenizer,
    save_method="merged_16bit",
)
```

### Exportar a GGUF para Ollama / llama.cpp

```python
# Cuantizar a Q4_K_M (buen equilibrio entre tamaño y calidad)
model.save_pretrained_gguf(
    "/workspace/gguf-output",
    tokenizer,
    quantization_method="q4_k_m",
)

# Otras opciones: q5_k_m, q8_0, f16
```

Después de exportar, servir con Ollama:

```bash
# Crear un Modelfile de Ollama
cat > Modelfile <<EOF
FROM /workspace/gguf-output/unsloth.Q4_K_M.gguf
TEMPLATE "{{ .System }}\n{{ .Prompt }}"
PARAMETER temperature 0.7
EOF

ollama create my-finetuned -f Modelfile
ollama run my-finetuned "Resume los puntos clave de la arquitectura de transformers"
```

## Ejemplos de uso

### Ajuste fino en un conjunto de datos de chat personalizado

```python
from unsloth.chat_templates import get_chat_template

tokenizer = get_chat_template(tokenizer, chat_template="llama-3.1")

def format_chat(example):
    messages = [
        {"role": "system", "content": "Eres un asistente útil."},
        {"role": "user", "content": example["instruction"]},
        {"role": "assistant", "content": example["output"]},
    ]
    return {"text": tokenizer.apply_chat_template(messages, tokenize=False)}

dataset = dataset.map(format_chat)
```

### Entrenamiento de alineación DPO / ORPO

```python
from trl import DPOTrainer, DPOConfig

dpo_trainer = DPOTrainer(
    model=model,
    ref_model=None,          # Unsloth maneja el modelo de referencia internamente
    args=DPOConfig(
        per_device_train_batch_size=2,
        gradient_accumulation_steps=4,
        learning_rate=5e-6,
        num_train_epochs=1,
        beta=0.1,
        output_dir="/workspace/dpo-output",
    ),
    train_dataset=dpo_dataset,
    tokenizer=tokenizer,
)
dpo_trainer.train()
```

## Referencia de uso de VRAM

| Modelo         | Cuant   | Método | VRAM    | GPU         |
| -------------- | ------- | ------ | ------- | ----------- |
| Llama 3.1 8B   | 4 bits  | QLoRA  | \~10 GB | RTX 3060    |
| Llama 3.1 8B   | 16 bits | LoRA   | \~18 GB | RTX 3090    |
| Qwen 2.5 14B   | 4 bits  | QLoRA  | \~14 GB | RTX 3090    |
| Mistral 7B     | 4 bits  | QLoRA  | \~9 GB  | RTX 3060    |
| DeepSeek-R1 7B | 4 bits  | QLoRA  | \~10 GB | RTX 3060    |
| Llama 3.3 70B  | 4 bits  | QLoRA  | \~44 GB | 2× RTX 3090 |

## Consejos

* **Usar siempre `use_gradient_checkpointing="unsloth"`** — este es el mayor ahorro de VRAM, único de Unsloth
* **Establecer `lora_dropout=0`** — los kernels Triton de Unsloth están optimizados para dropout cero y funcionan más rápido
* **Usa `packing=True`** en SFTTrainer para evitar desperdicio por padding en ejemplos cortos
* **Comienza con `r=16`** para el rango de LoRA — aumentarlo a 32 o 64 solo si la pérdida de validación se estanca
* **Monitorizar con wandb** — añadir `report_to="wandb"` en TrainingArguments para el seguimiento de la pérdida
* **Ajuste del tamaño de lote** — aumentar `per_device_train_batch_size` hasta acercarte al límite de VRAM, luego compensar con `gradient_accumulation_steps`

## Solución de problemas

| Problema                                    | Solución                                                                                  |
| ------------------------------------------- | ----------------------------------------------------------------------------------------- |
| `OutOfMemoryError` durante el entrenamiento | Reducir el tamaño de batch a 1, disminuir `max_seq_length`, o usar cuantización de 4 bits |
| Errores de compilación de kernels Triton    | Ejecuta `pip install triton --upgrade` y asegurar que el toolkit de CUDA coincida         |
| Paso inicial lento (compilando)             | Normal — Triton compila los kernels en la primera ejecución, en caché después             |
| `bitsandbytes` Error de versión de CUDA     | Instala la versión correspondiente: `pip install bitsandbytes --upgrade`                  |
| Picos de pérdida durante el entrenamiento   | Reducir la tasa de aprendizaje a 1e-4, añadir pasos de warmup                             |
| El exportado a GGUF falla                   | Asegura suficiente RAM (2× el tamaño del modelo) y espacio en disco para la conversión    |

## Recursos

* [Unsloth GitHub](https://github.com/unslothai/unsloth)
* [Wiki de Unsloth — Todos los notebooks](https://github.com/unslothai/unsloth/wiki)
* [CLORE.AI Marketplace](https://clore.ai/marketplace)
