Voz em tempo real: o desafio que o modelo request-response não resolve
Agentes de voz, legendagem ao vivo, análise de contact centers e ferramentas de acessibilidade têm algo em comum: todas dependem de transcrição de fala em tempo real. Isso significa que a aplicação precisa transmitir o áudio enquanto já recebe o texto de volta — simultaneamente, por uma única conexão persistente.
O modelo tradicional de requisição e resposta (request-response) não serve para esse cenário. Nele, a transcrição só começa depois que o arquivo de áudio inteiro foi recebido, adicionando uma latência que quebra completamente a experiência em tempo real.
A partir de novembro de 2025, a AWS passou a oferecer o streaming bidirecional para inferência em tempo real no Amazon SageMaker AI, permitindo que dados fluam continuamente nas duas direções entre clientes e contêineres de modelo. Combinado com a Realtime API do vLLM — que usa WebSockets para streaming bidirecional entre cliente e servidor — essa dupla forma uma solução completa para aplicações de voz.
O post original da AWS demonstra como implantar o Voxtral-Mini-4B-Realtime-2602, o modelo compacto de fala em tempo real da Mistral AI, em um endpoint do SageMaker AI usando um contêiner vLLM com streaming bidirecional. O exemplo completo está disponível no repositório GitHub.
O que cada componente entrega
Construir uma aplicação de voz em produção exige que vários componentes de infraestrutura funcionem juntos dentro de orçamentos de latência muito apertados. O SageMaker AI e o vLLM resolvem partes distintas dessa pilha:
Modelo de fala com serving eficiente em GPU
No núcleo de qualquer aplicação de voz está um modelo de Reconhecimento Automático de Fala (ASR) que processa o áudio de forma incremental, produzindo tokens de transcrição à medida que o áudio chega — sem esperar pela gravação completa. O vLLM serve esses modelos por meio de sua Realtime API, um endpoint nativo WebSocket em /v1/realtime que aplica execução de grafo CUDA por partes (piecewise CUDA graph execution) para reduzir a sobrecarga de lançamento de kernels de GPU, resultando em menor latência por token durante a transcrição em streaming. Por ser open source, o vLLM garante controle total sobre configuração do modelo, quantização e configurações de compilação, sem dependência de fornecedor (vendor lock-in) na camada de serving.
Infraestrutura de streaming bidirecional
O SageMaker AI resolve o problema do protocolo com streaming bidirecional nativo via HTTP/2 na porta 8443, fazendo a ponte automaticamente entre o protocolo de event stream HTTP/2 no lado do cliente e o WebSocket no lado do contêiner. Não é necessário construir ou gerenciar essa camada de tradução de protocolo — o SageMaker AI cuida disso de forma transparente.
Processamento e codificação de áudio
O áudio bruto de microfones ou sistemas de telefonia chega em vários formatos e taxas de amostragem. Antes de chegar ao modelo, ele precisa ser reamostrado (tipicamente para 16 kHz mono PCM16), dividido em segmentos de tamanho adequado e codificado em base64 para transmissão. O pipeline do lado do cliente cuida dessa conversão, enquanto a Realtime API do vLLM define o protocolo: chunks PCM16 em base64 entram via WebSocket, e os tokens de transcrição voltam em streaming.
Gerenciamento de conexão e resiliência
O SageMaker AI mantém conexões WebSocket com frames de keepalive ping/pong, verifica a saúde do contêiner e fornece monitoramento em nível de endpoint pelo Amazon CloudWatch — tudo isso sem instrumentação customizada.
Visão geral da solução
A solução conecta três camadas:
- Cliente → SageMaker AI: A aplicação se conecta ao endpoint de runtime do SageMaker AI na porta 8443 via HTTP/2. Cada mensagem JSON do protocolo vLLM Realtime (como
input_audio_buffer.appendoutranscription.delta) é enviada dentro de umRequestPayloadPartcomDataTypedefinido como"UTF8". - SageMaker AI → Contêiner Docker: O SageMaker AI faz a ponte automaticamente entre o event stream HTTP/2 e o WebSocket, estabelecendo uma conexão WebSocket com o contêiner em
ws://localhost:8080/invocations-bidirectional-streame encaminhando os frames de dados nos dois sentidos. - Contêiner Docker: Dentro do contêiner, uma bridge leve em FastAPI (
app.py) escuta na porta 8080 e, ao receber uma conexão WebSocket do SageMaker AI, abre uma segunda conexão WebSocket para a Realtime API do vLLM emws://localhost:8081/v1/realtime, encaminhando mensagens bidirecionalmente.
O protocolo da Realtime API
A Realtime API fornece transcrição de áudio em streaming via WebSocket. O áudio deve ser codificado como base64 PCM16 a 16 kHz mono. O fluxo de mensagens funciona assim:
- Cliente conecta em
ws://host/v1/realtime - Servidor envia evento
session.created - Cliente envia opcionalmente
session.updatecom modelo e parâmetros - Cliente envia
input_audio_buffer.commitquando pronto para enviar áudio - Cliente envia eventos
input_audio_buffer.appendcom chunks PCM16 em base64 - Servidor envia eventos
transcription.deltacom texto incremental - Servidor envia
transcription.donecom a transcrição final e estatísticas de uso - Repete a partir do passo 5 para o próximo enunciado
O modelo começa a transcrever assim que tem contexto de áudio suficiente, enviando tokens de transcription.delta de volta ao cliente enquanto ele continua enviando chunks de áudio — sem necessidade de esperar o envio completo.
Construindo o contêiner vLLM customizado
A solução parte do SageMaker AI vLLM Deep Learning Container e adiciona três elementos: o label Docker de streaming bidirecional, uma bridge WebSocket que traduz entre as rotas esperadas pelo SageMaker AI e os caminhos nativos da API do vLLM, e um entrypoint que executa ambos os processos.
FROM public.ecr.aws/deep-learning-containers/vllm:0.17.1-gpu-py312-cu129-ubuntu22.04-sagemaker-v1.0-soci
# Tell SageMaker AI this container supports bidirectional streaming
LABEL com.amazonaws.sagemaker.capabilities.bidirectional-streaming=true
WORKDIR /opt/ml/code
# Install bridge dependencies
COPY requirements.txt .
RUN pip install --upgrade --no-cache-dir -r requirements.txt
# WebSocket bridge: routes /invocations-bidirectional-stream → /v1/realtime
COPY app.py .
COPY sagemaker-entrypoint.sh entrypoint.sh
RUN chmod +x entrypoint.sh
ENTRYPOINT ["./entrypoint.sh"]
HEALTHCHECK --interval=30s --timeout=10s --start-period=120s --retries=3 \
CMD curl -f http://localhost:8080/ping || exit 1
O label com.amazonaws.sagemaker.capabilities.bidirectional-streaming=true sinaliza ao SageMaker AI que o contêiner suporta streaming bidirecional. Sem esse label, o SageMaker AI não estabelecerá conexões WebSocket com o contêiner.
A bridge (app.py) é uma aplicação FastAPI que escuta na porta 8080 e encaminha conexões WebSocket para o endpoint /v1/realtime do vLLM na porta interna 8081. Ela também faz proxy dos health checks de /ping para o /health do vLLM.
VLLM_WS_URL = "ws://localhost:8081/v1/realtime"
@app.websocket("/invocations-bidirectional-stream")
async def websocket_bridge(sm_ws: WebSocket):
await sm_ws.accept()
async with websockets.connect(VLLM_WS_URL) as vllm_ws:
async def sm_to_vllm():
"""Forward SageMaker AI → vLLM."""
while True:
message = await sm_ws.receive()
if "text" in message and message["text"]:
await vllm_ws.send(message["text"])
elif "bytes" in message and message["bytes"]:
# Fallback for non-UTF8 clients
await vllm_ws.send(message["bytes"].decode("utf-8"))
async def vllm_to_sm():
"""Forward vLLM → SageMaker AI."""
async for msg in vllm_ws:
if isinstance(msg, str):
await sm_ws.send_text(msg)
elif isinstance(msg, bytes):
await sm_ws.send_bytes(msg)
await asyncio.gather(sm_to_vllm(), vllm_to_sm())
Implantando no endpoint do SageMaker AI
As variáveis de ambiente SM_VLLM_* configuram os parâmetros do servidor vLLM:
vllm_env = {
"SM_VLLM_MAX_MODEL_LEN": "45000",
"SM_VLLM_COMPILATION_CONFIG": '{"cudagraph_mode": "PIECEWISE"}'
}
O Voxtral-Mini-4B suporta até 262.144 tokens de contexto. O valor MAX_MODEL_LEN=45000 é suficiente para gravar ao vivo aproximadamente uma hora de áudio (3600 segundos / 0,08 segundos por token). O COMPILATION_CONFIG com cudagraph_mode: PIECEWISE oferece otimização de grafo CUDA para melhor throughput de inferência.
O trecho abaixo cria o endpoint no SageMaker AI:
# Create model
voxtral_model = Model.create(
model_name=model_name,
primary_container=ContainerDefinition(
image=inference_image,
model_data_source=ModelDataSource(
s3_data_source=S3ModelDataSource(
s3_uri=f"{model_artifact}/",
s3_data_type="S3Prefix",
compression_type="None",
)
),
environment=vllm_env
),
execution_role_arn=role,
)
# Create config
endpoint_config = EndpointConfig.create(
endpoint_config_name=endpoint_config_name,
production_variants=[
ProductionVariant(
variant_name="AllTraffic",
model_name=model_name,
initial_variant_weight=1.0,
instance_type=instance_type,
initial_instance_count=1,
model_data_download_timeout_in_seconds=health_check_timeout,
)
]
)
# Create endpoint
endpoint = Endpoint.create(
endpoint_name=endpoint_name,
endpoint_config_name=endpoint_config_name
)
endpoint.wait_for_status("InService")
Testando com streaming bidirecional
Com o endpoint em execução, a invocação é feita pelo SDK Python aws-sdk-sagemaker-runtime-http2, que se comunica via event streams HTTP/2 na porta 8443 do endpoint de runtime do SageMaker AI.
O repositório inclui um cliente completo sagemaker_bidi_client.py que encapsula o SDK de streaming bidirecional em uma classe SageMakerRealtimeClient. Quando transcribe_audio() é executado, ele primeiro envia um evento session.update para selecionar o modelo e depois transmite o arquivo de áudio em chunks de 4 KB PCM16. O loop de recebimento roda como uma asyncio.Task em segundo plano, enquanto a corrotina principal envia os chunks de áudio — garantindo que ambas as direções do stream HTTP/2 estejam ativas simultaneamente.
O detalhe-chave que torna esse overlap observável é o await asyncio.sleep(chunk_duration) após cada envio. Ele cadencia a transmissão para corresponder à reprodução em tempo real (~128 ms por chunk de 4 KB a 16 kHz) e cede o controle ao event loop, dando à tarefa de recebimento a chance de processar eventos transcription.delta enquanto mais áudio ainda está sendo enviado.
Para executar o cliente:
python sagemaker_bidi_client.py ./audio.wav \
--region us-east-1
Demo ao vivo com microfone e Gradio
O cliente baseado em arquivo é útil para testes, mas o streaming bidirecional entrega sua menor latência com áudio ao vivo. O repositório inclui um cliente de microfone baseado em Gradio (sagemaker_bidi_microphone_client.py) que captura o áudio do microfone e o transmite ao SageMaker AI em tempo real:
python sagemaker_bidi_microphone_client.py \
--endpoint-name \
--region us-east-1
O cliente de microfone usa a mesma configuração DataType="UTF8" e o mesmo protocolo da Realtime API do vLLM que o cliente baseado em arquivo. Ele captura o áudio do navegador via Gradio, reamosta para 16 kHz PCM16, codifica cada chunk em base64 e o envia pelo stream bidirecional do SageMaker AI. O texto de transcrição é atualizado na interface à medida que o usuário fala, sem esperar o fim do enunciado.
Considerações importantes
- A Realtime API do vLLM espera áudio como PCM16 codificado em base64 a 16 kHz mono. Se o áudio de origem usar um formato ou taxa de amostragem diferente, converta antes de transmitir.
- O Voxtral-Mini-4B-Realtime-2602 é um modelo de 4 bilhões de parâmetros e cabe em uma única GPU. Uma instância
ml.g6.4xlarge(1x NVIDIA L4) é suficiente para hospedá-lo. - O SageMaker AI mantém a conexão WebSocket com frames ping/pong a cada 60 segundos, e a conexão é encerrada se 5 pings consecutivos ficarem sem resposta. Para sessões longas, o cliente deve tratar a reconexão em vez de assumir que o stream permanecerá aberto indefinidamente.
- O tamanho do chunk e o cadenciamento também valem ser ajustados. O exemplo usa chunks de 4 KB, equivalente a aproximadamente 128 ms de áudio a 16 kHz PCM16. Chunks menores reduzem a latência, mas aumentam a sobrecarga por mensagem; chunks maiores melhoram o throughput ao custo de maior latência.
Limpeza dos recursos
Para evitar cobranças contínuas, é importante excluir os recursos criados após os testes. O endpoint do SageMaker AI cobra pela instância subjacente enquanto estiver ativo, portanto removê-lo é o passo mais crítico. O notebook que acompanha a solução inclui uma célula de limpeza que exclui o endpoint, a configuração do endpoint e o modelo. Se a imagem de contêiner customizada no Amazon Elastic Container Registry (ECR) ou os artefatos de modelo no Amazon Simple Storage Service (S3) não forem mais necessários, esses recursos devem ser excluídos separadamente para evitar cobranças de armazenamento.
Conclusão e próximos passos
A combinação do SageMaker AI com o vLLM demonstra como é possível ir de um modelo de fala no Hugging Face a um serviço de transcrição em tempo real totalmente gerenciado, sem construir infraestrutura de streaming customizada nem gerenciar servidores de GPU. A infraestrutura de streaming bidirecional do SageMaker AI atua como uma ponte transparente entre event streams HTTP/2 (lado do cliente) e WebSocket (lado do contêiner).
Esse padrão vai além da transcrição de fala. Casos de uso que exigem comunicação contínua e bidirecional — agentes de voz, tradução em tempo real, geração de áudio interativa ou diálogo em streaming com múltiplos turnos — podem usar a mesma arquitetura.
Para ir além, a AWS sugere as seguintes direções:
- Estender a demo Gradio em uma aplicação completa: Use o cliente de microfone ao vivo como ponto de partida e adicione funcionalidades como exportação de transcrição ou sumarização encadeando a saída de transcrição em um LLM de texto.
- Ajustar o endpoint para seus requisitos de latência e custo: Experimente tipos de instância, tamanhos de chunk e configurações de compilação do vLLM para encontrar o equilíbrio certo para sua carga de trabalho.
- Implantar um modelo diferente: Substitua o Voxtral-Mini-4B-Realtime-2602 por outro modelo suportado pela Realtime API do vLLM atualizando o artefato do modelo e o identificador nos clientes.
- Aprofundar o conhecimento sobre streaming bidirecional: Consulte a documentação oficial para entender o contrato completo do event stream HTTP/2 e aplicá-lo a outros casos de uso.
O notebook completo, o cliente baseado em arquivo e a demo ao vivo com microfone estão disponíveis no GitHub.
Pré-requisitos
Para reproduzir a solução, são necessários:
- Uma conta AWS com permissões do SageMaker AI (incluindo
sagemaker:InvokeEndpoint*para streaming bidirecional) - Ambiente Docker (SageMaker AI Studio com Docker habilitado ou uma máquina local)
- Python 3.12+
- Acesso ao modelo Voxtral-Mini-4B-Realtime-2602 no Hugging Face
- O pacote Python aws-sdk-sagemaker-runtime-http2 para invocar a API de streaming bidirecional
Fonte
Build real-time voice applications with Amazon SageMaker AI and vLLM (https://aws.amazon.com/blogs/machine-learning/build-real-time-voice-applications-with-amazon-sagemaker-ai-and-vllm/)
Leave a Reply