Hypura – ordonnanceur d’inférence LLM conscient de la hiérarchie de stockage pour Apple Silicon
(github.com/t8)- Optimise le placement des tenseurs entre GPU, RAM et NVMe pour exécuter de grands modèles de langage grâce à un ordonnanceur d’inférence conscient de la hiérarchie de stockage
- Permet d’exécuter sur un Mac Mini 32 Go le modèle Mixtral 8x7B (31GB) à 2.2 tok/s et le modèle Llama 70B (40GB) à 0.3 tok/s
- Analyse les schémas d’accès et la bande passante matérielle pour faire tourner de manière stable même des modèles dépassant la mémoire physique, y compris des modèles que
llama.cppne pouvait pas traiter à cause d’un OOM - Grâce au routage des experts pour l’architecture MoE, au cache de neurones et au prefetch, réduit les E/S jusqu’à 75 % et atteint un taux de cache hit de 99.5 %
- Sélectionne automatiquement les modes Full-resident, Expert-streaming et Dense FFN-streaming selon la taille du modèle et le matériel afin de maintenir les meilleures performances
- Fournit une API HTTP compatible Ollama, intégrable avec OpenClaw et autres outils, et utilise le SSD en lecture seule pour permettre une inférence sur NVMe sans dégradation de durée de vie
Vue d’ensemble
- Hypura est un ordonnanceur d’inférence LLM conscient de la hiérarchie de stockage pour Apple Silicon, un outil qui effectue une optimisation du placement des tenseurs entre GPU, RAM et NVMe
- En répartissant les tenseurs selon les schémas d’accès, le coût en bande passante et les performances matérielles, il permet d’exécuter de façon stable de grands modèles dépassant la mémoire physique
- Sur un Mac Mini 32 Go, il permet d’exécuter Mixtral 8x7B (31GB) à 2.2 tok/s et Llama 70B (40GB) à 0.3 tok/s
- Dans le même environnement, llama.cpp ne peut pas s’exécuter à cause d’un OOM (Out of Memory)
Contexte du problème
- Les Mac grand public disposent d’une mémoire unifiée rapide et d’un stockage NVMe, mais leur capacité mémoire reste limitée
- Par exemple, un M1 Max 32 Go ne peut pas charger directement un modèle de 40 Go, ce qui provoque un swap excessif et une fin d’exécution par OOM
- Hypura résout ce problème en analysant la structure du modèle pour effectuer un placement optimal par couche
Placement par couche fondé sur la structure du modèle
- Norms et Embeddings : petits, mais consultés à chaque token, donc fixés sur le GPU
- Routage des experts MoE : exploite la parcimonie, avec seulement 2 experts actifs sur 8 par token
- Intercepte le routeur pour identifier les experts actifs, puis charge depuis le NVMe uniquement les parties nécessaires
- Réduction des E/S de 75 % et taux de hit du cache de neurones de 99.5 %
- Effectue un prefetch anticipé des prochains experts actifs via le suivi de co-activation (co-activation tracking)
- Poids FFN denses : représentent environ 60 % de la taille du modèle
- Streaming depuis le NVMe via un pool de buffers dynamique
- La profondeur d’anticipation du prefetch (prefetch lookahead depth) est ajustée automatiquement selon la mémoire disponible
- Résultat : des modèles qui plantaient avec l’approche
mmapclassique peuvent désormais être exécutés, tandis que les modèles tenant en mémoire fonctionnent à la vitesse du GPU Metal sans surcoût
Fonctionnement
- Hypura lit les fichiers GGUF et profile la bande passante GPU, RAM et NVMe
- Chaque tenseur est placé dans l’une des trois couches suivantes
- GPU (Metal) : couches Attention, Norm et Embedding
- RAM : couches de débordement qui ne peuvent pas être chargées sur le GPU
- NVMe : couches restantes, avec E/S directes via
F_NOCACHE+pread
- Sélectionne automatiquement le mode d’inférence selon la taille du modèle et le matériel
- Full-resident : charge l’ensemble du modèle en GPU+RAM, sans E/S NVMe
- Expert-streaming : pour les modèles MoE, seuls les tenseurs non experts résident sur le GPU, les tenseurs experts sont streamés depuis le NVMe
- Dense FFN-streaming : pour les grands modèles non-MoE, Attention+Norm sur le GPU, FFN streamé depuis le NVMe
- La taille du pool de buffers, la profondeur de prefetch et le budget mémoire sont calculés automatiquement selon le profil matériel
Performances
- Environnement de test : M1 Max, 32 Go de mémoire unifiée, NVMe 5.1GB/s
- Principaux résultats de benchmark
- Qwen 2.5 14B Q4_K_M (8.4GB) : entièrement chargé sur le GPU, 21 tok/s
- Mixtral 8x7B Q5_K_M (30.9GB) : mode Expert-streaming, 2.2 tok/s, 99.5 % de taux de hit du cache
- Llama 3.3 70B Q4_K_M (39.6GB) : mode Dense FFN-streaming, pool de 24 slots, prefetch sur 7 couches, 0.3 tok/s
- Les modèles qui tiennent en mémoire ont 0 surcoût, et les modèles plus volumineux restent exécutables grâce à Hypura
Installation et exécution
- Rust 1.75+ et CMake requis
- Procédure d’installation
git clone --recurse-submodules https://github.com/hypura/hypura.git cd hypura cargo build --release - Exemples d’exécution
hypura profile hypura run ./model.gguf --prompt "Hello, world" hypura run ./model.gguf --interactive hypura bench ./model.gguf hypura inspect ./model.gguf - Pour les modèles non vérifiés, il est recommandé de tester avec
--max-tokens 10
Serveur compatible Ollama
- Hypura fournit une API HTTP compatible Ollama, entièrement compatible avec OpenClaw et les autres outils basés sur Ollama
hypura serve ./model.gguf Endpoint: http://127.0.0.1:8080 API: /api/generate, /api/chat, /api/tags - Principaux endpoints
Endpoint Fonction GET /Vérification de l’état GET /api/tagsListe des modèles chargés GET /api/versionVersion du serveur POST /api/showMétadonnées du modèle POST /api/generateGénération de texte POST /api/chatGénération conversationnelle - Pour l’intégration avec OpenClaw, définissez l’URL de base Ollama sur Hypura dans
~/.openclaw/openclaw.json - Options du serveur
hypura serve [OPTIONS] --host défaut 127.0.0.1 --port défaut 8080 --context défaut 4096
Architecture
- Structure en workspace Cargo, composée de deux crates
hypura: binaire principal et bibliothèquehypura-sys: bindings FFI pour llama.cpp (build CMake)
- Principaux modules
Module Rôle scheduler/placement.rsOptimisation du placement des tenseurs entre GPU/RAM/NVMe compute/inference.rsMoteur d’inférence et fonctions de chargement/génération pour le serveur compute/nvme_backend.rsStreaming NVMe, cache de neurones, callback d’évaluation server/routes.rsHandlers HTTP compatibles Ollama profiler/Profilage matériel cli/bench.rsOutil de benchmark model/tensor_role.rsClassification du rôle des tenseurs
FAQ
-
Aucun problème de durée de vie du SSD
- Hypura ne fait que lire sur le SSD, sans écriture
- Les E/S NVMe sont effectuées en lecture seule via
pread()+F_NOCACHE - Le SSD ne sert que de stockage à froid, les calculs étant réalisés en RAM/GPU
- Les écritures se limitent à un niveau négligeable de quelques Ko, comme les résultats JSON des benchmarks ou les fichiers de statistiques
Consignes de sécurité
- Si le modèle dépasse la limite de RAM (avec 4 Go de marge),
bench --baselineest bloqué - Pour les modèles non vérifiés, tester avec
--max-tokens 10 - Les modèles de test sont stockés dans le répertoire
./test-models/
Licence
- MIT License
Avis éthique
- Le code du dépôt n’a pas été entièrement écrit directement par son auteur
- Il a été produit dans le cadre d’une expérience de génération de code guidée par instructions avec un LLM
- Il s’agit d’un projet visant à explorer le potentiel de l’inférence fondée sur le NVMe
Aucun commentaire pour le moment.