Benchmarks y techo de memoria en oMLX
Índice de contenidos
- Puntos clave
- El banco de pruebas del panel
- Qué mide exactamente
- Cómo medir sin engañarte
- El ranking comunitario
- El techo de memoria, que decide antes que nada
- Los errores que verás cuando no cabe
- Qué cambia la caché en los números
- Preguntas frecuentes
- ¿Por qué mis benchmarks de oMLX salen peor la primera vez?
- ¿Cuánto contexto cabe en mi Mac?
- ¿Puedo subir el techo de memoria por encima del valor por defecto?
- Conclusión
- Fuentes
oMLX trae un banco de pruebas en el panel que mide tiempo hasta el primer token, tiempo por token, tokens por segundo y pico de memoria, con prompts de 1.024 a 200.000 tokens. El techo de memoria por defecto es la RAM del sistema menos 8 GB, y es lo que decide qué contexto cabe.
Un número de tokens por segundo sin decir con qué contexto, con qué lote y con la caché caliente o fría no significa nada. oMLX trae un banco de pruebas integrado que mide las cuatro variables que sí importan, y un techo de memoria que decide antes que nada si la prueba cabe. Este artículo cubre ambas cosas y los mensajes de error que aparecen cuando no cabe.
Puntos clave
- El banco de pruebas vive en el panel de administración y mide rendimiento y calidad por separado.
- Las métricas son cuatro: tiempo hasta el primer token, tiempo por token de salida, tokens por segundo de generación y pico de memoria.
- Los prompts van de 1.024 a 200.000 tokens, y los lotes se prueban a 2x, 4x y 8x.
- El techo de memoria por defecto es la RAM del sistema menos 8 GB, y se ajusta con
memory_guard_tieren cuatro niveles. - Sin activar el modo de calentamiento, la primera medición incluye la compilación en tiempo de ejecución y sale sistemáticamente peor.
El banco de pruebas del panel
Está integrado en el panel de administración y tiene dos modos que responden a preguntas distintas.
El modo de rendimiento y latencia mide velocidad: cuánto tarda el modelo en empezar a responder, a qué ritmo genera y cuánta memoria pica. Es el que usas para decidir si un modelo es utilizable en tu máquina.
El modo de evaluación de calidad ejecuta pruebas estandarizadas como MMLU, GSM8K y HumanEval. Responde a otra pregunta: si el modelo, con la cuantización que le has puesto, sigue razonando bien. Esta parte importa mucho cuando bajas de bits, porque el coste en calidad no es lineal.
Los resultados llegan al navegador por Server-Sent Events con un modelo de reproducción al suscribirse, lo que significa que puedes cerrar la pestaña, volver y seguir viendo la prueba en marcha. Detalle pequeño, pero una prueba con contexto de 200.000 tokens tarda lo suyo.
Qué mide exactamente
Cuatro métricas, y conviene no confundirlas porque miden fases distintas de la misma petición:
| Métrica | Qué es | Qué la empeora |
|---|---|---|
| TTFT | Tiempo desde que se envía la petición hasta el primer token | Un prompt largo, la caché fría, la compilación en el primer uso |
| TPOT | Tiempo por token durante la generación | El tamaño del modelo, la cuantización, la competencia por memoria |
| Tokens por segundo | Rendimiento de generación | Lo mismo que TPOT, expresado al revés |
| Pico de memoria | Máximo ocupado, leído del propio motor | El contexto, el lote, el tamaño del modelo |
La separación entre TTFT y TPOT es la que más se ignora y la que más explica. El prefill, que es procesar el prompt entero, y la generación, que es producir token a token, escalan de forma distinta: el primero crece con la longitud del contexto, el segundo apenas. Un modelo puede tardar quince segundos en arrancar con un contexto de 100.000 tokens y luego generar a buena velocidad. Si solo miras tokens por segundo, no verás ese problema.
Las notas de la versión 0.6.4 lo ilustran bien: la mejora medida sobre un Apple M3 Ultra fue de un 33,5 % en procesamiento de prompt y un 24,2 % en tiempo total de petición con contexto de 32K. Dos cifras distintas para el mismo cambio, porque tocan fases distintas.
Cómo medir sin engañarte
Tres parámetros del banco de pruebas cambian el resultado más que el modelo:
El modo de calentamiento. Fuerza la compilación en tiempo de ejecución antes de empezar a medir. Sin él, la primera pasada incluye ese coste y sale peor que las siguientes. Actívalo siempre, salvo que lo que quieras medir sea precisamente cuánto tarda un arranque en frío.
La longitud del prompt. El menú va de 1.024 a 200.000 tokens. Mide con la longitud que vayas a usar de verdad. Un número obtenido con 1.024 tokens no dice nada sobre cómo se comportará el modelo con un fichero de código entero.
La prueba de caché. Hay dos escenarios, mismo prompt y prompt distinto, y comparan la caché de prefijo caliente contra la fría. La diferencia entre ambos es exactamente lo que te ahorra la caché por niveles en tu carga de trabajo real. Si trabajas siempre sobre el mismo contexto largo, el escenario de mismo prompt es tu caso y el de prompt distinto es pesimista.
El tamaño de lote (2x, 4x y 8x) solo importa si vas a servir peticiones concurrentes. Para un único usuario delante de un asistente, el lote de uno es el número honesto.
El ranking comunitario
Los resultados de la evaluación de calidad se pueden subir a omlx.ai, donde alimentan una clasificación comunitaria. La subida va en dos pasos: primero los metadatos del equipo y las puntuaciones finales, y después los resultados brutos por pregunta comprimidos.
Es útil para comparar tu máquina con otras del mismo chip, con la reserva de siempre: son mediciones enviadas por usuarios, con configuraciones que no controlas.
El techo de memoria, que decide antes que nada
En un Mac con memoria unificada no hay una memoria de vídeo aparte. Cada modelo cargado sale del mismo presupuesto que el sistema operativo y el resto de aplicaciones, así que oMLX impone un límite propio para que el Mac entero no se quede sin memoria.
Ese límite por defecto es la RAM del sistema menos 8 GB. En un Mac de 128 GB quedan 120 GB para modelos y caché; en uno de 16 GB quedan 8 GB, que es poco para casi cualquier cosa útil.
El nivel se ajusta con memory_guard_tier, que admite cuatro valores: safe, balanced (el predeterminado), aggressive y custom. Con custom fijas el techo tú mismo en memory_guard_custom_ceiling_gb. Desde la línea de comandos son --memory-guard y --memory-guard-gb.
Hay además un vigilante de prefill, prefill_memory_guard, activado por defecto, que comprueba si la petición cabe antes de empezar a procesarla. Es lo que convierte un cierre por falta de memoria en un error legible.
{
"memory_guard_tier": "custom",
"memory_guard_custom_ceiling_gb": 96,
"prefill_memory_guard": true,
"max_concurrent_requests": 8,
"hot_cache_max_size": "20%",
"ssd_cache_max_size": "auto"
}
Cuidado con hot_cache_max_size: viene en "0", que desactiva la caché caliente en RAM. Si quieres que los bloques calientes se queden en memoria hay que ponerle un valor, en porcentaje o en gigabytes. ssd_cache_max_size viene en "auto", que se resuelve al 10 % de la capacidad del disco.
Los errores que verás cuando no cabe
Los mensajes que se encuentra la gente son de dos familias, y significan cosas distintas.
Los que hablan de que el prefill no cabe en la memoria disponible vienen del vigilante de prefill. El prompt que has mandado, con ese modelo y ese contexto, necesita más memoria de la que queda bajo el techo. No es que el modelo no quepa: es que el prompt no cabe. Las salidas son acortar el contexto, descargar otro modelo o subir el techo.
Los que hablan de que algo no cabe bajo el techo de memoria vienen del vigilante general, al intentar cargar un modelo. Aquí el problema es el modelo entero, y las salidas son una cuantización más agresiva, fijar menos modelos o cambiar de nivel.
Antes de tocar el techo, mira qué hay cargado. La expulsión por menos usado recientemente libera modelos sola, pero un modelo fijado no se descarga nunca y un TTL largo mantiene vivos modelos que no usas. El reparto está contado en detalle en gestión de modelos y memoria en oMLX.
Subir el techo por encima del valor por defecto es tentador y suele salir mal. Esos 8 GB de reserva no son conservadurismo gratuito: son lo que necesita macOS para no empezar a comprimir memoria, momento en el que el rendimiento cae mucho más de lo que ganas con el contexto extra.
Qué cambia la caché en los números
La caché de claves y valores por niveles altera el TTFT de forma drástica y no toca el TPOT. Los bloques calientes viven en RAM y los fríos se vuelcan al SSD en formato safetensors; cuando llega una petición con el mismo prefijo, se recuperan del disco en lugar de recalcularse, y eso funciona incluso después de reiniciar el servidor.
Encima de eso, TurboQuant cuantiza la propia caché con un códec de error cuadrático medio y un cuantizador de Lloyd-Max, y reduce su tamaño entre un 60 % y un 75 %. Menos memoria por token de contexto significa más contexto bajo el mismo techo.
La consecuencia práctica al medir es que tienes que decidir qué quieres saber. Con la caché caliente mides el caso bueno, el de una conversación que continúa. Con la caché fría mides el caso malo, el de la primera petición del día. Los dos números son verdad y describen momentos distintos.
Preguntas frecuentes
¿Por qué mis benchmarks de oMLX salen peor la primera vez?
Porque la primera pasada incluye la compilación en tiempo de ejecución y, si la caché de prefijo está fría, también el recálculo del prompt entero. Activa el modo de calentamiento del banco de pruebas y descarta la primera medición.
¿Cuánto contexto cabe en mi Mac?
Depende del techo de memoria, que por defecto es la RAM del sistema menos 8 GB, de lo que ocupe el modelo cargado y de cuánto comprima TurboQuant la caché. En lugar de calcularlo, mídelo: lanza el banco de pruebas subiendo la longitud de prompt hasta que el vigilante de prefill rechace la petición.
¿Puedo subir el techo de memoria por encima del valor por defecto?
Sí, con memory_guard_tier en custom y un valor en memory_guard_custom_ceiling_gb. Hazlo con cuidado: la reserva de 8 GB existe para que macOS no empiece a comprimir memoria, y cuando eso pasa se pierde más rendimiento del que gana el contexto extra.
Conclusión
Medir bien en oMLX es sobre todo decidir qué estás midiendo. Separa el prefill de la generación, di siempre con qué contexto y con qué estado de caché, y activa el calentamiento. Con eso, los números del banco de pruebas del panel son comparables entre modelos y entre máquinas; sin eso, son ruido.
El techo de memoria es el otro lado de la misma moneda, porque fija el límite superior de todo lo demás. Si vienes de instalar el servidor, la configuración está en la guía de la API y el puerto, y el banco de pruebas se encuentra en el panel de administración. La versión inglesa de este artículo está en Benchmarks and the memory ceiling in oMLX.
Fuentes
Código fuente
Accede a todo el código fuente de este artículo en GitHub.
Ver en GitHub