Detección y recuperación de problemas de nodos para nodos de AWS Neuron dentro de clústeres de Amazon EKS

Implementar la resiliencia del hardware en su infraestructura de entrenamiento es fundamental para mitigar los riesgos y permitir un entrenamiento de modelos ininterrumpido. Al implementar funciones como el monitoreo proactivo del estado y los mecanismos de recuperación automatizados, las organizaciones pueden crear un entorno tolerante a fallas capaz de manejar fallas de hardware u otros problemas sin comprometer la integridad del proceso de entrenamiento.

En el post presentamos el Neurona de AWS Detector y recuperación de problemas de nodos Conjunto de demonios para AWS Trainium y Inferencia de AWS en Servicio Amazon Elastic Kubernetes (Amazon EKS)Este componente puede detectar rápidamente incidencias poco frecuentes cuando fallan los dispositivos Neuron mediante el seguimiento de los registros de monitoreo. Marca los nodos de trabajo en un dispositivo Neuron defectuoso como no saludables y los reemplaza rápidamente con nuevos nodos de trabajo. Al acelerar la velocidad de detección y solución de problemas, aumenta la confiabilidad de su entrenamiento de ML y reduce el tiempo y los costos perdidos debido a fallas de hardware.

Esta solución es aplicable si está utilizando nodos administrados o grupos de nodos autoadministrados (que utilizan Grupos de escalado automático de Amazon EC2) en Amazon EKS. Al momento de escribir esta publicación, la recuperación automática de los nodos provistos por Carpintero Aún no es compatible.

Descripción general de la solución

La solución se basa en el detector y recuperación de problemas de nodos DaemonSet, una poderosa herramienta diseñada para detectar e informar automáticamente varios problemas a nivel de nodo en un clúster de Kubernetes.

El componente detector de problemas de nodo monitoreará continuamente el mensaje del kernel (kmsg) registra los nodos de trabajo. Si detecta mensajes de error relacionados específicamente con el dispositivo Neuron (que es el chip Trainium o AWS Inferentia), cambiará NodeCondition a NeuronHasError en el servidor API de Kubernetes.

El agente de recuperación de nodos es un componente independiente que verifica periódicamente las métricas de Prometheus expuestas por el detector de problemas de nodos. Cuando encuentra una condición de nodo que indica un problema con el dispositivo Neuron, tomará acciones automáticas. Primero, marcará la instancia afectada en el grupo de Auto Scaling relevante como no saludable, lo que invocará al grupo de Auto Scaling para detener la instancia y lanzar un reemplazo. Además, el agente de recuperación de nodos publicará Amazon CloudWatch Métricas para que los usuarios monitoreen y alerten sobre estos eventos.

El siguiente diagrama ilustra la arquitectura de la solución y el flujo de trabajo.

En el siguiente tutorial, creamos un clúster de EKS con nodos de trabajo Trn1, implementamos el complemento Neuron para el detector de problemas de nodos e inyectamos un mensaje de error en el nodo. Luego, observamos que el nodo que falla se detiene y se reemplaza por uno nuevo, y encontramos una métrica en CloudWatch que indica el error.

Prerrequisitos

Antes de comenzar, asegúrese de tener instaladas las siguientes herramientas en su máquina:

Implementar el complemento de detección y recuperación de problemas de nodos

Complete los siguientes pasos para configurar el complemento de detección y recuperación de problemas de nodo:

  1. Cree un clúster EKS utilizando los datos de un módulo Terraform de EKS:
    git clone https://github.com/awslabs/data-on-eks.git
    
    export TF_VAR_region=us-east-2
    export TF_VAR_trn1_32xl_desired_size=4
    export TF_VAR_trn1_32xl_min_size=4
    cd data-on-eks/ai-ml/trainium-inferentia/ && chmod +x install.sh
    ./install.sh
    
    aws eks --region us-east-2 describe-cluster --name trainium-inferentia
    
    # Creates k8s config file to authenticate with EKS
    aws eks --region us-east-2 update-kubeconfig --name trainium-inferentia
    
    kubectl get nodes
    NAME STATUS ROLES AGE VERSION
    ip-100-64-161-213.us-east-2.compute.internal Ready 31d v1.29.0-eks-5e0fdde
    ip-100-64-227-31.us-east-2.compute.internal Ready 31d v1.29.0-eks-5e0fdde
    ip-100-64-70-179.us-east-2.compute.internal Ready 31d v1.29.0-eks-5e0fdde

  2. Instalar lo requerido Gestión de identidad y acceso de AWS (IAM) Función para la cuenta de servicio y el complemento detector de problemas de nodo.
  3. Cree una política como se muestra a continuación. Actualice la Resource valor clave para que coincida con el ARN del grupo de nodos que contiene los nodos Trainium y AWS Inferentia, y actualice el ec2:ResourceTag/aws:autoscaling:groupName valor clave para que coincida con el nombre del grupo de escalamiento automático.

Puede obtener estos valores desde la consola de Amazon EKS. Seleccione Clústeres en el panel de navegación, abra el trainium-inferentia clúster, seleccione Grupos de nodos y localice su grupo de nodos.

# To create the policy, aws cli can be used as shown below where npd-policy-trimmed.json is the policy json constructed from the template above.

# Create npd-policy-trimmed.json
cat << EOF > npd-policy-trimmed.json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "autoscaling:SetInstanceHealth",
                "autoscaling:DescribeAutoScalingInstances"
            ],
            "Effect": "Allow",
            "Resource": <arn of the Auto Scaling group corresponding to the Neuron nodes for the cluster>
        },
        {
            "Action": [
                "ec2:DescribeInstances"
            ],
            "Effect": "Allow",
            "Resource": "*",
            "Condition": {
                "ForAllValues:StringEquals": {
                    "ec2:ResourceTag/aws:autoscaling:groupName": <name of the Auto Scaling group corresponding to the Neuron nodes for the cluster>
                }
            }
        },
        {
            "Action": [
                "cloudwatch:PutMetricData"
            ],
            "Effect": "Allow",
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "cloudwatch:Namespace": "NeuronHealthCheck"
                }
            }
        }
    ]
}
EOF

Este componente se instalará como un DaemonSet en su clúster EKS.

# To create the policy, aws cli can be used as shown below where npd-policy-trimmed.json is the policy json constructed from the template above.

aws iam create-policy  \
--policy-name NeuronProblemDetectorPolicy \
--policy-document file://npd-policy-trimmed.json

# Note the ARN

CLUSTER_NAME=trainium-inferentia # Your EKS Cluster Name 
AWS_REGION=us-east-2
ACCOUNT_ID=$(aws sts get-caller-identity --query 'Account' --output text)
POLICY_ARN=arn:aws:iam::$ACCOUNT_ID:policy/NeuronProblemDetectorPolicy

eksctl create addon --cluster $CLUSTER_NAME --name eks-pod-identity-agent \
  --region $AWS_REGION

eksctl create podidentityassociation \
    --cluster $CLUSTER_NAME \
    --namespace neuron-healthcheck-system \
    --service-account-name node-problem-detector \
    --permission-policy-arns="$POLICY_ARN" \
    --region $AWS_REGION
    
# Install the Neuron NPD and recovery plugin 

kubectl create ns neuron-healthcheck-system
curl https://raw.githubusercontent.com/aws-neuron/aws-neuron-sdk/215b421ac448d85f89be056e27e29842a6b03c9c/src/k8/neuron-problem-detector/k8s-neuron-problem-detector-and-recovery.yml | kubectl apply -f - 
curl https://raw.githubusercontent.com/aws-neuron/aws-neuron-sdk/215b421ac448d85f89be056e27e29842a6b03c9c/src/k8/neuron-problem-detector/k8s-neuron-problem-detector-and-recovery-rbac.yml | kubectl apply -f - 
curl https://raw.githubusercontent.com/aws-neuron/aws-neuron-sdk/215b421ac448d85f89be056e27e29842a6b03c9c/src/k8/neuron-problem-detector/k8s-neuron-problem-detector-and-recovery-config.yml | kubectl apply -f -

# Expected result (with 4 Neuron nodes in cluster):

kubectl get pod -n neuron-healthcheck-system
NAME READY STATUS RESTARTS AGE
node-problem-detector-49p6w 2/2 Running 0 31s
node-problem-detector-j7wct 2/2 Running 0 31s
node-problem-detector-qr6jm 2/2 Running 0 31s
node-problem-detector-vwq8x 2/2 Running 0 31s

Las imágenes de contenedores en los manifiestos de Kubernetes se almacenan en un repositorio público como registry.k8s.io y public.ecr.awsEn el caso de los entornos de producción, se recomienda que los clientes limiten las dependencias externas que afectan a estas áreas y alojen imágenes de contenedores en un registro privado y sincronice las imágenes desde repositorios públicos. Para obtener información detallada sobre la implementación, consulte la publicación del blog: Anuncio de extracción de caché para registration.k8s.io en Amazon Elastic Container Registry.

De manera predeterminada, el detector de problemas de nodos no realizará ninguna acción en el nodo que falló. Si desea que el agente finalice automáticamente la instancia EC2, actualice DaemonSet de la siguiente manera:

kubectl edit -n neuron-healthcheck-system ds/node-problem-detector

...
   env:
   - name: ENABLE_RECOVERY
     value: "true"

Pruebe el detector de problemas de nodos y la solución de recuperación

Una vez instalado el complemento, puede ver que las condiciones de Neuron aparecen al ejecutar kubectl describe nodeSimulamos un error de dispositivo inyectando registros de errores en la instancia:

# Verify node conditions on any node. Neuron conditions should show up.

kubectl describe node ip-100-64-58-151.us-east-2.compute.internal | grep Conditions: -A7

Conditions:
  Type             Status  LastHeartbeatTime                 LastTransitionTime                Reason                       Message
  ----             ------  -----------------                 ------------------                ------                       -------
  NeuronHealth     False   Fri, 29 Mar 2024 15:52:08 +0800   Thu, 28 Mar 2024 13:59:19 +0800   NeuronHasNoError             Neuron has no error
  MemoryPressure   False   Fri, 29 Mar 2024 15:51:03 +0800   Thu, 28 Mar 2024 13:58:39 +0800   KubeletHasSufficientMemory   kubelet has sufficient memory available
  DiskPressure     False   Fri, 29 Mar 2024 15:51:03 +0800   Thu, 28 Mar 2024 13:58:39 +0800   KubeletHasNoDiskPressure     kubelet has no disk pressure
  PIDPressure      False   Fri, 29 Mar 2024 15:51:03 +0800   Thu, 28 Mar 2024 13:58:39 +0800   KubeletHasSufficientPID      kubelet has sufficient PID available
  Ready            True    Fri, 29 Mar 2024 15:51:03 +0800   Thu, 28 Mar 2024 13:59:08 +0800   KubeletReady                 kubelet is posting ready status
# To get provider id
kubectl describe node ip-100-64-58-151.us-east-2.compute.internal | grep -i provider | sed -E 's/.*\/([^\/]+)$/\1/'

i-0381404aa69eae3f6

# SSH into to the worker node and simulate the hardware error on the neuron device
aws ssm start-session --target i-0381404aa69eae3f6 --region us-east-2

Starting session with SessionId: lindarr-0069460593240662a

sh-4.2$
sh-4.2$ sudo bash
[root@ip-192-168-93-211 bin]# echo "test NEURON_HW_ERR=DMA_ERROR test" >> /dev/kmsg

Aproximadamente 2 minutos después, podrás ver que se ha identificado el error:

kubectl describe node ip-100-64-58-151.us-east-2.compute.internal | grep 'Conditions:' -A7
Conditions:
  Type             Status  LastHeartbeatTime                 LastTransitionTime                Reason                       Message
  ----             ------  -----------------                 ------------------                ------                       -------
  NeuronHealth     True    Fri, 29 Mar 2024 17:42:43 +0800   Fri, 29 Mar 2024 17:42:38 +0800   NeuronHasError_DMA_ERROR     test NEURON_HW_ERR=DMA_ERROR test

...

Events:
  Type     Reason                    Age   From            Message
  ----     ------                    ----  ----            -------
  Warning  NeuronHasError_DMA_ERROR  36s   kernel-monitor  Node condition NeuronHealth is now: True, reason: NeuronHasError_DMA_ERROR, message: "test NEURON_HW_ERR=DMA_ERROR test"

Ahora que el detector de problemas del nodo detectó el error y el agente de recuperación tomó automáticamente la acción de establecer el nodo como no saludable, Amazon EKS acordonará el nodo y desalojará los pods en él:

# Verify the Node scheduling is disabled.
kubectl get node 
NAME                                           STATUS                        ROLES    AGE    VERSION
ip-100-64-1-48.us-east-2.compute.internal      Ready                         <none>   156m   v1.29.0-eks-5e0fdde
ip-100-64-103-26.us-east-2.compute.internal    Ready                         <none>   94s    v1.29.0-eks-5e0fdde
ip-100-64-239-245.us-east-2.compute.internal   Ready                         <none>   154m   v1.29.0-eks-5e0fdde
ip-100-64-52-40.us-east-2.compute.internal     Ready                         <none>   156m   v1.29.0-eks-5e0fdde
ip-100-64-58-151.us-east-2.compute.internal    NotReady,SchedulingDisabled   <none>   27h    v1.29.0-eks-5e0fdde

Puede abrir la consola de CloudWatch y verificar la métrica para NeuronHealthCheckPuedes ver el CloudWatch NeuronHasError_DMA_ERROR La métrica tiene el valor 1.

Después del reemplazo, puedes ver que se ha creado un nuevo nodo de trabajo:

# The new node with age 28s is the new node

kubectl get node 
NAME                                           STATUS   ROLES    AGE   VERSION
ip-192-168-65-77.us-east-2.compute.internal    Ready    <none>   28s   v1.29.0-eks-5e0fddev1.28.5-eks-5e0fdde
ip-192-168-81-176.us-east-2.compute.internal   Ready    <none>   9d    v1.29.5-eks-5e0fdde
ip-192-168-91-218.us-east-2.compute.internal   Ready    <none>   9d    v1.29.0-eks-5e0fdde
ip-192-168-94-83.us-east-2.compute.internal    Ready    <none>   9d    v1.29.0-eks-5e0fdde

Veamos un escenario del mundo real, en el que se ejecuta un trabajo de entrenamiento distribuido, utilizando un operador MPI como se describe en Llama-2 en Trainiumy hay un error de Neuron irrecuperable en uno de los nodos. Antes de que se implemente el complemento, el trabajo de entrenamiento se bloqueará, lo que resultará en pérdida de tiempo y costos computacionales. Una vez implementado el complemento, el detector de problemas de nodos eliminará de manera proactiva el nodo problemático del clúster. En los scripts de entrenamiento, guarda puntos de control periódicamente para que el entrenamiento se reanude desde el punto de control anterior.

La siguiente captura de pantalla muestra registros de ejemplo de un trabajo de capacitación distribuido.

Se ha iniciado el entrenamiento. (Puede ignorar loss=nan por ahora; es un problema conocido y se eliminará. Para uso inmediato, consulte la métrica reduction_train_loss).

La siguiente captura de pantalla muestra el punto de control creado en el paso 77.

El entrenamiento se detuvo después de que uno de los nodos tuvo un problema en el paso 86. El error se inyectó manualmente para realizar pruebas.

Después de que se detectó el nodo defectuoso y fue reemplazado por el complemento Neuron para problemas y recuperación de nodos, el proceso de entrenamiento se reanudó en el paso 77, que fue el último punto de control.

Aunque los grupos de escalado automático detendrán los nodos que no funcionan correctamente, pueden encontrar problemas que impidan el lanzamiento de nodos de reemplazo. En tales casos, los trabajos de capacitación se detendrán y requerirán intervención manual. Sin embargo, el nodo detenido no generará más cargos en la instancia EC2 asociada.

Si desea realizar acciones personalizadas además de detener instancias, puede crear alarmas de CloudWatch que observen las métricas. NeuronHasError_DMA_ERROR,NeuronHasError_HANG_ON_COLLECTIVES, NeuronHasError_HBM_UNCORRECTABLE_ERROR, NeuronHasError_SRAM_UNCORRECTABLE_ERRORy NeuronHasError_NC_UNCORRECTABLE_ERRORy use una consulta de CloudWatch Metrics Insights como SELECT AVG(NeuronHasError_DMA_ERROR) FROM NeuronHealthCheck Para sumar estos valores y evaluar las alarmas, las siguientes capturas de pantalla muestran un ejemplo.

Limpiar

Para limpiar todos los recursos provistos para esta publicación, ejecute el script de limpieza:

# neuron-problem-detector-role-$CLUSTER_NAME
eksctl delete podidentityassociation \
--service-account-name node-problem-detector \
--namespace neuron-healthcheck-system \
--cluster $CLUSTER_NAME \
--region $AWS_REGION

# delete the EKS Cluster
cd data-on-eks/ai-ml/trainium-inferentia
./cleanup.sh

Conclusión

En esta publicación, mostramos cómo funciona el detector de problemas y el DaemonSet de recuperación de Neuron para Amazon EKS en instancias EC2 impulsadas por Trainium y AWS Inferentia. Si está ejecutando instancias EC2 basadas en Neuron y usa nodos administrados o grupos de nodos autoadministrados, puede implementar el detector y el DaemonSet de recuperación en su clúster EKS y beneficiarse de una confiabilidad mejorada y tolerancia a fallas de sus cargas de trabajo de entrenamiento de aprendizaje automático en caso de falla de un nodo.


Sobre los autores

Harish Rao es un arquitecto de soluciones sénior en AWS, especializado en entrenamiento e inferencia de IA distribuida a gran escala. Capacita a los clientes para aprovechar el poder de la IA para impulsar la innovación y resolver desafíos complejos. Fuera del trabajo, Harish adopta un estilo de vida activo, disfruta de la tranquilidad del senderismo, la intensidad del ráquetbol y la claridad mental de las prácticas de atención plena.

Ziwen Ning es ingeniero de desarrollo de software en AWS. Actualmente se centra en mejorar la experiencia de IA/ML mediante la integración de AWS Neuron con entornos en contenedores y Kubernetes. En su tiempo libre, disfruta desafiándose a sí mismo con bádminton, natación y otros deportes, y sumergirse en la música.

Geeta Gharpur es una desarrolladora de software sénior del equipo de ingeniería de ML de Annapurna. Se centra en ejecutar cargas de trabajo de IA/ML a gran escala en Kubernetes. Vive en Sunnyvale, California, y disfruta escuchando Audible en su tiempo libre.

Darren Lin es un arquitecto de soluciones especializado en la nube nativa en AWS que se centra en dominios como Linux, Kubernetes, contenedores, observabilidad y tecnologías de código abierto. En su tiempo libre, le gusta hacer ejercicio y divertirse con su familia.