Hypura – Programador de inferencia LLM consciente de la jerarquía de almacenamiento para Apple Silicon
(github.com/t8)- Optimiza la colocación de tensores entre GPU, RAM y NVMe para ejecutar modelos de lenguaje grandes con un programador de inferencia consciente de la jerarquía de almacenamiento
- Puede ejecutar el modelo Mixtral 8x7B (31GB) a 2.2 tok/s y el modelo Llama 70B (40GB) a 0.3 tok/s en una Mac Mini de 32GB
- Analiza patrones de acceso y ancho de banda del hardware para ejecutar de forma estable incluso modelos que superan la memoria física, incluyendo modelos que antes fallaban con OOM en llama.cpp
- Mediante enrutamiento de expertos en arquitectura MoE, caché de neuronas y prefetch, reduce la E/S hasta en 75% y logra una tasa de acierto de caché de 99.5%
- Selecciona automáticamente los modos Full-resident, Expert-streaming y Dense FFN-streaming según el tamaño del modelo y el hardware para mantener el mejor rendimiento
- Ofrece una API HTTP compatible con Ollama para integrarse con OpenClaw y otros, y usa el SSD en modo solo lectura para admitir inferencia basada en NVMe sin degradar su vida útil
Descripción general
- Hypura es un programador de inferencia LLM consciente de la jerarquía de almacenamiento para entornos Apple Silicon, una herramienta que realiza optimización de colocación de tensores entre GPU, RAM y NVMe
- Distribuye los tensores en función de patrones de acceso, costo de ancho de banda y rendimiento del hardware, lo que permite ejecutar de forma estable modelos grandes que exceden la memoria física
- En una Mac Mini de 32GB puede ejecutar el modelo Mixtral 8x7B (31GB) a 2.2 tok/s y el modelo Llama 70B (40GB) a 0.3 tok/s
- En el mismo entorno, llama.cpp no puede ejecutarlos por OOM (Out of Memory)
Contexto del problema
- Las Mac de consumo cuentan con memoria unificada rápida y almacenamiento NVMe, pero su capacidad de memoria es limitada
- Por ejemplo, una M1 Max de 32GB no puede cargar directamente un modelo de 40GB, lo que provoca swap excesivo y terminación por OOM
- Hypura resuelve este problema analizando la estructura del modelo y realizando una colocación óptima por jerarquías
Colocación por jerarquías basada en la estructura del modelo
- Norms y Embeddings: son pequeños, pero se accede a ellos en cada token, por lo que se fijan en la GPU
- Enrutamiento de expertos MoE: aprovecha la dispersión; solo se activan 2 expertos de 8 por token
- Con intercepción del router identifica los expertos activos y carga desde NVMe solo la parte necesaria
- Reduce la E/S en 75% y consigue una tasa de acierto de la caché de neuronas de 99.5%
- Con seguimiento de coactivación (co-activation tracking) predice los siguientes expertos activos y realiza prefetch por adelantado
- Pesos Dense FFN: representan aproximadamente 60% del tamaño del modelo
- Se transmiten desde NVMe mediante un buffer pool dinámico
- La profundidad de anticipación de prefetch (prefetch lookahead depth) se ajusta automáticamente según la memoria disponible
- Como resultado, también pueden ejecutarse modelos que antes se caían con el método tradicional basado en mmap, y los modelos que sí caben en memoria funcionan a velocidad de GPU Metal sin sobrecosto
Cómo funciona
- Hypura lee archivos GGUF y perfila el ancho de banda de GPU, RAM y NVMe
- Coloca cada tensor en una de las siguientes tres jerarquías
- GPU (Metal): capas de Attention, Norm y Embedding
- RAM: capas de desbordamiento que no pueden cargarse en la GPU
- NVMe: las capas restantes, con E/S directa mediante
F_NOCACHE+pread
- Según el tamaño del modelo y el hardware, selecciona automáticamente el modo de inferencia
- Full-resident: carga todo el modelo en GPU+RAM, sin E/S de NVMe
- Expert-streaming: para modelos MoE; solo los tensores no expertos permanecen en la GPU y los tensores de expertos se transmiten desde NVMe
- Dense FFN-streaming: para modelos grandes no MoE; Attention y Norm van en GPU, y FFN se transmite desde NVMe
- El tamaño del buffer pool, la profundidad de prefetch y el presupuesto de memoria se calculan automáticamente según el perfil del hardware
Rendimiento
- Entorno de prueba: M1 Max, 32GB de memoria unificada, NVMe de 5.1GB/s
- Resultados principales de benchmark
- Qwen 2.5 14B Q4_K_M (8.4GB): carga completa en GPU, 21 tok/s
- Mixtral 8x7B Q5_K_M (30.9GB): modo Expert-streaming, 2.2 tok/s, 99.5% de acierto de caché
- Llama 3.3 70B Q4_K_M (39.6GB): modo Dense FFN-streaming, 0.3 tok/s, pool de 24 slots, prefetch de 7 capas
- Los modelos que caben en memoria tienen sobrecosto cero, y los que la exceden se mantienen ejecutables gracias a Hypura
Instalación y ejecución
- Requiere Rust 1.75+ y CMake
- Procedimiento de instalación
git clone --recurse-submodules https://github.com/hypura/hypura.git cd hypura cargo build --release - Ejemplos de ejecución
hypura profile hypura run ./model.gguf --prompt "Hello, world" hypura run ./model.gguf --interactive hypura bench ./model.gguf hypura inspect ./model.gguf - Para modelos no verificados, se recomienda probar con
--max-tokens 10
Servidor compatible con Ollama
- Hypura ofrece una API HTTP compatible con Ollama, totalmente compatible con herramientas basadas en Ollama como OpenClaw
hypura serve ./model.gguf Endpoint: http://127.0.0.1:8080 API: /api/generate, /api/chat, /api/tags - Endpoints principales
Endpoint Función GET /Verificar estado GET /api/tagsLista de modelos cargados GET /api/versionVersión del servidor POST /api/showMetadatos del modelo POST /api/generateGeneración de texto POST /api/chatGeneración conversacional - La integración con OpenClaw se realiza configurando la base URL de Ollama a Hypura en
~/.openclaw/openclaw.json - Opciones del servidor
hypura serve [OPTIONS] --host valor predeterminado 127.0.0.1 --port valor predeterminado 8080 --context valor predeterminado 4096
Arquitectura
- Tiene una estructura de Cargo workspace, compuesta por dos crates
hypura: binario principal y bibliotecahypura-sys: bindings FFI de llama.cpp (build con CMake)
- Módulos principales
Módulo Rol scheduler/placement.rsOptimización de colocación de tensores entre GPU/RAM/NVMe compute/inference.rsMotor de inferencia y funciones de carga/generación para el servidor compute/nvme_backend.rsStreaming NVMe, caché de neuronas y callback de evaluación server/routes.rsHandlers HTTP compatibles con Ollama profiler/Perfilado de hardware cli/bench.rsHerramienta de benchmark model/tensor_role.rsClasificación del rol de tensores
FAQ
-
Sin problema de vida útil del SSD
- Hypura solo lee desde el SSD, no escribe
- La E/S NVMe se realiza en modo solo lectura con
pread()+F_NOCACHE - El SSD solo cumple el rol de almacenamiento en frío, mientras que el cómputo se realiza en RAM/GPU
- Las escrituras que ocurren son de nivel mínimo, en KB, como JSON de resultados de benchmark o archivos de estadísticas
Guía de seguridad
- Si el modelo supera el límite de RAM (dejando 4GB de margen), se bloquea
bench --baseline - Para modelos no verificados, probar con
--max-tokens 10 - Los modelos de prueba se almacenan en el directorio
./test-models/
Licencia
- MIT License
Aviso ético
- El código del repositorio no fue escrito directamente por el autor
- Fue creado como un experimento de generación de código guiada por instrucciones usando LLM
- Es un proyecto para explorar las posibilidades de la inferencia basada en NVMe
1 comentarios
Comentarios de Hacker News
Me gustaría sugerirle algo al mantenedor. La tabla comparativa actual incluye modelos antiguos como Qwen 2.5 14B, Mixtral 8x7B y Llama 3.3 70B
Últimamente ha habido muchos reportes de que los modelos Qwen 3.5 MoE muestran un rendimiento sorprendente en hardware de Apple
Podría ser útil consultar la publicación de Simon Willison
Si es posible, también estaría bien agregar a la tabla el modelo Kimi K2.5 (1T parámetros)
Tweets relacionados: seikixtc, danpacary
Aparecía un mensaje de error relacionado con Heroku, aunque ahora ya volvió a funcionar con normalidad
Entré para ver esta publicación, y vi que ya habías escrito también sobre litellm. La leí con gusto
En trabajo local, incluso una velocidad de menos de 1 token por segundo puede ser bastante útil si es una tarea en segundo plano
La diferencia entre “termina de inmediato” y “termina durante la noche” sigue siendo un salto de rendimiento significativo
En la práctica, lo importante es qué tan secuencial es el patrón de lectura
Un NVMe alcanza 5–7 GB/s en lectura secuencial, pero en lectura aleatoria cae a alrededor de 500 MB/s
En un modelo de 1T, con fp16, hay que hacer streaming de 2 TB por cada forward pass, así que en teoría toma más de 300 segundos por token
No sirve para uso interactivo, pero podría tener potencial para inferencia por lotes
Pero en modelos MoE pequeños puede generar varios tokens por segundo, así que sí puede ser realmente utilizable
No se leen los 2 TB completos, sino que solo se accede a algunas capas de expertos
Como cada capa está en el orden de unos MiB, la eficiencia de acceso en NVMe tampoco es tan mala
Me preguntaba de dónde salió eso de “modelo de 1T parámetros”. En el repo solo se ven modelos de 70B o menos
Los modelos realistas son los MoE pequeños que pueden generar varios tokens por segundo
El punto de MoE es que, gracias a la activación dispersa, no se lee el total de 2 TB
Pero el patrón de acceso se aleatoriza, lo que lo vuelve la peor condición posible para NVMe
En tareas donde la latencia importa, como la inferencia de agentes, esa parte es crucial
Esto hace que Intel Optane parezca estarse revolcando en su tumba
Aunque en la práctica no son más rápidos que NVMe. En software que soporta lectura/escritura en paralelo, casi no hay diferencia
Aun así, si juntas cuatro en RAID 0, probablemente puedas saturar por completo el ancho de banda de PCIe 16x
El hardware Mac de consumo tiene memoria unificada y NVMe rápidos, pero con capacidad limitada
Si cargas un modelo de 40 GB en un M1 Max de 32 GB, el swap se dispara y al final entra en estado de panic
macOS no tiene un OOM killer al estilo Linux; simplemente se queda sin espacio de swap
Importa tener “la mayor cantidad de memoria posible”, pero la variable más grande es el ancho de banda
El M4 Pro tiene 273 GB/s, el M4 Max 546 GB/s y el M4 Ultra 819 GB/s
Una vez que el modelo cabe en memoria, el ancho de banda determina la velocidad de tokens
Según Hypura, el M4 Max es el sweet spot. Con 64 GB puede correr cómodamente un modelo 70B (Q4), y generar al doble de velocidad que el Pro
Este proyecto funciona básicamente como una especie de memoria swap inteligente
Es interesante que regule el uso para no castigar demasiado al NVMe
Aun así, si realmente se le mete mucha carga al NVMe, preocupa el posible desgaste
La vida útil de un SSD sí se reduce por la cantidad de escrituras, pero es muy raro que una carga de lectura dañe el controlador
Si eso pasara, habría algún otro problema en el sistema
Estaría bien comparar este proyecto con experimentos anteriores y otro intento
Se había reportado que este, al estar basado en mmap, tenía bastante sobrecarga