Gestión de modelos en oMLX: descarga, alias, TTL y caché en disco
oMLX gestiona el ciclo de vida de cada modelo con cuatro piezas: un descargador que trae pesos desde Hugging Face, alias que renombran el modelo en la API, un TTL que lo descarga tras un tiempo inactivo y una caché KV por niveles que vuelca bloques al SSD cuando la RAM se llena.
En un Mac con memoria unificada no hay VRAM aparte: cada modelo que cargas sale del mismo límite de memoria que usa el resto del sistema. Por eso la parte más interesante de oMLX no es servir peticiones, sino decidir qué modelo ocupa RAM en cada momento. Este artículo recorre las cuatro piezas que gobiernan esa decisión y cómo se configuran.
Puntos clave
- El descargador integrado busca y trae modelos MLX desde Hugging Face sin salir del panel de administración.
- Un alias cambia el nombre con el que el modelo aparece en la API; el endpoint
/v1/modelsdevuelve el alias y las peticiones aceptan tanto el alias como el nombre del directorio. - El TTL por modelo lo descarga solo tras un periodo inactivo, y la expulsión LRU libera los menos usados cuando falta memoria.
- El límite total por defecto es la RAM del sistema menos 8 GB, pensado para evitar que el Mac entero se quede sin memoria.
- La caché KV por niveles vuelca bloques al SSD en formato safetensors y los recupera después, incluso tras reiniciar el servidor.
Dónde viven los modelos
Los modelos se guardan en subdirectorios del directorio de modelos, que se elige con --model-dir. oMLX admite carpetas de dos niveles, del estilo mlx-community/nombre-del-modelo/, que es exactamente la forma en que Hugging Face organiza sus repositorios, y detecta el tipo de modelo automáticamente.
Esa convención importa más de lo que parece: si descargas los pesos por tu cuenta y los dejas en una carpeta plana, pierdes la correspondencia con el identificador del repositorio de origen y acabas con nombres ambiguos en la API.
El descargador integrado
El panel de administración incorpora un buscador que consulta Hugging Face, muestra las fichas de modelo con el tamaño de los ficheros y descarga con un clic. Es la vía recomendada porque deja los pesos en la estructura de dos niveles ya correcta.
La alternativa manual sigue disponible: clonar el repositorio en --model-dir respetando la jerarquía. Conviene mirar el tamaño antes de empezar, porque un modelo grande cuantizado puede ocupar decenas de gigabytes y la descarga no es reanudable a voluntad.
Alias: separar el nombre de la ruta
Un alias es un nombre visible en la API distinto del nombre del directorio. Se define en el panel, por modelo, y a partir de ahí /v1/models devuelve el alias mientras las peticiones siguen aceptando ambos.
Sirve para dos cosas concretas. La primera, estabilizar los nombres: si tu cliente pide coder-rapido en lugar de Qwen3-Coder-30B-A3B-Instruct-mlx-8bit, puedes cambiar el modelo real por debajo sin tocar el cliente. La segunda, mapear nombres que un cliente espera encontrar. Es el mismo truco que hace falta cuando apuntas Claude Code a tu servidor local.
TTL, anclaje y expulsión LRU
Aquí es donde oMLX decide, sin ti, qué sale de memoria. Tres mecanismos actúan a la vez:
| Mecanismo | Qué hace | Dónde se configura |
|---|---|---|
| TTL por modelo | Descarga el modelo tras un tiempo de inactividad | Panel, por modelo |
| Anclaje | Mantiene siempre cargado un modelo de uso frecuente | Panel, por modelo |
| Expulsión LRU | Expulsa los modelos menos usados recientemente cuando falta memoria | Automático |
| Límite total | Techo de memoria del proceso; por defecto, la RAM del sistema menos 8 GB | --memory-guard-gb, --memory-guard |
La combinación útil en un equipo de trabajo suele ser: anclar el modelo pequeño que usas todo el día, poner un TTL corto a los grandes que solo aparecen en tareas puntuales y dejar que el LRU se encargue del resto. Así el modelo caro se descarga solo cuando dejas de usarlo, en vez de quedarse ocupando memoria hasta que te acuerdas.
El límite total merece una nota. Su valor por defecto, la RAM del sistema menos 8 GB, no es una cifra arbitraria: son los 8 GB que el sistema operativo y tus aplicaciones necesitan para no empezar a paginar. Si lo subes con --memory-guard-gb, el que se queda sin margen es macOS.
La caché KV por niveles
Esta es la pieza menos evidente y la que más rendimiento aporta en trabajo repetitivo. La caché de claves y valores opera en dos niveles: uno caliente en RAM, con los bloques de acceso frecuente, y uno frío en SSD.
Cuando el nivel caliente se llena, los bloques se vuelcan al disco en formato safetensors. En peticiones posteriores cuyo prefijo coincide, según la documentación del proyecto los bloques "are restored from disk instead of recomputed from scratch – even after a server restart", es decir, se restauran desde disco en lugar de recalcularse desde cero, incluso después de reiniciar el servidor.
Que el formato sea safetensors no es un detalle menor. Hugging Face lo define como "a new simple format for storing tensors safely (as opposed to pickle) and that is still fast (zero-copy)": un formato de carga sin copia, que es justo lo que quieres cuando estás recuperando bloques de disco en el camino crítico de una respuesta.
Se activa apuntando un directorio:
omlx serve --model-dir ~/models \
--paged-ssd-cache-dir ~/.omlx/cache \
--hot-cache-max-size 20% \
--max-concurrent-requests 16
--hot-cache-max-size acepta un porcentaje del límite de memoria y --max-concurrent-requests sube el paralelismo desde su valor por defecto de 8. Subirlo tiene sentido si sirves a varios clientes; en un uso individual, 8 sobra y cada petición concurrente compite por la misma memoria.
Dónde se guarda todo esto
Los ajustes persisten en ~/.omlx/settings.json, y los indicadores de la línea de órdenes tienen precedencia sobre lo guardado. Esa precedencia es la que conviene recordar cuando algo no cuadra: si arrancaste el servidor con un indicador y luego cambiaste el valor en el panel, el indicador sigue mandando en esa ejecución.
Para inspeccionar el estado sin abrir el panel, la API de administración expone el estado de carga, la memoria ocupada y la ventana de contexto de cada modelo. Si prefieres consultarlo desde una conversación en lugar de con curl, el puente MCP para oMLX envuelve justo esos endpoints.
Preguntas frecuentes
¿El TTL descarga un modelo en mitad de una petición? No. El TTL cuenta tiempo inactivo; una petición en curso mantiene el modelo vivo.
¿La caché en SSD desgasta el disco? Escribe bloques de forma continua, así que sí genera escritura sostenida. Si te preocupa, deja el nivel caliente más grande y el frío en un disco externo mediante --paged-ssd-cache-dir.
¿Puedo cambiar los ajustes de un modelo sin reiniciar? Sí. Los parámetros de muestreo, los argumentos de la plantilla de chat, el TTL, el alias y el tipo de modelo se cambian desde el panel sin reiniciar el servidor.
Conclusión
La gestión de modelos en oMLX se reduce a decidir dos cosas: qué ocupa RAM y qué se recalcula. Los alias y el descargador resuelven la parte de organización; el TTL, el anclaje y el LRU resuelven la de memoria; y la caché KV por niveles evita repetir trabajo que ya hiciste. Si vas a montarlo desde cero, empieza por la guía de instalación y ajuste de oMLX y vuelve aquí cuando tengas más de un modelo compitiendo por la misma memoria. La versión en inglés está en model management in oMLX.