Ajudar a melhorar esta página
Para contribuir com este guia de usuário, escolha o link Editar esta página no GitHub, disponível no painel direito de cada página.
Inferência de modelos de IA em escala automática em GPUs com o Amazon EKS
dica
Registre-se
Esta seção aborda os conceitos e procedimentos para ajustar a escala automaticamente de workloads de inferência de IA em GPUs com o Amazon EKS.
A réplica única do modelo vLLM que você implantou na seção anterior, Carregar e disponibilizar modelos, consegue atender a um número limitado de requisições simultâneas antes que as novas comecem a esperar, o que aumenta a latência e pode causar o esgotamento do tempo limite nas requisições. Para acompanhar o tráfego, você pode escalar automaticamente a implantação horizontalmente. O ajuste de escala automático adiciona réplicas de workloads à medida que a demanda aumenta e as remove à medida que a demanda diminui para que você possa evitar o superprovisionamento da capacidade da GPU.
O ajuste de escala automático de inferência ocorre em dois estágios.
-
Escalabilidade de nós: quando o programador do Kubernetes não tem espaço para colocar novos pods nos nós existentes, os pods ficam
Pending. O Karpenter responde a podsPendingprovisionando nós com GPU para acomodá-los e remove os nós quando as réplicas das workloads são reduzidas. -
Escalabilidade de pods: o Horizontal Pod Autoscaler
(HPA) monitora uma métrica configurada. Quando essa métrica ultrapassa um limite configurado, o HPA aumenta a contagem de réplicas de workloads e novos pods do vLLM são criados.
O estágio de escalabilidade de nós fornece a capacidade de GPU de que as réplicas de workloads precisam para serem executadas. O estágio de escalabilidade de pods ajusta o número de réplicas de workloads para manter a métrica escolhida próxima da meta.
Provisionamento de nós de GPU com o Karpenter
O Karpenter gerencia o ciclo de vida dos nós, provisionando nós quando as workloads precisam deles e consolidando ou removendo nós quando não precisam. Ele funciona com o agendador do Kubernetes em vez de substituí-lo. O agendador aloca pods nos nós. O Karpenter provisiona a capacidade para os pods que o agendador não consegue acomodar e, em seguida, permite que o agendador os vincule quando o nó estiver Ready.
O Karpenter lida com os nós de GPU de forma diferente de uma frota de nós de CPU.
- As GPUs são solicitadas como unidades inteiras
-
A menos que você use uma técnica de compartilhamento de GPU, como fatiamento de tempo ou MIG, um pod obtém uma ou mais GPUs inteiras em vez de uma fração, como faria com a CPU ou a memória. Cada GPU tem sua própria memória dedicada, portanto, as réplicas no mesmo nó não compartilham a memória da GPU. A forma como isso é mapeado para os nós depende do tipo de instância:
-
Instância de GPU única (como
g6.xlarge): o nó contém exatamente uma réplica. Réplicas, GPUs e nós escalam individualmente, e cada réplica é isolada em sua própria instância. -
Instância de várias GPUs (como
g6.12xlarge, que tem 4 GPUs): o plug-in de dispositivo anuncia a contagem total de GPUs para que o Karpenter possa empacotar várias réplicas em um nó, uma por GPU. -
Pod com várias GPUs: um pod pode solicitar mais de uma GPU. Por exemplo, configure
nvidia.com/gpu: 2para fragmentar um modelo grande em duas GPUs, e o Karpenter colocará o pod em um nó com essa quantidade de GPUs livres.
-
- O Karpenter otimiza a disponibilidade e o custo de GPUs
-
O Karpenter equilibra a alocação de capacidade escassa de GPU com a execução de baixo custo:
-
Seleção de instância: com um NodePool flexível, o Karpenter seleciona o tipo de instância de menor custo que atenda aos pods
Pending. Quando uma inicialização encontra capacidade insuficiente, ela tenta automaticamente outros tipos de instância e zonas de disponibilidade, o que aumenta as chances de alocar capacidade de GPU. -
Consolidação: quando a demanda cai e as réplicas têm sua escala reduzida horizontalmente, o Karpenter recupera os nós liberados.
WhenEmptyOrUnderutilizedremove nós vazios e reempacota réplicas em menos nós, enquantoWhenEmptyrecupera um nó somente depois que nada está programado nele. -
Proteção de pods em andamento: para evitar que os pods sejam interrompidos durante a consolidação, adicione a anotação
karpenter.sh/do-not-disrupt, defina um PodDisruptionBudget ou use a configuraçãoconsolidateAfterpara atrasar a consolidação.
-
Assim que o Karpenter disponibiliza a capacidade de GPU, a etapa de escalabilidade de pods assume o controle: o HPA adiciona e remove réplicas com base na métrica configurada. O restante desta seção aborda como escolher essa métrica de escalabilidade para workloads de inferência.
Escalabilidade automática de GPU vs CPU
No Kubernetes, as workloads tradicionais baseadas em CPU são escaladas automaticamente, mas a inferência baseada em GPU não. Existem três diferenças principais:
Disponibilidade de métricas para ajuste de escala automático
- O Kubernetes fornece métricas de CPU e memória ao HPA prontas para uso
-
O kubelet em cada nó indica o uso da CPU e da memória para a API de métricas do Kubernetes para que o HPA possa ler esses valores diretamente e escalar as workloads sem componentes adicionais.
- Workloads aceleradas exigem configurações, exportadores e adaptadores adicionais de métricas
-
O kubelet não reporta métricas de GPU ou inferência. Para escalar a inferência baseada em GPU, você deve adicionar exportadores que publiquem os sinais relevantes, como métricas da aplicação do vLLM e métricas de GPU do exportador DCGM, além de adaptadores que exponham essas métricas para o HPA.
Alocação e compartilhamento de recursos
- As workloads tradicionais compartilham CPU e memória em frações
-
Os cgroups do Linux dividem a CPU e a memória em recursos fracionários, permitindo que vários pods compartilhem o mesmo nó. Um pod pode solicitar uma parte da capacidade de um nó, como 100 millicores de CPU ou 512 MiB de memória.
- Workloads aceleradas alocam e compartilham GPUs por meio de um framework de alocação de GPU
-
As GPUs não são compartilhadas por meio de cgroups, como CPU e memória. Atualmente, a configuração mais comum do Kubernetes usa o plug-in de dispositivo da NVIDIA, que aloca GPUs inteiras aos pods (por exemplo,
nvidia.com/gpu: 1). A alocação dinâmica de recursos(DRA) é uma API Kubernetes mais recente que aloca GPUs por meio de declarações de recursos, fornecendo agendamento e gerenciamento de recursos mais flexíveis. Tanto o plug-in de dispositivo quanto o DRA podem ser compatíveis com técnicas de compartilhamento de GPU. O fatiamento de tempo permite que vários pods compartilhem uma GPU intercalando o acesso ao longo do tempo, enquanto a GPU de várias instâncias (MIG) particiona GPUs compatíveis, como NVIDIA A100 e H100, em instâncias de GPU isoladas por hardware.
Sinais de escalabilidade
- As workloads tradicionais geralmente são escaladas com base na utilização da CPU e da memória
-
A utilização é o sinal padrão de ajuste de escala automático para workloads de CPU e memória. É um indicador de atraso porque aumenta somente depois que a workload já está sob carga, mas para muitas aplicações tradicionais é suficiente para orientar as decisões de escalabilidade.
- As workloads aceleradas devem ser escaladas com base em métricas preditivas, não na utilização da GPU
-
A utilização da GPU (
DCGM_FI_DEV_GPU_UTIL) mostra se a GPU está ocupada, não o quão ocupada ela está. Como um servidor de inferência como o vLLM pode permanecer próximo de 100% em uma ampla variedade de requisições recebidas, a utilização é um sinal de ajuste de escala automático não confiável. Em vez disso, escale com base nos principais indicadores que aumentam à medida que a demanda se aproxima da capacidade, como profundidade da fila de requisições, tempo até o primeiro token (TTFT) e latência da requisição.
Dessas três diferenças abordadas acima, considere cuidadosamente seus sinais de escalabilidade. Como a utilização da GPU não é um sinal de alta confiança da capacidade de inferência restante, você precisa identificar e coletar sinais que rastreiem a demanda real no servidor de inferência do modelo.
A próxima seção aborda quais sinais usar como métricas de escalabilidade e como eles funcionam juntos.
Escolha de métricas de escalabilidade
Nenhuma métrica única informa quando escalar suas réplicas de inferência do modelo, então você escala com base em uma combinação de sinais do servidor de inferência. Esses sinais funcionam juntos, cada um baseado no anterior para capturar a demanda mais cedo e de forma mais confiável do que qualquer métrica isolada:
| Signal | Métrica | Função na escalabilidade |
|---|---|---|
|
Fila |
Profundidade da fila de requisições (número de requisições aguardando para serem processadas) |
Um indicador importante e o melhor acionador padrão, porque uma fila se forma no momento em que a demanda excede a capacidade. |
|
Latência |
Latência de requisição (latência p95 ou TTFT) |
Aciona a escalabilidade quando as respostas são lentas, mesmo que a fila ainda não tenha sido criada, mantendo a latência voltada para o usuário dentro da meta. |
|
Memória da GPU |
Utilização do KV cache (quão cheia está a memória de requisição da GPU) |
Protege contra a falta de memória da GPU; à medida que se aproxima do limite, o servidor começa a rejeitar ou enfileirar requisições. |
Juntos, eles formam camadas de defesa: a profundidade da fila de requisições é o principal gatilho que é acionado no momento em que a demanda ultrapassa a capacidade, a latência da requisição adiciona uma verificação de respostas lentas antes que a fila se forme e a utilização do KV cache é a salvaguarda que evita a falta de memória da GPU.
Aplicação de tudo na prática
As subseções a seguir mostram como colocar esses sinais em funcionamento com um autoescalador específico.
-
Encontrar limites de métricas de escalabilidade. Teste de carga de uma única réplica do vLLM para encontrar seu teto de capacidade e os limites de profundidade de fila e latência para escalar. Comece aqui.
-
Escalar com o HPA e KEDA. Ajuste a escala automaticamente das réplicas do vLLM com o KEDA e o Horizontal Pod Autoscaler usando a profundidade da fila de requisições e a latência de ponta a ponta como sinais de escalabilidade.