Optimización de Modelos LLM¶
Tiempo de lectura: 25 minutos | Dificultad: Intermedia | Categoría: Inteligencia Artificial
Resumen¶
La optimización de modelos LLM es crucial para ejecutar modelos grandes en hardware limitado. Esta guía cubre técnicas como cuantización, pruning, distilación y estrategias de deployment que permiten reducir el uso de memoria y mejorar el rendimiento sin sacrificar significativamente la calidad.
🎯 Por Qué Optimizar Modelos LLM¶
Problemas Comunes sin Optimización¶
- Memoria insuficiente: Modelos de 7B-70B parámetros requieren 14-140GB+ de RAM/VRAM
- Velocidad lenta: Inferencia puede tomar segundos por token
- Costos elevados: Hardware GPU caro para deployment
- Escalabilidad limitada: Dificultad para servir múltiples usuarios
Beneficios de la Optimización¶
- ✅ 70-90% menos memoria con cuantización 4-bit
- ✅ 2-5x más velocidad de inferencia
- ✅ Hardware más accesible: GPUs de gama media o CPUs
- ✅ Mayor throughput: Más usuarios simultáneos
- ✅ Costos reducidos: Menos hardware necesario
🔢 Cuantización (Quantization)¶
¿Qué es la Cuantización?¶
La cuantización reduce la precisión de los pesos del modelo de float32 (4 bytes) a formatos más pequeños como float16, int8 o int4, manteniendo la funcionalidad.
Tipos de Cuantización¶
1. Post-Training Quantization (PTQ)¶
- Se aplica después del entrenamiento
- No requiere re-entrenamiento
- Rápida y sencilla de implementar
# Ejemplo con Ollama (GGUF quantization)
ollama pull llama2:7b
ollama pull llama2:7b-q4_0 # Versión cuantizada 4-bit
2. Quantization-Aware Training (QAT)¶
- Se entrena considerando la cuantización
- Mejor precisión pero más complejo
- Usado en producción crítica
Niveles de Cuantización¶
| Precisión | Memoria | Velocidad | Calidad | Uso |
|---|---|---|---|---|
| FP32 | 100% | 100% | 100% | Entrenamiento |
| FP16 | 50% | ~2x | 99.9% | GPUs modernas |
| INT8 | 25% | ~4x | 98-99% | GPUs, CPUs |
| INT4 | 12.5% | ~8x | 95-97% | CPUs, edge |
Implementación Práctica¶
Con Ollama (GGUF)¶
# Descargar modelo base
ollama pull llama2:7b
# Crear modelo cuantizado personalizado
cat > Modelfile << EOF
FROM llama2:7b
PARAMETER temperature 0.8
PARAMETER top_p 0.9
QUANTIZE q4_0
EOF
ollama create llama2-custom:q4_0 -f Modelfile
Con llama.cpp¶
# Convertir y cuantizar modelo
git clone https://github.com/ggerganov/llama.cpp
cd llama.cpp
# Convertir PyTorch a GGML
python convert.py --model /path/to/model.bin --type f16
# Cuantizar a diferentes formatos
./quantize /path/to/model-f16.bin /path/to/model-q4_0.bin q4_0
🌿 Pruning (Poda)¶
Concepto Básico¶
El pruning elimina conexiones neuronales poco importantes, reduciendo el tamaño del modelo sin afectar significativamente el rendimiento.
Técnicas de Pruning¶
1. Weight Pruning¶
- Elimina pesos individuales por debajo de un threshold
- Efectivo pero requiere fine-tuning posterior
2. Structured Pruning¶
- Elimina neuronas, capas o atención heads completas
- Más eficiente para hardware
- Ejemplos: eliminar 20-30% de atención heads
3. Dynamic Pruning¶
- Ajusta la estructura durante inferencia
- Trade-off entre calidad y velocidad
Ejemplo Práctico¶
import torch
from transformers import AutoModelForCausalLM
# Cargar modelo
model = AutoModelForCausalLM.from_pretrained("microsoft/DialoGPT-medium")
# Aplicar pruning (simplificado)
def prune_weights(model, threshold=0.1):
for name, param in model.named_parameters():
if 'weight' in name:
mask = torch.abs(param) > threshold
param.data *= mask.float()
prune_weights(model)
🧪 Distilación (Knowledge Distillation)¶
¿Qué es la Distilación?¶
La distilación transfiere conocimiento de un modelo grande ("teacher") a uno más pequeño ("student"), manteniendo la mayoría del rendimiento.
Proceso de Distilación¶
- Teacher Model: Modelo grande y preciso
- Student Model: Modelo pequeño a entrenar
- Soft Targets: El student aprende de las distribuciones de probabilidad del teacher
- Fine-tuning: Ajuste final en datos reales
Ventajas¶
- ✅ Mejor ratio calidad/tamaño que cuantización sola
- ✅ Modelo más pequeño pero inteligente
- ✅ Transfer learning efectivo
Ejemplo con Hugging Face¶
from transformers import AutoModelForCausalLM, AutoTokenizer
import torch
# Modelo teacher (grande)
teacher = AutoModelForCausalLM.from_pretrained("gpt2-large")
# Modelo student (pequeño)
student = AutoModelForCausalLM.from_pretrained("gpt2")
# Función de pérdida de distilación
def distillation_loss(student_logits, teacher_logits, temperature=2.0):
soft_targets = torch.softmax(teacher_logits / temperature, dim=-1)
student_soft = torch.log_softmax(student_logits / temperature, dim=-1)
return torch.nn.functional.kl_div(student_soft, soft_targets, reduction='batchmean')
🚀 Estrategias de Deployment¶
1. CPU vs GPU Optimization¶
Optimizaciones para CPU¶
# Usar llama.cpp con optimizaciones CPU
./main -m model.bin --threads 8 --ctx-size 2048 -p "Prompt"
Optimizaciones para GPU¶
# Con vLLM
from vllm import LLM
llm = LLM(
model="microsoft/DialoGPT-large",
tensor_parallel_size=2, # Multi-GPU
gpu_memory_utilization=0.9,
max_model_len=4096
)
2. Batch Processing¶
# Procesamiento por lotes para mayor throughput
prompts = ["Prompt 1", "Prompt 2", "Prompt 3"]
# Inferencia por lotes
outputs = llm.generate(prompts, max_tokens=100)
3. Model Caching y Prefilling¶
# Cache de KV para prompts comunes
from transformers import Cache
cache = Cache()
model = AutoModelForCausalLM.from_pretrained("gpt2", use_cache=True)
# Primera inferencia crea cache
output1 = model.generate("Common prefix", use_cache=True)
# Inferencias posteriores reutilizan cache
output2 = model.generate("Common prefix + continuation", past_key_values=output1.past_key_values)
📊 Benchmarks y Comparativas¶
Resultados Típicos de Optimización¶
| Técnica | Modelo | Tamaño Original | Tamaño Optimizado | Degradación | Velocidad |
|---|---|---|---|---|---|
| FP16 | LLaMA-7B | 13GB | 6.5GB | ~0% | 2x |
| INT8 | LLaMA-7B | 13GB | 3.5GB | 1-2% | 4x |
| INT4 | LLaMA-7B | 13GB | 1.8GB | 3-5% | 8x |
| Pruning 20% | GPT-2 | 1.5GB | 1.2GB | 2-3% | 1.5x |
| Distilación | BERT Large→Base | 340M→110M params | 67% menos | 3-5% | 2x |
Hardware Recommendations¶
| Hardware | Modelo Máximo | Técnica Recomendada |
|---|---|---|
| CPU (16GB RAM) | 7B Q4 | GGUF + llama.cpp |
| GPU RTX 3060 (12GB) | 13B FP16 | vLLM + tensor parallel |
| GPU RTX 4080 (16GB) | 30B Q4 | Ollama + cuantización |
| CPU Server (128GB) | 70B Q4 | llama.cpp + threads |
🛠️ Herramientas y Frameworks¶
Frameworks de Optimización¶
1. GGUF (GPT-Generated Unified Format)¶
- Formato de cuantización de llama.cpp
- Compatible con múltiples plataformas
- Optimizado para CPU y GPU
# Convertir modelo a GGUF
python convert-hf-to-gguf.py --model /path/to/model --outdir /output/dir
2. AWQ (Activation-aware Weight Quantization)¶
- Cuantización que considera activaciones
- Mejor precisión que PTQ estándar
- Especialmente bueno para GPUs
3. GPTQ (GPT Quantization)¶
- Cuantización post-entrenamiento
- Mantiene alta calidad
- Compatible con AutoGPTQ
Herramientas Prácticas¶
# Benchmark con llama.cpp
./llama-bench -m model.gguf -p 512 -n 128 -t 8
# Perfilado de memoria
python -c "
import torch
from transformers import AutoModel
model = AutoModel.from_pretrained('model')
print(f'Model size: {sum(p.numel() for p in model.parameters()) / 1e6:.1f}M parameters')
print(f'Memory: {torch.cuda.memory_allocated()/1e9:.2f}GB')
"
⚠️ Consideraciones y Limitaciones¶
Trade-offs Importantes¶
- Precisión vs Velocidad: Más cuantización = más velocidad pero menos precisión
- Calidad vs Tamaño: Modelos más pequeños pueden perder capacidades específicas
- Hardware vs Software: Optimizaciones dependen del hardware objetivo
Errores Comunes¶
- Cuantización excesiva: INT2/INT3 puede hacer modelos inutilizables
- Pruning agresivo: Eliminar >50% puede causar colapso del rendimiento
- Ignorar fine-tuning: Modelos optimizados necesitan ajuste posterior
Mejores Prácticas¶
- ✅ Probar exhaustivamente después de optimizar
- ✅ Monitorear calidad con métricas automatizadas
- ✅ A/B testing entre versiones optimizadas
- ✅ Documentar trade-offs para stakeholders
🔗 Recursos Adicionales¶
📚 Próximos Pasos¶
Después de optimizar modelos, considera:
- Chatbots Locales - Construir interfaces conversacionales
- Prompt Engineering - Técnicas para mejores resultados
- Deployment en Producción - Servir modelos optimizados a escala
¿Has optimizado algún modelo LLM? Comparte tus experiencias y mejores prácticas en los comentarios.