O fim do suporte ao TorchServe e o que isso significa na prática
O TorchServe não está mais sendo mantido ativamente. O aviso oficial do projeto deixa claro: não há previsão de atualizações, correções de bugs, novos recursos ou patches de segurança, e vulnerabilidades podem ficar sem resposta.
Para equipes que hoje rodam inferência de modelos com TorchServe, isso significa duas consequências diretas: os patches de segurança param de chegar e as atualizações de compatibilidade com versões mais recentes do PyTorch e do CUDA também param. O time passa a ser responsável por toda a cadeia de dependências — escolher versões compatíveis na pilha de GPU, corrigir vulnerabilidades em cada camada e depurar falhas sutis quando qualquer componente sai de alinhamento. É um trabalho sem diferencial competitivo que atrasa a entrega de modelos sem agregar valor ao produto final.
O que são os AWS Deep Learning Containers e como o Ray Serve DLC se encaixa
Os AWS Deep Learning Containers (DLCs) já resolvem esse tipo de problema há algum tempo para cargas de trabalho de treinamento. São imagens Docker pré-construídas e otimizadas para desempenho que empacotam um framework, suas dependências e a pilha de GPU em uma combinação testada e com patches aplicados — pronta para uso imediato.
Com o lançamento do Ray Serve DLC, essa mesma abordagem chega agora à inferência. O resultado é um container construído especificamente para servir modelos atrás de um endpoint HTTP, mantido e testado pela AWS, com toda a pilha de inferência já montada.
Como o Ray Serve DLC é construído
A variante de CPU do Ray Serve DLC é baseada na imagem Amazon Linux 2023. Já a variante de GPU é construída sobre a imagem oficial da NVIDIA para Amazon Linux 2023, que inclui tanto a camada do sistema operacional quanto as bibliotecas de runtime do CUDA. Sobre essa base, o DLC adiciona:
- O framework de deep learning PyTorch
- A camada de serving do Ray Serve com FastAPI e Uvicorn
- Utilitários comuns para cargas de trabalho de visão, áudio e multimodal
- FFmpeg compilado com aceleração de hardware NVIDIA para pré-processamento de vídeo
Todos os componentes são validados e testados juntos antes de cada release, o que elimina o problema de versões incompatíveis entre o runtime do CUDA, o framework e a camada de serving. Patches de segurança são aplicados no momento do build.
O Ray Serve DLC é publicado como imagens separadas para o Amazon Elastic Kubernetes Service (EKS), para o Amazon Elastic Compute Cloud (EC2) e para o Amazon SageMaker — cada um com um entrypoint dedicado adequado ao contrato de serving daquele ambiente. Todos compartilham a mesma pilha e dependências subjacentes. Para a lista atual de tags de imagem disponíveis, consulte a página de imagens disponíveis do Ray DLC.
Compondo a aplicação Ray Serve
O DLC já entrega a pilha de inferência comum, então muitos modelos — incluindo o modelo Qwen3-VL-2B — rodam nele sem necessidade de uma imagem customizada. Para modelos que precisam de bibliotecas extras, é possível adicioná-las em camadas sobre a mesma base testada.
No exemplo apresentado pela AWS, a versão GPU do Ray Serve DLC é usada para servir o modelo vision-language Qwen3-VL-2B. A aplicação é injetada no container por meio de um ConfigMap, o que mantém o deploy flexível: é possível alterar o código de serving sem reconstruir a imagem. O DLC já fornece a pilha de GPU, PyTorch, Ray Serve e Transformers.
Escrevendo a aplicação de serving
Com o Ray Serve, um endpoint de modelo é uma classe Python decorada com @serve.deployment. O método __call__ trata as requisições HTTP e .bind() registra o deployment. Não há archiver de modelo, hierarquia de classes handler nem arquivo de configuração de propriedades.
Para quem vem do TorchServe, isso substitui o handler customizado, a etapa do torch-model-archiver e o arquivo config.properties.
O exemplo a seguir carrega o modelo vision-language Qwen3-VL-2B na GPU e o expõe como um endpoint HTTP. Quando uma requisição chega com uma URL de imagem e um prompt de texto, o modelo gera uma resposta em linguagem natural descrevendo ou respondendo perguntas sobre a imagem:
from ray import serve
from transformers import AutoModelForImageTextToText, AutoProcessor
import torch
@serve.deployment(ray_actor_options={"num_gpus": 1})
class QwenVLService:
def __init__(self):
model_name = "Qwen/Qwen3-VL-2B-Instruct"
self.processor = AutoProcessor.from_pretrained(model_name)
self.model = AutoModelForImageTextToText.from_pretrained(
model_name, torch_dtype=torch.float16
).to("cuda")
async def __call__(self, request):
try:
body = await request.json()
image_url = body.get("image_url")
prompt = body.get("prompt")
messages = [{"role": "user", "content": [
{"type": "image", "image": image_url},
{"type": "text", "text": prompt},
]}]
inputs = self.processor.apply_chat_template(
messages,
tokenize=True,
add_generation_prompt=True,
return_dict=True,
return_tensors="pt"
).to("cuda")
generated_ids = self.model.generate(**inputs, max_new_tokens=200)
trimmed = [o[len(i):] for i, o in zip(inputs.input_ids, generated_ids)]
output = self.processor.batch_decode(trimmed, skip_special_tokens=True)[0]
return {"response": output}
Except Exception:
logger.exception("Qwen inference request failed")
return {"error": "Unable to generate a response. Please try again later."}
app = QwenVLService.bind()
Toda a lógica de serving em qwen_serve.py é adicionada a um ConfigMap chamado qwen-serve-code. O decorator @serve.deployment com ray_actor_options={"num_gpus": 1} instrui o Ray a agendar esse deployment em um worker com uma GPU disponível. O modelo é carregado em float16 para caber nos 24 GB de VRAM disponíveis na GPU A10G usada no exemplo.
Deploy no Amazon EKS
O deploy é feito com o Ray Serve DLC junto ao ConfigMap qwen-serve-code. A arquitetura resultante é um cluster Amazon EKS com um único nó de GPU rodando um pod que serve o modelo via HTTP na porta 8000.

O deploy usa uma única instância g5.xlarge (uma GPU NVIDIA A10G, 24 GB de VRAM). É uma configuração de inferência em nó único: um pod, uma GPU, uma máquina. Para serving distribuído em múltiplos nós — paralelismo de modelo entre máquinas ou autoescala horizontal com múltiplas réplicas — seria necessário construir sobre essa base usando KubeRay para orquestrar workers do Ray entre nós.
O repositório disponibilizado pela AWS inclui scripts que automatizam a configuração da infraestrutura:
deploy_cluster.sh: provisiona um cluster EKS usandoeksctl, com rede de Nuvem Privada Virtual (VPC), um provedor OIDC para autenticação de pods baseada em Gerenciamento de Identidade e Acesso (IAM) e add-ons essenciais do cluster.deploy_node_group.sh: adiciona um grupo de nós de GPU gerenciado com uma única instância g5.xlarge rotulada comorole=gpu-worker.deploy_ray_cluster.sh: aplica o ConfigMap com oqwen_serve.py, faz o deploy de um manifesto Kubernetes que agenda o pod no nó de GPU e inicia o Ray Serve na porta 8000.
Após executar os três scripts, é possível verificar que o pod está rodando e a GPU está alocada:
kubectl get pods -n inference
kubectl describe pod -n inference -l app=ray-serve | grep "nvidia.com/gpu"
Com o pod reportando como pronto, basta fazer o port-forward para testá-lo:
kubectl port-forward -n inference deploy/ray-cluster 8000:8000
Em outro terminal, é possível enviar uma requisição pedindo ao modelo Qwen3-VL-2B que descreva uma imagem:
curl -X POST http://127.0.0.1:8000/ \
-H "Content-Type: application/json" \
-d '{
"image_url": "https://s3.amazonaws.com/model-server/inputs/kitten.jpg",
"prompt": "Describe this image briefly."
}'
A resposta será um JSON com a descrição gerada pelo modelo. Para confirmar que a inferência está rodando na GPU:
kubectl exec -n inference deploy/ray-cluster -- nvidia-smi
Observação: o pod reporta como pronto um ou dois minutos antes do Ray Serve começar a responder, porque o modelo ainda está sendo carregado. Se a primeira requisição for recusada, basta aguardar um minuto e tentar novamente.
Limpeza dos recursos
Para evitar cobranças contínuas, os recursos devem ser removidos na ordem inversa:
./delete_ray_cluster.sh # Remove o deploy do Ray Serve
./delete_node_group.sh # Remove o grupo de nós de GPU
./delete_cluster.sh # Exclui o cluster EKS
Conclusão e próximos passos
Ao final desse processo, o resultado é um endpoint de inferência funcional — sem precisar manter compatibilidade com CUDA manualmente, sem escrever boilerplate de handler do TorchServe e sem montar um Dockerfile de múltiplos estágios que costura a pilha de GPU do zero. É exatamente para isso que o Ray Serve DLC foi projetado: oferecer um container com suporte e pré-testado para que as equipes possam focar no código do modelo, não na manutenção de infraestrutura.
Para equipes que ainda estão no TorchServe, esse é um caminho de migração sólido. O DLC elimina o problema de versões incompatíveis, simplifica upgrades para uma simples troca de tag e fornece patches de segurança regulares gerenciados pela AWS. Para cargas de trabalho que precisam escalar além de um único nó, o KubeRay estende essa mesma base para serving distribuído em múltiplos nós.
Para começar, acesse o exemplo de código completo com o deploy end-to-end. Para navegar por todas as imagens DLC disponíveis, incluindo variantes de CPU e outros frameworks, consulte a referência de AWS Deep Learning Containers.
Fonte
Simplify and support your TorchServe workloads using Ray Serve Deep Learning Containers (https://aws.amazon.com/blogs/machine-learning/simplify-and-support-your-torchserve-workloads-using-ray-serve-deep-learning-containers/)
Leave a Reply