Ayude a mejorar esta página
Para contribuir a esta guía del usuario, elija el enlace Edit this page on GitHub que se encuentra en el panel derecho de cada página.
Uso de la segmentación temporal con GPU de NVIDIA en Amazon EKS
La segmentación temporal permite que varios pods compartan una sola GPU de NVIDIA física. El programador de Kubernetes coloca varios pods en la misma GPU y el programador de CUDA de la GPU multiplexa en el tiempo el trabajo. La segmentación temporal es la estrategia más sencilla para compartir la GPU. Utiliza solo software, no requiere hardware especial y funciona en todos los tipos de instancias de GPU de NVIDIA en AWS. La segmentación temporal no aísla la memoria ni la computación entre los pods que comparten una GPU. Funciona mejor para cargas de trabajo que utilizan poco la GPU, como los servicios de inferencia que están inactivos entre solicitudes o los entornos de desarrollo en los que varios usuarios comparten una GPU. Para las cargas de trabajo que requieren aislamiento de memoria y computación por hardware, utilice GPU de varias instancias (MIG) en su lugar.
En Amazon EKS, puede administrar la segmentación temporal con el controlador de DRA de NVIDIA o el complemento para dispositivos de NVIDIA.
La segmentación temporal solo se puede utilizar con Karpenter si se utiliza el aprovisionamiento de capacidad estático
La segmentación temporal es una buena opción cuando:
-
El uso de la GPU es constantemente bajo, por ejemplo, los servicios de inferencia sensibles a la latencia que están inactivos entre solicitudes.
-
Varios desarrolladores comparten un único nodo de GPU para llevar a cabo tareas de desarrollo o de trabajo con cuadernos.
-
Los nodos utilizan un tipo de instancia de GPU que no admite MIG, como las familias
g5,g6og6e. -
Puede aceptar que un pod sea a veces más lento porque otro pod de la misma GPU esté ocupado.
Considere la posibilidad de adoptar otro enfoque cuando:
-
Necesite aislar la memoria. Los pods de una GPU con intervalos de tiempo compartido comparten la misma memoria que la GPU y un pod puede agotar la memoria de la que dependen otros pods. Use MIG para aislar la memoria.
-
Necesite una latencia predecible por pod o una calidad de servicio. El programador de GPU comparte la computación entre ranuras en la medida en que sea posible y sin garantías.
-
Ejecute cargas de trabajo de entrenamiento. La segmentación temporal agrega un cambio de contexto que reduce la eficiencia del entrenamiento. Un trabajo con punto de control que otro pod ralentiza debe volver a intentarlo desde el último punto de control.
Consideraciones
Revise las siguientes consideraciones antes de usar la segmentación temporal en producción.
Consideraciones generales
-
Sin aislamiento de memoria: los pods que comparten una GPU con segmentación temporal comparten su memoria. Un pod puede asignar memoria que otros pods necesitan, lo que puede producir errores de memoria insuficiente. Haga coincidir la cantidad de pods que comparten cada GPU con el consumo de memoria de las cargas de trabajo. Si los pods cargan modelos grandes de forma habitual, comparta menos pods por GPU o use MIG.
-
Uso compartido de computación al máximo esfuerzo: el programador de GPU comparte la computación entre los pods al máximo esfuerzo posible y no garantiza ninguna computación proporcional a cada pod.
-
La segmentación temporal y MPS no pueden compartir la misma GPU: la segmentación temporal establece el modo de computación de la GPU en
DEFAULT, mientras que el servicio multiproceso (MPS) de NVIDIA requiereEXCLUSIVE_PROCESS. Puede usar ambas estrategias en el mismo clúster, pero no en la misma GPU física al mismo tiempo. La segmentación temporal tampoco tiene ningún efecto en una instancia de MIG. Para compartir una única instancia de MIG entre contenedores, utilice MPS en su lugar. -
Métricas por contenedor: el administrador de GPU para centros de datos de NVIDIA (DCGM) no puede atribuir métricas a contenedores individuales cuando la segmentación temporal está activa. Las métricas de la GPU siguen disponibles, pero no puede identificar qué pod consumió una cantidad determinada de recursos de la GPU.
Consideraciones sobre el controlador de DRA de NVIDIA
-
Característica alfa: la segmentación temporal mediante el controlador de DRA requiere la puerta de características
TimeSlicingSettings, que es una característica alfa deshabilitada de forma predeterminada. Para obtener más información, consulte Uso de la segmentación temporal de la GPU con el controlador de DRA de NVIDIA. -
Solo uso compartido mediado por el usuario: los pods solo comparten una GPU cuando hacen referencia a la misma
ResourceClaimoResourceClaimTemplate, lo cual depende del espacio de nombres, por lo que el uso compartido no puede cruzar espacios de nombres. El uso compartido mediado por el sistema es una capacidad futura propuesta. -
Deshabilite el complemento para dispositivos integrado en Bottlerocket: el controlador de DRA no se puede ejecutar junto con el complemento para dispositivos de NVIDIA en el mismo nodo. En Bottlerocket, deshabilite el complemento para dispositivos integrado, que requiere la versión 1.63.0 o posterior de Bottlerocket. Para obtener más información, consulte Instalación del controlador de DRA de NVIDIA.
-
Compatibilidad con la computación: el controlador de DRA de NVIDIA es compatible con el aprovisionamiento de capacidad estática en Karpenter, los grupos de nodos administrados de EKS o los nodos autoadministrados, pero no es compatible con el modo automático de EKS. Para obtener más información, consulte la documentación de NodePool estática de Karpenter
en el sitio web de Karpenter.
Consideraciones sobre el complemento para dispositivos de NVIDIA
-
Uso compartido de computación al máximo con ranuras: el complemento para dispositivos anuncia un número fijo de ranuras por GPU. Si un solo pod solicita más de una ranura, no recibe computación adicional. Habilite la opción
fail-requests-greater-than-onepara rechazar los pods que soliciten más de una ranura. -
Aprovisionamiento con Karpenter: Karpenter considera cada solicitud
nvidia.com/gpucomo una GPU física, incluso cuando la GPU tiene habilitada la segmentación temporal. Para obtener más información, consulte el problema 2140 de Karpenteren GitHub. -
No es compatible con el modo automático de EKS: el modo automático de EKS administra el complemento para dispositivos de NVIDIA y no expone su configuración. Como la segmentación temporal requiere la configuración del complemento para dispositivos, no se puede aplicar una configuración de segmentación temporal en los nodos del modo automático de EKS.
-
Cambios en la configuración de la segmentación temporal: el complemento para dispositivos de NVIDIA no supervisa el
ConfigMapde la segmentación temporal para detectar cambios. Reinicie el complemento para dispositivos después de actualizar la configuración.
Opciones de configuración
Puede utilizar la segmentación temporal para las GPU de NVIDIA con las AMI de NVIDIA de AL2023 y Bottlerocket optimizadas para EKS. La configuración de la segmentación temporal varía en función de si se utiliza el controlador de DRA de NVIDIA o el complemento para dispositivos de NVIDIA.
Uso de la segmentación temporal de la GPU con el controlador de DRA de NVIDIA
Con el controlador de DRA de NVIDIA, los pods comparten una GPU al hacer referencia a una ResourceClaim común que solicita la DeviceClass gpu.nvidia.com con una segmentación temporal GpuConfig.
El controlador de DRA de NVIDIA implementa actualmente la segmentación temporal mediada por el usuario: una GPU solo se comparte entre los pods y los contenedores a los que se haga referencia de forma explícita en la misma instrucción. Como ResourceClaim y ResourceClaimTemplate dependen del espacio de nombres, los pods que comparten una GPU de este modo deben estar en el mismo espacio de nombres. Para compartir una GPU entre los contenedores de un solo pod, cada contenedor debe hacer referencia al mismo nombre de solicitud en la instrucción. Los contenedores que hacen referencia a diferentes nombres de solicitudes reciben cada uno una GPU independiente. Cree una ResourceClaimTemplate independiente para cada intervalo de segmentación temporal que necesite y una para cada espacio de nombres en el que desee compartir las GPU.
La segmentación temporal mediada por el sistema es aquella en la que el controlador comparte una GPU entre instrucciones independientes (incluso entre espacios de nombres) y se basa en criterios definidos por el sistema y no en una instrucción que configure el usuario. Para obtener más información sobre la segmentación temporal mediada por el sistema, consulte la segmentación temporal de GPU mediada por el sistema (problema n.º 659)
importante
La segmentación temporal mediante el controlador de DRA requiere la puerta de características TimeSlicingSettings, que es una característica alfa deshabilitada de forma predeterminada. Si solicita la estrategia de uso compartido TimeSlicing sin activar esta puerta de características, el controlador no preparará el dispositivo y el pod se quedará en ContainerCreating con un evento FailedPrepareDynamicResources que notifica error validating GPU config: unknown GPU sharing strategy: TimeSlicing. Habilite la puerta de características solo si acepta los riesgos de usar una capacidad alfa.
Requisitos previos
-
Un clúster de Amazon EKS que ejecuta la versión 1.34 de Kubernetes o una posterior. El controlador de DRA de NVIDIA es compatible con el aprovisionamiento de capacidad estática en Karpenter, los grupos de nodos administrados de EKS o los nodos autoadministrados.
-
Nodos con tipos de instancia de GPU NVIDIA con la AMI de NVIDIA de AL2023 optimizada para EKS.
-
El controlador de DRA de NVIDIA se ha instalado como se describe en Instalación del controlador de DRA de NVIDIA, con la puerta de características
TimeSlicingSettingshabilitada.
Procedimiento
-
Cree una
ResourceClaimque solicite una GPU con la estrategia de uso compartidoTimeSlicing. Varios pods que hacen referencia a esta instrucción comparten la misma GPU física.cat <<EOF | kubectl apply -f - apiVersion: resource.k8s.io/v1 kind: ResourceClaim metadata: name: shared-timeslice-gpu spec: devices: requests: - name: gpu exactly: deviceClassName: gpu.nvidia.com count: 1 config: - requests: ["gpu"] opaque: driver: gpu.nvidia.com parameters: apiVersion: resource.nvidia.com/v1beta1 kind: GpuConfig sharing: strategy: TimeSlicing timeSlicingConfig: interval: Long EOF -
Implemente dos o más pods que hagan referencia a la
ResourceClaimcompartida por el nombre. Cada pod hace referencia a la instrucción medianteresourceClaimsyresources.claims.cat <<EOF | kubectl apply -f - apiVersion: v1 kind: Pod metadata: name: share-a spec: tolerations: - key: nvidia.com/gpu operator: Exists effect: NoSchedule containers: - name: cuda image: nvidia/cuda:12.6.0-base-ubuntu22.04 command: ["nvidia-smi", "-L"] resources: claims: - name: gpu resourceClaims: - name: gpu resourceClaimName: shared-timeslice-gpu restartPolicy: OnFailure EOF -
Verifique que los pods compartan la misma GPU física. Ejecute
nvidia-smi -Len cada pod y confirme que muestren el mismo UUID de GPU.kubectl logs share-aUn ejemplo de salida sería el siguiente. Un segundo pod que haga referencia a la misma instrucción informa de un UUID de
GPUidéntico, lo que confirma que ambos pods comparten una GPU física.GPU 0: NVIDIA L4 (UUID: GPU-b41973ee-5d0a-cde8-6287-12b53f861f02)
Utilice la segmentación temporal de GPU en los nodos de Bottlerocket con el complemento para dispositivos de NVIDIA
En Bottlerocket, la AMI acelerada optimizada para EKS incluye el complemento para dispositivos de NVIDIA. Habilite la segmentación temporal a través de la configuración settings.kubelet-device-plugins.nvidia, que Bottlerocket convierte en la configuración del complemento para dispositivos cuando se inicia el nodo.
Requisitos previos
-
Un clúster de Amazon EKS. El siguiente procedimiento aprovisiona los nodos de GPU de NVIDIA con la AMI de NVIDIA de Bottlerocket optimizada para EKS.
-
Karpenter está instalado y configurado en su clúster, ya que en el siguiente procedimiento se utiliza una
EC2NodeClassde Karpenter para proporcionar la configuración de segmentación temporal en los datos de usuario del nodo de Bottlerocket. Para obtener más información, consulte Introducción a Karpenteren el sitio web de Karpenter. -
kubectlconfigurado para comunicarse con su clúster. Consulte Instalación o actualización de kubectl para obtener más información.
Procedimiento
Agregue la configuración de segmentación temporal a los datos de usuario de Bottlerocket para los nodos de GPU. En el siguiente ejemplo se configuran cuatro ranuras por GPU. La forma en que suministre los datos de usuario depende de cómo aprovisione los nodos. En el siguiente ejemplo, se muestra una EC2NodeClass de Karpenter.
cat <<EOF | kubectl apply -f - apiVersion: karpenter.k8s.aws/v1 kind: EC2NodeClass metadata: name: gpu-bottlerocket-timeslicing spec: amiFamily: Bottlerocket amiSelectorTerms: - alias: bottlerocket@latest role: eksctl-KarpenterNodeRole-<cluster-name> subnetSelectorTerms: - tags: karpenter.sh/discovery: <cluster-name> securityGroupSelectorTerms: - tags: karpenter.sh/discovery: <cluster-name> userData: | [settings.kubelet-device-plugins.nvidia] device-sharing-strategy = "time-slicing" [settings.kubelet-device-plugins.nvidia.time-slicing] replicas = 4 rename-by-default = false fail-requests-greater-than-one = true EOF
Cuando los nodos aprovisionados con esta configuración se unen al clúster, el complemento para dispositivos anuncia cuatro ranuras nvidia.com/gpu para cada GPU física. Los solicita en la especificación de la carga de trabajo junto con las solicitudes o los límites de los recursos del contenedor para el recurso extendido nvidia.com/gpu.
Utilice la segmentación temporal de GPU en los nodos de AL2023 con el complemento para dispositivos de NVIDIA
En AL2023, instale el complemento para dispositivos de NVIDIA tal y como se describe en Instalación del complemento para dispositivos de Kubernetes de NVIDIA y proporcione la configuración de segmentación temporal en un ConfigMap.
Requisitos previos
-
Un clúster de Amazon EKS con nodos que utilizan tipos de instancia de GPU de NVIDIA y la AMI de NVIDIA de AL2023 optimizada para EKS.
-
Si tiene Helm instalado en su entorno de línea de comandos, consulte las instrucciones de configuración de Helm para obtener más información.
-
kubectlconfigurado para comunicarse con su clúster. Consulte Instalación o actualización de kubectl para obtener más información.
Procedimiento
-
Cree el
ConfigMapde segmentación temporal en el espacio de nombresnvidia, donde instaló el complemento para dispositivos en Instalación del complemento para dispositivos de Kubernetes de NVIDIA. En este ejemplo, se configuran cuatro ranuras por GPU.cat <<EOF | kubectl apply -f - apiVersion: v1 kind: ConfigMap metadata: name: nvidia-device-plugin-config namespace: nvidia data: config.yaml: | version: v1 sharing: timeSlicing: renameByDefault: false failRequestsGreaterThanOne: true resources: - name: nvidia.com/gpu replicas: 4 EOF -
Actualice la versión existente del complemento para dispositivos de NVIDIA para hacer referencia al
ConfigMapcon el valorconfig.name. El indicador--reuse-valuesconserva los valores que estableció al instalar el complemento para dispositivos en Instalación del complemento para dispositivos de Kubernetes de NVIDIA.helm upgrade nvdp nvdp/nvidia-device-plugin \ --namespace nvidia \ --reuse-values \ --set config.name=nvidia-device-plugin-config
nota
El complemento para dispositivos no se recarga automáticamente cuando cambia el ConfigMap. Después de actualizar la configuración de segmentación temporal, reinicie los pods del complemento para dispositivos para aplicar el cambio.
Verificación de que la segmentación temporal de la GPU esté activa
Cuando los nodos con segmentación temporal estén Ready, confirme que el complemento para dispositivos anuncie el número esperado de ranuras y que los pods compartan una GPU física.
nota
La comprobación del UUID compartido de este procedimiento demuestra la segmentación temporal con mayor claridad cuando los pods aterrizan en la misma GPU física. En un nodo con una sola GPU, el complemento para dispositivos anuncia cuatro ranuras y los cuatro pods comparten esa GPU, por lo que muestran el mismo UUID. En un nodo con varias GPU físicas, el programador puede colocar los pods en diferentes GPU. Estos pods muestran diferentes UUID aunque la segmentación temporal esté activa. Para demostrar que se comparte en una GPU, programe la carga de trabajo en un tipo de instancia de una sola GPU. Por ejemplo, agregue un selector de nodos, como node.kubernetes.io/instance-type: g6.2xlarge, a la especificación del pod.
-
Confirme que el nodo anuncie el número configurado de ranuras de GPU. Con cuatro ranuras por GPU, un nodo con una GPU física informa de
4.kubectl get nodes "-o=custom-columns=NAME:.metadata.name,GPU:.status.allocatable.nvidia\.com/gpu"Un ejemplo de salida sería el siguiente.
NAME GPU ip-192-168-11-225.us-west-2.compute.internal 4 -
Cree una implementación que ejecute cuatro réplicas, cada una de las cuales solicite una ranura de GPU.
cat <<EOF | kubectl apply -f - apiVersion: apps/v1 kind: Deployment metadata: name: timeslicing-demo spec: replicas: 4 selector: matchLabels: app: timeslicing-demo template: metadata: labels: app: timeslicing-demo spec: tolerations: - key: nvidia.com/gpu operator: Exists effect: NoSchedule containers: - name: cuda image: nvidia/cuda:12.6.0-base-ubuntu22.04 command: ["bash", "-c", "nvidia-smi --query-gpu=uuid --format=csv,noheader; sleep infinity"] resources: limits: nvidia.com/gpu: 1 EOF -
Confirme que los cuatro pods estén programados en el mismo nodo.
kubectl get pods -l app=timeslicing-demo -o wide -
Confirme que los cuatro pods informen del mismo UUID de GPU. Un único UUID compartido en los cuatro pods confirma que una GPU física se está multiplexando en el tiempo.
kubectl logs -l app=timeslicing-demo --prefixUn ejemplo de salida sería el siguiente.
[pod/timeslicing-demo-xxxxxxxxxx-aaaaa/cuda] GPU-c0583cce-87c5-c736-db7f-6d3128c84d03 [pod/timeslicing-demo-xxxxxxxxxx-bbbbb/cuda] GPU-c0583cce-87c5-c736-db7f-6d3128c84d03 [pod/timeslicing-demo-xxxxxxxxxx-ccccc/cuda] GPU-c0583cce-87c5-c736-db7f-6d3128c84d03 [pod/timeslicing-demo-xxxxxxxxxx-ddddd/cuda] GPU-c0583cce-87c5-c736-db7f-6d3128c84d03