Autoscaling de IA no Kubernetes com KEDA e Métricas do vLLM (Adeus HPA por CPU) começa por reconhecer um descompasso comum: o pod pode exibir pouca atividade de CPU enquanto a GPU permanece ocupada e novas solicitações esperam na fila. Nesse quadro, escalar com base apenas em CPU ou memória não acompanha a pressão que o usuário sente.
Uma alternativa é orientar a escala por sinais mais próximos do trabalho de inferência, como solicitações aguardando atendimento e vazão de geração de tokens. A configuração, porém, precisa considerar o tempo entre criar um pod e deixá-lo pronto: carregar o modelo na VRAM pode atrasar a resposta a um pico.
Por que CPU não é o sinal certo para escalar inferência
O que CPU e memória deixam de mostrar
CPU e memória descrevem aspectos importantes do pod, mas não medem diretamente quantas solicitações de inferência ele consegue atender naquele momento. Se o modelo já está carregado e a GPU executa geração, os indicadores de CPU podem continuar relativamente estáveis enquanto o trabalho se acumula para processamento.
Imagine um serviço que recebe uma sequência de solicitações, cada uma aguardando a vez de ser atendida pelo mecanismo de inferência. A GPU pode estar ocupada, mas esse fato não precisa produzir um aumento proporcional no uso da CPU. A memória também pode parecer estável, pois o modelo já alocado ocupa espaço sem que esse número revele se há capacidade livre para novas solicitações.
Fila e latência como sinais de pressão
Utilização de recurso e capacidade de atendimento são coisas diferentes. Uma leitura de CPU informa quanto processamento daquele tipo está sendo usado; não indica, sozinha, se o serviço consegue acompanhar a entrada de solicitações ou reduzir o tempo de espera.
Quando a fila cresce, a experiência pode piorar antes que CPU ou memória atinjam qualquer condição que dispare o HPA. O usuário pode esperar mais pela primeira resposta e pela geração dos tokens seguintes, mesmo que o pod pareça tranquilo em um painel centrado nesses recursos.
Autoscaling orientado por demanda aproxima a decisão da pressão do serviço. A fila pode mostrar solicitações sem atendimento, enquanto métricas de geração ajudam a entender o trabalho que a capacidade atual está realizando. Esses sinais não substituem o acompanhamento de CPU, memória e GPU; mudam o papel deles, de gatilho isolado para contexto operacional.
Escolha métricas do vLLM que representem a demanda
vllm:num_requests_waiting
A métrica vllm:num_requests_waiting representa solicitações aguardando atendimento no vLLM. Para autoscaling, esse sinal é útil porque evidencia uma demanda que a capacidade ativa ainda não absorveu. Se o valor sobe e permanece elevado, existe motivo para investigar se novos pods ajudariam a reduzir a espera.
Uma fila momentânea, porém, não prova que seja necessário escalar imediatamente. Ela pode refletir uma chegada curta de solicitações, uma limitação externa ou outra condição transitória. Por isso, a equipe precisa observar como a métrica se comporta ao longo do tempo e confrontá-la com a disponibilidade real de recursos e com a prontidão dos pods.
vllm:avg_generation_throughput_tok_per_s
vllm:avg_generation_throughput_tok_per_s expressa a vazão média de geração em tokens por segundo. Ela descreve produção de tokens, não o tempo total percebido por cada pessoa. Tratar vazão como sinônimo direto de latência esconderia etapas como espera na fila, preparação da resposta e variação entre solicitações.
As métricas ficam mais úteis quando lidas em conjunto. Uma fila crescente acompanhada de vazão que não acompanha a demanda sugere pressão sobre a capacidade de processamento. Já uma fila curta com vazão variável pode apontar para um pico passageiro ou para um padrão de solicitações diferente, sem justificar automaticamente mais réplicas.
Antes de conectar qualquer consulta ao KEDA, confira os nomes e a disponibilidade das métricas na exposição Prometheus da versão e da configuração em uso. O endpoint do vLLM precisa realmente fornecer o sinal esperado, e a consulta Prometheus precisa retornar dados no formato que o escalador consegue interpretar.
Separe os sinais de escala dos indicadores de experiência ponta a ponta. Fila e vazão podem alimentar decisões operacionais; latência percebida, erros, pods prontos e disponibilidade ajudam a explicar se a inferência está atendendo bem. Um painel que misture essas funções sem distingui-las pode levar a ajustes equivocados.
Arquitetura: Prometheus, KEDA e pods de inferência
Fluxo da métrica até a decisão de escala
O vLLM expõe métricas em um endpoint que o Prometheus pode coletar. O KEDA consulta a fonte de métricas associada ao ScaledObject e usa o resultado para orientar a escala do workload no Kubernetes. Quando a quantidade de pods muda, o agendador tenta colocar os novos pods nos nós com recursos compatíveis.
Responsabilidades de cada componente
O Prometheus coleta e consulta séries temporais; não decide por conta própria quantas réplicas o workload deve ter. O KEDA associa a fonte de métricas a um alvo escalável por meio do ScaledObject, enquanto o Kubernetes executa as mudanças e tenta agendar os pods.
A decisão de aumentar réplicas não garante que elas serão executadas. Se faltarem GPUs disponíveis, se os limites do cluster impedirem o agendamento ou se os nós não tiverem recursos compatíveis, a escala desejada pode não virar capacidade utilizável. Acompanhe eventos do Kubernetes junto com as métricas para distinguir decisão de escala de pod efetivamente pronto.
Configure o KEDA ScaledObject com métricas do vLLM
Mapeie a métrica e defina o alvo
O exemplo abaixo ilustra a estrutura de um ScaledObject ligado a uma consulta Prometheus de fila. Os nomes entre colchetes são marcadores: substitua-os pelos valores do ambiente e confira os campos conforme a versão e a integração adotadas.
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata: name: [nome-do-scaledobject] / namespace: [namespace-do-workload]
spec: scaleTargetRef: name: [deployment-vllm]
triggers: type: prometheus
metadata: serverAddress: [endpoint-prometheus] / metricName: requests_waiting / query: [consulta-para-vllm:num_requests_waiting] / threshold: [alvo-operacional]
A consulta transforma a série exposta pelo Prometheus em um valor que o KEDA pode comparar com o alvo configurado. Escreva a expressão para representar a fila relevante do serviço, não um agregado acidental que some workloads distintos ou inclua séries que não correspondem às réplicas escaladas.
O alvo não tem um valor universal. Ele depende da capacidade observada do modelo, do padrão das solicitações, do tempo de carregamento e do nível de espera que a equipe aceita. Para defini-lo, faça testes controlados, observe como a fila evolui sob carga e verifique quando uma réplica adicional começa a atender tráfego.
Valide a configuração antes de confiar nela
Use vllm:avg_generation_throughput_tok_per_s como contexto para interpretar a fila, não como uma regra isolada que determine escala sem considerar o restante do serviço. Se a fila cresce enquanto a vazão não acompanha a demanda, a equipe pode investigar capacidade insuficiente; se os sinais divergem, examine o padrão de tráfego e a saúde dos pods antes de alterar o alvo.
Revise namespace, endereço do Prometheus, autenticação, consulta e referência do Deployment. Um ScaledObject no namespace errado ou um alvo com nome incorreto pode deixar o serviço sem a decisão esperada, ainda que as métricas existam e apareçam em um painel.
Defina também o comportamento diante de métrica ausente. Uma consulta sem série não deve ser interpretada automaticamente como fila vazia. Verifique como o KEDA sinaliza falhas de consulta e estabeleça alertas para indisponibilidade da fonte, para que um defeito de observabilidade não pareça queda de demanda.
Ajuste a velocidade de escala ao cold start do modelo
Por que um pod novo não atende imediatamente
Criar um pod e obter capacidade de inferência são etapas diferentes. O novo processo precisa ser agendado em um nó adequado, iniciar o serviço e carregar o modelo na VRAM antes de receber solicitações. Durante esse intervalo, o contador de réplicas pode aumentar sem que a fila diminua.
Se a política só reagir depois que a fila crescer bastante, um pico rápido pode terminar ou causar espera prolongada antes da nova capacidade ficar pronta. A equipe deve medir o intervalo real entre o sinal de pressão, a criação do pod e sua disponibilidade para atendimento, em vez de supor que uma réplica nova começa a servir imediatamente.
Equilibre reação, capacidade e estabilidade
Uma margem de capacidade preparada pode ajudar a absorver variações que chegam antes do fim do carregamento do modelo. Manter essa folga tem custo de recursos, portanto a decisão depende do perfil de tráfego, do tempo de cold start e do impacto de esperar na fila. Compare os períodos de pico e os intervalos de menor demanda antes de escolher a política.
Também ajuste a reação do escalador para evitar oscilações. Se a fila sobe e desce rapidamente, decisões baseadas em cada variação podem alternar réplicas antes que a nova capacidade produza efeito. Considere o comportamento observado da fila e o tempo necessário para o pod ficar pronto ao definir metas e regras de escala.
Readiness precisa indicar capacidade real de receber tráfego, não apenas que o contêiner iniciou. Se o pod ainda carrega o modelo, integrá-lo cedo demais ao balanceamento pode direcionar solicitações para uma réplica incapaz de atendê-las. Verifique que a condição de prontidão e a integração com o balanceamento acompanham o estado efetivo do serviço.
Teste opções em condições controladas. Uma carga que reproduza picos e períodos de retomada ajuda a comparar a fila, a quantidade de pods prontos e o custo de manter capacidade ociosa. Faça ajustes graduais, registrando qual mudança alterou o tempo de espera e qual apenas aumentou réplicas sem melhorar o atendimento.
Valide o autoscaling com observabilidade e testes
Acompanhe fila, tokens e disponibilidade
Monte um painel que mostre vllm:num_requests_waiting e vllm:avg_generation_throughput_tok_per_s junto com latência percebida, pods prontos e eventos de escala. Essa combinação ajuda a responder se a fila está aumentando, se a vazão mudou e se a capacidade solicitada já está efetivamente disponível.
Olhe para o intervalo entre os eventos, não apenas para valores isolados. Se a fila aumenta antes de novos pods ficarem prontos, o atraso pode estar no cold start ou no agendamento. Se o número de pods cresce, mas a fila persiste, verifique também a disponibilidade de GPU e a capacidade de processamento observada.
Teste falhas e cenários de pico
Execute testes controlados que registrem o crescimento da fila, a decisão do KEDA, a criação dos pods e o momento em que a nova capacidade atende solicitações. Inclua um caso em que o Prometheus deixe de fornecer a métrica e outro em que não haja GPU disponível para agendamento. O objetivo é ver como o sistema e os alertas se comportam, não apenas confirmar uma escala bem-sucedida.
Trate métrica ausente como um estado diferente de fila igual a zero. Uma falha no endpoint, na coleta ou na consulta pode produzir dados ausentes sem que a demanda tenha desaparecido. A resposta operacional deve ajudar a identificar a fonte do problema, em vez de deixar uma decisão de escala depender de uma interpretação silenciosa.
Relacione alertas e painéis a hipóteses verificáveis. Por exemplo, fila crescente com pods pendentes pode apontar para restrição de agendamento; fila crescente com pods prontos pede investigação da capacidade de inferência ou do padrão de solicitações. Essa leitura orienta a investigação sem tomar correlação como prova de causa.
Checklist para levar o autoscaling à operação
Erros comuns antes da produção
Antes de habilitar a escala, confirme que o endpoint do vLLM expõe as métricas esperadas e que a consulta Prometheus retorna a série correta. Verifique permissões do KEDA, namespace, autenticação e referência do workload; cada uma dessas partes pode impedir a decisão de alcançar o Deployment pretendido.
Não use CPU como substituta da pressão de inferência, nem trate vazão como sinônimo de latência. Confirme que há GPU disponível para agendar novas réplicas e que readiness só libera o pod quando ele consegue atender. Também confira o caminho de tráfego para garantir que a nova capacidade entra no balanceamento no momento certo.
Próximos passos para evoluir a configuração
Defina como a equipe vai revisar o alvo, a reação a picos e o comportamento durante indisponibilidade de métricas. Registre quem investiga fila persistente, pods pendentes e consultas sem dados, além de quais painéis e eventos devem ser consultados em cada situação.
Comece com uma configuração observável e uma carga controlada. Compare fila, vazão, latência percebida e tempo até a prontidão, alterando uma variável por vez para entender o efeito. Quando o comportamento estiver claro, leve os mesmos alertas e procedimentos para a operação e revise o alvo com dados do próprio serviço.
Perguntas frequentes
KEDA substitui o HPA no Kubernetes?
Não necessariamente. O KEDA pode conectar eventos e métricas a recursos escaláveis do Kubernetes; a decisão depende de como o workload e os sinais de escala foram configurados. A ideia aqui é deixar de usar CPU como único indicador para a demanda de inferência.
Posso usar vllm:avg_generation_throughput_tok_per_s sozinha para escalar?
É arriscado interpretar vazão sem contexto: ela não informa, por si só, se há solicitações esperando nem qual é a latência percebida. Combine-a com sinais de fila e disponibilidade do serviço.
O que acontece se a métrica de fila desaparecer?
O comportamento depende da consulta, do scaler e das políticas configuradas. Trate a ausência como uma condição operacional que precisa ser observável e testada, não como se a fila estivesse vazia.
Escalar pods garante que haverá GPUs disponíveis?
Não. O autoscaler pode solicitar mais réplicas, mas o agendamento ainda depende dos recursos e das restrições do cluster. Acompanhe pods pendentes e disponibilidade de GPU junto com as métricas de inferência.
Como considerar o tempo de carregamento do modelo na VRAM?
Meça o intervalo entre a criação do pod e sua prontidão para atender tráfego, e avalie a política de escala à luz desse atraso. Uma réplica criada não deve ser contabilizada como capacidade útil antes de estar pronta.
Sou um profissional na área de Tecnologia da informação, especializado em monitoramento de ambientes, Sysadmin e na cultura DevOps. Possuo certificações de Segurança, AWS e Zabbix.
