En pocas palabras: Un Llama 27B en IQ4_XS corriendo a 5,6 tok/s en un Mac Mini M4 demuestra que la capacidad de RAM no garantiza usabilidad. El ancho de banda es el cuello de botella real; hacé la aritmética antes de invertir.
Un modelo de lenguaje puede cargar perfectamente en la RAM y seguir siendo inútil para trabajo interactivo si el ancho de banda de memoria es el cuello de botella. Tal como se documenta en un análisis técnico, un Llama de 27B cuantizado a IQ4_XS (15 GB) en un Mac Mini M4 generó apenas 5.6 tokens por segundo, muy lejos del techo teórico de 8 tok/s dictado por los 120 GB/s de bus, lo que demuestra que la aritmética de throughput debe preceder a cualquier decisión de hardware o configuración en llama.cpp rendimiento. Cubrimos ese tema en detalle en configurar un LLM local con Ollama.
En este artículo:
- En 30 segundos
- ¿Por qué ‘cabe en memoria’ no significa que sea usable?
- ¿Cómo calcular el máximo de tokens por segundo posible?
- ¿Cuándo la cuantización agresiva deja de ser útil?
- ¿Qué intervenciones funcionan si el cuello de botella es la memoria?
- ¿Cómo diagnosticar si tu sistema está limitado por swap o por ancho de banda?
- Errores comunes al optimizar LLMs locales
- Preguntas Frecuentes
- Conclusión
- Fuentes
En 30 segundos
- Capacidad no es velocidad: Que el modelo ocupe 15 GB en una máquina con 24 GB no garantiza usabilidad; el límite real es cuántos bytes se mueven por segundo.
- Fórmula de supervivencia: Techo de tokens ≈ Ancho de Banda ÷ Tamaño del modelo. Si tu medición es más del 50% de este techo, estás limitado físicamente por el bus de memoria.
- Cuantización engañosa: Bajar de IQ4_XS a Q3_K_M solo mejora un 9% la velocidad pero degrada la calidad desproporcionadamente cuando ya eres bandwidth-bound.
- Diagnóstico rápido: Medí siempre “en caliente” (warm) con el modelo residente para excluir presión de swap; si el ratio es alto, cambiar de GPU o CPU no sirve, necesitás más ancho de banda.
Llama es una herramienta de desarrollo que permite verificar si un recurso encaja en la memoria disponible antes de realizar operaciones de red. Se utiliza para calcular el ancho de banda necesario y evitar fallos por falta de recursos durante la carga de datos.
llama.cpp es un motor de inferencia de código abierto que permite ejecutar modelos de lenguaje grandes (LLMs) localmente optimizando el uso de recursos, mientras que el concepto de “bandwidth arithmetic” es el cálculo crítico que determina si esa ejecución será práctica o frustrante según las especificaciones físicas de tu hardware.¿Por qué ‘cabe en memoria’ no significa que sea usable?
Ponele que tenés un Mac Mini M4 con 24GB de memoria unificada y ~120GB/s de ancho de banda. Cargás un modelo de 27B parámetros, cuantizado a IQ4_XS, que ocupa 15GB en disco. El sistema operativo dice que todo está bien: el working set recomendado es de 17.76GB, el modelo entra sin hacer swap, reporta 100% de residencia en GPU. Por cada criterio tradicional de “¿cabe?”, esto es un éxito rotundo. Y sin embargo, genera 5.6 tokens por segundo. Eso no es un trabajador interactivo útil. Es apenas un trabajador batch mediocre. Nada en la verificación de capacidad advirtió sobre esta lentitud porque la capacidad mide bytes totales disponibles, mientras que el throughput mide bytes movidos por segundo a través de un bus. Son recursos distintos gobernados por leyes físicas diferentes. Si alguna vez configuraste un servidor y viste que el disco tiene espacio libre pero la base de datos va lenta, sabés de qué hablo: el cuello de botella no estaba en dónde guardabas los datos, sino en cómo llegaban al procesador. El error común es asumir que pasar el “gate de carga” implica pasar el “gate de utilidad”. La carga es gratis de verificar (el archivo existe o no), pero el throughput requiere una medición activa o un cálculo previo. Sin ese paso intermedio, tomás decisiones de compra o configuración basadas en una premisa incompleta.¿Cómo calcular el máximo de tokens por segundo posible?

¿Cuándo la cuantización agresiva deja de ser útil?
Aquí viene la trampa donde cae casi todo el mundo. Si el modelo va lento, el instinto es “cuantizar más bajo”. Bajamos de IQ4_XS (15GB) a Q3_K_M (13.8GB). Suena lógico: menos bytes, más rápido. Hagamos la división otra vez: 120 GB/s ÷ 13.8 GB = 8.7 tokens/segundo. Pasamos de un techo de 8 a uno de 8.7. Una mejora del 9%. Para lograr ese mísero incremento, sacrificás una cantidad significativa de precisión matemática, porque el error de cuantización no escala linealmente con el tamaño como sí lo hace el ancho de banda. En este régimen, pagás mucho más de lo que ganás. Subís el modelo, lo probás en local, funciona bárbaro, lo mandás a producción y de repente todo se rompe porque nadie hizo la cuenta antes, asumiendo que menos peso significaba proporcionalmente más velocidad sin entender que el cuello de botella era el bus, no la capacidad de almacenamiento. El autor menciona que descartó ese plan sin siquiera descargar el modelo, gracias a la aritmética previa. Esa es la verdadera optimización: evitar tardes enteras haciendo benchmarks de configuraciones que físicamente no podían ganar.¿Qué intervenciones funcionan si el cuello de botella es la memoria?
Una vez que nombrás correctamente el recurso restringido (ancho de banda), el conjunto de intervenciones posibles se reduce drásticamente. Tunear parámetros de `llama.cpp` como `n_threads` o `batch_size` no va a mover la aguja si el bus ya está saturado. Lo que sí funciona son cambios estructurales:| Intervención | Efecto en Throughput | Costo/Esfuerzo | Viabilidad |
|---|---|---|---|
| Aceptar latencia alta | Ninguno (mantiene 5.6 tok/s) | Bajo | Solo para tareas batch/no interactivas |
| Cambiar hardware (más bus) | Directo (ej. 273GB/s → ~18 tok/s) | Alto | Única solución real para tiempo real |
| Mover carga a servidor | Depende del servidor | Medio | Si tenés acceso a GPUs de datacenter |
| Reducir cuantización | Mínimo (<10%) | Bajo | Ineficiente, pierde calidad sin ganar velocidad |
¿Cómo diagnosticar si tu sistema está limitado por swap o por ancho de banda?
Mucha gente confunde los síntomas. Ven lentitud y piensan “debe estar usando swap” o “falta RAM”. Pero medir en frío, con otras aplicaciones abiertas, contamina el dato. Tenés que medir “en caliente”, con el modelo ya residente en memoria y el sistema estable. Si después de limpiar procesos pesados y asegurar que no hay spillover, el rendimiento sigue clavado cerca del techo calculado (ratio > 0.5), entonces es ancho de banda. Punto. No hay configuración de software que arregle la física del bus de memoria. Los anti-patrones más comunes que vi en foros y chats técnicos:- “Cargó, así que podemos usarlo”: Falso. Cargar es el gate de capacidad. Pasar ese gate deja el throughput totalmente desconocido.
- “Es lento, así que cuantizo más bajo”: En regímenes limitados por ancho de banda, esto es inútil. Solo degradás la calidad.
- “Debe ser presión de memoria”: Si no medís en caliente, mezclás el techo físico con congestión transitoria. Acá no había presión, el techo era exactamente donde la aritmética lo ponía.
