Después del despliegue, encuentra tu http_pub URL en Mis pedidos:
Ve a la Mis pedidos página
Haz clic en tu pedido
Encuentra la http_pub URL (por ejemplo, abc123.clorecloud.net)
Usa https://YOUR_HTTP_PUB_URL en lugar de localhost en los ejemplos de abajo.
Preparación del conjunto de datos
Formato de chat (recomendado)
Formato de instrucciones
Formato Alpaca
Modelos modernos compatibles (2025)
Modelo
ID de HF
VRAM mínima (QLoRA)
Llama 3.1 / 3.3 8B
meta-llama/Llama-3.1-8B-Instruct
12GB
Qwen 2.5 7B / 14B
Qwen/Qwen2.5-7B-Instruct
12GB / 20GB
DeepSeek-R1-Distill (7B/8B)
deepseek-ai/DeepSeek-R1-Distill-Qwen-7B
12GB
Mistral 7B v0.3
mistralai/Mistral-7B-Instruct-v0.3
12GB
Gemma 2 9B
google/gemma-2-9b-it
14GB
Phi-4 14B
microsoft/phi-4
20GB
Script de fine-tuning QLoRA
Ejemplo moderno con PEFT 0.14+, Flash Attention 2, soporte DoRA y compatibilidad con Qwen2.5 / DeepSeek-R1:
Flash Attention 2
Flash Attention 2 reduce el uso de VRAM y acelera significativamente el entrenamiento. Requiere GPU Ampere+ (RTX 3090, RTX 4090, A100).
Configuración
VRAM (7B)
Velocidad
Atención estándar (fp16)
~22GB
línea base
Flash Attention 2 (bf16)
~16GB
+30%
Flash Attention 2 + QLoRA
~12GB
+30%
DoRA (LoRA descompuesto por pesos)
DoRA (PEFT >= 0.14) descompone los pesos preentrenados en componentes de magnitud y dirección. Mejora la calidad del fine-tuning, especialmente para rangos más pequeños.
Ejemplos de Qwen2.5 y DeepSeek-R1-Distill
Fine-tuning de Qwen2.5
Fine-tuning de DeepSeek-R1-Distill
Los modelos DeepSeek-R1-Distill (Qwen-7B, Qwen-14B, Llama-8B, Llama-70B) están centrados en el razonamiento. Ajusta el fine-tuning para adaptar su estilo de cadena de pensamiento a tu dominio.
Usando Axolotl (más fácil)
Axolotl simplifica el fine-tuning con configuraciones YAML:
Ejemplos de configuración de Axolotl
Modelo de chat
Modelo de código
Fusionando pesos LoRA
Después del entrenamiento, fusiona LoRA de nuevo en el modelo base:
Convertir a GGUF
Para usar con llama.cpp/Ollama:
Monitorización del entrenamiento
Weights & Biases
TensorBoard
Mejores prácticas
Hiperparámetros
Parámetro
Modelo 7B
Modelo 13B
Modelo 70B
tamaño_de_lote
4
2
1
grad_accum
4
8
16
lr
2e-4
1e-4
5e-5
lora_r
64
32
16
epochs
3
2-3
1-2
Tamaño del conjunto de datos
Mínimo: 1.000 ejemplos
Bueno: 10.000+ ejemplos
La calidad > la cantidad
Evitar el sobreajuste
Entrenamiento multi-GPU
Configuración de DeepSpeed:
Guardado y exportación
Solución de problemas
Errores OOM
Reduce el tamaño del lote
Aumenta la acumulación de gradiente
Usa gradient_checkpointing=True
Reduce lora_r
La pérdida de entrenamiento no disminuye
Verificar el formato de los datos
Aumentar la tasa de aprendizaje
Comprobar problemas con los datos
Pérdida NaN
Reducir la tasa de aprendizaje
Usar fp32 en lugar de fp16
Comprobar si hay datos corruptos
Estimación de costos
Tarifas típicas del mercado de CLORE.AI (a fecha de 2026):
GPU
Tarifa por hora
Tarifa diaria
Sesión de 4 horas
RTX 3060
~$0.03
~$0.70
~$0.12
RTX 3090
~$0.06
~$1.50
~$0.25
RTX 4090
~$0.10
~$2.30
~$0.40
A100 40 GB
~$0.17
~$4.00
~$0.70
A100 80GB
~$0.25
~$6.00
~$1.00
Los precios varían según el proveedor y la demanda. ConsultaCLORE.AI Marketplacelas tarifas actuales.
[
{
"instruction": "Da tres consejos para mantenerte saludable.",
"input": "",
"output": "1. Come comidas equilibradas..."
}
]
import torch
from transformers import (
AutoModelForCausalLM,
AutoTokenizer,
BitsAndBytesConfig,
TrainingArguments,
)
from peft import LoraConfig, get_peft_model, prepare_model_for_kbit_training
from datasets import load_dataset
from trl import SFTTrainer, SFTConfig
# === Configuración ===
# Elige uno de: Qwen2.5, DeepSeek-R1-Distill, Llama 3.1, Mistral, etc.
MODEL_NAME = "Qwen/Qwen2.5-7B-Instruct"
# MODEL_NAME = "deepseek-ai/DeepSeek-R1-Distill-Qwen-7B"
# MODEL_NAME = "meta-llama/Llama-3.1-8B-Instruct"
DATASET = "your_dataset.json" # o nombre de conjunto de datos de HuggingFace
OUTPUT_DIR = "./output"
MAX_SEQ_LENGTH = 4096 # Qwen2.5 admite hasta 32K de contexto
USE_DORA = True # DoRA mejora la calidad frente al LoRA estándar
USE_FLASH_ATTN = True # Flash Attention 2 ahorra VRAM y acelera
# === Cargar el modelo con cuantización de 4 bits ===
bnb_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type="nf4",
bnb_4bit_compute_dtype=torch.bfloat16,
bnb_4bit_use_double_quant=True,
)
model = AutoModelForCausalLM.from_pretrained(
MODEL_NAME,
quantization_config=bnb_config,
device_map="auto",
trust_remote_code=True, # Requerido para Qwen2.5 y DeepSeek
# Flash Attention 2: requiere GPU Ampere+ (RTX 30/40, A100)
attn_implementation="flash_attention_2" if USE_FLASH_ATTN else "eager",
)
tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME, trust_remote_code=True)
if tokenizer.pad_token is None:
tokenizer.pad_token = tokenizer.eos_token
tokenizer.padding_side = "right"
# === Configurar LoRA con DoRA opcional ===
# DoRA (Adaptación de bajo rango descompuesta por pesos) — se requiere PEFT >= 0.14
# use_dora=True descompone los pesos en magnitud + dirección para mejor calidad
lora_config = LoraConfig(
r=64, # Rango (más alto = más capacidad, más VRAM)
lora_alpha=16, # Factor de escalado (mantener igual o a la mitad de r)
target_modules=[
"q_proj", "k_proj", "v_proj", "o_proj", # Capas de atención
"gate_proj", "up_proj", "down_proj", # Capas MLP
],
lora_dropout=0.05,
bias="none",
task_type="CAUSAL_LM",
use_dora=USE_DORA, # DoRA: calidad mejorada (PEFT 0.14+)
# use_rslora=True, # Opcional: LoRA estabilizado por rango
)
# Preparar el modelo para entrenamiento QLoRA
model = prepare_model_for_kbit_training(
model,
use_gradient_checkpointing=True,
gradient_checkpointing_kwargs={"use_reentrant": False},
)
model = get_peft_model(model, lora_config)
# Imprimir resumen de parámetros entrenables
model.print_trainable_parameters()
# Ejemplo de salida: parámetros entrenables: 42,991,616 || todos los parámetros: 7,284,891,648 || % entrenable: 0.59
# === Cargar conjunto de datos ===
dataset = load_dataset("json", data_files=DATASET)
# O usa un conjunto de datos público:
# dataset = load_dataset("HuggingFaceH4/ultrachat_200k")
# === Formatear el conjunto de datos para Qwen2.5 / formato ChatML ===
def format_chat_qwen(example):
"""Formato para Qwen2.5 usando la plantilla ChatML."""
messages = example.get("messages", [])
if not messages:
# Manejar datos estilo alpaca
text = f"<|im_start|>system\nEres un asistente útil.<|im_end|>\n"
text += f"<|im_start|>user\n{example['instruction']}"
if example.get("input"):
text += f"\n{example['input']}"
text += f"<|im_end|>\n<|im_start|>assistant\n{example['output']}<|im_end|>"
else:
# Manejar el formato de mensajes (ChatML)
text = tokenizer.apply_chat_template(
messages,
tokenize=False,
add_generation_prompt=False,
)
return {"text": text}
dataset = dataset.map(format_chat_qwen, remove_columns=dataset["train"].column_names)
# === Argumentos de entrenamiento (PEFT 0.14+ / TRL 0.12+) ===
training_args = SFTConfig(
output_dir=OUTPUT_DIR,
num_train_epochs=3,
per_device_train_batch_size=2,
gradient_accumulation_steps=8, # Lote efectivo = 2 * 8 = 16
learning_rate=2e-4,
weight_decay=0.001,
warmup_ratio=0.03,
lr_scheduler_type="cosine",
logging_steps=10,
save_steps=100,
save_total_limit=3,
bf16=True, # Usa bf16 para GPUs modernas (A100, RTX 30/40)
# fp16=True, # Usa fp16 para GPUs más antiguas
optim="paged_adamw_8bit",
max_grad_norm=0.3,
group_by_length=True,
report_to="wandb", # o "tensorboard"
# Específico de SFTConfig:
max_seq_length=MAX_SEQ_LENGTH,
dataset_text_field="text",
packing=True, # Empaqueta varios ejemplos para mayor eficiencia
)
# === Entrenar ===
trainer = SFTTrainer(
model=model,
train_dataset=dataset["train"],
tokenizer=tokenizer,
args=training_args,
)
trainer.train()
# === Guardar adaptador LoRA ===
trainer.save_model(f"{OUTPUT_DIR}/final")
tokenizer.save_pretrained(f"{OUTPUT_DIR}/final")
print(f"Modelo guardado en {OUTPUT_DIR}/final")
# Activar en la carga del modelo:
model = AutoModelForCausalLM.from_pretrained(
MODEL_NAME,
attn_implementation="flash_attention_2", # <-- añade esto
torch_dtype=torch.bfloat16, # FA2 requiere bf16 o fp16
device_map="auto",
)
from peft import LoraConfig
# LoRA estándar
lora_config = LoraConfig(r=64, lora_alpha=16, use_dora=False, ...)
# DoRA — mismos parámetros, mejor calidad
lora_config = LoraConfig(r=64, lora_alpha=16, use_dora=True, ...)
# Nota: DoRA añade ~5-10% de sobrecarga de VRAM frente al LoRA estándar
# Nota: No es compatible con modelos cuantizados (4 bits/8 bits) en todos los casos
MODEL_NAME = "Qwen/Qwen2.5-7B-Instruct"
# Para 14B: "Qwen/Qwen2.5-14B-Instruct" (necesita 20GB+ de VRAM con QLoRA)
model = AutoModelForCausalLM.from_pretrained(
MODEL_NAME,
quantization_config=bnb_config,
device_map="auto",
trust_remote_code=True, # Requerido para Qwen2.5
attn_implementation="flash_attention_2",
)
tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME, trust_remote_code=True)
# Qwen2.5 usa formato ChatML — usa apply_chat_template
messages = [
{"role": "system", "content": "Eres un asistente útil."},
{"role": "user", "content": "¡Hola!"},
{"role": "assistant", "content": "¡Hola! ¿En qué puedo ayudarte?"},
]
text = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=False)
# Variantes de DeepSeek-R1-Distill
MODEL_NAME = "deepseek-ai/DeepSeek-R1-Distill-Qwen-7B" # 7B sobre base Qwen2.5
# MODEL_NAME = "deepseek-ai/DeepSeek-R1-Distill-Llama-8B" # 8B sobre base Llama3
# MODEL_NAME = "deepseek-ai/DeepSeek-R1-Distill-Qwen-14B" # 14B (necesita A100)
model = AutoModelForCausalLM.from_pretrained(
MODEL_NAME,
quantization_config=bnb_config,
device_map="auto",
trust_remote_code=True,
attn_implementation="flash_attention_2",
)
# DeepSeek-R1 usa etiquetas <think>...</think> para el razonamiento
# Mantén esto en los datos de entrenamiento para conservar la capacidad de cadena de pensamiento
example_format = """<|im_start|>user
Resuelve: ¿Cuánto es 15 * 23?<|im_end|>
<|im_start|>assistant
<think>
15 * 23 = 15 * 20 + 15 * 3 = 300 + 45 = 345
</think>
La respuesta es 345.<|im_end|>"""
# Módulos objetivo LoRA para DeepSeek-R1-Distill (base Qwen2.5)
lora_config = LoraConfig(
r=32,
lora_alpha=16,
target_modules=["q_proj", "k_proj", "v_proj", "o_proj",
"gate_proj", "up_proj", "down_proj"],
use_dora=True,
task_type="CAUSAL_LM",
)