Prefill et décodage : pourquoi l’inférence des LLM comporte deux phases
Traduction automatique
Cet article a été traduit automatiquement depuis la version originale en anglais.
Le prefill traite un prompt et crée son cache d’attention. Le décodage utilise ce cache pour générer les tokens suivants. Un prefill long ou regroupé en lots peut exploiter efficacement de grandes opérations matricielles ; le décodage avec de petits lots passe souvent plus de temps à lire les poids ainsi que les clés et valeurs en cache.
Cette distinction aide les ingénieurs à analyser séparément la lenteur du premier token et celle de la génération qui suit.
Identifiez la phase lente
Le prefill autorégressif classique produit les logits utilisés pour échantillonner le premier token de sortie. Les étapes de décodage suivantes ajoutent un token à la fois. Le délai avant le premier token comprend aussi l’attente en file, la tokenisation, l’ordonnancement et la transmission réseau. Un TTFT élevé ne prouve donc pas que le prefill lui-même est lent.
| Symptôme | Mesures à effectuer avant de modifier le serveur |
|---|---|
| Le premier token arrive plus lentement avec des prompts plus longs | Temps d’attente en file et durée du prefill selon la longueur d’entrée |
| Les tokens suivants ralentissent avec des historiques plus longs | Temps de décodage et trafic du KV cache |
| Un nouveau prompt long suspend les autres flux | Itérations de l’ordonnanceur et intervalles entre tokens |
| Les serveurs séparés passent du temps à transférer l’état | Octets KV transférés, bande passante et attente en file |
Le prefill réutilise les poids pour les différents tokens du prompt. L’implémentation peut néanmoins charger plusieurs fois les blocs de matrices ; elle ne garantit pas une seule lecture de chaque poids depuis la HBM. Splitwise décrit comment ces phases utilisent des ressources matérielles différentes.
Ce que change le prefill par blocs
Le prefill par blocs traite un prompt long sur plusieurs itérations de l’ordonnanceur. L’ordonnanceur documenté de vLLM admet d’abord les requêtes de décodage en cours et utilise le budget de tokens restant dans l’itération pour le prefill. La taille réelle du bloc dépend du budget disponible.
Cela peut réduire les interruptions des flux existants tout en augmentant le TTFT de la nouvelle requête. Des blocs plus petits ajoutent aussi du travail d’ordonnancement et relisent l’état antérieur du cache. Sarathi-Serve évalue ce compromis ; l’augmentation d’environ 25% du temps de prefill avec des blocs de 512 tokens a été mesurée pour Yi-34B avec un parallélisme tensoriel de degré deux.
Le serving désagrégé place, lui, le prefill et le décodage sur des groupes de GPU séparés. Il permet d’optimiser chaque phase indépendamment, mais doit transférer le KV cache de la requête. Vérifiez le coût du transfert et l’utilisation des groupes avant d’adopter cette conception. Le découpage en blocs modifie l’ordonnanceur ; la désagrégation modifie aussi le déploiement et la communication.
Guide d’ingénierie : prefill et décodage présente des chronologies pour les deux approches.