View a markdown version of this page

Mise à l'échelle et performances des applications - Amazon EKS

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

Mise à l'échelle et performances des applications

Astuce

Découvrez les meilleures pratiques grâce aux ateliers Amazon EKS.

Gestion des artefacts ML, des frameworks de service et optimisation du démarrage

Le déploiement de modèles d'apprentissage automatique (ML) sur Amazon EKS nécessite une réflexion approfondie sur la manière dont les modèles sont intégrés dans les images de conteneur et les environnements d'exécution. Cela garantit l'évolutivité, la reproductibilité et l'utilisation efficace des ressources. Cette rubrique décrit les différentes approches de gestion des artefacts du modèle ML, de sélection de frameworks de service et d'optimisation des temps de démarrage des conteneurs grâce à des techniques telles que la pré-mise en cache, toutes conçues pour réduire les temps de démarrage des conteneurs.

Gestion des artefacts du modèle ML dans les déploiements

L'une des décisions clés est de savoir comment gérer les artefacts du modèle ML (tels que les poids et les configurations) eux-mêmes. Le choix a un impact sur la taille de l'image, la vitesse de déploiement, la fréquence de mise à jour du modèle et la surcharge opérationnelle. Notez que lorsque nous parlons de stockage du « modèle », nous faisons référence aux artefacts du modèle (tels que les paramètres entraînés et les poids du modèle). Il existe différentes approches pour gérer les artefacts du modèle ML sur Amazon EKS. Chacun a ses inconvénients, et le meilleur dépend de la taille de votre modèle, de la cadence de mise à jour et des besoins en infrastructure. Envisagez les approches suivantes, de la moins recommandée à la plus recommandée :

  • Intégration du modèle dans l'image du conteneur : copiez les fichiers du modèle (par exemple, .safetensors, .pth, .h5) dans l'image du conteneur (par exemple, Dockerfile) lors de la création de l'image. Le modèle fait partie de l'image immuable. Nous recommandons d'utiliser cette approche pour les petits modèles avec des mises à jour peu fréquentes. Cela garantit la cohérence et la reproductibilité, n'entraîne aucun retard de chargement et simplifie la gestion des dépendances, mais entraîne des tailles d'image plus importantes, ralentit les builds et les pushs, nécessite une reconstruction et un redéploiement pour les mises à jour des modèles, et n'est pas idéal pour les grands modèles en raison du débit d'extraction des registres.

  • Téléchargement du modèle lors de l'exécution : au démarrage du conteneur, l'application télécharge le modèle depuis un stockage externe (par exemple, Amazon S3, soutenu par S3 CRT pour des transferts haut débit optimisés à l'aide de méthodes telles que Mountpoint pour le pilote CSI S3, AWS S3 CLI ou s5cmd OSS CLI) via des scripts dans un conteneur d'initialisation ou un point d'entrée. Nous recommandons de commencer par cette approche pour les grands modèles soumis à des mises à jour fréquentes. Cela permet de se concentrer sur les images de conteneur code/runtime, de faciliter les mises à jour des modèles sans avoir à les reconstruire, de prendre en charge le contrôle des versions via les métadonnées de stockage, mais cela peut entraîner des défaillances du réseau (nécessite une logique de nouvelle tentative) et nécessite une authentification et une mise en cache.

Pour en savoir plus, consultez la section Accélérer le processus d'extraction dans le cadre de l'atelier AI on EKS.

Au service des modèles ML

Le déploiement et le service de modèles d'apprentissage automatique (ML) sur Amazon EKS nécessitent de sélectionner une approche de diffusion de modèles appropriée afin d'optimiser la latence, le débit, l'évolutivité et la simplicité opérationnelle. Le choix dépend de votre type de modèle (par exemple, langage, modèle de vision), des exigences en matière de charge de travail (par exemple, inférence en temps réel) et de l'expertise de votre équipe. Les approches courantes incluent Python-based des configurations pour le prototypage, des serveurs de modèles dédiés pour les fonctionnalités de production et des moteurs d'inférence spécialisés pour des performances et une efficacité élevées. Chaque méthode implique des compromis en termes de complexité de configuration, de performances et d'utilisation des ressources. Notez que les infrastructures de service peuvent augmenter la taille des images de conteneur (plusieurs Go) en raison des dépendances, ce qui peut avoir un impact sur les temps de démarrage. Envisagez de découpler en utilisant des techniques de gestion des artefacts pour atténuer ce problème. Les options sont répertoriées de la moins recommandée à la plus recommandée :

À l'aide de frameworks Python (par exemple, FastAPI, HuggingFace Transformers with PyTorch) Développez une application personnalisée à l'aide de frameworks Python, en intégrant des fichiers de modèle (poids, configuration, tokenizer) dans une configuration de nœud conteneurisé.

  • Avantages : prototypage facile, sans infrastructure supplémentaire, compatible Python-only avec tous les HuggingFace modèles, déploiement simple de Kubernetes.

  • Inconvénients : se limite au traitement par request/simple lots uniques, génération lente de jetons (pas de noyaux optimisés), mémoire inefficace scaling/monitoring, manque et implique de longs temps de démarrage.

  • Recommandation : à utiliser pour le prototypage initial ou pour les tâches à nœud unique nécessitant une intégration logique personnalisée.

Utilisation de frameworks de service de modèles dédiés (par exemple TensorRT-LLM, TGI) Adoptez des serveurs spécialisés tels que TensorRT-LLM TGI pour l'inférence ML, la gestion du chargement, du routage et de l'optimisation des modèles. Ils prennent en charge des formats tels que les capteurs de sécurité, avec une compilation optionnelle ou des plugins.

  • Avantages : propose le traitement par lots (en static/in vol ou en continu), la quantification (INT8, FP8, GPTQ), des optimisations matérielles (NVIDIA, AMD, Intel, Inferentia) et un support multi-GPU (Parallélisme). Tensor/Pipeline TensorRT-LLM prend en charge divers modèles (LLM Encoder-Decoder), tandis que TGI tire parti HuggingFace de l'intégration.

  • Inconvénients : TensorRT-LLM nécessite une compilation et l'est NVIDIA-only ; le TGI peut être moins efficace pour le traitement par lots ; les deux entraînent une surcharge de configuration et peuvent ne pas convenir à tous les types de modèles (par exemple, les modèles autres que les transformateurs).

  • Recommandation : convient aux PyTorch/TensorFlow modèles nécessitant des capacités de production telles que A/B des tests ou un débit élevé avec du matériel compatible.

Utilisation de moteurs d'inférence spécialisés à haut débit (par exemple, vLLM) Utilisez des moteurs d'inférence avancés tels que vLLM, qui optimisent le service LLM avec, le traitement par lots en vol et la quantification (INT8, AWQ) PagedAttention, intégrables à la mise à l'échelle automatique d'EKS. FP8-KV

  • Avantages : haut débit et efficacité de la mémoire (40 à 60 % d'économies de VRAM), gestion dynamique des demandes, diffusion de jetons, prise en charge de plusieurs processeurs graphiques Tensor Parallel à nœud unique et large compatibilité matérielle.

  • Inconvénients : optimisé pour les transformateurs à décodeur uniquement (par exemple, LLama), moins efficace pour les modèles sans transformateur, nécessite du matériel compatible (par exemple, des GPU NVIDIA) et des efforts de configuration.

  • Recommandation : le meilleur choix pour l'inférence LLM à volume élevé et à faible latence sur EKS, afin d'optimiser l'évolutivité et les performances.

Optimisation des temps d'extraction des images des conteneurs

Les images de conteneurs de grande taille peuvent entraîner des retards de démarrage à froid qui ont un impact sur la latence de démarrage du pod. Pour les charges de travail sensibles à la latence, telles que les charges de travail d'inférence en temps réel redimensionnées horizontalement, le démarrage rapide du pod est essentiel. Envisagez les approches suivantes pour optimiser les temps d'extraction des images de conteneurs :

Réduction de la taille des images des conteneurs

La réduction de la taille des images du conteneur au démarrage est un autre moyen de réduire la taille des images. Vous pouvez effectuer des réductions à chaque étape du processus de création de l'image du conteneur. Pour commencer, choisissez les images de base qui contiennent le moins de dépendances requises. Lors de la création d'images, n'incluez que les bibliothèques et artefacts essentiels requis. Lorsque vous créez des images, essayez de combiner plusieurs COPY commandes RUN ou plusieurs pour créer un plus petit nombre de couches plus grandes. Pour les AI/ML frameworks, utilisez des versions en plusieurs étapes pour séparer la construction et l'exécution, en copiant uniquement les artefacts requis (par exemple, via COPY —from= pour les registres ou les contextes locaux) et en sélectionnant des variantes telles que des images destinées à l'exécution uniquement (par exemple, pytorch/pytorch:2.7.1-cuda11.8-cudnn9-runtime à 3,03 Go contre devel à 6,66 Go). Pour en savoir plus, consultez la section Réduction de la taille de l'image du conteneur dans l'atelier AI on EKS.

Réduisez la latence d'extraction des images

Pour les clusters EKS exécutés dans des sous-réseaux privés, configurez les points de terminaison de l'interface VPC pour Amazon ECR afin de conserver le trafic d'extraction d'images sur le réseau privé AWS, de réduire la latence et d'éliminer les frais de traitement des données liés aux passerelles NAT. Consultez Créer les points de terminaison VPC pour Amazon ECR pour obtenir des instructions de configuration.

En outre, si vos charges de travail reposent sur des images de conteneurs en amont provenant de registres externes, pensez à utiliser le cache ECR pour créer un proxy et mettre en cache ces images dans votre registre ECR privé.

Optimisation de la bande passante réseau pour les extractions d'images

Lorsque vous extrayez de grandes images de conteneurs, la bande passante réseau disponible pour vos nœuds de travail EKS a un impact direct sur le temps de démarrage des charges de travail de formation et d'inférence. Toutes les Nitro-based instances de la génération actuelle utilisent l'Elastic Network Adapter (ENA), mais la bande passante disponible varie considérablement en fonction de la taille de l'instance, et il est essentiel de comprendre la différence entre la bande passante de base et la bande passante de rafale (voir bande passante réseau des instances Amazon EC2). Pour réduire le temps nécessaire à la préparation de vos charges de travail, sélectionnez des tailles d'instance dotées d'une bande passante réseau de base suffisante par rapport à la taille de vos images et tirez simultanément.

Utilisation du snapshotter SOCI pour les images Pre-pull

Pour les images de très grande taille que vous ne pouvez pas facilement minimiser, vous pouvez utiliser le snapshotter open source Seekable OCI (SOCI) configuré en mode pull and unpack en parallèle. Cette solution vous permet d'utiliser des images existantes sans reconstruire ni modifier vos pipelines de génération. Cette option est particulièrement efficace lors du déploiement de charges de travail comportant de très grandes images sur des instances de calcul EC2 hautes performances. Il fonctionne parfaitement avec les réseaux à haut débit et les configurations de stockage hautes performances, comme c'est généralement le cas pour les charges de travail AI/ML évolutives.

Le pull/unpack mode parallèle SOCI améliore les performances d'extraction d'images de bout en bout grâce à des stratégies de parallélisation configurables. L'accélération de l'extraction et de la préparation des images a un impact direct sur la rapidité avec laquelle vous pouvez déployer de nouvelles charges de travail et faire évoluer efficacement votre cluster. Les extractions d'images comportent deux phases principales :

1. Extraction de couches depuis le registre vers le nœud

Pour optimiser l'extraction des couches, SOCI crée plusieurs connexions HTTP simultanées par couche, multipliant ainsi le débit de téléchargement au-delà de la limite de connexion unique. Il divise les grandes couches en morceaux et les télécharge simultanément sur plusieurs connexions. Cette approche permet de saturer la bande passante réseau disponible et de réduire considérablement les temps de téléchargement. Cela est particulièrement utile pour les AI/ML charges de travail où une seule couche peut atteindre plusieurs gigaoctets.

2. Déballage et préparation de ces couches pour créer des conteneurs

Pour optimiser le déballage des couches, SOCI traite plusieurs couches simultanément. Au lieu d'attendre que chaque couche soit complètement déballée avant de commencer la suivante, il utilise les cœurs de processeur disponibles pour décompresser et extraire plusieurs couches simultanément. Ce traitement parallèle transforme la phase de I/O-bound déballage traditionnelle en une CPU-optimized opération qui s'adapte à vos cœurs disponibles. Le système orchestre soigneusement cette parallélisation afin de maintenir la cohérence du système de fichiers tout en maximisant le débit.

Le mode SOCI parallel pull utilise un système de contrôle à double seuil avec des paramètres configurables à la fois pour la simultanéité des téléchargements et le déballage du parallélisme. Ce contrôle granulaire vous permet d'affiner le comportement du SOCI pour répondre à vos exigences de performance et aux conditions environnementales spécifiques. La compréhension de ces paramètres vous permet d'optimiser votre temps d'exécution pour obtenir les meilleures performances d'extraction.

Références

Utilisation des instantanés EBS pour les images Pre-pull

Vous pouvez prendre un instantané Amazon Elastic Block Store (EBS) des images de conteneurs mises en cache et le réutiliser pour les nœuds de travail EKS. Cela garantit que les images sont préextraites localement au démarrage du nœud, ce qui réduit le temps d'initialisation du module. Consultez Réduire le temps de démarrage des conteneurs sur Amazon EKS avec le volume de données Bottlerocket pour plus d'informations sur l'utilisation des plans Karpenter et EKS Terraform pour les groupes de nœuds gérés.

Pour en savoir plus, consultez les sections Utilisation de snapshotter containerd et Précharger des images de conteneurs dans des volumes de données Bottlerocket avec des instantanés EBS dans l'atelier AI on EKS.

Utilisation du cache d'exécution du conteneur pour les Pre-pull images

Vous pouvez pré-extraire des images de conteneur sur des nœuds à l'aide des ressources Kubernetes (par exemple, DaemonSet ou Deployment) pour remplir le cache d'exécution du conteneur du nœud. Le cache d'exécution du conteneur est le stockage local géré par le runtime du conteneur (par exemple, containerd) où les images sont stockées après avoir été extraites d'un registre. Pre-pulling garantit que les images sont disponibles localement, évitant ainsi les retards de téléchargement lors du démarrage du pod. Cette approche est particulièrement utile lorsque les images changent souvent (mises à jour fréquentes, par exemple), lorsque les instantanés EBS ne sont pas préconfigurés, lorsque la création d'un volume EBS prend plus de temps que l'extraction directe depuis un registre de conteneurs, ou lorsque des nœuds se trouvent déjà dans le cluster et doivent créer des pods à la demande en utilisant l'une des nombreuses images possibles.

Pre-pulling toutes les variantes garantissent un démarrage rapide, quelle que soit l'image requise. Par exemple, dans le cadre d'une charge de travail de ML massivement parallèle nécessitant 100 000 petits modèles conçus à l'aide de 10 techniques différentes, le pré-extraction de 10 images DaemonSet sur un grand cluster (par exemple, des milliers de nœuds) minimise le temps de démarrage du pod, permettant ainsi de terminer le processus en moins de 10 secondes en évitant les extractions à la demande. L'approche du cache d'exécution du conteneur élimine le besoin de gérer les instantanés EBS, ce qui vous permet de toujours obtenir la dernière version de l'image du conteneur, mais pour les charges de travail d'inférence en temps réel où les nœuds évoluent DaemonSets, les nouveaux nœuds ajoutés par des outils tels que Cluster Autoscaler peuvent planifier des pods de charge de travail avant que le pré-pull ne termine l'extraction de l'image. in/out DaemonSet Cela peut amener le pod initial du nouveau nœud à déclencher le pull de toute façon, ce qui peut retarder le démarrage et avoir un impact sur les exigences de faible latence. De plus, la collecte d'images par Kubelet peut affecter les images pré-extraites en supprimant celles qui ne sont pas utilisées lorsque l'utilisation du disque dépasse certains seuils ou si elles dépassent un âge maximum d'inutilisation configuré. Dans le cas de in/out modèles de mise à l'échelle, cela peut entraîner l'expulsion d'images sur des nœuds inactifs, ce qui nécessite des extractions supplémentaires lors des mises à l'échelle ultérieures et réduit la fiabilité du cache pour les charges de travail en rafale.

Consultez le GitHub référentiel AWS pour des exemples de pré-extraction d'images dans le cache d'exécution du conteneur.

Envisagez NVMe pour le stockage kubelet et containerd

Envisagez de configurer kubelet et containerd d'utiliser des disques de stockage d'instances NVMe éphémères pour améliorer les performances des disques. Le processus d'extraction d'un conteneur consiste à télécharger une image de conteneur à partir d'un registre et à décompresser ses couches dans un format utilisable. Pour optimiser les I/O opérations lors de la décompression, vous devez évaluer ce qui fournit des niveaux de I/O performance et de débit supérieurs pour le type d'instance de votre hôte de conteneur : instances adossées NVMe avec stockage local ou volume EBS. IOPS/throughput Pour les instances EC2 avec stockage local NVMe, envisagez de configurer le système de fichiers sous-jacent du nœud pour kubelet ()/var/lib/kubelet, containerd () et Pod logs (/var/lib/containerd/var/log/pods) afin d'utiliser des disques de stockage d'instances NVMe éphémères pour des niveaux de performance et de débit supérieurs. I/O

Le stockage éphémère du nœud peut être partagé entre les pods qui demandent un stockage éphémère et les images des conteneurs téléchargées sur le nœud. Si vous utilisez Karpenter avec Bottlerocket ou des AMI optimisées EKS pour AL2023, vous pouvez configurer l'instance en réglant EC2NodeClassl'StorePolicy instance sur RAID0 ou, si vous utilisez des groupes de nœuds gérés, en configurant l'entrée locale dans le StoragePolicy cadre des données utilisateur. NodeConfig