Local LLMs
Correr modelos on-premise con llama.cpp: privacidad, coste y control total
Usar LLMs locales significa correr el modelo en tu propio hardware — sin llamadas a APIs externas, sin enviar datos a servidores de terceros, sin coste por token. La contrapartida es que necesitas gestionar el hardware, la memoria, y la configuración del entorno. El motor más adoptado para esto es llama.cpp, una implementación en C++ de inferencia de LLMs optimizada para CPU y GPU que puede correr modelos de decenas de miles de millones de parámetros en hardware de consumo.
El formato GGUF (GPT-Generated Unified Format) es el estándar de facto para distribuir modelos cuantizados para llama.cpp. Un archivo .gguf contiene los pesos del modelo más metadatos de configuración. Antes de GGUF existía GGML; si ves referencias a archivos .bin de GGML, son el formato anterior — no compatibles directamente. Sitios como Hugging Face hospedan cientos de modelos en GGUF listos para descargar.
La cuantización reduce la precisión numérica de los pesos del modelo para que ocupen menos memoria y se ejecuten más rápido, con una pérdida de calidad controlada. Q4_K_M es el balance calidad/velocidad más recomendado para hardware de consumo: cuantiza a 4 bits con una mejora de agrupamiento (K-means), resultando en modelos que ocupan aproximadamente la cuarta parte del tamaño en float16. Q8_0 es más preciso pero el doble de grande; Q2_K es muy pequeño pero con pérdida de calidad notable.
El offloading controla cuántas capas del modelo van a la GPU (rápido, paralelo) vs. cuántas van a la CPU/RAM (lento, serial). El flag `-ngl` (n_gpu_layers) en llama.cpp define cuántas capas se mueven a la VRAM. Si tienes 8GB de VRAM, puedes offloadear más capas que con 4GB. El objetivo es maximizar `-ngl` sin exceder la VRAM disponible — si excedes, el proceso falla con un error de memoria. Puedes ajustar `-ngl` de forma empírica: empieza alto y baja si falla.
Resultados reales medidos con Qwen3.6-35B en GPU propia demuestran que con hardware correcto es posible lograr velocidades de inferencia competitivas — y ese tipo de benchmarks están documentados en https://labs.benjacode.com. El modelo Qwen3.6-35B en Q4_K_M ocupa aproximadamente 20GB, viable en una GPU con 24GB de VRAM. Modelos más pequeños como Qwen2.5-7B o Mistral-7B caben completos en 6-8GB de VRAM con cuantización Q4.
La privacidad y el coste son las razones principales para correr modelos locales en producción: datos sensibles (salud, legal, financiero) que no pueden salir de tu infraestructura; workloads con millones de tokens al día donde el coste de API es prohibitivo; entornos sin acceso a internet; y la capacidad de hacer fine-tuning en tus propios datos. La desventaja principal es la capacidad de los modelos locales: Qwen3.6-35B es excelente, pero sigue por debajo de los modelos frontier (GPT-4o, Claude Opus) en benchmarks complejos.
# Download a model (GGUF format)
huggingface-cli download \
bartowski/Qwen2.5-7B-Instruct-GGUF \
Qwen2.5-7B-Instruct-Q4_K_M.gguf \
--local-dir ./models
# Run with llama.cpp CLI
llama-cli \
--model ./models/Qwen2.5-7B-Instruct-Q4_K_M.gguf \
--n-gpu-layers 35 \ # layers to offload to GPU
--ctx-size 4096 \ # context window in tokens
--threads 8 \ # CPU threads for non-GPU layers
--prompt 'Q: What is RAG?\nA:'
# Run as OpenAI-compatible server
llama-server \
--model ./models/Qwen2.5-7B-Instruct-Q4_K_M.gguf \
--n-gpu-layers 35 \
--ctx-size 8192 \
--host 0.0.0.0 \
--port 8080
# Call the local server with OpenAI client
from openai import OpenAI
client = OpenAI(base_url='http://localhost:8080/v1', api_key='na')
response = client.chat.completions.create(
model='local',
messages=[{'role': 'user', 'content': 'Explain quantization in 2 sentences.'}],
max_tokens=256,
temperature=0.0
)
# VRAM estimation formula
# VRAM (GB) ≈ (params_B * bits_per_weight) / 8 + 1GB overhead
# Example: 7B model, Q4 (4 bits) = (7 * 4) / 8 + 1 = 4.5 GB
# Example: 35B model, Q4 (4 bits) = (35 * 4) / 8 + 1 = 18.5 GBDebugging lab
Detecta y corrige el error en el código.
- 4.5.5.1
llama-cli --model model.gguf --n-gpu-layers 0 --ctx-size 32768 # running 7B model entirely on CPU
- 4.5.5.2
# Trying to load a 35B Q8_0 model (38GB) on a 24GB VRAM GPU llama-cli --model qwen35b-q8_0.gguf --n-gpu-layers 94
- 4.5.5.3
# Exposing local LLM server to the internet llama-server --model model.gguf --host 0.0.0.0 --port 8080 # no auth, public IP
- 4.5.5.4
# Using a GGML .bin file with modern llama.cpp llama-cli --model old-model.bin
- 4.5.5.5
# Context overflow: task requires 6000 tokens but ctx-size is 2048 llama-server --model model.gguf --n-gpu-layers 35 --ctx-size 2048