As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.
Computação e escalonamento automático
dica
Inscreva-se nos
Otimização de recursos de GPU e gerenciamento de custos
Agende cargas de trabalho com requisitos de GPU usando rótulos Well-Known
Para AI/ML cargas de trabalho sensíveis a diferentes características da GPU (por exemplo, GPU, memória da GPU), recomendamos especificar os requisitos da GPU usando rótulos de agendamento conhecidos
Exemplo
Por exemplo, usando o seletor de nó de nome de GPU ao usar o Karpenter:
apiVersion: v1 kind: Pod metadata: name: gpu-pod-example spec: containers: - name: ml-workload image: <image> resources: limits: nvidia.com/gpu: 1 # Request one NVIDIA GPU nodeSelector: karpenter.k8s.aws/instance-gpu-name: "l40s" # Run on nodes with NVIDIA L40S GPUs
Use o plug-in de dispositivo Kubernetes para expor GPUs
Para expor GPUs em nós, o driver de GPU NVIDIA deve ser instalado no sistema operacional do nó e no tempo de execução do contêiner configurado para permitir que o agendador Kubernetes atribua pods aos nós com GPUs disponíveis. O processo de configuração do plug-in de dispositivo NVIDIA Kubernetes depende da AMI acelerada do EKS que você está usando:
-
AMI acelerada Bottlerocket : essa AMI inclui o driver de GPU NVIDIA e o plug-in de dispositivo NVIDIA Kubernetes
está pré-instalado e pronto para uso, permitindo o suporte à GPU pronto para uso. Nenhuma configuração adicional é necessária para expor as GPUs ao agendador Kubernetes. -
AMI acelerada AL2023
: essa AMI inclui o driver de GPU NVIDIA, mas o plug-in de dispositivo NVIDIA Kubernetes não está pré-instalado. Você deve instalar e configurar o plug-in do dispositivo separadamente, normalmente por meio de um DaemonSet. Observe que, se você usar eksctl para criar seu cluster e especificar um tipo de instância de GPU (por exemplo, g5.xlarge) no seu ClusterConfig,eksctlselecionará automaticamente a AMI apropriada e instalará o plug-in de dispositivo NVIDIA Kubernetes. Para saber mais, consulte Suporte de GPUna documentação do eksctl.
Se você decidir usar as AMIs aceleradas EKS e o operador de GPU NVIDIA
Para verificar se o NVIDIA Device Plugin está ativo e se as GPUs estão expostas corretamente, execute:
kubectl describe node | grep nvidia.com/gpu
Esse comando verifica se o nvidia.com/gpu recurso está na capacidade e nos recursos alocáveis do nó. Por exemplo, um nó com uma GPU deve aparecernvidia.com/gpu: 1. Consulte o Guia de agendamento de GPU do Kubernetes para obter mais informações.
Use muitos tipos diferentes de instâncias do EC2
Usar o maior número possível de tipos diferentes de instâncias do EC2 é uma prática recomendada importante para escalabilidade no Amazon EKS, conforme descrito na seção. Plano de dados do Kubernetes Essa recomendação também se aplica a instâncias com hardware acelerado (por exemplo, GPUs). Se você criar um cluster que usa somente um tipo de instância e tentar escalar o número de nós além da capacidade da região, poderá receber um erro de capacidade insuficiente (ICE), indicando que nenhuma instância está disponível. É importante entender as características exclusivas de suas AI/ML cargas de trabalho antes de diversificá-las arbitrariamente. Analise os tipos de instância disponíveis usando a ferramenta
As instâncias de computação acelerada são oferecidas em diferentes modelos de compra para atender às cargas de trabalho de curto, médio e estado estável. Para cargas de trabalho de curto prazo, flexíveis e tolerantes a falhas, nas quais você gostaria de evitar fazer uma reserva, consulte as instâncias Spot. Blocos de capacidade, On-Demand instâncias e planos de economia permitem provisionar instâncias de computação acelerada para cargas de trabalho de médio e longo prazo. Para aumentar as chances de acessar com sucesso a capacidade necessária em sua opção de compra preferida, é recomendável usar uma lista diversificada de tipos de instâncias e zonas de disponibilidade. Como alternativa, se você encontrar ICEs para um modelo de compra específico, tente novamente usar um modelo diferente.
Exemplo O exemplo a seguir mostra como permitir que um Karpenter NodePool provisione instâncias G e P maiores que as gerações 3 (por exemplo, p3). Para saber mais, consulte a seção Melhores práticas de escalabilidade do EKS.
- key: karpenter.k8s.aws/instance-category operator: In values: ["g", "p"] # Diversifies across G-series and P-series - key: karpenter.k8s.aws/instance-generation operator: Gt values: ["3"] # Selects instance generations greater than 3
Para obter detalhes sobre o uso de instâncias spot para GPUs, consulte “Considere usar instâncias spot do Amazon EC2 para GPUs com Karpenter” abaixo.
Considere usar instâncias spot do Amazon EC2 para GPUs com Karpenter
As instâncias spot do Amazon EC2 permitem que você aproveite a capacidade não utilizada do EC2 na nuvem da AWS e estão disponíveis com um desconto de até 90% em comparação aos preços. On-Demand As instâncias spot do Amazon EC2 podem ser interrompidas com um aviso de dois minutos quando o EC2 precisar recuperar a capacidade. Para obter mais informações, consulte Instâncias spot no Guia do usuário do Amazon EC2. O Amazon EC2 Spot pode ser uma ótima opção para cargas de trabalho tolerantes a falhas, sem estado e flexíveis (horário e tipo de instância). Para saber mais sobre quando usar instâncias spot, consulte as melhores práticas de instâncias spot do EC2. Você também pode usar instâncias spot para AI/ML cargas de trabalho, se elas estiverem Spot-friendly.
Casos de uso
Spot-friendly as cargas de trabalho podem ser big data, cargas de trabalho em contêineres, servidores web sem estado CI/CD, computação de alto desempenho (HPC) e cargas de trabalho de renderização. As instâncias spot não são adequadas para cargas de trabalho inflexíveis, com estado, intolerantes a falhas ou fortemente acopladas entre os nós da instância (por exemplo, cargas de trabalho com processos paralelos que dependem muito uns dos outros para computação, exigindo comunicação constante entre nós, como aplicativos de computação de MPI-based alto desempenho, como dinâmica de fluidos computacional ou bancos de dados distribuídos com interdependências complexas). Aqui estão os casos de uso específicos que recomendamos (em nenhuma ordem específica):
-
Real-time inferência on-line: use instâncias spot para escalonamento com custo otimizado para suas cargas de trabalho de inferência em tempo real, desde que suas cargas de trabalho sejam amigáveis ao local. Em outras palavras, o tempo de inferência é inferior a dois minutos, o aplicativo é tolerante a falhas a interrupções e pode ser executado em diferentes tipos de instância. Garanta alta disponibilidade por meio da diversidade de instâncias (por exemplo, em vários tipos de instâncias e zonas de disponibilidade) ou reservas, ao mesmo tempo em que implementa a tolerância a falhas no nível do aplicativo para lidar com possíveis interrupções pontuais.
-
Hyper-parameter ajuste: use instâncias Spot para executar tarefas de ajuste exploratório de forma oportunista, pois as interrupções podem ser toleradas sem perdas significativas, especialmente para experimentos de curta duração.
-
Aumento de dados: use instâncias Spot para realizar tarefas de pré-processamento e aumento de dados que podem ser reiniciadas a partir dos pontos de verificação se forem interrompidas, tornando-as ideais para a disponibilidade variável do Spot.
-
Fine-tuning modelos: use instâncias Spot para fazer ajustes com mecanismos robustos de checkpoint para retomar a partir do último estado salvo, minimizando o impacto das interrupções da instância.
-
Inferência em lote: use instâncias Spot para processar grandes lotes de solicitações de inferência off-line em tempo não real, onde os trabalhos podem ser pausados e retomados, oferecendo o melhor alinhamento com a economia de custos do Spot e lidando com possíveis interrupções por meio de novas tentativas ou diversificação.
-
Subconjuntos de treinamento oportunista: use instâncias Spot para cargas de trabalho de treinamento marginais ou experimentais (por exemplo, modelos menores com menos de 10 milhões de parâmetros), em que interrupções são aceitáveis e otimizações de eficiência, como diversificação entre tipos de instâncias ou regiões, podem ser aplicadas, embora não sejam recomendadas para treinamento em escala de produção devido a possíveis interrupções.
Considerações
Para usar instâncias spot para cargas de trabalho aceleradas no Amazon EKS, há várias considerações importantes (em nenhuma ordem específica):
-
Use o Karpenter para gerenciar instâncias Spot com consolidação avançada ativada. Especificando karpenter. sh/capacity-digite como “spot” em seu Karpenter NodePool, o Karpenter provisionará instâncias Spot por padrão sem qualquer configuração adicional. No entanto, para permitir a Spot-to-Spot consolidação avançada, que substitui os nós Spot subutilizados por alternativas Spot mais baratas, você precisa ativar o SpotToSpotConsolidation feature gate definindo --feature-gates SpotToSpotConsolidation =true nos argumentos do controlador Karpenter ou
por meio da variável de ambiente FEATURE_GATES. A Karpenter usa a estratégia de alocação otimizada de preço-capacidade para provisionar instâncias do EC2. Com base nos NodePool requisitos e nas restrições do pod, o Karpenter empacota pods não programáveis e envia um conjunto diversificado de tipos de instâncias para a API Amazon EC2 Fleet. https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-fleet-request-type.html Você pode usar a ferramenta EC2 Instance Type Explorer para gerar uma lista de tipos de instância que correspondam aos seus requisitos de computação específicos. -
Garanta que as cargas de trabalho sejam independentes de estado, tolerantes a falhas e flexíveis. As cargas de trabalho devem ser independentes de estado, tolerantes a falhas e flexíveis em termos de tamanho. instance/GPU Isso permite uma retomada perfeita após as interrupções do Spot, e a flexibilidade da instância permite que você permaneça no Spot por mais tempo. Habilite o tratamento de interrupções pontuais
no Karpenter configurando o valor settings.interruptionQueue Helm com o nome da fila do AWS SQS para capturar eventos de interrupção spot. Por exemplo, ao instalar via Helm, use --set “settings.interruptionQueue=$ {CLUSTER_NAME}”. Para ver um exemplo, consulte o guia Getting Started with Karpenter . Quando o Karpenter percebe um evento de interrupção do Spot, ele automaticamente isola, contamina, drena e encerra o (s) nodo (s) antes do evento de interrupção para maximizar o período de carência de terminação dos pods. Ao mesmo tempo, o Karpenter iniciará imediatamente um novo nó para que ele fique pronto o mais rápido possível. -
Evite restringir excessivamente a seleção do tipo de instância. Você deve evitar, tanto quanto possível, restringir os tipos de instância. Ao não restringir os tipos de instância, há uma chance maior de adquirir capacidade spot em grandes escalas com menor frequência de interrupções de instâncias spot a um custo menor. Por exemplo, evite limitar a tipos específicos (por exemplo, g5.xlarge). Considere especificar um conjunto diversificado de categorias e gerações de instâncias usando chaves como karpenter.k8s. aws/instance-category e karpenter.k8s. aws/instance-geração. O Karpenter permite uma diversificação mais fácil da capacidade de instâncias spot e sob demanda em vários tipos de instâncias e zonas de disponibilidade (AZs). Além disso, se sua AI/ML carga de trabalho exigir um número específico ou limitado de aceleradores, mas for flexível entre regiões, você poderá usar o Spot Placement Score para identificar dinamicamente a região ideal para implantar sua carga de trabalho antes do lançamento.
-
Amplie NodePool os requisitos para incluir um número maior de famílias de instâncias EC2 semelhantes. Cada pool de instâncias spot consiste em uma capacidade de instância EC2 não utilizada para um tipo de instância específico em uma zona de disponibilidade (AZ) específica. Quando o Karpenter tenta provisionar um novo nó, ele seleciona um tipo de instância que atenda aos requisitos do NodePool. Se nenhum tipo de instância compatível tiver capacidade spot em qualquer AZ, o provisionamento falhará. Para evitar esse problema, permita instâncias mais amplas da série G (geração 4 ou superior) da NVIDIA em todos os tamanhos e zonas de disponibilidade (AZs), considerando as necessidades de hardware, como memória de GPU ou Ray Tracing. Como as instâncias podem ser de tipos diferentes, você precisa garantir que sua carga de trabalho possa ser executada em cada tipo e que o desempenho obtido atenda às suas necessidades.
-
Aproveite todas as zonas de disponibilidade em uma região. A capacidade disponível varia de acordo com a zona de disponibilidade (AZ). Um tipo de instância específico pode não estar disponível em uma AZ, mas é abundante em outra. Cada combinação exclusiva de um tipo de instância e uma zona de disponibilidade constitui um pool de capacidade spot separado. Ao solicitar capacidade em todas as AZs em uma região dentro dos NodePool requisitos do Karpenter, você está efetivamente pesquisando mais piscinas ao mesmo tempo. Isso maximiza o número de pools de capacidade spot e, portanto, aumenta a probabilidade de aquisição de capacidade spot. Para fazer isso, em sua NodePool configuração, omita o topology.kubernetes. io/zone chave inteiramente para permitir que o Karpenter selecione entre todas as AZs disponíveis na região ou liste explicitamente as AZs usando o operador: In e forneça os valores (por exemplo, us-west-2a).
-
Considere usar o Spot Placement Score (SPS) para ter visibilidade da probabilidade de acessar com êxito a capacidade necessária usando instâncias Spot. O Spot Placement Score (SPS) é uma ferramenta que fornece uma pontuação para ajudar você a avaliar a probabilidade de sucesso de uma solicitação Spot. Ao usar o SPS, você primeiro especifica seus requisitos de computação para suas instâncias spot e, em seguida, o Amazon EC2 retorna as 10 principais regiões ou zonas de disponibilidade (AZs) nas quais sua solicitação spot provavelmente será bem-sucedida. Regiões e zonas de disponibilidade são pontuadas em uma escala de 1 a 10. Uma pontuação de 10 indica que sua solicitação Spot é altamente provável, mas não garantida, de sucesso. Uma pontuação de 1 indica que sua solicitação de spot tem muito pouca probabilidade de ter êxito. A mesma pontuação pode ser retornada para diferentes regiões ou zonas de disponibilidade. Para saber mais, consulte Orientação para criar um painel do Spot Placement Score Tracker na AWS. Como a capacidade spot flutua o tempo todo, o SPS ajudará você a identificar qual combinação de tipos de instância, AZs e regiões funciona melhor para suas restrições de carga de trabalho (ou seja, flexibilidade, desempenho, tamanho etc.). Se sua AI/ML carga de trabalho exigir um número específico ou limitado de aceleradores, mas for flexível entre regiões, você poderá usar a pontuação de posicionamento Spot para identificar dinamicamente a região ideal para implantar sua carga de trabalho antes do lançamento. Para ajudar você a descobrir automaticamente a probabilidade de adquirir capacidade spot, fornecemos uma orientação para criar um painel de controle SPS. Essa solução monitora as pontuações do SPS ao longo do tempo usando uma configuração YAML para configurações diversificadas (por exemplo, requisitos de instância, incluindo GPUs), armazena métricas e fornece painéis CloudWatch para comparar configurações. Defina painéis por carga de trabalho para avaliar as necessidades de vCPU, memória e GPU, garantindo configurações ideais para clusters EKS, incluindo a consideração do uso de outras regiões da AWS. Para saber mais, consulte Como funciona a pontuação de colocação no Spot.
-
Gerencie com elegância as interrupções e testes do Spot. Para um pod com um período de encerramento superior a dois minutos, o nó antigo será interrompido antes que esses pods sejam reprogramados, o que pode afetar a disponibilidade da carga de trabalho. Considere o aviso de interrupção pontual de dois minutos ao projetar seus aplicativos, implemente o ponto de verificação em aplicativos de longa execução (por exemplo, salvando o progresso em um armazenamento persistente como o Amazon S3) para retomar após as interrupções, estenda o encerramento GracePeriodSeconds (o padrão é 30 segundos) nas especificações do pod para permitir mais tempo para o desligamento normal e lidar com interrupções usando os ganchos de ciclo de vida do PrestOp, sinais and/or SIGTERM em seu aplicativo para atividades de desligamento normal, como limpeza, economia de estado e fechamento da conexão. Para cargas de trabalho em tempo real, onde o tempo de escalabilidade é importante e as cargas de trabalho levam mais de dois minutos para que o aplicativo esteja pronto para atender ao tráfego, considere otimizar a inicialização do contêiner e os tempos de carregamento do modelo de ML por meio de análises e melhores práticas. Armazenamento Escalabilidade e desempenho de aplicativos Para testar um nó substituto, use o AWS Fault Injection Service
(FIS) para simular interrupções pontuais.
Além dessas principais práticas recomendadas do Spot, leve esses fatores em consideração ao gerenciar cargas de trabalho de GPU no Amazon EKS. Diferentemente das CPU-based cargas de trabalho, as cargas de trabalho da GPU são particularmente sensíveis aos detalhes do hardware, como os recursos da GPU e a memória de GPU disponível. As cargas de trabalho da GPU podem ser limitadas pelos tipos de instância que elas podem usar, com menos opções disponíveis em comparação às CPUs. Como primeira etapa, avalie se sua carga de trabalho é flexível em instâncias. Se você não sabe quantos tipos de instância sua carga de trabalho pode usar, teste-os individualmente para garantir a compatibilidade e a funcionalidade. Identifique o quão flexível você pode ser para diversificar o máximo possível e, ao mesmo tempo, confirme que a diversificação mantém a carga de trabalho funcionando e compreenda quaisquer impactos no desempenho (por exemplo, na produtividade ou no tempo de conclusão). Como parte da diversificação de suas cargas de trabalho, considere o seguinte:
-
Analise a compatibilidade do CUDA e da estrutura. Suas cargas de trabalho de GPU podem ser otimizadas para hardwares e tipos de GPU específicos (por exemplo, V100 em p3 versus A100 em p4) ou escritas para versões específicas de CUDA para bibliotecas como, portanto TensorFlow, verifique a compatibilidade de suas cargas de trabalho. Essa compatibilidade é crucial para evitar erros de tempo de execução, falhas, falhas na aceleração da GPU (por exemplo, versões CUDA incompatíveis com estruturas como PyTorch ou TensorFlow podem impedir a execução) ou a capacidade de aproveitar recursos de hardware, como precisão. FP16/INT8
-
Memória GPU. Certifique-se de avaliar os requisitos de memória de seus modelos e definir o perfil do uso de memória do seu modelo durante o tempo de execução usando ferramentas como o DCGM Exporter
e defina a memória GPU mínima necessária para o tipo de instância em rótulos conhecidos como karpenter.k8s. aws/instance-gpu-memória. A GPU VRAM varia entre os tipos de instância (por exemplo, NVIDIA T4 tem 16 GB, A10G tem 24 GB, V100 tem 16-32 GB) e os modelos de ML (por exemplo, modelos de linguagem grande) podem exceder a memória disponível, causando erros de falta de memória (OOM) ou falhas. Para instâncias spot no EKS, isso pode limitar a diversificação. Por exemplo, você não pode incluir tipos de VRAM mais baixos se seu modelo não se adequar, o que pode limitar o acesso aos pools de capacidade e aumentar o risco de interrupção. Observe que, para inferência de uma única GPU e de um único nó (por exemplo, vários pods programados no mesmo nó para utilizar seus recursos de GPU), isso pode limitar a diversificação, pois você só pode incluir tipos de instância com VRAM suficiente em sua configuração spot. -
Floating-point precisão e desempenho. Nem todas as arquiteturas de GPU da Nvidia têm a mesma precisão de ponto flutuante (por exemplo,). FP16/INT8 Avalie o desempenho dos tipos principais (CUDA/Tensor/RT) e a precisão de ponto flutuante necessários para suas cargas de trabalho. Executar em uma GPU mais barata e de menor desempenho não significa que seja melhor, então considere avaliar o desempenho em termos de trabalho concluído em um período específico para entender o impacto da diversificação.
Cenário: diversificação para cargas de trabalho de inferência em tempo real
Para uma carga de trabalho de inferência on-line em tempo real em instâncias spot, você pode configurar um Karpenter NodePool para diversificar entre famílias e gerações de instâncias de GPU compatíveis. Essa abordagem garante alta disponibilidade com base em vários pools de spot e, ao mesmo tempo, mantém o desempenho por meio de restrições nos recursos, memória e arquitetura da GPU. Ele suporta o uso de alternativas quando a capacidade da instância é restrita, minimizando as interrupções e otimizando a latência da inferência. Este exemplo NodePool afirma: use instâncias das séries g e p maiores que 3, que tenham mais de 20 GB de memória GPU.
Exemplo
apiVersion: karpenter.sh/v1 kind: NodePool metadata: name: gpu-inference-spot spec: template: metadata: labels: role: gpu-spot-worker spec: requirements: - key: karpenter.sh/capacity-type operator: In values: ["spot"] # Use Spot Instances - key: karpenter.k8s.aws/instance-category operator: In values: ["g", "p"] # Diversifies across G-series and P-series - key: karpenter.k8s.aws/instance-generation operator: Gt values: ["3"] # Selects instance generations greater than 3 - key: kubernetes.io/arch operator: In values: ["amd64"] # Specifies AMD64 architecture, compatible with NVIDIA GPUs - key: karpenter.k8s.aws/instance-gpu-memory operator: Gt values: ["20480"] # Ensures more than 20GB (20480 MiB) total GPU memory taints: - key: nvidia.com/gpu effect: NoSchedule nodeClassRef: name: gpu-inference-ec2 group: karpenter.k8s.aws kind: EC2NodeClass expireAfter: 720h limits: cpu: 100 memory: 100Gi disruption: consolidationPolicy: WhenEmptyOrUnderutilized consolidateAfter: 5m # Enables consolidation of underutilized nodes after 5 minutes
Implemente o checkpoint para trabalhos de treinamento de longa duração
O ponto de verificação é uma técnica de tolerância a falhas que envolve salvar periodicamente o estado de um processo, permitindo que ele seja retomado a partir do último ponto salvo em caso de interrupções. No aprendizado de máquina, ele é comumente associado ao treinamento, em que trabalhos de longa duração podem salvar os pesos do modelo e os estados do otimizador para retomar o treinamento após falhas, como problemas de hardware ou interrupções de instâncias spot.
Você usa pontos de verificação para salvar o estado dos modelos de aprendizado de máquina (ML) durante o treinamento. Os pontos de verificação são snapshots do modelo e podem ser configurados pelas funções de retorno de chamada dos frameworks de ML. Você pode usar pontos de verificação salvos para reiniciar um trabalho de treinamento a partir do ponto de verificação salvo pela última vez. Usando pontos de verificação, você salva os instantâneos do modelo durante o treinamento devido a uma interrupção inesperada no trabalho ou na instância de treinamento. Isso permite que você retome o treinamento do modelo no futuro a partir de um ponto de verificação. Além de implementar um sistema de resiliência de nós, recomendamos implementar o checkpoint para mitigar o impacto das interrupções, incluindo aquelas causadas por falhas de hardware ou interrupções de instâncias spot do Amazon EC2.
Sem o checkpoint, as interrupções podem resultar em perda de tempo de computação e perda de progresso, o que é caro para trabalhos de treinamento de longa duração. O ponto de verificação permite que os trabalhos salvem seu estado periodicamente (por exemplo, pesos do modelo e estados do otimizador) e sejam retomados a partir do último ponto de verificação (último lote processado) após uma interrupção. Para implementar o checkpoint, projete seu aplicativo para processar dados em grandes lotes e salvar os resultados intermediários em armazenamento persistente, como um bucket do Amazon S3 por meio do driver CSI Mountpoint for Amazon S3, enquanto o trabalho de treinamento avança.
Casos de uso
O checkpoint é particularmente benéfico em cenários específicos para equilibrar a tolerância a falhas com a sobrecarga de desempenho. Considere usar o checkpoint nos seguintes casos:
-
A duração do trabalho excede algumas horas: para trabalhos de treinamento de longa duração (por exemplo, mais de 1 a 2 horas para modelos pequenos ou days/weeks para grandes modelos de base com bilhões de parâmetros), em que a perda de progresso devido a interrupções é cara. Trabalhos mais curtos podem não justificar a I/O sobrecarga.
-
Para instâncias Spot ou falhas de hardware: em ambientes propensos a interrupções, como EC2 Spot (aviso de 2 minutos) ou falhas de hardware (por exemplo, erros de memória da GPU), o checkpoint permite uma rápida retomada, tornando o Spot viável para economia de custos em cargas de trabalho tolerantes a falhas.
-
Treinamento distribuído em escala: para configurações com hundreds/thousands aceleradores (por exemplo, >100 GPUs), em que o tempo médio entre falhas diminui linearmente com a escala. Use para model/data paralelismo para lidar com o acesso simultâneo ao ponto de verificação e evitar reinicializações completas.
-
Large-scale modelos com alta demanda de recursos: no treinamento LLM em escala de petabytes, em que as falhas são inevitáveis devido ao tamanho do cluster; abordagens hierárquicas (locais rápidos a cada 5 a 30 minutos para transientes, duráveis a cada hora para falhas graves) otimizam o tempo de recuperação versus a eficiência.
Use blocos de capacidade de ML para garantir a capacidade das instâncias P e Trainium
Os blocos de capacidade para ML permitem que você reserve instâncias de GPU muito procuradas, especificamente instâncias P (por exemplo, p6-b200, p5, p5e, p5en, p4d, p4de) e instâncias Trainium (por exemplo, trn1, trn2), para começar quase imediatamente ou em uma data futura para dar suporte às suas cargas de trabalho de aprendizado de máquina (ML) de curta duração. Essas reservas são ideais para garantir a capacidade para tarefas de computação intensiva, como treinamento e ajuste de modelos. O preço do EC2 Capacity Blocks consiste em uma taxa de reserva e uma taxa de sistema operacional. Para saber mais sobre preços, consulte os preços do EC2 Capacity Blocks for ML.
Para reservar GPUs para AI/ML cargas de trabalho no Amazon EKS para garantir a capacidade previsível, recomendamos usar blocos de capacidade de ML para curto prazo ou reservas de capacidade (ODCRs) para garantia de On-Demand capacidade de uso geral.
-
Os ODCRs permitem que você reserve a capacidade da instância EC2 (por exemplo, instâncias de GPU como g5 ou p5) em uma zona de disponibilidade específica por um período, garantindo a disponibilidade, mesmo durante alta demanda. Os ODCRs não têm nenhum compromisso de longo prazo, mas você paga a On-Demand taxa pela capacidade reservada, seja usada ou inativa. No EKS, os ODCRs são suportados por tipos de nós como Karpenter
e grupos de nós gerenciados. Para priorizar ODCRs no Karpenter, configure o para usar o campo. NodeClass capacityReservationSelectorTermsVeja a documentação do Karpenter NodePools . -
Os blocos de capacidade são um mecanismo de reserva especializado para instâncias de GPU (por exemplo, p5, p4d) ou Trainium (trn1, trn2), projetado para cargas de trabalho de ML de curto prazo, como treinamento de modelos, ajuste fino ou experimentação. Você reserva capacidade por um período definido (normalmente de 24 horas a 182 dias) a partir de uma data futura, pagando somente pelo tempo reservado. Eles são pré-pagos, exigem planejamento prévio para as necessidades de capacidade e não oferecem suporte ao escalonamento automático, mas estão localizados no EC2 para redes de baixa latência. UltraClusters Eles cobram apenas pelo período reservado. Para saber mais, consulte Encontre e compre blocos de capacidade ou comece configurando grupos de nós gerenciados com blocos de capacidade usando as instruções em Criar um grupo de nós gerenciados com blocos de capacidade para ML.
Reserve capacidade por meio do AWS Management Console e configure seus nós para usar blocos de capacidade de ML. Planeje reservas com base nos cronogramas de carga de trabalho e teste em um cluster de teste. Consulte a documentação do Capacity Blocks para obter mais informações.
Considere as On-Demand reservas spot ou de On-Demand capacidade (ODCRs) do Amazon EC2 para instâncias G do Amazon EC2
Para instâncias G do Amazon EC2 On-Demand, considere as diferentes opções de compra entre instâncias spot e reservas de On-Demand capacidade do Amazon EC2. Os ODCRs permitem que você reserve a capacidade da instância EC2 em uma zona de disponibilidade específica por um determinado período, garantindo disponibilidade mesmo durante alta demanda. Diferentemente dos blocos de capacidade de ML, que estão disponíveis apenas para instâncias P e Trainium, os ODCRs podem ser usados para uma variedade maior de tipos de instâncias, incluindo instâncias G, tornando-os adequados para cargas de trabalho que exigem diferentes recursos de GPU, como inferência ou gráficos. Ao usar instâncias spot do Amazon EC2, ser capaz de diversificar em diferentes tipos de instâncias, tamanhos e zonas de disponibilidade é fundamental para poder permanecer no Spot por mais tempo.
Os ODCRs não têm nenhum compromisso de longo prazo, mas você paga a On-Demand taxa pela capacidade reservada, seja usada ou inativa. Os ODCRs podem ser criados para uso imediato ou programados para uma data futura, fornecendo flexibilidade no planejamento da capacidade. No Amazon EKS, os ODCRs são suportados por tipos de nós como Karpenter capacityReservationSelectorTerms Veja a documentação do Karpenter NodePools .
Considere outros tipos e tamanhos de instâncias aceleradas
Selecionar a instância e o tamanho acelerados apropriados é essencial para otimizar o desempenho e o custo em suas cargas de trabalho de ML no Amazon EKS. Por exemplo, diferentes famílias de instâncias de GPU têm desempenho e recursos diferentes, como memória de GPU. Para ajudar você a escolher a opção com melhor relação custo-benefício, revise as instâncias de GPU disponíveis na página Tipos de instância do
Se você usar uma instância de GPU em um nó EKS, ela terá o nvidia-device-plugin-daemonset pod no kube-system namespace por padrão. Para ter uma ideia rápida de se você está utilizando totalmente as GPU (s) em sua instância, você pode usar https://docs.nvidia.com/deploy/nvidia-smi/index.html
kubectl exec nvidia-device-plugin-daemonset-xxxxx \ -n kube-system -- nvidia-smi \ --query-gpu=index,power.draw,power.limit,temperature.gpu,utilization.gpu,utilization.memory,memory.free,memory.used \ --format=csv -l 5
-
Se
utilization.memoryestiver próximo de 100%, é provável que seu (s) código (s) esteja (ão) limitado (s) à memória. Isso significa que a GPU (memória) está totalmente utilizada, mas pode sugerir que uma otimização adicional do desempenho deva ser investigada. -
Se
utilization.gpuestiver próximo de 100%, isso não significa necessariamente que a GPU esteja totalmente utilizada. Uma métrica melhor a ser analisada é a proporção depower.drawparapower.limit. Se essa proporção for de 100% ou mais, seus códigos estão utilizando totalmente a capacidade computacional da GPU. -
A
-l 5bandeira diz para gerar as métricas a cada 5 segundos. No caso de um único tipo de instância de GPU, o sinalizador de consulta de índice não é necessário.
Para saber mais, consulte as instâncias de GPU na documentação da AWS.
Otimize a alocação de recursos de GPU com Time-Slicing MIG e alocação fracionária de GPU
Limites de recursos estáticos no Kubernetes (por exemplo, CPU, memória, contagem de GPU) podem levar ao superprovisionamento ou à subutilização, especialmente para cargas de trabalho dinâmicas, como inferência. AI/ML Selecionar a GPU certa é importante. Para cargas de trabalho de baixo volume ou picos, a divisão de tempo permite que várias cargas de trabalho compartilhem uma única GPU compartilhando seus recursos de computação, potencialmente melhorando a eficiência e reduzindo o desperdício. O compartilhamento de GPU pode ser obtido por meio de diferentes opções:
-
Aproveite os seletores de nós/afinidade de nós para influenciar o agendamento: garanta que os nós provisionados e os pods estejam programados nas GPUs apropriadas para a carga de trabalho (por exemplo,)
karpenter.k8s.aws/instance-gpu-name: "a100" -
Time-Slicing: programa cargas de trabalho para compartilhar os recursos de computação de uma GPU ao longo do tempo, permitindo a execução simultânea sem particionamento físico. Isso é ideal para cargas de trabalho com demandas computacionais variáveis, mas que podem não ter isolamento de memória.
-
Multi-Instance GPU (MIG): O MIG permite que uma única GPU NVIDIA seja particionada em várias instâncias isoladas e é compatível com as GPUs NVIDIA Ampere (por exemplo, GPU A100), NVIDIA Hopper (por exemplo, GPU H100) e NVIDIA Blackwell (por exemplo, GPUs Blackwell). Cada instância MIG recebe recursos dedicados de computação e memória, permitindo o compartilhamento de recursos em ambientes multilocatários ou cargas de trabalho que exigem garantias de recursos, o que permite otimizar a utilização de recursos da GPU, incluindo cenários como atender a vários modelos com tamanhos de lote diferentes por meio de divisão de tempo.
-
Alocação fracionária de GPU: usa agendamento baseado em software para alocar partes da computação ou da memória de uma GPU para cargas de trabalho, oferecendo flexibilidade para cargas de trabalho dinâmicas. O NVIDIA KAI Scheduler
, parte da Run:ai plataforma, permite isso ao permitir que os pods solicitem recursos fracionários da GPU.
Para habilitar esses recursos no EKS, você pode implantar o NVIDIA Device Plugin, que expõe as GPUs como recursos programáveis e oferece suporte à divisão de tempo e MIG. Para saber mais, veja Time-Slicing GPUs no Kubernetes
Exemplo
Por exemplo, para ativar a divisão de tempo com o NVIDIA Device Plugin:
apiVersion: v1 kind: ConfigMap metadata: name: nvidia-device-plugin-config namespace: kube-system data: config.yaml: | version: v1 sharing: timeSlicing: resources: - name: nvidia.com/gpu replicas: 4 # Allow 4 pods to share each GPU
Exemplo
Por exemplo, para usar o KAI Scheduler para alocação fracionária de GPU, implante-o junto com o NVIDIA GPU Operator e especifique recursos fracionários de GPU na especificação do pod:
apiVersion: v1 kind: Pod metadata: name: fractional-gpu-pod-example annotations: gpu-fraction: "0.5" # Annotation for 50% GPU labels: runai/queue: "default" # Required queue assignment spec: containers: - name: ml-workload image: nvcr.io/nvidia/pytorch:25.04-py3 resources: limits: nvidia.com/gpu: 1 nodeSelector: nvidia.com/gpu: "true" schedulerName: kai-scheduler
Resiliência de nós e gerenciamento de tarefas de treinamento
Implemente verificações de integridade do nó com recuperação automatizada
Para trabalhos de treinamento distribuído no Amazon EKS que exigem comunicação frequente entre nós, como treinamento em modelos de várias GPUs em vários nós, problemas de hardware, como falhas de GPU ou EFA, podem causar interrupções nos trabalhos de treinamento. Essas interrupções podem levar à perda do progresso do treinamento e ao aumento dos custos, especialmente para AI/ML cargas de trabalho de longa duração que dependem de hardware estável.
Para ajudar a aumentar a resiliência contra falhas de hardware, como falhas de GPU em clusters EKS que executam cargas de trabalho de GPU, recomendamos usar o EKS Node Monitoring Agent with Auto Repair ou a Amazon. SageMaker HyperPod Embora o EKS Node Monitoring Agent with Auto Repair forneça recursos como monitoramento da integridade do nó e reparo automático usando mecanismos padrão do Kubernetes, SageMaker HyperPod oferece resiliência direcionada e recursos adicionais projetados especificamente para treinamento de ML em grande escala, como verificações profundas de integridade e retomada automática do trabalho.
-
O EKS Node Monitoring Agent com Node Auto Repair monitora continuamente a integridade do nó lendo registros e aplicando NodeConditions, incluindo condições padrão
Readye condições específicas do hardware acelerado para identificar problemas como falhas na GPU ou na rede. Quando um nó é considerado insalubre, o Node Auto Repair o isola e o substitui por um novo nó. O reagendamento de pods e a reinicialização de trabalhos dependem dos mecanismos padrão do Kubernetes e da política de reinicialização do trabalho. -
O agente de verificações SageMaker HyperPod
profundas de integridade e monitoramento de integridade monitora continuamente o status de integridade da GPU e das instâncias. Trainium-based Ele é personalizado para AI/ML cargas de trabalho, usando rótulos (por exemplo, node-health-status) para gerenciar a integridade do nó. Quando um nó é considerado iníntegro, HyperPod aciona a substituição automática do hardware defeituoso, como GPUs. Ele detecta falhas relacionadas à rede do EFA por meio de suas verificações básicas de saúde por padrão e oferece suporte à retomada automática para trabalhos de treinamento interrompidos, permitindo que os trabalhos continuem a partir do último ponto de verificação, minimizando as interrupções em tarefas de ML em grande escala.
Tanto para o EKS Node Monitoring Agent com Auto Repair quanto para SageMaker HyperPod clusters que usam o EFA, para monitorar EFA-specific métricas como erros de acesso remoto direto à memória (RDMA) e quedas de pacotes, certifique-se de que o driver AWS EFA esteja instalado. Além disso, recomendamos implantar o CloudWatch Observability Add-on ou usar ferramentas como o DCGM Exporter com Prometheus e Grafana para monitorar o EFA, a GPU e, para, métricas específicas relacionadas a seus recursos. SageMaker HyperPod
Desative a consolidação Karpenter para cargas de trabalho sensíveis a interrupções
Para cargas de trabalho sensíveis a interrupções, como processamento, tarefas de AI/ML previsão em grande escala ou treinamento, recomendamos ajustar as políticas de consolidação da Karpenter para evitar interrupções durante
A política de WhenEmptyOrUnderutilized consolidação pode encerrar os nós prematuramente, levando a tempos de execução mais longos. Por exemplo, as interrupções podem atrasar a retomada do trabalho devido ao reagendamento do pod e ao recarregamento de dados, o que pode ser caro para trabalhos de inferência em lote de longa duração. Para atenuar isso, você pode definir como WhenEmpty e consolidationPolicy configurar uma consolidateAfter duração, como 1 hora, para reter os nós durante picos de carga de trabalho. Por exemplo:
disruption: consolidationPolicy: WhenEmpty consolidateAfter: 60m
Essa abordagem melhora a latência de inicialização do pod para cargas de trabalho de inferência em lote com picos e outras tarefas sensíveis a interrupções, como processamento de dados de inferência on-line em tempo real ou treinamento de modelos, em que o custo da interrupção supera a economia de custos de computação. Os orçamentos de
Use ttl SecondsAfterFinished para tarefas automáticas de Clean-Up Kubernetes
Recomendamos a configuração ttlSecondsAfterFinished de trabalhos do Kubernetes no Amazon EKS para excluir automaticamente objetos de trabalho concluídos. Objetos de trabalho persistentes consomem recursos do cluster, como memória do servidor de API, e complicam o monitoramento ao sobrecarregar painéis (por exemplo, Grafana, Amazon). CloudWatch Por exemplo, definir um TTL de 1 hora garante que os trabalhos sejam removidos logo após a conclusão, mantendo seu cluster organizado. Para obter mais detalhes, consulte Limpeza automática para trabalhos
Configurar a preempção de Low-Priority tarefas para Higher-Priority Jobs/workloads
Para AI/ML cargas de trabalho de prioridade mista no Amazon EKS, você pode configurar a preempção de tarefas de baixa prioridade para garantir que tarefas de maior prioridade (por exemplo, inferência em tempo real) recebam recursos imediatamente. Sem preempção, cargas de trabalho de baixa prioridade, como processos em lote (por exemplo, inferência em lote, processamento de dados), serviços que não sejam em lote (por exemplo, tarefas em segundo plano, tarefas cron) ou CPU/memory-intensive trabalhos (por exemplo, serviços da web), podem atrasar os pods críticos ao ocupar nós. A preempção permite que o Kubernetes elimine pods de baixa prioridade quando pods de alta prioridade precisam de recursos, garantindo a alocação eficiente de recursos em nós com GPUs, CPUs ou memória. Recomendamos usar o Kubernetes PriorityClass para atribuir prioridades e controlar o comportamento de PodDisruptionBudget despejo.
apiVersion: scheduling.k8s.io/v1 kind: PriorityClass metadata: name: low-priority value: 100 --- spec: priorityClassName: low-priority
Consulte a documentação de prioridade e preempção do Kubernetes para obter mais informações.
Escalabilidade e desempenho de aplicativos
Personalize a capacidade de computação para cargas de trabalho de ML com Karpenter ou Static Nodes
Para garantir uma capacidade computacional econômica e responsiva para fluxos de trabalho de aprendizado de máquina (ML) no Amazon EKS, recomendamos adaptar sua estratégia de provisionamento de nós às características de sua carga de trabalho e aos compromissos de custo. Abaixo estão duas abordagens a serem consideradas: escalabilidade just-in-time com Karpenter
-
Just-in-time escaladores de plano de dados como Karpenter: para fluxos de trabalho dinâmicos de ML com demandas de computação variáveis (por exemplo, GPU-based inferência seguida de CPU-based plotagem), recomendamos o uso de escaladores de plano de dados just-in-time, como o Karpenter.
-
Use grupos de nós estáticos para cargas de trabalho previsíveis: para cargas de trabalho de ML previsíveis e estáveis ou ao usar instâncias reservadas, os grupos de nós gerenciados do EKS podem ajudar a garantir que a capacidade reservada seja totalmente provisionada e utilizada, maximizando a economia. Essa abordagem é ideal para tipos específicos de instâncias confirmados por meio de RIs ou ODCRs.
Exemplo
Esse é um exemplo de um Karpenter diversificado NodePool g Amazon EC2 em que a geração de instâncias é maior que três.
apiVersion: karpenter.sh/v1 kind: NodePool metadata: name: gpu-inference spec: template: spec: nodeClassRef: group: karpenter.k8s.aws kind: EC2NodeClass name: default requirements: - key: karpenter.sh/capacity-type operator: In values: ["on-demand"] - key: karpenter.k8s.aws/instance-category operator: In values: ["g"] - key: karpenter.k8s.aws/instance-generation operator: Gt values: ["3"] - key: kubernetes.io/arch operator: In values: ["amd64"] taints: - key: nvidia.com/gpu effect: NoSchedule limits: cpu: "1000" memory: "4000Gi" nvidia.com/gpu: "10" *# Limit the total number of GPUs to 10 for the NodePool* disruption: consolidationPolicy: WhenEmpty consolidateAfter: 60m expireAfter: 720h
Exemplo
Exemplo de uso de grupos de nós estáticos para uma carga de trabalho de treinamento:
apiVersion: eksctl.io/v1alpha5 kind: ClusterConfig metadata: name: ml-cluster region: us-west-2 managedNodeGroups: - name: gpu-node-group instanceType: p4d.24xlarge minSize: 2 maxSize: 2 desiredCapacity: 2 taints: - key: nvidia.com/gpu effect: NoSchedule
Use contaminações e tolerâncias para evitar que cargas de trabalho não aceleradas sejam programadas em instâncias aceleradas
Programar cargas de trabalho não aceleradas em recursos de GPU não é eficiente em termos de computação. Recomendamos o uso de contaminações e tolerância para garantir que os pods de cargas de trabalho não aceleradas não sejam programados em nós inadequados. Consulte a documentação do Kubernetes
Escala com base no desempenho do modelo
Para cargas de trabalho de inferência, recomendamos usar o Kubernetes Event-Driven Autoscaling (KEDA) para escalar com base nas métricas de desempenho do modelo, como solicitações de inferência ou taxa de transferência de tokens, com períodos de resfriamento apropriados. As políticas de escalabilidade estática podem provisionar recursos excessivamente ou insuficientes, afetando o custo e a latência. Saiba mais na documentação da
Alocação dinâmica de recursos para gerenciamento avançado de GPU
A alocação dinâmica de recursos (DRA)
-
Fine-grained Alocação de GPU
-
Mecanismos avançados de compartilhamento, como Multi-Process serviço (MPS) e Multi-Instance GPU (MIG)
-
Suporte para arquiteturas de hardware de próxima geração, incluindo NVIDIA GB200 UltraServers
A alocação tradicional de GPU trata as GPUs como recursos inteiros opacos, criando uma subutilização significativa (geralmente de 30 a 40% em clusters de produção). Isso ocorre porque as cargas de trabalho recebem acesso exclusivo a GPUs inteiras, mesmo quando exigem apenas recursos fracionários. O DRA transforma esse modelo introduzindo a alocação declarativa estruturada que fornece ao agendador Kubernetes visibilidade completa das características de hardware e dos requisitos de carga de trabalho. Isso permite decisões inteligentes de posicionamento e compartilhamento eficiente de recursos.
Vantagens de usar o DRA em vez do plug-in de dispositivo NVIDIA
O plug-in de dispositivo NVIDIA (a partir da versão0.12.0) suporta mecanismos de compartilhamento de GPU, incluindo divisão de tempo, MPS e MIG. No entanto, existem limitações arquitetônicas que o DRA aborda.
Limitações do plug-in de dispositivo NVIDIA
-
Configuração estática: as configurações de compartilhamento de GPU (réplicas de divisão de tempo e configurações de MPS) exigem pré-configuração em todo o cluster.
ConfigMapsIsso dificulta o fornecimento de diferentes estratégias de compartilhamento para diferentes cargas de trabalho. -
Seleção granular limitada: embora o plug-in do dispositivo exponha as características da GPU por meio de rótulos de nós, as cargas de trabalho não podem solicitar dinamicamente configurações específicas de GPU (tamanho da memória e recursos de computação) como parte da decisão de agendamento.
-
Sem coordenação de recursos entre nós: não é possível gerenciar recursos de GPU distribuídos em vários nós nem expressar requisitos complexos de topologia, como domínios NVLink, para sistemas como o NVIDIA GB200.
-
Restrições do agendador: o agendador do Kubernetes trata os recursos da GPU como números inteiros opacos, limitando sua capacidade de tomar decisões sensíveis à topologia ou lidar com dependências complexas de recursos.
-
Complexidade da configuração: a configuração de diferentes estratégias de compartilhamento exige uma rotulagem cuidadosa
ConfigMapse múltipla dos nós, criando complexidade operacional.
Soluções com DRA
-
Seleção dinâmica de recursos: o DRA permite que as cargas de trabalho especifiquem requisitos detalhados (memória de GPU, versões de driver e atributos específicos) no momento da solicitação.
resourceclaimsIsso permite uma correspondência de recursos mais flexível. -
Reconhecimento de topologia: por meio de parâmetros estruturados e seletores de dispositivos, o DRA lida com requisitos complexos, como comunicação de GPU entre nós e interconexões coerentes com a memória.
-
Cross-node gerenciamento de recursos:
computeDomainspermite a coordenação de recursos de GPU distribuídos em vários nós, essenciais para sistemas como o GB200 com canais IMEX. -
Workload-specific configuração: cada uma
ResourceClaimespecifica estratégias e configurações de compartilhamento diferentes, permitindo um controle refinado por carga de trabalho em vez de configurações em todo o cluster. -
Integração aprimorada do agendador: o DRA fornece ao agendador informações detalhadas do dispositivo e permite decisões de posicionamento mais inteligentes com base na topologia do hardware e nas características dos recursos.
Importante: O DRA não substitui totalmente o plug-in do dispositivo NVIDIA. O driver NVIDIA DRA funciona junto com o plug-in do dispositivo para fornecer recursos aprimorados. O plug-in do dispositivo continua a lidar com a descoberta e o gerenciamento básicos da GPU, enquanto o DRA adiciona recursos avançados de alocação e agendamento.
Instâncias suportadas pelo DRA e seus recursos
O suporte ao DRA varia de acordo com a família de instâncias do Amazon EC2 e a arquitetura de GPU, conforme mostrado na tabela a seguir.
| Família de instâncias | Tipo de GPU | Time-slicing | Suporte MIG | Suporte MPS | Suporte IMEX | Casos de uso |
|---|---|---|---|---|---|---|
|
G5 |
NVIDIA A10G |
Sim |
Não |
Sim |
Não |
Cargas de trabalho gráficas e de inferência |
|
G6 |
NVIDIA L4 |
Sim |
Não |
Sim |
Não |
Inferência de IA e processamento de vídeo |
|
G6e |
NVIDIA L40S |
Sim |
Não |
Sim |
Não |
Treinamento, inferência e gráficos |
|
P4d/P4de |
NVIDIA A100 |
Sim |
Sim |
Sim |
Não |
Large-scale treinamento e HPC |
|
P5 |
NVIDIA H100 |
Sim |
Sim |
Sim |
Não |
Treinamento do modelo básico |
|
P6 |
NVIDIA B200 |
Sim |
Sim |
Sim |
Não |
Modelos de bilhões ou trilhões de parâmetros, treinamento distribuído e inferência |
|
P6e |
NVIDIA GB200 |
Sim |
Sim |
Sim |
Sim |
Modelos de bilhões ou trilhões de parâmetros, treinamento distribuído e inferência |
A seguir estão as descrições de cada recurso na tabela:
-
Time-slicing: permite que várias cargas de trabalho compartilhem recursos de computação da GPU ao longo do tempo.
-
Multi-Instance GPU (MIG): Hardware-level particionamento que cria instâncias de GPU isoladas.
-
Multi-Process serviço (MPS): permite a execução simultânea de vários processos CUDA em uma única GPU.
-
Internode Memory Exchange (IMEX): Memory-coherent comunicação entre nós para GB200. UltraServers
Recursos adicionais do
Para obter mais informações sobre os drivers Kubernetes DRA e NVIDIA DRA, consulte os seguintes recursos em: GitHub
-
Alocação dinâmica de recursos do Kubernetes https://github.com/kubernetes/dynamic-resource-allocation
Configure a alocação dinâmica de recursos para gerenciamento avançado de GPU
O tópico a seguir mostra como configurar a alocação dinâmica de recursos (DRA) para gerenciamento avançado de GPU.
Pré-requisitos
Antes de implementar o DRA no Amazon EKS, certifique-se de que seu ambiente atenda aos seguintes requisitos.
Configuração do cluster
-
Cluster Amazon EKS em execução na versão
1.33ou posterior -
Grupos de nós gerenciados do Amazon EKS (atualmente, o DRA é suportado somente por grupos de nós gerenciados com AMIs otimizadas para AL2023 e Bottlerocket NVIDIA, não com Karpenter) https://github.com/kubernetes-sigs/karpenter/issues/1231
-
Nodes de GPU-enabled trabalho da NVIDIA com tipos de instância apropriados
Componentes necessários
-
Versão do plug-in do dispositivo NVIDIA
0.17.1ou posterior -
Versão do driver NVIDIA DRA
25.3.0ou posterior
Etapa 1: Criar cluster com grupo de DRA-enabled nós usando eksctl
-
Crie um arquivo de configuração de cluster chamado
dra-eks-cluster.yaml:--- apiVersion: eksctl.io/v1alpha5 kind: ClusterConfig metadata: name: dra-eks-cluster region: us-west-2 version: '1.33' managedNodeGroups: - name: gpu-dra-nodes amiFamily: AmazonLinux2023 instanceType: g6.12xlarge desiredCapacity: 2 minSize: 1 maxSize: 3 labels: node-type: "gpu-dra" nvidia.com/gpu.present: "true" taints: - key: nvidia.com/gpu value: "true" effect: NoSchedule -
Crie o cluster:
eksctl create cluster -f dra-eks-cluster.yaml
Etapa 2: implantar o plug-in do dispositivo NVIDIA
Implante o plug-in do dispositivo NVIDIA para permitir a descoberta básica da GPU:
-
Adicione o repositório Helm do plug-in de dispositivo NVIDIA:
helm repo add nvidia https://nvidia.github.io/k8s-device-plugin helm repo update -
Crie valores personalizados para o plug-in do dispositivo:
cat <<EOF > nvidia-device-plugin-values.yaml gfd: enabled: true nfd: enabled: true tolerations: - key: nvidia.com/gpu operator: Exists effect: NoSchedule EOF -
Instale o plug-in do dispositivo NVIDIA:
helm install nvidia-device-plugin nvidia/nvidia-device-plugin \ --namespace nvidia-device-plugin \ --create-namespace \ --version 0.17.1 \ --values nvidia-device-plugin-values.yaml
Etapa 3: implantar o gráfico Helm do driver NVIDIA DRA
-
Crie um arquivo de
dra-driver-values.yamlvalores para o driver DRA:--- nvidiaDriverRoot: / gpuResourcesEnabledOverride: true resources: gpus: enabled: true computeDomains: enabled: true # Enable for GB200 IMEX support controller: tolerations: - key: nvidia.com/gpu operator: Exists effect: NoSchedule kubeletPlugin: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: "nvidia.com/gpu.present" operator: In values: ["true"] tolerations: - key: nvidia.com/gpu operator: Exists effect: NoSchedule -
Adicione o repositório NVIDIA NGC Helm:
helm repo add nvidia https://helm.ngc.nvidia.com/nvidia helm repo update -
Instale o driver NVIDIA DRA:
helm install nvidia-dra-driver nvidia/nvidia-dra-driver-gpu \ --version="25.3.0-rc.2" \ --namespace nvidia-dra-driver \ --create-namespace \ --values dra-driver-values.yaml
Etapa 4: Verificar a instalação do DRA
-
Verifique se os recursos da API DRA estão disponíveis:
kubectl api-resources | grep resource.k8s.io/v1beta1A saída esperada é a seguinte:
deviceclasses resource.k8s.io/v1beta1 false DeviceClass resourceclaims resource.k8s.io/v1beta1 true ResourceClaim resourceclaimtemplates resource.k8s.io/v1beta1 true ResourceClaimTemplate resourceslices resource.k8s.io/v1beta1 false ResourceSlice -
Verifique as classes de dispositivos disponíveis:
kubectl get deviceclassesVeja a seguir um exemplo da saída esperada:
NAME AGE compute-domain-daemon.nvidia.com 4h39m compute-domain-default-channel.nvidia.com 4h39m gpu.nvidia.com 4h39m mig.nvidia.com 4h39mQuando uma instância de GPU G6 recém-criada se junta ao seu cluster Amazon EKS com o DRA ativado, as seguintes ações ocorrem:
-
O driver NVIDIA DRA descobre automaticamente a GPU A10G e cria duas nesse nó.
resourceslices -
A
gpu.nvidia.comfatia registra o dispositivo físico da GPU A10G com suas especificações (memória, capacidade de computação e muito mais). -
Como o A10G não oferece suporte ao particionamento MIG, a
compute-domain.nvidia.comfatia cria um único domínio de computação representando todo o contexto computacional da GPU. -
Em seguida, eles
resourceslicessão publicados no servidor da API Kubernetes, disponibilizando os recursos da GPU para agendamento.resourceclaimsAgora, o agendador DRA pode alocar essa GPU de forma inteligente para pods que solicitam recursos de GPU
resourceclaimtemplates, fornecendo um gerenciamento de recursos mais flexível em comparação com as abordagens tradicionais de plug-ins de dispositivos. Isso acontece automaticamente sem intervenção manual. O nó simplesmente fica disponível para cargas de trabalho de GPU quando o driver DRA conclui o processo de descoberta e registro de recursos.Quando você executa o seguinte comando:
kubectl get resourceslicesVeja a seguir um exemplo da saída esperada:
NAME NODE DRIVER POOL AGE ip-100-64-129-47.ec2.internal-compute-domain.nvidia.com-rwsts ip-100-64-129-47.ec2.internal compute-domain.nvidia.com ip-100-64-129-47.ec2.internal 35m ip-100-64-129-47.ec2.internal-gpu.nvidia.com-6kndg ip-100-64-129-47.ec2.internal gpu.nvidia.com ip-100-64-129-47.ec2.internal 35m
-
Avance para Agende uma carga de trabalho simples de GPU usando a alocação dinâmica de recursos.
Agende uma carga de trabalho simples de GPU usando a alocação dinâmica de recursos
Para programar uma carga de trabalho simples de GPU usando a alocação dinâmica de recursos (DRA), siga as etapas a seguir. Antes de continuar, certifique-se de ter seguidoConfigure a alocação dinâmica de recursos para gerenciamento avançado de GPU.
-
Crie um básico
ResourceClaimTemplatepara alocação de GPU com um arquivo chamado:basic-gpu-claim-template.yaml--- apiVersion: v1 kind: Namespace metadata: name: gpu-test1 --- apiVersion: resource.k8s.io/v1beta1 kind: ResourceClaimTemplate metadata: namespace: gpu-test1 name: single-gpu spec: spec: devices: requests: - name: gpu deviceClassName: gpu.nvidia.com -
Aplique o modelo:
kubectl apply -f basic-gpu-claim-template.yaml -
Verifique o status:
kubectl get resourceclaimtemplates -n gpu-test1A seguir está um exemplo de saída:
NAME AGE single-gpu 9m16s -
Crie um pod que use o
ResourceClaimTemplatecom um arquivo chamadobasic-gpu-pod.yaml:--- apiVersion: v1 kind: Pod metadata: namespace: gpu-test1 name: gpu-pod labels: app: pod spec: containers: - name: ctr0 image: ubuntu:22.04 command: ["bash", "-c"] args: ["nvidia-smi -L; trap 'exit 0' TERM; sleep 9999 & wait"] resources: claims: - name: gpu0 resourceClaims: - name: gpu0 resourceClaimTemplateName: single-gpu nodeSelector: NodeGroupType: gpu-dra nvidia.com/gpu.present: "true" tolerations: - key: "nvidia.com/gpu" operator: "Exists" effect: "NoSchedule" -
Aplique e monitore o Pod:
kubectl apply -f basic-gpu-pod.yaml -
Verifique o status do pod:
kubectl get pod -n gpu-test1Veja a seguir um exemplo de saída esperada:
NAME READY STATUS RESTARTS AGE gpu-pod 1/1 Running 0 13m -
Verifique o
ResourceClaimstatus:kubectl get resourceclaims -n gpu-test1Veja a seguir um exemplo de saída esperada:
NAME STATE AGE gpu-pod-gpu0-l76cg allocated,reserved 9m6s -
Visualize os registros do pod para ver as informações da GPU:
kubectl logs gpu-pod -n gpu-test1Veja a seguir um exemplo de saída esperada:
GPU 0: NVIDIA L4 (UUID: GPU-da7c24d7-c7e3-ed3b-418c-bcecc32af7c5)
Continue Técnicas de otimização de GPU com alocação dinâmica de recursos para obter técnicas mais avançadas de otimização de GPU usando DRA.
Técnicas de otimização de GPU com alocação dinâmica de recursos
As cargas de trabalho de GPU modernas exigem um gerenciamento sofisticado de recursos para alcançar a utilização ideal e a eficiência de custos. O DRA permite várias técnicas avançadas de otimização que abordam diferentes casos de uso e recursos de hardware:
-
Time-slicingpermite que várias cargas de trabalho compartilhem recursos de computação da GPU ao longo do tempo, tornando-a ideal para cargas de trabalho de inferência com uso esporádico da GPU. Para ver um exemplo, consulte Otimize as cargas de trabalho da GPU com redução de tempo.
-
Multi-Process O serviço (MPS) permite a execução simultânea de vários processos CUDA em uma única GPU com melhor isolamento do que divisão de tempo. Para ver um exemplo, consulte Otimize as cargas de trabalho da GPU com o MPS.
-
Multi-Instance A GPU (MIG) fornece particionamento em nível de hardware, criando instâncias de GPU isoladas com recursos dedicados de computação e memória. Para ver um exemplo, consulte Otimize as cargas de trabalho da GPU com a GPU Multi-Instance.
-
O Internode Memory Exchange (IMEX) permite a comunicação coerente com a memória entre os nós para treinamento distribuído em sistemas NVIDIA GB200. Para ver um exemplo, consulte Otimize cargas de trabalho de GPU com IMEX usando instâncias GB200 P6e.
Essas técnicas podem melhorar significativamente a utilização dos recursos. As organizações relatam que a utilização da GPU aumenta de 30 a 40% com a alocação tradicional para 80 a 90% com estratégias de compartilhamento otimizadas. A escolha da técnica depende das características da carga de trabalho, dos requisitos de isolamento e dos recursos de hardware.
Otimize as cargas de trabalho da GPU com redução de tempo
Time-slicing permite que várias cargas de trabalho compartilhem recursos de computação da GPU programando-os para serem executados sequencialmente na mesma GPU física. É ideal para cargas de trabalho de inferência com uso esporádico da GPU.
Execute as etapas a seguir.
-
Defina a
ResourceClaimTemplatepara divisão de tempo com um arquivo chamado:timeslicing-claim-template.yaml--- apiVersion: v1 kind: Namespace metadata: name: timeslicing-gpu --- apiVersion: resource.k8s.io/v1beta1 kind: ResourceClaimTemplate metadata: name: timeslicing-gpu-template namespace: timeslicing-gpu spec: spec: devices: requests: - name: shared-gpu deviceClassName: gpu.nvidia.com config: - requests: ["shared-gpu"] opaque: driver: gpu.nvidia.com parameters: apiVersion: resource.nvidia.com/v1beta1 kind: GpuConfig sharing: strategy: TimeSlicing -
Defina um pod usando a divisão de tempo com um arquivo chamado:
timeslicing-pod.yaml--- # Pod 1 - Inference workload apiVersion: v1 kind: Pod metadata: name: inference-pod-1 namespace: timeslicing-gpu labels: app: gpu-inference spec: restartPolicy: Never containers: - name: inference-container image: nvcr.io/nvidia/pytorch:25.04-py3 command: ["python", "-c"] args: - | import torch import time import os print(f"=== POD 1 STARTING ===") print(f"GPU available: {torch.cuda.is_available()}") print(f"GPU count: {torch.cuda.device_count()}") if torch.cuda.is_available(): device = torch.cuda.current_device() print(f"Current GPU: {torch.cuda.get_device_name(device)}") print(f"GPU Memory: {torch.cuda.get_device_properties(device).total_memory / 1024**3:.1f} GB") # Simulate inference workload for i in range(20): x = torch.randn(1000, 1000).cuda() y = torch.mm(x, x.t()) print(f"Pod 1 - Iteration {i+1} completed at {time.strftime('%H:%M:%S')}") time.sleep(60) else: print("No GPU available!") time.sleep(5) resources: claims: - name: shared-gpu-claim resourceClaims: - name: shared-gpu-claim resourceClaimTemplateName: timeslicing-gpu-template nodeSelector: NodeGroupType: "gpu-dra" nvidia.com/gpu.present: "true" tolerations: - key: nvidia.com/gpu operator: Exists effect: NoSchedule --- # Pod 2 - Training workload apiVersion: v1 kind: Pod metadata: name: training-pod-2 namespace: timeslicing-gpu labels: app: gpu-training spec: restartPolicy: Never containers: - name: training-container image: nvcr.io/nvidia/pytorch:25.04-py3 command: ["python", "-c"] args: - | import torch import time import os print(f"=== POD 2 STARTING ===") print(f"GPU available: {torch.cuda.is_available()}") print(f"GPU count: {torch.cuda.device_count()}") if torch.cuda.is_available(): device = torch.cuda.current_device() print(f"Current GPU: {torch.cuda.get_device_name(device)}") print(f"GPU Memory: {torch.cuda.get_device_properties(device).total_memory / 1024**3:.1f} GB") # Simulate training workload with heavier compute for i in range(15): x = torch.randn(2000, 2000).cuda() y = torch.mm(x, x.t()) loss = torch.sum(y) print(f"Pod 2 - Training step {i+1}, Loss: {loss.item():.2f} at {time.strftime('%H:%M:%S')}") time.sleep(5) else: print("No GPU available!") time.sleep(60) resources: claims: - name: shared-gpu-claim-2 resourceClaims: - name: shared-gpu-claim-2 resourceClaimTemplateName: timeslicing-gpu-template nodeSelector: NodeGroupType: "gpu-dra" nvidia.com/gpu.present: "true" tolerations: - key: nvidia.com/gpu operator: Exists effect: NoSchedule -
Aplique o modelo e o pod:
kubectl apply -f timeslicing-claim-template.yaml kubectl apply -f timeslicing-pod.yaml -
Monitore as reivindicações de recursos:
kubectl get resourceclaims -n timeslicing-gpu -wA seguir está um exemplo de saída:
NAME STATE AGE inference-pod-1-shared-gpu-claim-9p97x allocated,reserved 21s training-pod-2-shared-gpu-claim-2-qghnb pending 21s inference-pod-1-shared-gpu-claim-9p97x pending 105s training-pod-2-shared-gpu-claim-2-qghnb pending 105s inference-pod-1-shared-gpu-claim-9p97x pending 105s training-pod-2-shared-gpu-claim-2-qghnb allocated,reserved 105s inference-pod-1-shared-gpu-claim-9p97x pending 105s
Primeiro pod (inference-pod-1)
-
Estado:
allocated,reserved -
Significado: o DRA encontrou uma GPU disponível e a reservou para este Pod
-
Status do pod: começa a funcionar imediatamente
Segundo pod (training-pod-2)
-
Estado:
pending -
Significado: Esperando que o DRA configure a divisão de tempo na mesma GPU
-
Status do pod: Aguardando para ser agendado
-
O estado passará de
pendingallocated,reservedpararunning
Otimize as cargas de trabalho da GPU com o MPS
Multi-Process O serviço (MPS) permite a execução simultânea de vários contextos CUDA em uma única GPU com melhor isolamento do que divisão de tempo.
Execute as etapas a seguir.
-
Defina um
ResourceClaimTemplatepara MPS com um arquivo chamadomps-claim-template.yaml:--- apiVersion: v1 kind: Namespace metadata: name: mps-gpu --- apiVersion: resource.k8s.io/v1beta1 kind: ResourceClaimTemplate metadata: name: mps-gpu-template namespace: mps-gpu spec: spec: devices: requests: - name: shared-gpu deviceClassName: gpu.nvidia.com config: - requests: ["shared-gpu"] opaque: driver: gpu.nvidia.com parameters: apiVersion: resource.nvidia.com/v1beta1 kind: GpuConfig sharing: strategy: MPS -
Defina um pod usando MPS com um arquivo chamado
mps-pod.yaml:--- # Single Pod with Multiple Containers sharing GPU via MPS apiVersion: v1 kind: Pod metadata: name: mps-multi-container-pod namespace: mps-gpu labels: app: mps-demo spec: restartPolicy: Never containers: # Container 1 - Inference workload - name: inference-container image: nvcr.io/nvidia/pytorch:25.04-py3 command: ["python", "-c"] args: - | import torch import torch.nn as nn import time import os print(f"=== INFERENCE CONTAINER STARTING ===") print(f"Process ID: {os.getpid()}") print(f"GPU available: {torch.cuda.is_available()}") print(f"GPU count: {torch.cuda.device_count()}") if torch.cuda.is_available(): device = torch.cuda.current_device() print(f"Current GPU: {torch.cuda.get_device_name(device)}") print(f"GPU Memory: {torch.cuda.get_device_properties(device).total_memory / 1024**3:.1f} GB") # Create inference model model = nn.Sequential( nn.Linear(1000, 500), nn.ReLU(), nn.Linear(500, 100) ).cuda() # Run inference for i in range(1, 999999): with torch.no_grad(): x = torch.randn(128, 1000).cuda() output = model(x) result = torch.sum(output) print(f"Inference Container PID {os.getpid()}: Batch {i}, Result: {result.item():.2f} at {time.strftime('%H:%M:%S')}") time.sleep(2) else: print("No GPU available!") time.sleep(60) resources: claims: - name: shared-gpu-claim request: shared-gpu # Container 2 - Training workload - name: training-container image: nvcr.io/nvidia/pytorch:25.04-py3 command: ["python", "-c"] args: - | import torch import torch.nn as nn import time import os print(f"=== TRAINING CONTAINER STARTING ===") print(f"Process ID: {os.getpid()}") print(f"GPU available: {torch.cuda.is_available()}") print(f"GPU count: {torch.cuda.device_count()}") if torch.cuda.is_available(): device = torch.cuda.current_device() print(f"Current GPU: {torch.cuda.get_device_name(device)}") print(f"GPU Memory: {torch.cuda.get_device_properties(device).total_memory / 1024**3:.1f} GB") # Create training model model = nn.Sequential( nn.Linear(2000, 1000), nn.ReLU(), nn.Linear(1000, 500), nn.ReLU(), nn.Linear(500, 10) ).cuda() criterion = nn.MSELoss() optimizer = torch.optim.Adam(model.parameters(), lr=0.001) # Run training for epoch in range(1, 999999): x = torch.randn(64, 2000).cuda() target = torch.randn(64, 10).cuda() optimizer.zero_grad() output = model(x) loss = criterion(output, target) loss.backward() optimizer.step() print(f"Training Container PID {os.getpid()}: Epoch {epoch}, Loss: {loss.item():.4f} at {time.strftime('%H:%M:%S')}") time.sleep(3) else: print("No GPU available!") time.sleep(60) resources: claims: - name: shared-gpu-claim request: shared-gpu resourceClaims: - name: shared-gpu-claim resourceClaimTemplateName: mps-gpu-template nodeSelector: NodeGroupType: "gpu-dra" nvidia.com/gpu.present: "true" tolerations: - key: nvidia.com/gpu operator: Exists effect: NoSchedule -
Aplique o modelo e crie vários pods MPS:
kubectl apply -f mps-claim-template.yaml kubectl apply -f mps-pod.yaml -
Monitore as reivindicações de recursos:
kubectl get resourceclaims -n mps-gpu -wA seguir está um exemplo de saída:
NAME STATE AGE mps-multi-container-pod-shared-gpu-claim-2p9kx allocated,reserved 86s
Essa configuração demonstra o verdadeiro compartilhamento de GPU usando o NVIDIA Multi-Process Service (MPS) por meio da alocação dinâmica de recursos (DRA). Diferentemente da divisão de tempo, em que as cargas de trabalho se revezam usando a GPU sequencialmente, o MPS permite que os dois contêineres sejam executados simultaneamente na mesma GPU física. O principal insight é que o compartilhamento do DRA MPS exige vários contêineres em um único pod, não vários pods separados. Quando implantado, o driver DRA aloca um ResourceClaim para o pod e configura automaticamente o MPS para permitir que os contêineres de inferência e treinamento sejam executados simultaneamente.
Cada contêiner obtém seu próprio espaço de memória de GPU e recursos de computação isolados, com o daemon MPS coordenando o acesso ao hardware subjacente. Você pode verificar se isso está funcionando fazendo o seguinte:
-
Verificação
nvidia-smi, que mostrará os dois contêineres como processos M+C (MPS + Compute) compartilhando o mesmo dispositivo de GPU. -
Monitorando os registros de ambos os contêineres, que exibirão carimbos de data/hora intercalados que comprovam a execução simultânea.
Essa abordagem maximiza a utilização da GPU ao permitir que cargas de trabalho complementares compartilhem o caro hardware da GPU de forma eficiente, em vez de deixá-lo subutilizado por um único processo.
Contêiner 1: contêiner de inferência
root@mps-multi-container-pod:/workspace# nvidia-smi
Wed Jul 16 21:09:30 2025
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 570.158.01 Driver Version: 570.158.01 CUDA Version: 12.9 |
|-----------------------------------------+------------------------+----------------------+
| GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. |
| | | MIG M. |
|=========================================+========================+======================|
| 0 NVIDIA L4 On | 00000000:35:00.0 Off | 0 |
| N/A 48C P0 28W / 72W | 597MiB / 23034MiB | 0% E. Process |
| | | N/A |
+-----------------------------------------+------------------------+----------------------+
+-----------------------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=========================================================================================|
| 0 N/A N/A 1 M+C python 246MiB |
+-----------------------------------------------------------------------------------------+
Contêiner 2: contêiner de treinamento
root@mps-multi-container-pod:/workspace# nvidia-smi
Wed Jul 16 21:16:00 2025
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 570.158.01 Driver Version: 570.158.01 CUDA Version: 12.9 |
|-----------------------------------------+------------------------+----------------------+
| GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. |
| | | MIG M. |
|=========================================+========================+======================|
| 0 NVIDIA L4 On | 00000000:35:00.0 Off | 0 |
| N/A 51C P0 28W / 72W | 597MiB / 23034MiB | 0% E. Process |
| | | N/A |
+-----------------------------------------+------------------------+----------------------+
+-----------------------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=========================================================================================|
| 0 N/A N/A 1 M+C python 314MiB |
+-----------------------------------------------------------------------------------------+
Otimize as cargas de trabalho da GPU com a GPU Multi-Instance
Multi-instance A GPU (MIG) fornece particionamento em nível de hardware, criando instâncias de GPU isoladas com recursos dedicados de computação e memória.
O uso do particionamento MIG dinâmico com vários perfis requer o NVIDIA GPU Operator. WITH0—REBOOT=true a configuração do MIG Manager é essencial para implantações bem-sucedidas do MIG.
Você precisa do driver NVIDIA DRA
Etapa 1: implantar o NVIDIA GPU Operator
-
Adicione o repositório NVIDIA GPU Operator:
helm repo add nvidia https://nvidia.github.io/gpu-operator helm repo update -
Crie um arquivo
gpu-operator-values.yaml:driver: enabled: false mig: strategy: mixed migManager: enabled: true env: - name: WITH_REBOOT value: "true" config: create: true name: custom-mig-parted-configs default: "all-disabled" data: config.yaml: |- version: v1 mig-configs: all-disabled: - devices: all mig-enabled: false # P4D profiles (A100 40GB) p4d-half-balanced: - devices: [0, 1, 2, 3] mig-enabled: true mig-devices: "1g.5gb": 2 "2g.10gb": 1 "3g.20gb": 1 - devices: [4, 5, 6, 7] mig-enabled: false # P4DE profiles (A100 80GB) p4de-half-balanced: - devices: [0, 1, 2, 3] mig-enabled: true mig-devices: "1g.10gb": 2 "2g.20gb": 1 "3g.40gb": 1 - devices: [4, 5, 6, 7] mig-enabled: false devicePlugin: enabled: true config: name: "" create: false default: "" toolkit: enabled: true nfd: enabled: true gfd: enabled: true dcgmExporter: enabled: true serviceMonitor: enabled: true interval: 15s honorLabels: false additionalLabels: release: kube-prometheus-stack nodeStatusExporter: enabled: false operator: defaultRuntime: containerd runtimeClass: nvidia resources: limits: cpu: 500m memory: 350Mi requests: cpu: 200m memory: 100Mi daemonsets: tolerations: - key: "nvidia.com/gpu" operator: "Exists" effect: "NoSchedule" nodeSelector: accelerator: nvidia priorityClassName: system-node-critical -
Instale o GPU Operator usando o
gpu-operator-values.yamlarquivo:helm install gpu-operator nvidia/gpu-operator \ --namespace gpu-operator \ --create-namespace \ --version v25.3.1 \ --values gpu-operator-values.yamlEste gráfico do Helm implanta os seguintes componentes e vários perfis MIG:
-
Plugin de dispositivo (agendamento de recursos da GPU)
-
Exportador DCGM (métricas e monitoramento de GPU)
-
Node Feature Discovery (NFD - rotulagem de hardware)
-
Descoberta de recursos de GPU (rotulagem GFD) GPU-specific
-
Gerenciador MIG (particionamento de Multi-instance GPU)
-
Kit de ferramentas de contêiner (tempo de execução do contêiner de GPU)
-
Controlador do operador (gerenciamento do ciclo de vida)
-
-
Verifique os pods de implantação:
kubectl get pods -n gpu-operatorA seguir está um exemplo de saída:
NAME READY STATUS RESTARTS AGE gpu-feature-discovery-27rdq 1/1 Running 0 3h31m gpu-operator-555774698d-48brn 1/1 Running 0 4h8m nvidia-container-toolkit-daemonset-sxmh9 1/1 Running 1 (3h32m ago) 4h1m nvidia-cuda-validator-qb77g 0/1 Completed 0 3h31m nvidia-dcgm-exporter-cvzd7 1/1 Running 0 3h31m nvidia-device-plugin-daemonset-5ljm5 1/1 Running 0 3h31m nvidia-gpu-operator-node-feature-discovery-gc-67f66fc557-q5wkt 1/1 Running 0 4h8m nvidia-gpu-operator-node-feature-discovery-master-5d8ffddcsl6s6 1/1 Running 0 4h8m nvidia-gpu-operator-node-feature-discovery-worker-6t4w7 1/1 Running 1 (3h32m ago) 4h1m nvidia-gpu-operator-node-feature-discovery-worker-9w7g8 1/1 Running 0 4h8m nvidia-gpu-operator-node-feature-discovery-worker-k5fgs 1/1 Running 0 4h8m nvidia-mig-manager-zvf54 1/1 Running 1 (3h32m ago) 3h35m -
Crie um cluster Amazon EKS com um grupo de nós gerenciado por P4de para testar os exemplos do MIG:
apiVersion: eksctl.io/v1alpha5 kind: ClusterConfig metadata: name: dra-eks-cluster region: us-east-1 version: '1.33' managedNodeGroups: # P4DE MIG Node Group with Capacity Block Reservation - name: p4de-mig-nodes amiFamily: AmazonLinux2023 instanceType: p4de.24xlarge # Capacity settings desiredCapacity: 0 minSize: 0 maxSize: 1 # Use specific subnet in us-east-1b for capacity reservation subnets: - us-east-1b # AL2023 NodeConfig for RAID0 local storage only nodeadmConfig: apiVersion: node.eks.aws/v1alpha1 kind: NodeConfig spec: instance: localStorage: strategy: RAID0 # Node labels for MIG configuration labels: nvidia.com/gpu.present: "true" nvidia.com/gpu.product: "A100-SXM4-80GB" nvidia.com/mig.config: "p4de-half-balanced" node-type: "p4de" vpc.amazonaws.com/efa.present: "true" accelerator: "nvidia" # Node taints taints: - key: nvidia.com/gpu value: "true" effect: NoSchedule # EFA support efaEnabled: true # Placement group for high-performance networking placementGroup: groupName: p4de-placement-group strategy: cluster # Capacity Block Reservation (CBR) # Ensure CBR ID matches the subnet AZ with the Nodegroup subnet spot: false capacityReservation: capacityReservationTarget: capacityReservationId: "cr-abcdefghij" # Replace with your capacity reservation IDO NVIDIA GPU Operator usa o rótulo adicionado aos nós
nvidia.com/mig.config: "p4de-half-balanced"e particiona a GPU com o perfil fornecido. -
Faça login na
p4deinstância. -
Execute este comando: .
nvidia-smi -LVocê deve ver o seguinte exemplo de saída:
[root@ip-100-64-173-145 bin]# nvidia-smi -L GPU 0: NVIDIA A100-SXM4-80GB (UUID: GPU-ab52e33c-be48-38f2-119e-b62b9935925a) MIG 3g.40gb Device 0: (UUID: MIG-da972af8-a20a-5f51-849f-bc0439f7970e) MIG 2g.20gb Device 1: (UUID: MIG-7f9768b7-11a6-5de9-a8aa-e9c424400da4) MIG 1g.10gb Device 2: (UUID: MIG-498adad6-6cf7-53af-9d1a-10cfd1fa53b2) MIG 1g.10gb Device 3: (UUID: MIG-3f55ef65-1991-571a-ac50-0dbf50d80c5a) GPU 1: NVIDIA A100-SXM4-80GB (UUID: GPU-0eabeccc-7498-c282-0ac7-d3c09f6af0c8) MIG 3g.40gb Device 0: (UUID: MIG-80543849-ea3b-595b-b162-847568fe6e0e) MIG 2g.20gb Device 1: (UUID: MIG-3af1958f-fac4-59f1-8477-9f8d08c55029) MIG 1g.10gb Device 2: (UUID: MIG-401088d2-716f-527b-a970-b1fc7a4ac6b2) MIG 1g.10gb Device 3: (UUID: MIG-8c56c75e-5141-501c-8f43-8cf22f422569) GPU 2: NVIDIA A100-SXM4-80GB (UUID: GPU-1c7a1289-243f-7872-a35c-1d2d8af22dd0) MIG 3g.40gb Device 0: (UUID: MIG-e9b44486-09fc-591a-b904-0d378caf2276) MIG 2g.20gb Device 1: (UUID: MIG-ded93941-9f64-56a3-a9b1-a129c6edf6e4) MIG 1g.10gb Device 2: (UUID: MIG-6c317d83-a078-5c25-9fa3-c8308b379aa1) MIG 1g.10gb Device 3: (UUID: MIG-2b070d39-d4e9-5b11-bda6-e903372e3d08) GPU 3: NVIDIA A100-SXM4-80GB (UUID: GPU-9a6250e2-5c59-10b7-2da8-b61d8a937233) MIG 3g.40gb Device 0: (UUID: MIG-20e3cd87-7a57-5f1b-82e7-97b14ab1a5aa) MIG 2g.20gb Device 1: (UUID: MIG-04430354-1575-5b42-95f4-bda6901f1ace) MIG 1g.10gb Device 2: (UUID: MIG-d62ec8b6-e097-5e99-a60c-abf8eb906f91) MIG 1g.10gb Device 3: (UUID: MIG-fce20069-2baa-5dd4-988a-cead08348ada) GPU 4: NVIDIA A100-SXM4-80GB (UUID: GPU-5d09daf0-c2eb-75fd-3919-7ad8fafa5f86) GPU 5: NVIDIA A100-SXM4-80GB (UUID: GPU-99194e04-ab2a-b519-4793-81cb2e8e9179) GPU 6: NVIDIA A100-SXM4-80GB (UUID: GPU-c1a1910f-465a-e16f-5af1-c6aafe499cd6) GPU 7: NVIDIA A100-SXM4-80GB (UUID: GPU-c2cfafbc-fd6e-2679-e955-2a9e09377f78)
O NVIDIA GPU Operator aplicou com sucesso o perfil p4de-half-balanced MIG à sua instância P4DE, criando partições de GPU em nível de hardware conforme configurado. Veja como o particionamento funciona:
O operador de GPU aplicou essa configuração a partir do seu perfil MIG incorporado:
p4de-half-balanced:
- devices: [0, 1, 2, 3] # First 4 GPUs: MIG enabled
mig-enabled: true
mig-devices:
"1g.10gb": 2 # 2x small instances (10GB each)
"2g.20gb": 1 # 1x medium instance (20GB)
"3g.40gb": 1 # 1x large instance (40GB)
- devices: [4, 5, 6, 7] # Last 4 GPUs: Full GPUs
mig-enabled: false
A partir de sua nvidia-smi -L saída, veja o que o operador de GPU criou:
-
MIG-enabled GPUs (0-3): hardware particionado
-
GPU 0: NVIDIA A100-SXM4-80GB
-
Dispositivo MIG 3g.40gb 0 — Grandes cargas de trabalho (40 GB de memória, 42 SMs)
-
Dispositivo MIG 2g.20gb 1 — Cargas de trabalho médias (20 GB de memória, 28 SMs)
-
Dispositivo MIG 1g.10gb 2 — Pequenas cargas de trabalho (10 GB de memória, 14 SMs)
-
Dispositivo MIG 1g.10gb 3 — Cargas de trabalho pequenas (10 GB de memória, 14 SMs)
-
-
GPU 1: NVIDIA A100-SXM4-80GB
-
Dispositivo MIG 3g.40gb 0 — Layout de partição idêntico
-
Dispositivo MIG 2g.20gb 1
-
Dispositivo MIG 1g.10gb 2
-
Dispositivo MIG 1g.10gb 3
-
-
GPU 2 e GPU 3 — Mesmo padrão da GPU 0 e da GPU 1
-
-
GPUs completas (4-7): sem particionamento MIG
-
GPU 4: NVIDIA A100-SXM4-80GB — GPU completa de 80 GB
-
GPU 5: NVIDIA A100-SXM4-80GB — GPU completa de 80 GB
-
GPU 6: NVIDIA A100-SXM4-80GB — GPU completa de 80 GB
-
GPU 7: NVIDIA A100-SXM4-80GB — GPU completa de 80 GB
-
Depois que o NVIDIA GPU Operator cria as partições MIG, o driver NVIDIA DRA detecta automaticamente essas instâncias isoladas por hardware e as disponibiliza para alocação dinâmica de recursos no Kubernetes. O driver DRA descobre cada instância MIG com seu perfil específico (1g.10gb, 2g.20gb, 3g.40gb) e as expõe como recursos programáveis por meio da classe de dispositivo. mig.nvidia.com
O driver DRA monitora continuamente a topologia MIG e mantém um inventário das instâncias disponíveis em todas as GPUs. Quando um pod solicita um perfil MIG específico por meio de umResourceClaimTemplate, o driver DRA seleciona de forma inteligente uma instância MIG apropriada de qualquer GPU disponível, permitindo uma verdadeira multilocação em nível de hardware. Essa alocação dinâmica permite que várias cargas de trabalho isoladas sejam executadas simultaneamente na mesma GPU física, mantendo limites rígidos de recursos e garantias de desempenho.
Etapa 2: testar a alocação de recursos do MIG
Agora, vamos executar alguns exemplos para demonstrar como o DRA aloca dinamicamente instâncias MIG para diferentes cargas de trabalho. Implante resourceclaimtemplates e teste os pods para ver como o driver DRA coloca as cargas de trabalho nas partições MIG disponíveis, permitindo que vários contêineres compartilhem recursos de GPU com isolamento em nível de hardware.
-
Crie
mig-claim-template.yamlpara conter o MIG:resourceclaimtemplatesapiVersion: v1 kind: Namespace metadata: name: mig-gpu --- # Template for 3g.40gb MIG instance (Large training) apiVersion: resource.k8s.io/v1beta1 kind: ResourceClaimTemplate metadata: name: mig-large-template namespace: mig-gpu spec: spec: devices: requests: - name: mig-large deviceClassName: mig.nvidia.com selectors: - cel: expression: | device.attributes['gpu.nvidia.com'].profile == '3g.40gb' --- # Template for 2g.20gb MIG instance (Medium training) apiVersion: resource.k8s.io/v1beta1 kind: ResourceClaimTemplate metadata: name: mig-medium-template namespace: mig-gpu spec: spec: devices: requests: - name: mig-medium deviceClassName: mig.nvidia.com selectors: - cel: expression: | device.attributes['gpu.nvidia.com'].profile == '2g.20gb' --- # Template for 1g.10gb MIG instance (Small inference) apiVersion: resource.k8s.io/v1beta1 kind: ResourceClaimTemplate metadata: name: mig-small-template namespace: mig-gpu spec: spec: devices: requests: - name: mig-small deviceClassName: mig.nvidia.com selectors: - cel: expression: | device.attributes['gpu.nvidia.com'].profile == '1g.10gb' -
Aplique os três modelos:
kubectl apply -f mig-claim-template.yaml -
Execute este comando: .
kubectl get resourceclaimtemplates -n mig-gpuA seguir está um exemplo de saída:
NAME AGE mig-large-template 71m mig-medium-template 71m mig-small-template 71m -
Crie
mig-pod.yamlpara agendar vários trabalhos para aproveitar issoresourceclaimtemplates:--- # ConfigMap containing Python scripts for MIG pods apiVersion: v1 kind: ConfigMap metadata: name: mig-scripts-configmap namespace: mig-gpu data: large-training-script.py: | import torch import torch.nn as nn import torch.optim as optim import time import os print(f"=== LARGE TRAINING POD (3g.40gb) ===") print(f"Process ID: {os.getpid()}") print(f"GPU available: {torch.cuda.is_available()}") print(f"GPU count: {torch.cuda.device_count()}") if torch.cuda.is_available(): device = torch.cuda.current_device() print(f"Using GPU: {torch.cuda.get_device_name(device)}") print(f"GPU Memory: {torch.cuda.get_device_properties(device).total_memory / 1e9:.1f} GB") # Large model for 3g.40gb instance model = nn.Sequential( nn.Linear(2048, 1024), nn.ReLU(), nn.Linear(1024, 512), nn.ReLU(), nn.Linear(512, 256), nn.ReLU(), nn.Linear(256, 10) ).cuda() optimizer = optim.Adam(model.parameters()) criterion = nn.CrossEntropyLoss() print(f"Model parameters: {sum(p.numel() for p in model.parameters())}") # Training loop for epoch in range(100): # Large batch for 3g.40gb x = torch.randn(256, 2048).cuda() y = torch.randint(0, 10, (256,)).cuda() optimizer.zero_grad() output = model(x) loss = criterion(output, y) loss.backward() optimizer.step() if epoch % 10 == 0: print(f"Large Training - Epoch {epoch}, Loss: {loss.item():.4f}, GPU Memory: {torch.cuda.memory_allocated()/1e9:.2f}GB") time.sleep(3) print("Large training completed on 3g.40gb MIG instance") medium-training-script.py: | import torch import torch.nn as nn import torch.optim as optim import time import os print(f"=== MEDIUM TRAINING POD (2g.20gb) ===") print(f"Process ID: {os.getpid()}") print(f"GPU available: {torch.cuda.is_available()}") print(f"GPU count: {torch.cuda.device_count()}") if torch.cuda.is_available(): device = torch.cuda.current_device() print(f"Using GPU: {torch.cuda.get_device_name(device)}") print(f"GPU Memory: {torch.cuda.get_device_properties(device).total_memory / 1e9:.1f} GB") # Medium model for 2g.20gb instance model = nn.Sequential( nn.Linear(1024, 512), nn.ReLU(), nn.Linear(512, 256), nn.ReLU(), nn.Linear(256, 10) ).cuda() optimizer = optim.Adam(model.parameters()) criterion = nn.CrossEntropyLoss() print(f"Model parameters: {sum(p.numel() for p in model.parameters())}") # Training loop for epoch in range(100): # Medium batch for 2g.20gb x = torch.randn(128, 1024).cuda() y = torch.randint(0, 10, (128,)).cuda() optimizer.zero_grad() output = model(x) loss = criterion(output, y) loss.backward() optimizer.step() if epoch % 10 == 0: print(f"Medium Training - Epoch {epoch}, Loss: {loss.item():.4f}, GPU Memory: {torch.cuda.memory_allocated()/1e9:.2f}GB") time.sleep(4) print("Medium training completed on 2g.20gb MIG instance") small-inference-script.py: | import torch import torch.nn as nn import time import os print(f"=== SMALL INFERENCE POD (1g.10gb) ===") print(f"Process ID: {os.getpid()}") print(f"GPU available: {torch.cuda.is_available()}") print(f"GPU count: {torch.cuda.device_count()}") if torch.cuda.is_available(): device = torch.cuda.current_device() print(f"Using GPU: {torch.cuda.get_device_name(device)}") print(f"GPU Memory: {torch.cuda.get_device_properties(device).total_memory / 1e9:.1f} GB") # Small model for 1g.10gb instance model = nn.Sequential( nn.Linear(512, 256), nn.ReLU(), nn.Linear(256, 10) ).cuda() print(f"Model parameters: {sum(p.numel() for p in model.parameters())}") # Inference loop for i in range(200): with torch.no_grad(): # Small batch for 1g.10gb x = torch.randn(32, 512).cuda() output = model(x) prediction = torch.argmax(output, dim=1) if i % 20 == 0: print(f"Small Inference - Batch {i}, Predictions: {prediction[:5].tolist()}, GPU Memory: {torch.cuda.memory_allocated()/1e9:.2f}GB") time.sleep(2) print("Small inference completed on 1g.10gb MIG instance") --- # Pod 1: Large training workload (3g.40gb) apiVersion: v1 kind: Pod metadata: name: mig-large-training-pod namespace: mig-gpu labels: app: mig-large-training workload-type: training spec: restartPolicy: Never containers: - name: large-training-container image: nvcr.io/nvidia/pytorch:25.04-py3 command: ["python", "/scripts/large-training-script.py"] volumeMounts: - name: script-volume mountPath: /scripts readOnly: true resources: claims: - name: mig-large-claim resourceClaims: - name: mig-large-claim resourceClaimTemplateName: mig-large-template nodeSelector: node.kubernetes.io/instance-type: p4de.24xlarge nvidia.com/gpu.present: "true" tolerations: - key: nvidia.com/gpu operator: Exists effect: NoSchedule volumes: - name: script-volume configMap: name: mig-scripts-configmap defaultMode: 0755 --- # Pod 2: Medium training workload (2g.20gb) - can run on SAME GPU as Pod 1 apiVersion: v1 kind: Pod metadata: name: mig-medium-training-pod namespace: mig-gpu labels: app: mig-medium-training workload-type: training spec: restartPolicy: Never containers: - name: medium-training-container image: nvcr.io/nvidia/pytorch:25.04-py3 command: ["python", "/scripts/medium-training-script.py"] volumeMounts: - name: script-volume mountPath: /scripts readOnly: true resources: claims: - name: mig-medium-claim resourceClaims: - name: mig-medium-claim resourceClaimTemplateName: mig-medium-template nodeSelector: node.kubernetes.io/instance-type: p4de.24xlarge nvidia.com/gpu.present: "true" tolerations: - key: nvidia.com/gpu operator: Exists effect: NoSchedule volumes: - name: script-volume configMap: name: mig-scripts-configmap defaultMode: 0755 --- # Pod 3: Small inference workload (1g.10gb) - can run on SAME GPU as Pod 1 & 2 apiVersion: v1 kind: Pod metadata: name: mig-small-inference-pod namespace: mig-gpu labels: app: mig-small-inference workload-type: inference spec: restartPolicy: Never containers: - name: small-inference-container image: nvcr.io/nvidia/pytorch:25.04-py3 command: ["python", "/scripts/small-inference-script.py"] volumeMounts: - name: script-volume mountPath: /scripts readOnly: true resources: claims: - name: mig-small-claim resourceClaims: - name: mig-small-claim resourceClaimTemplateName: mig-small-template nodeSelector: node.kubernetes.io/instance-type: p4de.24xlarge nvidia.com/gpu.present: "true" tolerations: - key: nvidia.com/gpu operator: Exists effect: NoSchedule volumes: - name: script-volume configMap: name: mig-scripts-configmap defaultMode: 0755 -
Aplique essa especificação, que deve implantar três pods:
kubctl apply -f mig-pod.yamlEsses pods devem ser programados pelo driver do DRA.
-
Verifique os registros do pod do driver DRA e você verá uma saída semelhante a esta:
I0717 21:50:22.925811 1 driver.go:87] NodePrepareResource is called: number of claims: 1 I0717 21:50:22.932499 1 driver.go:129] Returning newly prepared devices for claim '933e9c72-6fd6-49c5-933c-a896407dc6d1': [&Device{RequestNames:[mig-large],PoolName:ip-100-64-173-145.ec2.internal,DeviceName:gpu-0-mig-9-4-4,CDIDeviceIDs:[k8s.gpu.nvidia.com/device=**gpu-0-mig-9-4-4**],}] I0717 21:50:23.186472 1 driver.go:87] NodePrepareResource is called: number of claims: 1 I0717 21:50:23.191226 1 driver.go:129] Returning newly prepared devices for claim '61e5ddd2-8c2e-4c19-93ae-d317fecb44a4': [&Device{RequestNames:[mig-medium],PoolName:ip-100-64-173-145.ec2.internal,DeviceName:gpu-2-mig-14-0-2,CDIDeviceIDs:[k8s.gpu.nvidia.com/device=**gpu-2-mig-14-0-2**],}] I0717 21:50:23.450024 1 driver.go:87] NodePrepareResource is called: number of claims: 1 I0717 21:50:23.455991 1 driver.go:129] Returning newly prepared devices for claim '1eda9b2c-2ea6-401e-96d0-90e9b3c111b5': [&Device{RequestNames:[mig-small],PoolName:ip-100-64-173-145.ec2.internal,DeviceName:gpu-1-mig-19-2-1,CDIDeviceIDs:[k8s.gpu.nvidia.com/device=**gpu-1-mig-19-2-1**],}] -
Verifique o
resourceclaimspara ver o status do pod:kubectl get resourceclaims -n mig-gpu -wA seguir está um exemplo de saída:
NAME STATE AGE mig-large-training-pod-mig-large-claim-6dpn8 pending 0s mig-large-training-pod-mig-large-claim-6dpn8 pending 0s mig-large-training-pod-mig-large-claim-6dpn8 allocated,reserved 0s mig-medium-training-pod-mig-medium-claim-bk596 pending 0s mig-medium-training-pod-mig-medium-claim-bk596 pending 0s mig-medium-training-pod-mig-medium-claim-bk596 allocated,reserved 0s mig-small-inference-pod-mig-small-claim-d2t58 pending 0s mig-small-inference-pod-mig-small-claim-d2t58 pending 0s mig-small-inference-pod-mig-small-claim-d2t58 allocated,reserved 0sComo você pode ver, todos os pods foram movidos de pendentes para
allocated,reservedo driver DRA. -
Execute
nvidia-smia partir do nodo. Você notará que três processadores Python estão em execução:root@ip-100-64-173-145 bin]# nvidia-smi +-----------------------------------------------------------------------------------------+ | NVIDIA-SMI 570.158.01 Driver Version: 570.158.01 CUDA Version: 12.8 | |-----------------------------------------+------------------------+----------------------+ | GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. | | | | MIG M. | |=========================================+========================+======================| | 0 NVIDIA A100-SXM4-80GB On | 00000000:10:1C.0 Off | On | | N/A 63C P0 127W / 400W | 569MiB / 81920MiB | N/A Default | | | | Enabled | +-----------------------------------------+------------------------+----------------------+ | 1 NVIDIA A100-SXM4-80GB On | 00000000:10:1D.0 Off | On | | N/A 56C P0 121W / 400W | 374MiB / 81920MiB | N/A Default | | | | Enabled | +-----------------------------------------+------------------------+----------------------+ | 2 NVIDIA A100-SXM4-80GB On | 00000000:20:1C.0 Off | On | | N/A 63C P0 128W / 400W | 467MiB / 81920MiB | N/A Default | | | | Enabled | +-----------------------------------------+------------------------+----------------------+ | 3 NVIDIA A100-SXM4-80GB On | 00000000:20:1D.0 Off | On | | N/A 57C P0 118W / 400W | 249MiB / 81920MiB | N/A Default | | | | Enabled | +-----------------------------------------+------------------------+----------------------+ | 4 NVIDIA A100-SXM4-80GB On | 00000000:90:1C.0 Off | 0 | | N/A 51C P0 77W / 400W | 0MiB / 81920MiB | 0% Default | | | | Disabled | +-----------------------------------------+------------------------+----------------------+ | 5 NVIDIA A100-SXM4-80GB On | 00000000:90:1D.0 Off | 0 | | N/A 46C P0 69W / 400W | 0MiB / 81920MiB | 0% Default | | | | Disabled | +-----------------------------------------+------------------------+----------------------+ | 6 NVIDIA A100-SXM4-80GB On | 00000000:A0:1C.0 Off | 0 | | N/A 52C P0 74W / 400W | 0MiB / 81920MiB | 0% Default | | | | Disabled | +-----------------------------------------+------------------------+----------------------+ | 7 NVIDIA A100-SXM4-80GB On | 00000000:A0:1D.0 Off | 0 | | N/A 47C P0 72W / 400W | 0MiB / 81920MiB | 0% Default | | | | Disabled | +-----------------------------------------+------------------------+----------------------+ +-----------------------------------------------------------------------------------------+ | MIG devices: | +------------------+----------------------------------+-----------+-----------------------+ | GPU GI CI MIG | Memory-Usage | Vol| Shared | | ID ID Dev | BAR1-Usage | SM Unc| CE ENC DEC OFA JPG | | | | ECC| | |==================+==================================+===========+=======================| | 0 2 0 0 | 428MiB / 40192MiB | 42 0 | 3 0 2 0 0 | | | 2MiB / 32767MiB | | | +------------------+----------------------------------+-----------+-----------------------+ | 0 3 0 1 | 71MiB / 19968MiB | 28 0 | 2 0 1 0 0 | | | 0MiB / 16383MiB | | | +------------------+----------------------------------+-----------+-----------------------+ | 0 9 0 2 | 36MiB / 9728MiB | 14 0 | 1 0 0 0 0 | | | 0MiB / 8191MiB | | | +------------------+----------------------------------+-----------+-----------------------+ | 0 10 0 3 | 36MiB / 9728MiB | 14 0 | 1 0 0 0 0 | | | 0MiB / 8191MiB | | | +------------------+----------------------------------+-----------+-----------------------+ | 1 1 0 0 | 107MiB / 40192MiB | 42 0 | 3 0 2 0 0 | | | 0MiB / 32767MiB | | | +------------------+----------------------------------+-----------+-----------------------+ | 1 5 0 1 | 71MiB / 19968MiB | 28 0 | 2 0 1 0 0 | | | 0MiB / 16383MiB | | | +------------------+----------------------------------+-----------+-----------------------+ | 1 13 0 2 | 161MiB / 9728MiB | 14 0 | 1 0 0 0 0 | | | 2MiB / 8191MiB | | | +------------------+----------------------------------+-----------+-----------------------+ | 1 14 0 3 | 36MiB / 9728MiB | 14 0 | 1 0 0 0 0 | | | 0MiB / 8191MiB | | | +------------------+----------------------------------+-----------+-----------------------+ | 2 1 0 0 | 107MiB / 40192MiB | 42 0 | 3 0 2 0 0 | | | 0MiB / 32767MiB | | | +------------------+----------------------------------+-----------+-----------------------+ | 2 5 0 1 | 289MiB / 19968MiB | 28 0 | 2 0 1 0 0 | | | 2MiB / 16383MiB | | | +------------------+----------------------------------+-----------+-----------------------+ | 2 13 0 2 | 36MiB / 9728MiB | 14 0 | 1 0 0 0 0 | | | 0MiB / 8191MiB | | | +------------------+----------------------------------+-----------+-----------------------+ | 2 14 0 3 | 36MiB / 9728MiB | 14 0 | 1 0 0 0 0 | | | 0MiB / 8191MiB | | | +------------------+----------------------------------+-----------+-----------------------+ | 3 1 0 0 | 107MiB / 40192MiB | 42 0 | 3 0 2 0 0 | | | 0MiB / 32767MiB | | | +------------------+----------------------------------+-----------+-----------------------+ | 3 5 0 1 | 71MiB / 19968MiB | 28 0 | 2 0 1 0 0 | | | 0MiB / 16383MiB | | | +------------------+----------------------------------+-----------+-----------------------+ | 3 13 0 2 | 36MiB / 9728MiB | 14 0 | 1 0 0 0 0 | | | 0MiB / 8191MiB | | | +------------------+----------------------------------+-----------+-----------------------+ | 3 14 0 3 | 36MiB / 9728MiB | 14 0 | 1 0 0 0 0 | | | 0MiB / 8191MiB | | | +------------------+----------------------------------+-----------+-----------------------+ +-----------------------------------------------------------------------------------------+ | Processes: | | GPU GI CI PID Type Process name GPU Memory | | ID ID Usage | |=========================================================================================| **| 0 2 0 64080 C python 312MiB | | 1 13 0 64085 C python 118MiB | | 2 5 0 64073 C python 210MiB |** +-----------------------------------------------------------------------------------------+
Otimize cargas de trabalho de GPU com IMEX usando instâncias GB200 P6e
O IMEX (Internode Memory Exchange) permite a comunicação coerente com a memória entre os nós para treinamento distribuído na NVIDIA GB200. UltraServers
Execute as etapas a seguir.
-
Defina um
ComputeDomainpara treinamento de vários nós com um arquivo chamadoimex-compute-domain.yaml:apiVersion: resource.nvidia.com/v1beta1 kind: ComputeDomain metadata: name: distributed-training-domain namespace: default spec: numNodes: 2 channel: resourceClaimTemplate: name: imex-channel-template -
Defina um pod usando canais IMEX com um arquivo chamado
imex-pod.yaml:apiVersion: v1 kind: Pod metadata: name: imex-distributed-training namespace: default labels: app: imex-training spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: nvidia.com/gpu.clique operator: Exists containers: - name: distributed-training image: nvcr.io/nvidia/pytorch:25.04-py3 command: ["bash", "-c"] args: - | echo "=== IMEX Channel Verification ===" ls -la /dev/nvidia-caps-imex-channels/ echo "" echo "=== GPU Information ===" nvidia-smi echo "" echo "=== NCCL Test (if available) ===" python -c " import torch import torch.distributed as dist import os print(f'CUDA available: {torch.cuda.is_available()}') print(f'CUDA device count: {torch.cuda.device_count()}') if torch.cuda.is_available(): for i in range(torch.cuda.device_count()): print(f'GPU {i}: {torch.cuda.get_device_name(i)}') # Check for IMEX environment variables imex_vars = [k for k in os.environ.keys() if 'IMEX' in k or 'NVLINK' in k] if imex_vars: print('IMEX Environment Variables:') for var in imex_vars: print(f' {var}={os.environ[var]}') print('IMEX channel verification completed') " # Keep container running for inspection sleep 3600 resources: claims: - name: imex-channel-0 - name: imex-channel-1 resourceClaims: - name: imex-channel-0 resourceClaimTemplateName: imex-channel-template - name: imex-channel-1 resourceClaimTemplateName: imex-channel-template tolerations: - key: nvidia.com/gpu operator: Exists effect: NoSchedulenota
Isso requer instâncias P6e GB200.
-
Implante o IMEX aplicando os modelos
ComputeDomaine:kubectl apply -f imex-claim-template.yaml kubectl apply -f imex-compute-domain.yaml kubectl apply -f imex-pod.yaml -
Verifique o
ComputeDomainstatus.kubectl get computedomain distributed-training-domain -
Monitore a implantação do daemon IMEX.
kubectl get pods -n nvidia-dra-driver -l resource.nvidia.com/computeDomain -
Confira os canais IMEX no Pod:
kubectl exec imex-distributed-training -- ls -la /dev/nvidia-caps-imex-channels/ -
Veja os registros do pod:
kubectl logs imex-distributed-trainingVeja a seguir um exemplo da saída esperada:
=== IMEX Channel Verification === total 0 drwxr-xr-x. 2 root root 80 Jul 8 10:45 . drwxr-xr-x. 6 root root 380 Jul 8 10:45 .. crw-rw-rw-. 1 root root 241, 0 Jul 8 10:45 channel0 crw-rw-rw-. 1 root root 241, 1 Jul 8 10:45 channel1
Para obter mais informações, consulte o exemplo da NVIDIA