Explorar notas
Inferencia local
La inferencia local ejecuta el modelo en hardware que controlas directamente. Un runtime como LM Studio o llama.cpp carga los pesos y genera la respuesta en tu equipo, así que memoria, contexto y reparto CPU/GPU pasan a formar parte del rendimiento que obtienes.
El problema práctico es hacer que el modelo y el estado necesario para la sesión quepan en la memoria disponible sin volver la generación demasiado lenta.
Pesos, formatos y cuantización
Los pesos contienen los parámetros aprendidos del modelo. El número de parámetros da una primera idea del tamaño, pero la precisión utilizada para representarlos cambia mucho la memoria necesaria.
Un modelo de 27B almacenado a 16 bits necesita del orden de 54 GB solo para los pesos. Una GPU de 16 GB no puede cargar esa representación completa. La cuantización reduce la precisión de los valores y permite distribuir el mismo modelo en ficheros mucho menores.
Nombres como Q4_K_M o Q3_K_XL identifican esquemas concretos del ecosistema del runtime. Una cuantización de menos bits suele ahorrar memoria y puede cambiar calidad o velocidad. El compromiso se comprueba mejor sobre las tareas reales que mirando solo el tamaño del fichero.
GGUF es el formato utilizado por llama.cpp para guardar tensors y metadata del modelo. No es una cuantización: un fichero GGUF puede contener pesos con distintos esquemas.
VRAM, RAM y offload
Que el fichero de pesos mida menos que la VRAM no garantiza que la configuración completa vaya a cargar. También necesitan memoria la KV cache, los buffers del runtime y el propio sistema.
Cuando el modelo no cabe entero en VRAM, llama.cpp puede repartir capas entre GPU y CPU mediante GPU offload. Esto permite ejecutar modelos mayores, pero mover una parte relevante del cálculo a CPU puede reducir mucho la velocidad.
Las pruebas con Qwen3.8-27B y OpenCode lo mostraron claramente. El Q4 de unos 16,8 GB solo permitía 54/65 unidades de offload y generaba alrededor de 9 tokens/s. Un Q3 de unos 13,4 GB dejaba margen para mantener la carga completa en GPU y las requests cortas pasaron a unos 40–45 tokens/s.
Eso no demuestra que Q3 sea cinco veces más rápido que Q4. Cambiaron a la vez la cuantización y el reparto CPU/GPU. En esa configuración, eliminar el offload parcial resolvió el cuello de botella principal.
Contexto y KV cache
Una ventana de contexto mayor también consume más memoria. Durante prefill y decode, el runtime mantiene una KV cache con estado calculado para los tokens anteriores. Al crecer el contexto, esa cache deja menos margen para pesos y buffers.
En LM Studio se puede ajustar la longitud cargada y, para modelos compatibles, la precisión o ubicación de K y V. Cuantizar la cache puede recuperar VRAM a cambio de otro posible compromiso de calidad o rendimiento.
En el experimento Qwen, pasar K y V a Q4_0 permitió mantener una sesión grande con full GPU offload. La memoria dedicada llegó aproximadamente a 15,4 de 16 GB. La configuración seguía siendo utilizable, pero quedaba claro el coste físico de una ventana larga.
Carga el contexto que necesita la tarea y deja margen para el runtime en lugar de utilizar el máximo anunciado por defecto.
Runtime y ajustes
LM Studio proporciona una interfaz sobre llama.cpp para descargar, cargar y servir modelos. llama.cpp también ofrece herramientas como llama-cli y llama-server.
Los ajustes que más han cambiado mis pruebas son:
- GPU offload: cuánto trabajo puede permanecer en GPU.
- Context length y KV cache: cuánto contexto cabe y cuánta VRAM consume.
- Threads: relevantes cuando existe trabajo importante en CPU.
- Flash Attention: optimización del runtime que puede reducir memoria o mejorar velocidad en configuraciones compatibles.
Los parámetros de batch también pueden afectar al procesamiento del prompt. Los tocaría después de medir dónde está el cuello de botella; cambiar varios sliders a la vez hace difícil saber qué produjo la mejora.
Speculative decoding
Speculative decoding utiliza una ruta más barata, a menudo otro modelo pequeño, para proponer varios tokens que el modelo principal verifica. Puede acelerar decode cuando se aceptan suficientes candidatos y puede añadir overhead cuando el draft model encaja mal.
Tiene más sentido probarlo después de estabilizar memoria, contexto y reparto CPU/GPU.
API local
LM Studio y llama-server pueden exponer endpoints HTTP OpenAI-compatible. Un cliente puede reutilizar un SDK o un harness cambiando el base_url para apuntar al servidor local.
LM Studio realiza la inferencia. OpenCode, Codex u otro cliente puede aportar el harness, las tools y el loop. Servir el modelo por API no le da por sí solo acceso al filesystem o a la shell.
El servidor también puede escuchar en la LAN. En el experimento Qwen, LM Studio utilizaba la GPU del host Windows mientras OpenCode y las tools de pentesting se ejecutaban en una Kali virtualizada. La inferencia seguía siendo local aunque el cliente estuviera en otra máquina.
APIs de modelos cubre el formato de esas requests y los límites de compatibilidad.
Benchmarking
Un benchmark local es útil cuando permite comparar configuraciones y repetir la prueba. Como mínimo conviene registrar:
- Modelo y cuantización exactos.
- Runtime, hardware y GPU offload.
- Longitud de contexto y configuración de la KV cache.
- Tamaño del prompt y del output.
- Tokens/s de generación y, cuando importe, tiempo de prefill o TTFT.
- Uso máximo de VRAM y RAM.
Una prueba con un prompt corto no representa necesariamente una sesión de agente con 50K tokens activos. En el artículo de Qwen, las generaciones cortas del Q3 rondaban 40–45 tokens/s, mientras la prueba de contexto largo generó alrededor de 21 tokens/s. Ambas cifras corresponden a condiciones distintas y son útiles si se conservan esas condiciones al compararlas.
También conviene indicar si el tiempo incluye cargar el modelo o parte de un servidor ya warm.
Ajuste práctico
Una secuencia fácil de interpretar es:
- Elegir un tamaño de modelo razonable para la tarea.
- Escoger una cuantización que deje margen de memoria.
- Mantener en GPU todo lo posible y medir el efecto del offload.
- Cargar un contexto realista para el workload.
- Revisar el consumo de la KV cache y los buffers.
- Medir prefill, tokens/s y memoria con el uso real.
- Ajustar threads, batch o speculative decoding cuando ataquen un cuello de botella observado.
Una configuración útil mantiene suficiente calidad y contexto a una velocidad razonable para el hardware disponible.