Modèle / jeu de données
huggingface/text-embeddings-inference avatar
huggingface/text-embeddings-inference

Text Embeddings Inference : servir des embeddings sans graphe compilé

A blazing fast inference solution for text embeddings models

5 049 étoiles429 forksRustApache-2.0

En bref

De quoi s’agit-il ?
TEI est un serveur Rust signé Hugging Face pour l'inférence d'embeddings et de modèles de reclassement. Le projet vise les déploiements contraints en latence, avec des images Docker légères et un batching dynamique par tokens.
À qui s’adresse-t-il ?
TEI convient aux équipes qui servent un modèle d'embeddings ou de reclassement unique derrière une API HTTP, avec un GPU ou un Mac Apple Silicon comme cible. Il ne convient pas si vous devez exécuter plusieurs modèles hétérogènes dans un seul processus, si vous dépendez d'une architecture non listée dans le tableau des modèles supportés, ou si votre chaîne d'outils est verrouillée sur Python.
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 que TEI attaque : le coût fixe du serving d'embeddings

Un modèle d'embeddings n'a rien d'un chatbot. Il reçoit du texte, renvoie un vecteur, et ne génère rien. Pourtant, la plupart des piles d'inférence Python embarquent un moteur de génération complet, avec compilation de graphe au démarrage et gestion de cache KV dont un encodeur n'a pas besoin. TEI prend le problème par l'autre bout : un serveur écrit en Rust, bâti sur Candle, Flash Attention et cuBLASLt, qui charge des poids Safetensors ou ONNX et expose une API HTTP. Le README insiste sur un point précis : aucune étape de compilation de graphe. C'est ce qui explique la promesse de démarrage rapide et d'images Docker réduites, deux propriétés utiles quand on veut éteindre une instance entre deux pics de trafic. Le public visé est donc l'ingénieur qui doit tenir un service de recherche sémantique, de déduplication ou de reclassement, avec une latence mesurable et une facture GPU qui ne dépend pas du nombre de modèles résidents.

Batching dynamique par tokens : ce que le README décrit vraiment

Le mécanisme central annoncé est le token based dynamic batching. Au lieu de regrouper les requêtes par nombre de textes, TEI les regroupe par nombre de tokens, ce qui lisse la charge quand les entrées ont des longueurs très variables, cas fréquent en recherche documentaire où une requête fait dix tokens et un passage en fait cinq cents. Le README ne détaille pas l'algorithme de la file d'attente, et je ne peux pas affirmer comment les lots sont formés en pratique. Ce qui est documenté, en revanche, c'est la surface opérationnelle : métriques Prometheus, traçage distribué via Open Telemetry, documentation Swagger de l'API, et une interface gRPC en plus du HTTP. Le chargement des poids passe par Safetensors ou ONNX, ce qui laisse le choix entre conversion préalable et chargement direct. Le support Metal est mentionné pour l'exécution locale sur Mac, ce qui donne une cible de développement différente de la cible de production.

Mettre en route : Docker, variables et modèles non gated

Le chemin le plus court documenté est Docker. Le README renvoie à une section Docker Images et à une page quick_tour sur le site de documentation Hugging Face, où figurent les commandes exactes. Je n'ai pas exécuté ces commandes, donc je m'en tiens à ce que le dépôt expose comme points d'entrée : une image Docker par famille de matériel, une variable d'environnement pour indiquer le modèle, et un port HTTP à exposer. Pour un modèle privé ou gated, le README prévoit une section dédiée, ce qui suppose un jeton Hugging Face passé au conteneur. Pour un déploiement en environnement isolé, la section air gapped deployment indique comment faire tourner le serveur sans accès au Hub, ce qui implique de pré-télécharger les poids et de monter le volume correspondant. La documentation API est publiée en Swagger, et un exemple gRPC existe pour les clients qui ne veulent pas de HTTP. Sur Apple Silicon, une installation via Homebrew est proposée en alternative au conteneur, ce qui évite d'installer Docker pour un test local.

Ce que TEI ne fait pas, et les cas où il faut passer à autre chose

Le tableau des modèles supportés est une contrainte dure, pas une indication. TEI liste des familles précises : Nomic, BERT, CamemBERT, XLM-RoBERTa avec positions absolues, JinaBERT avec positions Alibi, Mistral, Alibaba GTE, Qwen2 et Qwen3 avec positions Rope, MPNet, ModernBERT, Gemma3. Un modèle dont l'architecture sort de cette liste ne se contentera pas d'être plus lent : il ne se chargera pas. C'est le premier mode d'échec à vérifier avant toute décision. Le second concerne le reclassement et la classification de séquences, pour lesquels le README ne cite que CamemBERT et XLM-RoBERTa en positions absolues, un périmètre nettement plus étroit que celui des embeddings. Troisième point : le support ROCm pour les GPU AMD Instinct est explicitement marqué expérimental dans la table des matières. Quatrième point : TEI sert un modèle par instance. Si votre application doit router entre un petit modèle multilingue et un gros modèle de raisonnement, il faut plusieurs processus, avec la mémoire GPU que cela implique. Enfin, l'intégration dans un pipeline Python existant demande de passer par HTTP ou gRPC, ce qui ajoute un saut réseau là où un appel de fonction suffisait.

Face à sentence-transformers servi par un framework Python

L'alternative la plus directe reste sentence-transformers chargé dans un serveur Python, ou un serveur d'inférence générique qui accepte aussi les encodeurs. La différence d'approche est nette. Côté Python, on garde l'accès à l'écosystème complet : n'importe quelle architecture implémentée dans transformers fonctionne, les têtes personnalisées aussi, et le débogage se fait dans le même langage que le reste de la pile. Côté TEI, on accepte une liste fermée d'architectures en échange d'un binaire qui démarre sans compilation de graphe et d'une image Docker annoncée comme petite. Le compromis se joue donc entre couverture des modèles et coût opérationnel du service. Une équipe qui expérimente beaucoup de modèles récents, y compris des architectures publiées la semaine précédente, sera régulièrement bloquée par la liste de TEI. Une équipe qui a arrêté son choix sur un modèle et veut le servir à coût stable trouvera dans TEI un chemin plus court, à condition que ce modèle soit dans le tableau.

Maintenance, versions et implications de licence

Le rythme de publication est soutenu : v1.9.1 en février 2026, v1.9.2 le même mois, v1.9.3 en mars 2026, avec un dernier push sur main en septembre 2026. Le dépôt n'est pas archivé. Cela implique une charge de mise à jour réelle : suivre les versions mineures pour bénéficier des nouvelles architectures, et vérifier à chaque saut que vos modèles restent dans le périmètre supporté. Le code du dépôt est sous Apache-2.0, une licence permissive qui autorise l'usage commercial et la modification, avec les obligations habituelles de conservation des mentions. Cette licence couvre le code de TEI, pas les poids des modèles. Le tableau des modèles supportés signale explicitement que google/embeddinggemma-300m est gated, ce qui veut dire qu'un accès doit être demandé et que des conditions propres s'appliquent. Pour les modèles marqués Very Expensive dans la colonne taille, la contrainte n'est pas juridique mais matérielle : un Qwen3-Embedding-8B ne tient pas sur la même carte qu'un modèle de 137M paramètres, et le choix du modèle détermine le coût d'exploitation bien plus que le choix du serveur.

Comment lire les chiffres du README

Le README affiche quatre graphiques de benchmark pour BAAI/bge-base-en-v1.5 sur une NVIDIA A10, avec une longueur de séquence de 512 tokens, en latence et en débit, pour des tailles de lot de 1 et de 32. Ces courbes sont produites par les mainteneurs, sur un matériel et un modèle donnés. Elles ne disent rien de votre modèle, de votre distribution de longueurs de texte, ni de votre GPU. Le projet ne publie pas de protocole de reproduction dans l'extrait fourni, et je n'ai pas cherché à reproduire ces mesures. Traitez ces graphiques comme un ordre de grandeur et comme une indication de ce que les auteurs considèrent comme la charge de référence, pas comme une prévision. La seule affirmation que je retiens du README sans réserve est structurelle : pas de compilation de graphe, donc un démarrage plus court qu'une pile qui compile. Le reste se mesure chez vous, avec votre modèle et vos requêtes.

Conclusion éditoriale

TEI convient aux équipes qui servent un modèle d'embeddings ou de reclassement unique derrière une API HTTP, avec un GPU ou un Mac Apple Silicon comme cible. Il ne convient pas si vous devez exécuter plusieurs modèles hétérogènes dans un seul processus, si vous dépendez d'une architecture non listée dans le tableau des modèles supportés, ou si votre chaîne d'outils est verrouillée sur Python. Avant d'adopter, vérifiez trois points dans le dépôt : que votre modèle figure explicitement dans la liste des architectures prises en charge, que l'image Docker correspond à votre matériel (NVIDIA, ROCm expérimental, ou build local), et que la licence Apache-2.0 du code couvre bien votre usage, sachant que les poids des modèles téléchargés depuis le Hub ont leurs propres conditions, parfois restrictives comme le cas gated de google/embeddinggemma-300m.

Sources officielles

  1. huggingface/text-embeddings-inference on GitHub
  2. License: Apache-2.0
  3. Project website
  4. README
  5. Releases
Notes de la communauté

Notes de la communauté