Cuantizacion de modelos y llama.cpp en tu portatil

Portátil moderno mostrando salida de terminal con texto generado

Hace 18 meses, ejecutar un LLM razonable en hardware de consumo era ciencia ficción. En 2023, gracias a llama.cpp y a las técnicas de cuantización, puedes correr Llama 2 13B en un portátil con 16 GB de RAM sin GPU dedicada. Cubrimos cómo funciona la cuantización, qué calidad pierdes (y cuál no), y cuándo esto es opción real frente a APIs gestionadas.

El problema y la idea

Un modelo Llama 2 13B en precisión float16 ocupa unos 26 GB de memoria. Sin GPU con esa cantidad de VRAM, descartado. Y aunque tengas RAM suficiente, la inferencia en CPU sería lentísima por el ancho de banda de memoria.

La cuantización resuelve ambos problemas al mismo tiempo: en lugar de almacenar cada peso del modelo como float16 (16 bits), lo almacenas con menos bits — 8, 5, 4 o incluso 3. El modelo cabe en menos memoria y la inferencia es más rápida porque mueves menos bytes desde RAM a CPU.

A cambio pierdes precisión. El truco está en que esa pérdida es mucho menor de lo que la intuición sugiere. Llama 2 13B en Q4 (4 bits) ocupa ~7.5 GB y la calidad de respuesta es notablemente cercana al modelo original.

Niveles de cuantización en llama.cpp

llama.cpp ofrece varios niveles, identificados en el nombre del fichero GGUF:

  • Q8_0: 8 bits. Pérdida de calidad mínima respecto a fp16. Útil si tienes RAM de sobra.
  • Q6_K: 6 bits con técnica K-quants. Calidad muy buena. Sweet spot para hardware decente.
  • Q5_K_M: 5 bits, variante mediana de K-quants. Excelente balance.
  • Q4_K_M: 4 bits, variante mediana de K-quants. El más popular — calidad razonable, tamaño manejable.
  • Q4_0: 4 bits cuantización clásica. Más rápido pero menos preciso que K_M.
  • Q3_K_M / Q2_K: para casos donde la memoria es muy limitada. Calidad notablemente degradada.

Como regla práctica para 2023:

  • 16 GB RAM, sin GPU: Llama 2 13B en Q4_K_M, o 7B en Q5/Q6_K si quieres más calidad.
  • 32 GB RAM: Llama 2 13B en Q5_K_M o 70B en Q3_K_M (lento pero viable).
  • MacBook con Apple Silicon: aprovecha la unified memory; M1/M2 Pro+ corren 13B Q4 con razonable fluidez.

El formato GGUF

llama.cpp inicialmente usó GGML como formato de fichero. En agosto de 2023 se introdujo GGUF como sucesor — más extensible y con metadatos mejor estructurados. Si descargas modelos de Hugging Face en 2023 y posteriores, GGUF es el formato estándar.

El formato encapsula los pesos cuantizados, el vocabulario, la configuración del tokenizer y los hiperparámetros — todo en un único fichero autocontenido.

Cómo se usa en la práctica

# Compilar (con soporte Metal en Mac, CUDA en Linux con GPU)
git clone https://github.com/ggerganov/llama.cpp
cd llama.cpp
make

# Descargar un modelo cuantizado, por ejemplo desde Hugging Face
# (TheBloke publica versiones GGUF de prácticamente todos los modelos populares)

# Ejecutar
./main -m ./models/llama-2-13b-chat.Q4_K_M.gguf \
       -p "Explica la cuantización en una frase" \
       -n 256

Para integrarlo en aplicaciones, llama.cpp expone:

  • Servidor HTTP (./server) compatible parcialmente con la API de OpenAI.
  • Bindings Python (llama-cpp-python).
  • Integración con LangChain y LlamaIndex como LLM local.

La calidad real que obtienes

Hablando claro: un Llama 2 13B Q4 no es GPT-4. Donde rinde bien:

  • Resúmenes y reescrituras cortas con instrucciones claras.
  • Q&A sobre contexto provisto (RAG con documentos).
  • Clasificación y extracción estructurada con pocos ejemplos few-shot.
  • Generación de código sencillo en lenguajes populares (Python, JS).
  • Conversación general en inglés, decente en otros idiomas.

Donde flaquea:

  • Razonamiento multi-paso complejo. La diferencia con GPT-4 es notable.
  • Conocimiento factual reciente. Su corpus es estático, sin acceso a internet.
  • Idiomas distintos del inglés — funciona pero notablemente peor.
  • Coding tareas no triviales. CodeLlama dedicado supera a Llama 2 base en este área.

Casos de uso donde llama.cpp brilla

Más allá del experimento personal, hay casos de uso reales donde correr local tiene sentido:

  • Privacy crítica. Documentos médicos, legales, código propietario que no puede salir de la red.
  • Coste a escala. Si procesas millones de peticiones simples, el coste de API se acumula. Local puede ser dramáticamente más barato.
  • Latencia ultra-baja. Sin roundtrip a un proveedor.
  • Edge / sin conectividad. Aplicaciones embebidas, terreno, dispositivos médicos sin red garantizada.
  • Experimentación libre. Probar fine-tuning, prompts agresivos, scenarios sin preocuparse por consumo de API.

Limitaciones que recordar

  • Velocidad: 5-30 tokens/segundo en CPU típica. Comparado con GPT-4 (~50 tps en API), es lento para conversación interactiva.
  • Context window: depende del modelo. Llama 2 base es 4K tokens; modelos extendidos llegan a 32K o más, pero a coste de calidad y velocidad.
  • Soporte multilingüe limitado sin fine-tuning específico.
  • Mantenimiento: tu propia infra de modelos. Actualizar a uno nuevo significa re-descargar y re-evaluar.

Conclusión

llama.cpp más cuantización han democratizado los LLMs en hardware de consumo. La calidad obtenible con un Llama 2 13B Q4_K_M en un portátil de 16 GB es notablemente útil para muchos casos de uso reales — no para todos, pero sí para muchos. Vale la pena tenerlo en el toolkit junto a APIs comerciales: cada uno gana en escenarios distintos.

Síguenos en jacar.es para más sobre LLMs locales, edge AI y construcción de productos con modelos open source.

Entradas relacionadas