Perplexity réduit le temps de recherche avant même la réponse

Perplexity détaille Ivy, Tulip et ROSE, trois composants conçus pour accélérer le calcul des embeddings et le classement des résultats sur GPU.

Avant qu’une réponse apparaisse dans Perplexity, une autre opération a déjà commencé. Le service doit convertir la question en une représentation numérique, retrouver les documents les plus proches dans son index, puis classer les résultats selon leur pertinence. Quelques millisecondes gagnées à chaque étape prennent une tout autre importance lorsqu’elles sont répétées à l’échelle d’un moteur de recherche.

Dans une publication technique datée du 4 septembre 2026, Perplexity décrit l’infrastructure utilisée pour exécuter ses modèles d’embedding et de classement. L’entreprise l’organise autour de trois composants baptisés Ivy, Tulip et ROSE. Le premier prépare les requêtes, le deuxième les regroupe et les planifie, tandis que le troisième exécute les modèles sur les accélérateurs.

Un embedding représente un texte sous la forme d’un vecteur, soit une suite de valeurs décrivant sa position dans un espace mathématique. Deux passages dont le sens est proche doivent produire des vecteurs voisins, même s’ils n’utilisent pas les mêmes mots. Une question sur le prix d’un train peut ainsi être rapprochée d’un document parlant de tarif ferroviaire.

Lors de la construction d’un index, des millions ou des milliards de documents doivent être convertis de cette manière. Le débit prime alors sur le temps nécessaire pour traiter un élément isolé. Au moment d’une recherche, la situation s’inverse : une requête souvent courte doit être convertie immédiatement pour ne pas ralentir la réponse visible par l’utilisateur.

Le classement intervient après la première sélection. Un modèle de scoring examine un lot de documents et leur attribue une valeur afin de conserver les plus pertinents. Cette étape doit traiter davantage de textes qu’une simple question, sans ajouter une attente excessive avant la génération de la réponse.

Perplexity cherche à couvrir ces différents usages avec une infrastructure commune. Ses modèles d’embedding sont généralement de petits Transformers, parfois dérivés de modèles de langage. L’entreprise réutilise donc une partie du code déjà employé pour servir ses grands modèles.

L’encodage massif de documents se rapproche de la phase de préremplissage d’un modèle de langage, pendant laquelle de nombreux tokens sont traités simultanément. Une requête courte ressemble davantage à la génération token par token : le processeur graphique dispose de moins de calcul à effectuer et le poids des opérations annexes devient plus visible.

Ivy constitue le point d’entrée HTTP. Écrit en Rust, il reçoit les appels des services de Perplexity, analyse le JSON, convertit le texte en tokens, applique les formats attendus par chaque modèle et découpe les lots volumineux. Les requêtes sont ensuite transmises avec un protocole gRPC interne.

Ce découpage évite d’envoyer un lot entier vers une seule instance, au risque de la saturer pendant que les autres attendent. Ivy répartit les fragments entre plusieurs répliques et tente de lisser leur charge. La couche intègre également le système de tokenisation développé en interne par Perplexity.

Tulip reçoit les requêtes gRPC préparées par Ivy. Ce serveur utilise Rust, Tokio et Tonic pour suivre les demandes, constituer les lots et les envoyer vers le GPU. Son ordonnanceur reste volontairement simple : les séquences en attente sont sélectionnées selon leur ordre d’arrivée.

Cette simplicité vient du comportement des petits modèles observés par Perplexity. Pour les longueurs traitées en production, les couches denses occuperaient davantage de temps que l’attention. Le coût progresse donc surtout avec le nombre total de tokens, plutôt qu’avec le nombre de séquences présentes dans le lot.

Sur un modèle de moins d’un milliard de paramètres, Perplexity situe la saturation du GPU autour de 512 tokens. Une fois ce niveau atteint, ajouter davantage de requêtes au même lot n’améliore plus forcément l’efficacité. Tulip peut donc privilégier une planification rapide sans rechercher en permanence la combinaison parfaite.

ROSE, pour Runtime-Optimized Serving Engine, exécute le modèle. Cette couche est principalement développée en Python et contient les opérations de calcul, les définitions de modèles et les implémentations adaptées aux différentes cartes graphiques. Elle avait d’abord été conçue pour les modèles de langage, puis étendue aux embeddings.

Les couches denses sont identiques dans les deux cas, puisque chaque représentation de token y est traitée indépendamment. Les différences apparaissent surtout dans l’attention. ROSE accepte des entrées de longueurs variables sans les compléter artificiellement jusqu’à une taille commune. Il n’instancie pas non plus le cache KV nécessaire à la génération autorégressive, puisque l’encodeur traite toute la séquence en une seule passe.

Cette réutilisation réduit le travail nécessaire pour mettre en production un modèle issu d’un modèle de langage existant. Perplexity indique que son modèle `pplx-embed` et le décodage de Qwen3.5 utilisent ainsi une partie des mêmes briques de calcul.

L’optimisation ne porte pas seulement sur ce qui se passe dans le GPU. Lorsqu’un lot est réduit, le temps consacré par le CPU à préparer et lancer les opérations peut dépasser la durée du calcul lui-même. Le matériel attend alors des instructions au lieu de travailler en continu.

Les graphes CUDA réduisent ce délai. Plutôt que de lancer séparément chaque multiplication matricielle, normalisation, activation et opération d’attention, le système enregistre à l’avance toute la suite d’actions nécessaire à une passe du modèle. Une seule commande peut ensuite rejouer cet ensemble.

Le gain est particulièrement sensible sur les requêtes courtes. Les lots plus lourds occupent déjà suffisamment longtemps le GPU pour rendre le coût de lancement moins important. Sur les petits modèles étudiés, Perplexity place le point de bascule à plusieurs milliers de tokens et plusieurs dizaines de séquences.

Cette méthode crée un autre problème. Un graphe distinct peut être nécessaire pour chaque