O número da demonstração não é a capacidade do serviço
Um modelo que gera texto depressa para uma única pessoa não tem, por esse motivo, capacidade demonstrada para uma equipa. Uma demonstração isolada costuma partir de um pedido curto, sem fila, com a cache e o processo já aquecidos e sem outras conversas a reter memória. Um serviço partilhado opera em condições diferentes: os pedidos chegam a ritmos irregulares, têm entradas e saídas heterogéneas, competem pela memória da GPU e aguardam quando o sistema não consegue executá-los de imediato.
A capacidade útil não deve ser comunicada como um único número de tokens por segundo. Convém exprimi-la como um compromisso condicionado: para cenários definidos de entrada e saída, uma determinada concorrência mantém objetivos de tempo até ao primeiro token, tempo total de resposta e taxa de rejeição ou espera. Esta formulação permite confrontar uma promessa interna com um teste repetível e evita extrapolações a partir de uma demonstração favorável.
No serving de modelos generativos, existem métricas distintas para o tempo em fila, o tempo até ao primeiro token, o tempo de geração, a latência entre tokens e a latência de ponta a ponta. Esta separação é importante porque duas configurações com o mesmo desempenho médio podem proporcionar experiências muito diferentes: uma pode começar a responder cedo, mas terminar lentamente; outra pode atrasar o início devido à acumulação de trabalho. Os guias de modelos locais e as comparações de runtimes devem analisar estas dimensões separadamente antes de recomendar uma configuração.
A pergunta operacional também não é apenas «quantas pessoas existem na empresa?». É «quantos pedidos ativos, de que dimensão e com que objetivo de latência têm de ser sustentados ao mesmo tempo?». Trinta pessoas com utilização ocasional podem implicar uma concorrência reduzida. Em contrapartida, algumas automatizações que anexam documentos extensos ou produzem respostas longas podem saturar o mesmo servidor. A medição tem de representar estas cargas, e não uma noção abstrata de utilizador.
Defina o serviço antes de escolher ou expandir o hardware
Comece por descrever a procura esperada em unidades que o servidor consiga observar. Registe o número de pedidos ativos, e não apenas de utilizadores registados; a distribuição de tokens de entrada; o máximo permitido de saída; o tipo de tarefa; a taxa de chegadas; e os objetivos de disponibilidade e latência. Se não existir tráfego histórico, formule hipóteses explícitas e teste cenários conservadores. Uma estimativa não se torna um facto por ser apresentada com precisão numérica.
Separe pelo menos três classes de trabalho. O chat curto costuma ter poucas entradas e saídas moderadas. Uma consulta com recuperação aumentada pode incluir excertos de documentos e ter uma entrada considerável, embora a resposta seja curta. A redação, extração ou geração de código pode exigir saídas longas e manter a conversa ativa durante mais tempo. Misturá-las numa média única esconde os casos que consomem mais memória ou bloqueiam a fila.
Para cada classe, defina um orçamento: tokens de entrada típicos e máximos, tokens de saída típicos e máximos, pedidos simultâneos previstos e limites de experiência. O objetivo de latência deve incluir, no mínimo, o tempo até ao primeiro token e o tempo até à conclusão. Deve também decidir se um utilizador pode cancelar uma geração, o que acontece quando atinge um limite e se existem classes prioritárias. Sem estas regras, a capacidade depende de decisões implícitas tomadas pelo runtime sob pressão.
A comparação entre modelos locais só é útil depois de fixar este contrato de serviço. Um modelo menor pode permitir maior concorrência ou respostas mais previsíveis no mesmo hardware; outro modelo pode justificar-se pela qualidade numa carga concreta, mas exigir limites mais estritos. Não existe uma configuração universalmente suficiente: a decisão deve relacionar a qualidade necessária com resultados medidos segundo o seu próprio padrão de utilização.
Cenários iniciais a medir separadamente
| Cenário | Entrada e saída a controlar | Risco principal | Indicadores de aceitação |
|---|---|---|---|
| Chat curto | Entrada curta; saída limitada | Fila causada por picos | TTFT e tempo total nos percentis definidos |
| Consulta com recuperação | Entrada ampla de documentos; saída curta ou média | Prefill e ocupação da cache KV | TTFT, utilização da cache KV e pedidos em espera |
| Geração extensa | Entrada média; saída longa | Retenção prolongada de memória e decode | Tempo total, cancelamentos e degradação da fila |
Construa um orçamento de memória, mas não o confunda com uma garantia
A memória disponível para servir um modelo não se reduz ao tamanho publicado dos seus pesos. Tem de coexistir com os pesos carregados, a cache de chaves e valores das conversas ativas, buffers e espaço temporário de execução, estruturas do runtime e uma reserva para variações e recuperação. A distribuição exata depende do modelo, da quantização, do runtime, do hardware e da configuração; por isso, uma fórmula genérica não deve ser apresentada como se fosse uma medição universal.
A cache KV é decisiva para a concorrência. Conserva o estado de atenção necessário para continuar uma sequência e cresce com os tokens processados. Num serviço, a sua ocupação muda por pedido: uma conversa extensa, uma entrada recuperada de grande dimensão ou uma saída longa podem reter uma parte relevante da memória durante mais tempo do que uma pergunta curta. A investigação sobre PagedAttention identifica a gestão desta cache, incluindo a fragmentação e a duplicação em certos padrões, como um fator que condiciona o tamanho efetivo do lote.
É razoável usar um orçamento de trabalho para planear, desde que seja identificado como estimativa. Primeiro, meça a memória base com o modelo já carregado e sem tráfego. Depois, observe como ela muda ao executar cada cenário com comprimentos controlados e concorrência crescente. Reserve capacidade que não seja atribuída à carga nominal. Por fim, valide que a política de admissão impede que o limite seja ultrapassado durante um pico. O resultado relevante é o comportamento observado na configuração concreta, e não um cálculo isolado.
As métricas do runtime podem expor a utilização da cache KV, os pedidos em execução e os pedidos à espera, além de medidas de prefill e decode. Estas observações permitem atribuir um incidente com mais prudência: não comprovam por si só uma causa física única, mas ajudam a distinguir uma fila crescente de uma pressão sustentada sobre a cache ou de uma geração lenta. Guarde a configuração que produziu cada série temporal para que a análise seja reproduzível.
Processo para estimar o orçamento de memória
- 01Fixe o modelo, a revisão disponível, a quantização, o runtime, o controlador, a GPU e os limites de contexto; registe esses valores.
- 02Meça uma linha de base depois de carregar o modelo e concluir um aquecimento sem tráfego de teste.
- 03Execute cada cenário com um único pedido e comprimentos conhecidos de entrada e saída; observe memória, cache KV, TTFT e tempo total.
- 04Aumente a concorrência em passos pequenos, mantendo o cenário constante e registando fila, erros, cancelamentos e percentis.
- 05Defina um limite operacional abaixo do primeiro ponto de instabilidade e confirme que deixa margem para um pico ou um cancelamento tardio.
Prefill e descodificação: duas fases, dois possíveis estrangulamentos
O pedido não consome recursos da mesma forma durante toda a sua vida. No prefill, o sistema processa a entrada para construir o estado que a geração utilizará. Na descodificação, produz tokens sucessivos e atualiza esse estado. Um pedido com um documento longo pode ter um início lento mesmo que a sua resposta seja breve; uma resposta extensa pode começar cedo e, ainda assim, reter recursos durante muito tempo. Medir apenas a duração completa elimina esta diferença.
O tempo até ao primeiro token é um sinal útil para o utilizador e costuma refletir tanto a espera em fila como o trabalho prévio necessário para começar a gerar. A latência entre tokens, o tempo por token de saída e o tempo total fornecem outra perspetiva sobre a fase de geração. Convém registar também a dimensão real da entrada e da saída, porque uma variação nestes comprimentos pode explicar uma aparente variação de latência sem que o hardware tenha mudado.
O batching contínuo pode aumentar o aproveitamento ao misturar trabalho de pedidos distintos, mas não elimina os limites de memória nem garante equidade entre cargas. Uma carga de contexto amplo pode competir com chats curtos; as decisões do escalonador afetam quem começa primeiro e quem permanece em fila. Por isso, um teste representativo deve incluir tanto lotes homogéneos como uma mistura controlada de cenários, comunicados separadamente.
Não interprete uma redução do desempenho médio como um diagnóstico automático. Pode dever-se a chegadas mais rápidas do que a capacidade de serviço, a entradas mais longas, a um máximo de saída elevado, a pressão de memória ou a uma política de escalonamento. A instrumentação deve fornecer contexto suficiente para identificar correlações e, se não for possível atribuir a causa, essa incerteza deve ser declarada.
Da VRAM à concorrência operacional
A concorrência operacional é o maior número de pedidos que o serviço consegue admitir para um cenário definido sem incumprir os seus objetivos. Não deve ser deduzida diretamente da memória livre nem de um máximo teórico de contexto. A memória pode ser suficiente e, ainda assim, a fila ou a latência excederem o orçamento. Inversamente, um resultado aceitável numa concorrência concreta não valida uma carga com entradas ou saídas maiores.
Construa uma matriz de ensaio. Numa dimensão, estabeleça as classes de carga e os seus comprimentos de entrada e saída. Noutra, aumente os pedidos simultâneos. Para cada célula, repita o teste após aquecimento e recolha percentis de espera, TTFT, latência de geração e tempo de ponta a ponta. Anote tokens realmente processados, utilização da cache, pedidos ativos e em fila, cancelamentos, rejeições e erros. As médias podem ser adicionadas, mas não devem substituir os percentis.
A capacidade deve ser definida pelo pior resultado que se aceita, e não pelo máximo que consegue concluir uma execução. Se o p95 de início ultrapassar o objetivo, se a fila crescer de modo persistente ou se surgirem erros de memória, essa concorrência não é capacidade operacional para esse cenário. Pode ser mantida como ponto de falha estudado, útil para ajustar limites, mas não como uma promessa ao utilizador.
Também é importante testar a recuperação após pressão. Depois de um pico, observe se a fila regressa a níveis normais, se a memória é libertada como esperado e se os novos pedidos recuperam a latência habitual. Um sistema que conclui um teste curto, mas não recupera rapidamente, pode ser frágil para uma API interna.
Como interpretar o resultado de uma célula de teste
| Observação | Interpretação prudente | Decisão inicial |
|---|---|---|
| TTFT dentro do objetivo e fila estável | O cenário cumpre sob essa carga testada | Manter como candidato e repetir |
| TTFT p95 aumenta; o tempo total continua aceitável | A experiência de início está a degradar-se | Reduzir concorrência ou limitar a entrada |
| A fila cresce durante a janela de teste | A chegada pode exceder a capacidade de serviço | Aplicar admissão, separar carga ou ampliar capacidade |
| Erros de memória ou cancelamentos não solicitados | Não há margem suficiente para essa carga | Baixar limites e rever a reserva de memória |
Utilize filas e admissão explícita antes de chegar à falha
A fila não é necessariamente um erro: pode ser uma decisão controlada para proteger pedidos já iniciados. O problema surge quando não existe limite, quando o utilizador não sabe que está à espera ou quando se continua a aceitar trabalho que não conseguirá cumprir o orçamento. Uma política de admissão deve decidir, antes de atribuir recursos, se um pedido pode entrar, aguardar, receber um limite menor ou ser rejeitado com uma resposta clara.
Os controlos habituais incluem limites por utilizador ou credencial, um máximo de tokens de entrada, um máximo de saída, um número máximo de pedidos ativos, um comprimento máximo de fila e um tempo máximo de espera. O cancelamento deve libertar trabalho e memória de forma verificável. Se existirem classes de prioridade, documente-as: uma prioridade não cria capacidade; apenas distribui de outro modo uma capacidade limitada.
A degradação deve ser explícita e compatível com o caso de utilização. Por exemplo, uma interface pode pedir ao utilizador que reduza documentos anexados, aplicar um limite de saída anunciado ou adiar uma tarefa não interativa. Não é adequado truncar silenciosamente informação crítica nem trocar de modelo sem informar quando isso altera o resultado esperado. A política deve determinar o que acontece antes de o runtime atingir um erro por falta de memória.
Os contadores de pedidos em espera e em execução, juntamente com métricas de trabalho de prefill e decode, permitem avaliar se as regras protegem o serviço. Teste deliberadamente uma carga acima da admitida: confirme que o novo trabalho é limitado e que a latência dos pedidos em curso não se degrada de forma descontrolada. Este ensaio de sobrecarga é tão importante como o teste nominal.
Protocolo reproduzível no seu próprio hardware
Um teste útil tem de poder ser repetido. Congele e registe a identidade do modelo disponível, a sua quantização, o runtime, a versão do controlador, o tipo e a quantidade de GPU, os limites de contexto e saída, os parâmetros de batching e a política de admissão. Se qualquer uma destas variáveis mudar, trate o resultado como uma nova medição, e não como continuação automática da anterior.
Prepare uma carga sintética baseada nos cenários definidos, sem utilizar conversas reais salvo se existir uma autorização específica e controlos adequados. A carga deve fixar ou registar os comprimentos de entrada e saída. Execute um aquecimento separado da medição, faça várias repetições e mantenha um período de observação suficiente para detetar filas crescentes. Comunique p50, p95 e p99 quando o volume de amostras permitir interpretá-los; juntamente com eles, indique o número de pedidos e o intervalo de teste.
A documentação de benchmarking do vLLM contempla métricas como TTFT, tempo por token de saída e latência entre tokens, e adverte que a cache de prefixos pode melhorar artificialmente os resultados se não for controlada. Se utilizar uma cache de prefixos em produção, teste-a de forma representativa e declare se os prompts se repetem; se não representar a carga esperada, desative-a ou separe-a noutro cenário. Um resultado que depende de uma reutilização irreal não é uma estimativa prudente de capacidade.
Não basta guardar um painel. Conserve um resumo da configuração, o gerador de carga, os parâmetros, os resultados agregados e os critérios de aceitação. A reprodutibilidade permite comparar uma atualização do modelo ou do runtime e descobrir regressões. Também evita que uma decisão de compra ou de implementação dependa de memórias sobre uma demonstração anterior.
Sequência de teste recomendada
- 01Estabeleça objetivos de TTFT, tempo total, taxa de espera, taxa de rejeição e comportamento de recuperação para cada cenário.
- 02Aqueça o serviço e exclua essa fase dos resultados medidos.
- 03Teste cada cenário isoladamente com concorrência crescente; registe os resultados por pedido.
- 04Teste uma mistura de cenários com um padrão de chegadas declarado e compare os resultados por classe.
- 05Submeta o serviço a um pico acima do limite; valide admissão, cancelamento e recuperação.
- 06Repita com a mesma configuração e documente a variação, as falhas e as mudanças face à hipótese inicial.
Decidir com evidência: limites, mudança de modelo ou mais hardware
Com os resultados reunidos, decida em função do requisito, não da intuição. Mantenha a configuração se cumprir os cenários prioritários com margem e recuperar após picos. Reduza o contexto ou o máximo de saída quando o produto o puder fazer de forma explícita e os testes mostrarem que a medida recupera os objetivos. Limite a concorrência se o padrão de procura admitir espera controlada. Separar cargas pode ser preferível quando as tarefas com documentos longos interferem com o chat interativo.
Adicionar GPU ou mudar de arquitetura é uma decisão razoável apenas depois de identificar que restrição se pretende aliviar. Se a pressão da cache dominar, o orçamento de memória e a distribuição de contexto são centrais. Se o prefill de entradas longas não cumprir o TTFT, avalie essa fase separadamente. Se a qualidade do modelo não satisfizer a tarefa, mais concorrência não resolve o problema. A evidência de um teste não permite inferir automaticamente qual destas alternativas será ótima sem a medir.
Mudar de modelo também exige repetir a matriz. Dois modelos com uma designação de dimensão semelhante podem usar configurações de contexto, quantizações e runtimes diferentes. A mudança pode alterar tanto a memória base como o comportamento de geração. Numa comparação interna, comunique as condições completas e não atribua ao tamanho dos pesos uma causalidade que não tenha sido isolada.
Se não existir uma configuração que cumpra o requisito com limites aceitáveis, a decisão honesta pode ser não implementar ainda o serviço partilhado. É preferível oferecer um piloto limitado, com âmbito claramente definido, do que prometer um assistente privado generalista sem orçamento de capacidade. O inventário de modelos locais e as comparações devem apresentar esta conclusão como uma possibilidade operacional, e não como um fracasso.
Decisões de acordo com o estrangulamento observado
| Constatação do teste | Mudança a avaliar | Validação necessária |
|---|---|---|
| Entrada extensa não cumpre TTFT | Reduzir contexto, melhorar a recuperação ou separar essa carga | Repetir o prefill com distribuição representativa |
| Saída longa degrada as restantes | Limitar saída, cancelar ou isolar tarefas longas | Medir fila e latência de chat durante a mistura |
| Memória sem margem | Baixar concorrência ou contexto; alterar a capacidade de hardware | Teste de pico e recuperação |
| Qualidade insuficiente com limites sustentáveis | Mudar de modelo ou redesenhar a tarefa | Avaliação de qualidade e nova matriz de capacidade |
Privacidade, telemetria e checklist de implementação
A instrumentação de capacidade não deve criar um repositório paralelo de conversas. As especificações de telemetria para IA generativa advertem que as mensagens de entrada, saída, instruções e argumentos podem conter informação sensível ou dados pessoais. Para medir concorrência, normalmente não é necessário guardar o texto completo: comprimentos em tokens, marcas temporais, identificadores pseudonimizados, resultado de admissão e métricas de latência costumam ser suficientes.
Antes de ativar rastreios detalhados, defina que campos são recolhidos, para que diagnóstico, quem lhes acede, durante quanto tempo são retidos e como são eliminados. Se prompts ou respostas forem conservados para depuração, a exceção deve ter justificação, controlos de acesso e um período de retenção limitado. Reveja também se atributos aparentemente inócuos, como nomes de ferramentas ou argumentos, podem revelar informação de negócio.
A evidência mínima de uma implementação interna inclui o contrato de serviço, os cenários, o ambiente técnico, o método de carga, percentis por cenário, comportamento ao ultrapassar o limite, política de admissão e tratamento da telemetria. Distinga sempre entre o que foi medido, o que foi estimado e o que ainda não foi testado. Esta disciplina permite ajustar o serviço sem transformar um número de demonstração numa garantia sem suporte.
A capacidade não é permanente. Alterações de modelo, quantização, controlador, runtime, parâmetros de contexto, cache ou política de escalonamento podem invalidar resultados anteriores. Programe uma repetição do teste quando mudarem elementos materiais e supervise em produção se as distribuições reais de entrada, saída e espera não se afastam dos cenários aprovados.
Checklist antes de anunciar capacidade interna
- 01O serviço declara cenários, comprimentos de entrada e saída, concorrência e objetivos de percentis?
- 02Foram separados chat curto, contexto amplo e saída extensa, com resultados por classe?
- 03Foram registados fila, TTFT, geração, tempo total, utilização da cache KV, rejeições e cancelamentos?
- 04Foi testada uma sobrecarga e confirmado que a admissão protege os pedidos em curso?
- 05A configuração técnica completa permite repetir o ensaio?
- 06A telemetria evita texto de conversas salvo numa exceção justificada, protegida e temporária?
- 07Foram documentadas margens, incertezas e condições que obrigam a repetir o teste?
Questões em aberto
- Não existe uma fórmula universal, baseada apenas em VRAM ou no tamanho dos pesos, que determine a concorrência de todos os modelos e runtimes.
- Os limiares aceitáveis de p50, p95, p99, espera e rejeição dependem do produto e não são definidos pelas fontes fornecidas.
- A atribuição exata de uma redução de desempenho pode exigir instrumentação adicional; as métricas permitem observar correlações, mas nem sempre comprovam uma causa única.
- O efeito da cache de prefixos, do batching e do escalonamento depende da configuração e da repetição real dos prompts; deve ser medido no ambiente próprio.
- Os resultados de carga sintética podem não representar o tráfego de produção se as distribuições de entrada, saída ou chegadas mudarem.
Continue a explorar
Fontes consultadas
Correções e transparência
Se encontrar informação incorreta ou desatualizada, envie-nos a página e a fonte que devemos rever.
Propor uma correção