Para AIGC, processamento de vídeo e outras cargas de trabalho de inferência de longa duração, a inferência síncrona pode causar tempos limite de conexão e distribuição desigual de carga entre réplicas. A inferência assíncrona do PAI permite que você envie solicitações e recupere resultados por meio de assinatura ou polling.
Informações básicas
Recursos
-
Inferência assíncrona
A inferência online de baixa latência geralmente utiliza inferência síncrona: 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 causar quedas de conexões HTTP e tempos limite no cliente. Com a inferência assíncrona, o cliente envia uma solicitação e recupera o resultado posteriormente via polling ou assinatura de notificações.
-
Serviço de fila
Cenários quase em tempo real, como processamento de vídeos curtos, análise de fluxos de áudio/vídeo ou processamento intensivo de imagens, precisam retornar resultados dentro de um período 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 serviço de fila para resolver esses problemas de distribuição de solicitações.
Como funciona
Um serviço 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 integradas: uma fila de entrada e uma fila de destino (sink). As solicitações vão primeiro para a 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 destino.
-
Quando a fila de destino está cheia, o framework do serviço para de consumir 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 da interface de inferência HTTP. A fila de destino será então ignorada.
-
O subserviço de fila recebe solicitações do cliente e as distribui para as réplicas de inferência com base na capacidade de concorrência. Cada réplica assina uma janela de solicitações, evitando sobrecarga e garantindo que todos os dados sejam eventualmente retornados ao cliente.
NotaPor exemplo, se cada réplica puder processar cinco fluxos de áudio, defina o tamanho da janela como 5. Quando uma réplica termina um fluxo e confirma o resultado, o subserviço de fila envia um novo fluxo. Isso limita cada réplica a cinco fluxos 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 serviço de inferência assíncrona
Criar um serviço de inferência assíncrona gera automaticamente um grupo de serviços com o mesmo nome, contendo um subserviço de fila. O subserviço de fila tem como padrão 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:
Implantar via console
-
Acesse a página Custom Deployment e configure os seguintes parâmetros principais. Outros 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.
Implantar via cliente eascmd
-
Prepare o arquivo de configuração do serviço chamado service.json.
-
Utilize uma implantação baseada em modelo e processador.
{ "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 Implantação baseada em JSON.
type: Defina este parâmetro como
Asyncpara criar um serviço 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 Implantação baseada em JSON.
type: Defina este parâmetro como Async para criar um serviço de inferência assíncrona.
instance: O número de réplicas para o subserviço de inferência. Isso não inclui as réplicas do subserviço de fila.
-
rpc.worker_threads: O número de threads para o framework de serviço EAS, que equivale 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 serviço de fluxo de vídeo onde cada réplica lida com dois fluxos por vez, defina isso como 2. O subserviço de fila enviará no máximo duas URLs de fluxo de vídeo e só enviará uma nova após receber um resultado.
-
-
Crie o serviço.
Após fazer login no cliente eascmd (Baixe e autentique o cliente), execute o comando create:
eascmd create service.json
Acesse um serviço 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 através dos seguintes endpoints. Acesse um serviço de fila.
|
Tipo de endpoint |
Formato |
Exemplo |
|
Endpoint da fila de entrada |
|
|
|
Endpoint da fila de destino |
|
|
Gerencie um serviço de inferência assíncrona
Gerencie um serviço de inferência assíncrona como um serviço comum. O sistema gerencia os subserviços automaticamente: excluir o serviço remove ambos os subserviços, e atualizar o subserviço de inferência deixa o subserviço de fila inalterado.
Mesmo com uma réplica configurada, a lista de instâncias mostra uma instância adicional do 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:
Quando o serviço é parado, ambos os subserviços escalam para 0 réplicas.
Com uma réplica de inferência, o subserviço de fila também possui uma réplica (a menos que configurado de outra forma).
Com duas ou mais réplicas de inferência, o subserviço de fila mantém duas réplicas (a menos que configurado de outra forma).
Se o Auto Scaling permitir um mínimo de 0 réplicas, o subserviço de fila retém uma réplica em standby quando as réplicas de inferência escalam 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 herdam as configurações 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. } }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 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 com 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 destino 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 é 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.
-
Configure 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 excedem o limiar, a mensagem é marcada como carta morta (dead letter). Política de carta morta.
-
Configure 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, a política de carta morta é aplicada.
-
Configure a política de carta morta 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, 8 KB de payload máximo), 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 de payload para a mesma fila simultaneamente.
-
Configure o comprimento máximo das filas de destino 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. } } } -
Configure o tamanho máximo de payload por mensagem para as filas de destino 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 destino 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 destino compartilham a memória igualmente. Aumente
queue.sink.memory_ratiose a fila de destino precisar de mais espaço (por exemplo, entrada de texto e saída de imagem) ou diminua para o caso inverso. Na lista de serviços, clique em Auto Scaling.
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 ficarem abaixo do limiar, o scale-out é cancelado. Unidade: segundos.
O valor padrão é
0segundos, o que significa que o scale-out é realizado imediatamente.0
Scale-in Starts in
Janela de observação para decisões de scale-in — o parâmetro chave para evitar instabilidade no serviço. 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 serviço.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
Contagem de réplicas a serem adicionadas quando o serviço escala a partir de
0réplicas.1
Detalhes completos dos parâmetros e uso do eascmd estão disponíveis em Auto Scaling horizontal.
-
Recursos do subserviço de fila
O subserviço de fila suporta as seguintes configurações de recursos.
Comprimento da fila ou tamanho máximo de payload
A memória da réplica da fila é fixa: aumentar o tamanho máximo de payload por mensagem reduz o comprimento máximo da fila.
Proporção de alocação de memória
Auto Scaling horizontal
Como funciona
O sistema dimensiona dinamicamente as réplicas de inferência com base no estado da fila, incluindo o dimensionamento para zero quando a fila está vazia. O diagrama a seguir ilustra o mecanismo.