Bonnes pratiques pour l'autoscaling des charges de travail d'inférence de grands modèles de langage (LLM) avec des TPU


Ce guide des bonnes pratiques présente les métriques disponibles et explique comment sélectionner des métriques appropriées pour configurer votre autoscaler horizontal de pods (HPA) pour vos charges de travail d'inférence JetStream à hôte unique avec des TPU sur GKE. L'autoscaler horizontal de pods est un moyen efficace de vous assurer que vos serveurs de modèles évoluent de manière appropriée en fonction de la charge. L'ajustement des paramètres HPA est le principal moyen d'aligner le coût de votre matériel provisionné sur la demande de trafic afin d'atteindre les objectifs de performances de votre serveur d'inférence.

Pour obtenir des exemples de mise en œuvre de ces bonnes pratiques, consultez la page Configurer l'autoscaling pour les charges de travail LLM sur les TPU avec GKE.

Objectifs

Ce guide est destiné aux clients d'IA générative, aux utilisateurs GKE nouveaux ou existants, aux ingénieurs en ML et aux ingénieurs LLMOps (DevOps) qui souhaitent optimiser leurs charges de travail JetStream à hôte unique à l'aide de TPU avec Kubernetes.

Après avoir lu ce guide, vous devriez être capable de :

  • Comprendre les principales métriques d'autoscaling pour l'inférence JetStream à hôte unique.
  • Comprendre les principaux compromis au niveau des métriques à utiliser pour l'autoscaling.

Présentation des métriques d'autoscaling pour l'inférence JetStream

Nous vous recommandons d'utiliser les métriques suivantes :

Métriques de serveur

Comme de nombreux autres serveurs d'inférence LLM, JetStream fournit des métriques de performances. GKE simplifie la surveillance et l'autoscaling de JetStream en se basant sur ces métriques au niveau du serveur. Pour configurer un autoscaling, vous devez d'abord comprendre comment le pipeline de requêtes JetStream influence les indicateurs clés de performance. Toutes les requêtes entrantes passent par une file d'attente de préremplissage, une file d'attente de transfert et une file d'attente de génération, puis deviennent une requête de décodage. JetStream accepte les requêtes de décodage de manière progressive et les traite simultanément à l'aide d'un nombre fixe de threads de décodage. Le pourcentage de moteurs de décodage occupés à traiter une requête de décodage à un moment donné est mesuré en tant que métrique jetstream_slots_used_percentage.

Pour le scaling de JetStream à hôte unique, cela a deux conséquences sur la latence et le débit :

  • Les requêtes ne seront pas mises en attente dans les files d'attente si le taux de requêtes entrantes est inférieur au taux auquel les emplacements de décodage peuvent traiter les requêtes. Si JetStream n'a pas de tâches en attente, le débit sera proportionnel au taux de requêtes entrantes. La latence restera principalement constante, mais augmentera légèrement et proportionnellement au nombre de requêtes de décodage simultanées, car les nouvelles requêtes de décodage acceptées interrompront le décodage.
  • Les requêtes seront mises en attente dans les files d'attente une fois que le taux de requêtes entrantes dépasse le taux auquel les emplacements de décodage peuvent traiter les requêtes. Si JetStream présente une tâche en attente, la latence des requêtes augmentera de façon plus significative et proportionnelle au nombre de requêtes en attente, tandis que le débit restera constant.

Les métriques de serveur suivantes auront la plus forte corrélation avec ces indicateurs de performances pertinents. Nous vous recommandons de les utiliser pour l'autoscaling :

  • jetstream_prefill_backlog_size : nombre de requêtes en attente de traitement dans la file d'attente du serveur (backlog). Cette métrique présente une forte corrélation avec la latence. Pour en savoir plus, consultez la section Bonnes pratiques associée.
  • jetstream_slots_used_percentage : nombre de requêtes en cours d'inférence en pourcentage du nombre total de requêtes que JetStream peut gérer. Cette métrique présente une forte corrélation avec le débit. Pour en savoir plus, consultez la section Bonnes pratiques associée.

Ces métriques sont souvent résilientes aux fluctuations de performances et de trafic, ce qui en fait un point de départ fiable pour l'autoscaling sur diverses configurations matérielles de TPU.

Métriques de TPU

Étant donné que l'inférence LLM est limitée par la mémoire et non par le calcul, nous vous recommandons d'ajuster JetStream en fonction de l'utilisation de la mémoire plutôt qu'avec d'autres métriques TPU, car cela reflète mieux l'utilisation des ressources du matériel. Pour en savoir plus, consultez la section Bonnes pratiques associée.

Éléments à prendre en compte pour choisir des métriques d'autoscaling

Tenez compte des considérations et des bonnes pratiques suivantes afin de sélectionner la meilleure métrique pour l'autoscaling sur GKE afin d'atteindre les objectifs de performances de votre charge de travail d'inférence.

Bonne pratique : Utiliser la taille de la file d'attente de préremplissage pour optimiser le débit et réduire les coûts en respectant un certain seuil de latence cible

Nous vous recommandons d'effectuer l'autoscaling de la taille de la file d'attente de préremplissage lors de l'optimisation du débit et des coûts, et lorsque vos objectifs de latence sont réalisables avec le débit maximal de la taille de lot par appareil de votre serveur de modèles.

La taille de la file d'attente de préremplissage est directement liée à la latence des requêtes. Les requêtes entrantes sont placées en file d'attente dans la file d'attente de préremplissage avant d'être traitées. Ce temps de file d'attente s'ajoute à la latence globale. La taille de la file d'attente est un indicateur sensible des pics de charge, car une charge accrue remplit rapidement la file d'attente.

L'autoscaling basé sur la taille de la file d'attente de préremplissage réduit la durée de file d'attente en procédant à un scaling à la hausse en cas de charge ou à un scaling à la baisse lorsque la file d'attente est vide. Cette approche est relativement facile à mettre en œuvre, car la taille de la file d'attente est indépendante de la taille de la requête, du modèle et du matériel.

Envisagez de vous concentrer sur la taille de la file d'attente de préremplissage si vous souhaitez optimiser le débit de chaque instance répliquée du serveur de modèles. La taille de la file d'attente de préremplissage suit les requêtes en attente, et non celles en cours de traitement. JetStream utilise un traitement par lot continu, ce qui optimise les requêtes simultanées et maintient la file d'attente faible lorsque de l'espace par lot est disponible. La file d'attente augmente considérablement lorsque l'espace par lot est limité. Utilisez donc le point de croissance comme signal pour lancer le scaling à la hausse. En combinant l'autoscaling de la taille de la file d'attente avec un débit par lot optimisé, vous pouvez optimiser le débit des requêtes.

Déterminer la valeur de seuil optimale de la taille de file d'attente optimale pour l'HPA

Pour choisir le seuil de taille de file d'attente approprié, commencez par une valeur comprise entre 3 et 5 et augmentez progressivement jusqu'à ce que les requêtes atteignent la latence souhaitée. Utilisez l'outil locust-load-inference pour les tests. Pour les seuils inférieurs à 10, ajustez les paramètres de scaling à la hausse de l'autoscaler horizontal de pods afin de gérer les pics de trafic.

Vous pouvez également créer un tableau de bord personnalisé Cloud Monitoring pour visualiser le comportement des métriques.

Limites

Tenez compte de la tolérance HPA, qui est définie par défaut sur une plage d'absence d'action de 0,1 autour de la valeur cible afin d'atténuer l'oscillation.

La taille de la file d'attente de pré-remplissage ne contrôle pas directement les requêtes simultanées. Par conséquent, son seuil ne peut pas garantir une latence inférieure à celle autorisée par la taille de lot par appareil. Pour contourner ce problème, vous pouvez réduire manuellement la taille de lot par appareil ou effectuer un autoscaling sur la taille de lot.

Bonne pratique : Utiliser le pourcentage "slots_used" pour atteindre des seuils de latence cible inférieurs à la taille de la file d'attente

Nous vous recommandons de choisir l'autoscaling basé sur les emplacements utilisés (slots_used) si vous avez des charges de travail sensibles à la latence où le scaling basé sur la file d'attente n'est pas assez rapide pour répondre à vos besoins.

L'autoscaling basé sur les emplacements utilisés "slot_used" garantit que le débit de vos charges de travail effectue un scaling à la hausse pour maximiser le nombre de requêtes simultanées traitées en parallèle, et un scaling à la baisse lorsque le nombre de requêtes traitées en parallèle est inférieur. Cela a deux conséquences sur la latence. Tout d'abord, comme l'autoscaling basé sur "slots_used" s'adapte pour garantir un emplacement pour chaque requête entrante, la proximité du seuil défini par rapport à 1 correspond à la probabilité qu'une requête passe du temps en file d'attente et ait donc une latence plus élevée. Deuxièmement, des tailles de lot plus importantes augmentent le débit, mais augmentent également la latence en raison de la phase de préremplissage de certaines requêtes interrompant la phase de décodage d'autres sur les serveurs de modèles avec traitement par lot continu. Vous pouvez surveiller les modèles de taille de lot et utiliser l'autoscaling pour minimiser les requêtes simultanées lors des pics de charge.

Si la taille de la file d'attente atteint déjà vos objectifs de latence, donnez-lui la priorité pour l'autoscaling. Cela permet d'optimiser le débit et la rentabilité. Toutefois, "slots_used" est utile pour les charges de travail sensibles à la latence.

Nous vous recommandons également d'ajuster la taille de lot par appareil sur une valeur appropriée avant d'explorer l'autoscaling basé sur "slots_used". Vous pouvez également associer ce mode à l'autoscaling basé sur la file d'attente.

Déterminer la valeur de seuil de pourcentage "slots_used" optimale pour l'HPA

Pour choisir le seuil approprié pour la taille de lot, augmentez de manière expérimentale la charge sur votre serveur et observez où la taille de lot augmente. Nous vous recommandons également d'utiliser l'outil locust-load-inference pour les tests. Une fois que vous avez identifié la taille de lot par appareil optimale pour laquelle l'utilisation de la mémoire est maximale, vous pouvez configurer votre pourcentage cible "slots_used". Définissez la valeur cible initiale légèrement en dessous de 1 et diminuez-la jusqu'à atteindre la latence souhaitée.

Vous pouvez également créer un tableau de bord personnalisé Cloud Monitoring pour visualiser le comportement des métriques.

Limites

Tenez compte de la tolérance HPA, qui est une plage sans action par défaut de 0,1 autour de la valeur cible afin d'atténuer l'oscillation.

L'autoscaling sur le pourcentage de "slots_used", tout en étant utile pour le contrôle de la latence, présente des limites. L'évolution de la taille des requêtes et des contraintes matérielles rend difficile la recherche du bon seuil de pourcentage de "slots_used". Si une règle de scaling tente de maintenir le pourcentage moyen de "slots_used" en dessous de 100 %, cela signifie qu'elle tente de maintenir un nombre non nul d'emplacements disponibles. Ces emplacements disponibles correspondent à un débit disponible non utilisé, ce qui n'est pas idéal si vous souhaitez exploiter au mieux les TPU disponibles.

Bonne pratique : Utiliser la mémoire TPU à haut débit (HBM) pour optimiser l'utilisation du matériel

L'utilisation de la mémoire TPU à haut débit (HBM) correspond le plus directement à l'utilisation du matériel, même par rapport aux métriques système, car elles ne tiennent pas compte de la taille des requêtes. Bien que le scaling de la taille de la file d'attente permette de mieux maximiser l'utilisation du matériel, cela se fait au détriment de la latence. Si vous préférez vous fier aux métriques du système plutôt qu'à celles du serveur, nous recommandons l'utilisation de la mémoire HBM comme la meilleure alternative pour l'autoscaling avec "slots_used" puisqu'ils correspondent tous les deux au débit. Pour en savoir plus sur la mémoire TPU, consultez la section Fonctionnement d'un TPU.

Augmenter la taille de lot au-delà du point optimal améliore le débit, mais augmente également le risque d'erreurs de mémoire insuffisante (OOM). Nous vous recommandons vivement d'effectuer un scaling en fonction de la métrique HBM pour équilibrer le débit et la stabilité. Nous vous recommandons de ne pas effectuer un scaling avec la taille de la file d'attente de pré-remplissage et l'utilisation de la mémoire HBM en même temps, car à mesure que la charge augmente, l'utilisation de la mémoire HBM augmente et déclenche le scaling en premier.

Déterminer la valeur de seuil optimale d'utilisation de la mémoire TPU HBM pour l'HPA

Avant de choisir le seuil d'utilisation de la mémoire, nous vous recommandons de définir la taille de lot par appareil sur une valeur qui maximise la mémoire utilisée lorsque la charge maximale attendue est atteinte. Notez que cette valeur devra être déterminée de manière expérimentale et dépendra fortement de la mémoire HBM totale, ainsi que de la longueur des requêtes et des réponses attendues. Nous vous recommandons d'utiliser l'outil locust-load-inference pour vos tests et expérimentations.

Comme pour la taille de lot par appareil, définissez le seuil de façon à maximiser l'utilisation de la mémoire TPU tout en réduisant le risque de comportement OOM.

Vous pouvez également créer un tableau de bord personnalisé Cloud Monitoring pour visualiser le comportement des métriques.

Limites

Deux facteurs importants diminuent le niveau de correspondance entre la latence et le débit et l'utilisation de la mémoire HBM, à savoir la volatilité de l'utilisation de la mémoire HBM et le taux d'échantillonnage plus faible des métriques TPU en général. De plus, bien qu'il existe toujours une correspondance entre l'utilisation de la mémoire HBM et la latence, l'augmentation de l'utilisation de la mémoire HBM a un impact beaucoup moins important que l'augmentation du nombre de requêtes en file d'attente.

Bonne pratique : Optimiser votre configuration HPA

Nous vous recommandons de définir les options de configuration HPA suivantes :

  • Intervalle de stabilisation : utilisez cette option de configuration HPA pour éviter les modifications rapides du nombre d'instances répliquées en raison des fluctuations des métriques. Les valeurs par défaut sont de 5 minutes pour le scaling à la baisse (éviter un scaling à la baisse prématuré) et de 0 pour le scaling à la hausse (garantir la réactivité). Ajustez la valeur en fonction de la volatilité de vos charges de travail et de votre réactivité préférée.
  • Règles de scaling : utilisez cette option de configuration HPA pour affiner le comportement du scaling à la hausse et à la baisse. Vous pouvez définir la limite de la règle "Pods" pour spécifier le nombre absolu d'instances répliquées modifiées par unité de temps, et la limite de la règle "Pourcentage" pour spécifier le pourcentage de variation.

Pour en savoir plus sur ces options, consultez la page Autoscaling horizontal des pods dans la documentation Open Source Kubernetes.

Étape suivante