Para cargas de trabalho de inferência de longa duração, como AIGC e processamento de vídeo, a inferência síncrona pode causar timeouts de conexão e distribuição desigual de carga entre réplicas. A inferência assíncrona do PAI permite enviar solicitações e recuperar resultados por assinatura ou polling.
Informações básicas
Recursos
-
Inferência assíncrona
A inferência online de baixa latência geralmente utiliza o modelo síncrono: o cliente envia uma solicitação e aguarda o resultado na mesma conexão.
Quando os tempos de inferência são longos ou imprevisíveis, a espera síncrona pode derrubar conexões HTTP e causar timeouts no cliente. Na inferência assíncrona, o cliente envia a solicitação e recupera o resultado posteriormente via polling ou assinatura de notificações.
-
Queue service
Cenários de quase tempo real, como processamento de vídeos curtos, análise de streams de áudio/vídeo ou processamento intensivo de imagens, precisam retornar resultados dentro de um prazo específico. Esses cenários enfrentam os seguintes desafios:
O algoritmo de balanceamento de carga round-robin não é adequado. As solicitações devem ser distribuídas com base na carga real de cada réplica.
Se uma réplica falhar, suas tarefas inacabadas devem ser reatribuídas a outras réplicas íntegras para processamento.
O PAI oferece um framework de queue service para resolver esses problemas de distribuição de solicitações.
Funcionamento
Um service de inferência assíncrona contém dois subserviços: um subserviço de inferência e um subserviço de fila. O subserviço de fila possui duas filas internas: uma fila de entrada (input queue) e uma fila de saída (sink queue). As solicitações chegam primeiro à fila de entrada. Cada réplica do subserviço de inferência assina a fila de entrada, processa as solicitações e grava as respostas na fila de saída.
-
Quando a fila de saída está cheia, o framework do service interrompe o consumo da fila de entrada para evitar resultados não entregáveis.
Se você gravar os resultados da inferência diretamente no OSS ou em seu próprio middleware de mensagens, retorne uma resposta vazia pela interface HTTP de inferência. Nesse caso, a fila de saída será ignorada.
-
O subserviço de fila recebe as solicitações do cliente e as distribui às réplicas de inferência conforme a capacidade de concorrência. Cada réplica assina uma janela de solicitações, o que evita sobrecarga e garante que todos os dados sejam eventualmente retornados ao cliente.
NotaPor exemplo, se cada réplica consegue processar cinco streams de áudio, defina o tamanho da janela como 5. Quando uma réplica termina um stream e confirma o resultado, o subserviço de fila envia um novo stream. Isso limita cada réplica a cinco streams simultâneos.
O subserviço de fila monitora as conexões das réplicas. Se uma réplica falhar, suas solicitações não processadas serão redistribuídas para réplicas íntegras, garantindo que nenhum dado seja perdido.
Crie um service de inferência assíncrona
A criação de um service de inferência assíncrona gera automaticamente um grupo de serviços com o mesmo nome, contendo um subserviço de fila. Por padrão, o subserviço de fila inicia com uma réplica (1 núcleo, 4 GB de memória) e escala até duas réplicas junto com o subserviço de inferência. Para personalizar, ajuste os Parâmetros do subserviço de fila.
O EAS suporta dois métodos de implantação para inferência assíncrona:
Implantação via console
-
Acesse a página Custom Deployment e configure os seguintes parâmetros principais. Os demais parâmetros estão descritos em Custom Deployment.
Deployment Method: Selecione Image-based Deployment ou Processor-based Deployment e marque a caixa de seleção Asynchronous Queue.
Após configurar os parâmetros, clique em Deploy.
Implantação via cliente eascmd
-
Prepare o arquivo de configuração do service chamado service.json.
-
Utilize uma implantação baseada em modelo e processor.
{ "processor": "pmml", "model_path": "http://example.oss-cn-shanghai.aliyuncs.com/models/lr.pmml", "metadata": { "name": "pmmlasync", "type": "Async", "cpu": 4, "instance": 1, "memory": 8000 } }Os parâmetros principais estão descritos abaixo. Outros parâmetros são abordados em JSON-based deployment.
type: Defina este parâmetro como
Asyncpara criar um service de inferência assíncrona.model_path: Substitua o valor pelo caminho do seu modelo.
-
Utilize uma implantação baseada em imagem.
{ "metadata": { "name": "image_async", "instance": 1, "rpc.worker_threads": 4, "type": "Async" }, "cloud": { "computing": { "instance_type": "ecs.gn6i-c16g1.4xlarge" } }, "queue": { "cpu": 1, "min_replica": 1, "memory": 4000, "resource": "" }, "containers": [ { "image": "eas-registry-vpc.cn-beijing.cr.aliyuncs.com/pai-eas/chat-llm-webui:3.0.1", "script": "python webui/webui_server.py --port=8000 --model-path=Qwen/Qwen-7B-Chat", "port": 8000 } ] }Os parâmetros principais estão descritos abaixo. Outros parâmetros são abordados em JSON-based deployment.
type: Defina este parâmetro como Async para criar um service de inferência assíncrona.
instance: Quantidade de réplicas do subserviço de inferência. Este valor não inclui as réplicas do subserviço de fila.
-
rpc.worker_threads: Número de threads do framework de service EAS, que corresponde ao tamanho da janela de assinatura. O subserviço de fila envia, no máximo, essa quantidade de mensagens simultaneamente e aguarda os resultados antes de enviar mais.
Por exemplo, para um service de stream de vídeo onde cada réplica lida com dois streams por vez, defina este valor como 2. O subserviço de fila enviará no máximo duas URLs de stream de vídeo e só enviará uma nova após receber um resultado.
-
-
Crie o service.
Após fazer login no cliente eascmd (Baixe and authenticate the client), execute o comando create:
eascmd create service.json
Acessar um service de inferência assíncrona
O sistema cria um grupo de serviços com o mesmo nome. Como o subserviço de fila gerencia o tráfego de entrada, acesse-o diretamente pelos endpoints abaixo. Access a queue service.
|
Tipo de endpoint |
Formato |
Exemplo |
|
Endpoint da fila de entrada |
|
|
|
Endpoint da fila de saída |
|
|
Gerencie um service de inferência assíncrona
Gerencie um service de inferência assíncrona como um service comum. O sistema administra os subserviços automaticamente: excluir o service remove ambos os subserviços, e atualizar o subserviço de inferência mantém o subserviço de fila inalterado.
Mesmo com apenas uma réplica configurada, a lista de instâncias exibirá uma instância adicional referente ao subserviço de fila.
A contagem de réplicas refere-se às réplicas do subserviço de inferência. As réplicas do subserviço de fila escalam automaticamente. Por exemplo, escalar as réplicas de inferência para 3 aumenta as réplicas da fila para 2.
Regras de dimensionamento de réplicas:
Ao parar o service, ambos os subserviços escalam para 0 réplicas.
Com uma réplica de inferência, o subserviço de fila também mantém uma réplica (salvo configuração diferente).
Com duas ou mais réplicas de inferência, o subserviço de fila mantém duas réplicas (salvo configuração diferente).
Se o Auto Scaling permitir um mínimo de 0 réplicas, o subserviço de fila manterá uma réplica em standby quando as réplicas de inferência escalarem para 0.
Parâmetros do subserviço de fila
O subserviço de fila funciona com a configuração padrão na maioria dos casos. Personalize-o no campo queue de nível superior do arquivo JSON:
{
"queue": {
"sink": {
"memory_ratio": 0.3
},
"source": {
"auto_evict": true,
}
}
As seções a seguir descrevem as opções de configuração.
Recursos do subserviço de fila
Por padrão, os recursos do subserviço de fila são herdados de metadata. Configure-os separadamente se necessário.
-
Declare o grupo de recursos para o subserviço de fila usando queue.resource.
{ "queue": { "resource": "eas-r-slzkbq4tw0p6xd****" // By default, it uses the resource group of the inference sub-service. } }O padrão é o grupo de recursos do subserviço de inferência.
-
Para implantar o subserviço de fila em um grupo de recursos público, defina resource como uma string vazia (
""). Isso é útil quando seu grupo de recursos dedicado não tem CPU ou memória suficiente.NotaSempre que possível, implante o subserviço de fila em um grupo de recursos público.
-
Declare a CPU (em núcleos) e a memória (em MB) para cada réplica do subserviço de fila usando queue.cpu e queue.memory.
{ "queue": { "cpu": 2, // Default: 1. "memory": 8000 // Default: 4000. } }A configuração padrão (1 núcleo de CPU, 4 GB de memória) é suficiente para a maioria dos cenários.
ImportantePara mais de 200 assinantes (réplicas do subserviço de inferência), configure 2 ou mais núcleos de CPU.
Não reduza a memória do subserviço de fila em ambiente de produção.
-
Configure o número mínimo de réplicas para o subserviço de fila usando queue.min_replica.
{ "queue": { "min_replica": 3 // Default: 1. } }As réplicas do subserviço de fila escalam automaticamente conforme as réplicas de inferência em execução (running). O intervalo padrão é
[1, min{2, the number of inference sub-service replicas}]. Se o Auto Scaling permitir escalar para 0, uma réplica da fila será mantida. Use queue.min_replica para ajustar esse mínimo.NotaMais réplicas de fila melhoram a disponibilidade, não o desempenho.
-
Configure a evicção automática de dados para as filas de saída e de entrada usando queue.sink.auto_evict ou queue.source.auto_evict, respectivamente.
{ "queue": { "sink": { "auto_evict": true // Enables automatic eviction for the sink queue. Default: false. }, "source": { "auto_evict": true // Enables automatic eviction for the input queue. Default: false. } } }A evicção automática vem desativada por padrão — uma fila cheia rejeita novos dados. Ative a evicção para descartar os dados mais antigos e abrir espaço para novas entradas.
-
Defina o número máximo de tentativas de entrega usando queue.max_delivery.
{ "queue": { "max_delivery": 10 // The maximum number of delivery attempts is 10. Default: 5. If set to 0, this feature is disabled, and data can be delivered an unlimited number of times. } }Quando as tentativas de entrega ultrapassam o limiar, a mensagem é marcada como dead letter. Dead-letter policy.
-
Estabeleça o tempo máximo de processamento para uma mensagem usando queue.max_idle.
{ "queue": { "max_idle": "1m" // Configures the maximum processing time for a single message to 1 minute. If this time is exceeded, the message is delivered to another subscriber, and the delivery count is incremented. The default value is 0, which means no maximum processing time. } }Unidades de tempo suportadas:
h(hora),m(minuto) es(segundo). Se o processamento exceder a duração configurada:Se o limiar de
queue.max_deliverynão for excedido, a mensagem é reentregue a outros assinantes.Se o limiar de
queue.max_deliveryfor excedido, aplica-se a política de dead letter.
-
Configure a política de dead letter usando queue.dead_message_policy.
{ "queue": { "dead_message_policy": "Rear" // The value can be Rear (default) or Drop. Rear moves the message to the end of the queue. Drop deletes the message. } } Com as configurações padrão (4 GB de memória, payload máximo de 8 KB), cada fila armazena até 230.399 mensagens. Para armazenar mais, aumente a memória. O sistema reserva 10% da memória total.
Não é possível configurar o comprimento máximo e o tamanho máximo do payload para a mesma fila simultaneamente.
-
Defina o comprimento máximo das filas de saída e de entrada usando queue.sink.max_length ou queue.source.max_length, respectivamente.
{ "queue": { "sink": { "max_length": 8000 // Configures the maximum length of the sink queue to 8,000 messages. }, "source": { "max_length": 2000 // Configures the maximum length of the input queue to 2,000 messages. } } } -
Especifique o tamanho máximo do payload por mensagem para as filas de saída e de entrada usando queue.sink.max_payload_size_kb ou queue.source.max_payload_size_kb, respectivamente.
{ "queue": { "sink": { "max_payload_size_kb": 10 // Configures the maximum payload size per message for the sink queue to 10 KB. Default: 8 KB. }, "source": { "max_payload_size_kb": 1024 // Configures the maximum payload size per message for the input queue to 1024 KB (1 MB). Default: 8 KB. } } } -
Ajuste a alocação de memória entre as filas de entrada e de saída usando queue.sink.memory_ratio.
{ "queue": { "sink": { "memory_ratio": 0.9 // Configures the memory ratio for the sink queue. Default: 0.5. } } }NotaPor padrão, as filas de entrada e de saída compartilham a memória igualmente. Aumente
queue.sink.memory_ratiose a fila de saída precisar de mais espaço (por exemplo, entrada de texto e saída de imagem) ou diminua para o cenário inverso. Na lista de serviços, clique em no nome do service desejado.
Acesse a aba Auto Scaling. Na seção Auto Scaling, clique em Enable Auto Scaling.
-
Na caixa de diálogo Auto Scaling Settings, configure os parâmetros.
-
Configurações básicas:
Parâmetro
Descrição
Exemplo
Minimum Replicas
Número mínimo de réplicas para operações de scale-in. Valor mínimo: 0.
0
Maximum Replicas
Número máximo de réplicas para operações de scale-out. Valor máximo: 1000.
10
General Scaling Metrics
Métricas de desempenho integradas usadas para acionar o dimensionamento.
Asynchronous Queue Length representa o número médio de tarefas enfileiradas por réplica.
Selecione Asynchronous Queue Length e defina o limiar como 10.
-
Configurações avançadas:
Parâmetro
Descrição
Exemplo
Scale-out Starts in
Janela de observação para decisões de scale-out. Após o acionamento do scale-out, o sistema observa as métricas durante este período. Se os valores das métricas caírem abaixo do limiar, o scale-out é cancelado. Unidade: segundos.
O valor padrão é
0segundos, o que significa que o scale-out é executado imediatamente.0
Scale-in Starts in
Janela de observação para decisões de scale-in — o parâmetro chave para evitar instabilidade no service. O scale-in ocorre somente após as métricas permanecerem abaixo do limiar durante toda esta duração. Unidade: segundos.
Padrão:
300segundos. Isso protege contra eventos frequentes de scale-in devido a flutuações de tráfego. Não defina um valor muito baixo para manter a estabilidade do service.300
Scale-in to 0 Instance Starts in
Quando Minimum Replicas é
0, este parâmetro define o tempo de espera antes que a contagem de réplicas seja reduzida para0.600
Scale-from-Zero Replica Count
Quantidade de réplicas a adicionar quando o service escala a partir de
0réplicas.1
Detalhes completos dos parâmetros e uso do eascmd estão disponíveis em Horizontal auto scaling.
-
Recursos funcionais do subserviço de fila
O subserviço de fila suporta as seguintes configurações funcionais.
Comprimento da fila ou tamanho máximo do payload
A memória da réplica da fila é fixa: aumentar o tamanho máximo do payload por mensagem reduz o comprimento máximo da fila.
Proporção de alocação de memória
Auto Scaling horizontal
Funcionamento
O sistema dimensiona dinamicamente as réplicas de inferência com base no estado da fila, inclusive escalando para zero quando a fila está vazia. O diagrama a seguir ilustra o mecanismo.