OpenLake : un moteur de stockage Rust pour sortir le cache KV des GPU
OpenLake is a high performance storage engine for efficient LLM inference and GPU Training
En bref
- De quoi s’agit-il ?
- OpenLake est un moteur de stockage distribué écrit en Rust, bâti sur io_uring, qui vise à garder les accélérateurs occupés pendant l'inférence et l'entraînement. Le projet se présente à la fois comme magasin d'objets compatible S3 et comme couche de déport du cache KV pour vLLM. Voici ce que la documentation permet réellement de vérifier, et ce qu'elle laisse dans le flou.
- À qui s’adresse-t-il ?
- OpenLake s'adresse en priorité aux équipes qui exploitent déjà vLLM sur un parc de GPU et qui veulent réutiliser un préfixe calculé d'un hôte à l'autre sans réécrire leur pile d'inférence. Celles qui cherchent un magasin d'objets généraliste, avec une documentation d'exploitation complète et des garanties de durabilité explicitées, devraient attendre : le README décrit le chemin nominal, pas la récupération après panne.
- Puis-je l’utiliser commercialement ?
- Oui. Apache-2.0 est une licence permissive : vous pouvez utiliser, modifier et vendre un logiciel qui en dépend, à condition de conserver les mentions de droit d’auteur et de licence.
- Est-il encore maintenu ?
- Oui. Les derniers commits datent d’il y a 1 jour.
- En quel langage est-il écrit ?
- Principalement Rust, d’après les statistiques de langage de GitHub.
Ces réponses reposent sur les données GitHub du projet (dernière synchronisation le 15 septembre 2026) et sur notre analyse. Elles ne constituent pas un avis juridique.
ANALYSE OPEN SOURCE APPROFONDIE
Le problème visé : un préfixe calculé une fois, relu mille fois
Dans une pile d'inférence classique, chaque requête longue refait le prefill. Le README résume l'enjeu avec une capture intitulée 66× speedup on time to first token first token when cached, mesurée sur une fenêtre de contexte de 128K. Le mécanisme décrit est simple à énoncer : le moteur d'inférence écrit le cache KV une fois, puis le relit en quelques millisecondes depuis la mémoire hôte et le disque. La cible est donc l'agent conversationnel qui reprend un long historique, le service qui sert le même document à des milliers d'utilisateurs, ou l'entraînement par renforcement qui enchaîne des rollouts sur des préfixes partagés. Le projet cite aussi la construction d'index vectoriels, le checkpointing et le stockage de contexte agentique. Ce ne sont pas des charges identiques : un index vectoriel se comporte comme des lectures aléatoires de petite taille, un checkpoint comme une écriture séquentielle massive. Le README les regroupe sous la même promesse de débit, sans détailler les réglages propres à chacune. C'est le premier point où la documentation reste en retrait par rapport à l'ambition affichée.
io_uring, RDMA et un découpage client/serveur
Le dépôt est organisé en crates, avec un binaire serveur openlaked et un client Python publié séparément sous le nom openlake-vllm. Le README indique que le moteur repose sur io_uring, l'interface d'E/S asynchrone du noyau Linux, et les sujets du dépôt mentionnent RDMA ainsi que le matériel Blackwell. La configuration multihôte fournie s'appelle kv_rdma.toml et le connecteur accepte une clé openlake_device dont la valeur ressemble à un nom de périphérique InfiniBand, mlx5_ib0 dans l'exemple. La topologie décrite est donc un ensemble de nœuds GPU qui exposent chacun un démon, avec un identifiant entier attribué à la main (0, 1, 2) et une liste ordonnée de pairs côté vLLM. Le README précise qu'un préfixe calculé sur un hôte GPU est servi à n'importe quel autre depuis le pool partagé. Cette phrase mérite d'être lue attentivement : elle implique que le cache KV transite par le réseau entre machines, ce qui déplace le goulot d'étranglement du calcul vers l'interconnexion. Le projet revendique par ailleurs un classement en tête du benchmark MLPerf Storage v3.0 2026 sur le checkpointing d'objets. Ce résultat provient d'un communiqué du projet lui-même et n'est pas reproductible à partir des seuls éléments fournis ici.
Mise en route sur un seul hôte
Le chemin le plus court tient en deux commandes. On installe le connecteur et on démarre le démon : pip install openlake-vllm puis openlaked. Ensuite, on lance vLLM avec un objet de configuration transmis via --kv-transfer-config, qui contient kv_connector à OpenLakeConnector, kv_connector_module_path à openlake_client.openlake_connector, kv_role à kv_both et un bloc kv_connector_extra_config où openlake_nodes vaut ["127.0.0.1:9400"] et openlake_device vaut local. Le README impose aussi export PYTHONHASHSEED=0 avant le serveur, sans expliquer pourquoi. Cette variable influence l'ordonnancement des dictionnaires en Python ; sa présence suggère une dépendance à un ordre stable, mais rien dans le matériel fourni ne confirme l'hypothèse. Par défaut, OpenLake déporte vers l'hôte local. Pour couvrir plusieurs machines, il faut démarrer openlaked avec un fichier de configuration explicite. Le projet fournit un guide Helm dans charts/openlake/README.md pour placer une instance par nœud sélectionné et générer la configuration ordonnée des pairs vLLM. C'est un détail d'exploitation qui compte : l'ordre de la liste openlake_nodes doit correspondre aux identifiants attribués aux démons, sinon le routage des préfixes n'a plus de sens.
Le magasin d'objets compatible S3, en quatre étapes
La seconde moitié du README décrit un usage différent : faire d'OpenLake un magasin d'objets à l'échelle du pétaoctet pour un parc de GPU. La procédure commence par l'installation de dépendances système (build-essential, pkg-config, clang, cmake, libhwloc-dev, libudev-dev, curl, git, awscli), puis l'installation de la chaîne Rust via rustup. On clone le dépôt, on compile avec cargo build --release --bin openlaked, on crée quatre répertoires de données (data/d0 à data/d3) et on démarre avec ./target/release/openlaked --config crates/openlake_server/configs/storage-tcp-local.toml. L'accès se fait ensuite avec n'importe quel client S3, les identifiants étant openlakeadmin pour la clé et le secret, la région us-east-1 et le point de terminaison http://127.0.0.1:90. Le README s'arrête au milieu de cette dernière ligne de commande, tronquée dans le matériel fourni. Deux remarques pratiques : la configuration par défaut répartit les données sur quatre chemins, ce qui suppose quatre supports ou au moins quatre points de montage pour que le parallélisme ait un sens ; et l'usage de clés identiques à celles de l'exemple ne convient qu'à un essai local. Le projet ne précise nulle part comment ces identifiants se gèrent en production.
Ce que la documentation ne dit pas
Trois zones d'ombre méritent d'être signalées avant toute adoption. D'abord la durabilité. Le README affirme que le stockage est fully persistent and durable, mais ne décrit ni la réplication, ni le quorum, ni le comportement en cas de perte d'un nœud du pool KV. Pour un cache, la perte se traduit par un recalcul de prefill, ce qui est acceptable. Pour un checkpoint d'entraînement, la même perte peut coûter des heures de calcul. Le projet traite les deux cas avec le même vocabulaire, et c'est un raccourci discutable. Ensuite la compression. La version 0.8 introduit ExANS, présenté comme un codec GPU sans perte pour le cache KV BF16, avec un gain de coût annoncé de 1,51×. Le README ne dit pas si ce codec est actif par défaut, ni quelle clé de configuration le contrôle, ni quel surcoût il impose au moment de la lecture. Enfin le dimensionnement. Aucun ordre de grandeur n'est donné sur la mémoire hôte nécessaire par gigaoctet de cache KV, ni sur le nombre de connexions RDMA à prévoir. Les chiffres publiés par le projet (million+ iops, lectures à 600 µs, 8× de débit) proviennent de ses propres billets et ne sont pas accompagnés ici des conditions de mesure.
Face à un cache de préfixe intégré au serveur
L'alternative la plus directe n'est pas un autre moteur de stockage, c'est le cache de préfixe déjà présent dans les serveurs d'inférence, qui conserve les blocs KV dans la mémoire du GPU ou de l'hôte et les évince selon une politique de récence. La différence tient à la portée. Un cache local disparaît au redémarrage du processus et ne franchit pas la frontière de la machine. OpenLake place le cache dans un pool persistant partagé par plusieurs hôtes, ce qui permet à un préfixe calculé sur le nœud A d'être servi au nœud B. Le coût de cette portée est réel : il faut un démon par nœud, un fichier de configuration par nœud avec un identifiant unique, une interconnexion rapide entre les machines, et l'acceptation que la lecture d'un préfixe distant soit bornée par le réseau plutôt que par la bande passante mémoire du GPU. Sur un seul serveur, où le cache local suffit, ajouter OpenLake revient à introduire un composant d'exploitation supplémentaire pour un gain nul. Le projet ne revendique d'ailleurs pas le contraire : son argument porte sur le passage à l'échelle et sur la réutilisation entre machines.
Licence, versions et coût de suivi
Le dépôt est publié sous Apache-2.0, une licence permissive qui autorise l'usage commercial et la modification, avec les obligations habituelles de conservation des mentions et de l'avis de licence, plus une clause de brevets. Rien dans le matériel fourni n'indique de composant sous licence différente, ni de dépendance à un service tiers facturé. Le rythme de publication est soutenu : trois versions entre le 12 août et le 5 septembre 2026, soit 0.8.0, 0.8.1 puis 0.9.0, avec un dernier push sur main au 6 septembre. Pour une équipe qui épingle une version, cela représente une mise à jour à évaluer tous les quinze jours environ. Le risque n'est pas théorique : le connecteur vLLM est un paquet Python séparé (openlake-vllm) qui doit rester aligné avec le binaire openlaked, et les exemples de configuration vivent dans le dépôt, sous crates/openlake_server/configs/. Une montée de version qui modifie une clé de kv_connector_extra_config casse le démarrage de vLLM sans avertissement côté serveur. Le README ne mentionne pas de politique de compatibilité entre versions du client et du démon, ce qui laisse la vérification à la charge de l'exploitant.
Conclusion éditoriale
OpenLake s'adresse en priorité aux équipes qui exploitent déjà vLLM sur un parc de GPU et qui veulent réutiliser un préfixe calculé d'un hôte à l'autre sans réécrire leur pile d'inférence. Celles qui cherchent un magasin d'objets généraliste, avec une documentation d'exploitation complète et des garanties de durabilité explicitées, devraient attendre : le README décrit le chemin nominal, pas la récupération après panne. Avant tout déploiement, vérifiez le fichier crates/openlake_server/configs/kv_rdma.toml, la valeur de self_id attribuée à chaque nœud et le contenu du chart charts/openlake, car c'est là que se joue la cohérence de l'ordre des pairs vLLM.
Notes de la communauté