Em uma implantação do Model Service Mesh com múltiplos modelos, um serviço Kubernetes distribui as solicitações de inferência aleatoriamente entre todos os runtimes de serviço de modelo. Se uma solicitação chegar a um runtime que não hospeda o modelo alvo, o Model Service Mesh a redireciona internamente até encontrar o runtime correto. Esse redirecionamento aumenta a latência.
O balanceamento de carga por subconjunto dinâmico resolve esse problema ao agrupar os runtimes com base nos modelos que hospedam. Quando uma solicitação de inferência chega ao gateway do Service Mesh (ASM), ele lê o nome do modelo no cabeçalho da solicitação e a encaminha diretamente para um runtime que hospeda esse modelo. Isso elimina o redirecionamento e reduz a latência de inferência.
Para obter uma visão geral do conceito, consulte Balanceamento de carga por subconjunto dinâmico.
Como funciona
O balanceamento de carga por subconjunto dinâmico depende de dois recursos do Istio: uma DestinationRule define quais runtimes agrupar e uma VirtualService define como corresponder as solicitações a esses grupos.
A DestinationRule agrupa os runtimes em subconjuntos. O ASM estende a DestinationRule padrão com o campo
dynamicSubset, que agrupa endpoints por uma chave de rótulo. O Model Service Mesh atualiza automaticamente os rótulos dos runtimes conforme os modelos são carregados ou descarregados, mantendo os subconjuntos atualizados sem intervenção manual.A VirtualService corresponde às solicitações recebidas aos subconjuntos. O ASM estende a VirtualService padrão com o campo
headerToDynamicSubsetKey, que mapeia um cabeçalho de solicitação (comomodel) para a chave de rótulo do subconjunto dinâmico. O gateway usa esse mapeamento para rotear cada solicitação ao subconjunto correto.
Se nenhum subconjunto corresponder à solicitação, a fallbackPolicy determina o comportamento:
|
Política de fallback |
Comportamento |
|
|
Roteia para qualquer runtime disponível, independentemente dos rótulos. Preserva a disponibilidade ao custo de possível redirecionamento. Utilizada neste tutorial. |
Pré-requisitos
Antes de começar, verifique se você tem:
Uma instância do ASM versão V1.21.6.47 ou posterior. Para mais informações, consulte Crie uma instância do ASM
Um cluster Container Service for Kubernetes (ACK) adicionado à instância do ASM. Para mais informações, consulte Adicionar um cluster a uma instância do ASM
Model Service Mesh ativado com o modelo sklearn-mnist implantado. Para mais informações, consulte Usar o Model Service Mesh para lançar um serviço de inferência multimodelo
Etapa 1: Implantar um segundo modelo
O balanceamento de carga por subconjunto dinâmico é voltado para cenários com múltiplos modelos. Esta etapa adiciona um modelo tf-mnist (um modelo MNIST baseado em TensorFlow servido pelo runtime Triton) juntamente com o modelo sklearn-mnist existente.
Esta etapa utiliza a persistent volume claim (PVC) my-models-pvc criada em Usar o Model Service Mesh para lançar um serviço de inferência multimodelo. O conteúdo do modelo tf-mnist compreende tudo dentro do diretório mnist.
Armazenar o modelo no volume persistente
-
Conecte-se ao cluster ACK com kubectl e copie o diretório do modelo
mnistpara o volume persistente:kubectl -n modelmesh-serving cp mnist pvc-access:/mnt/models/ -
Verifique se o modelo existe no volume persistente:
kubectl -n modelmesh-serving exec -it pvc-access -- ls -alr /mnt/models/Saída esperada:
-rw-r--r-- 1 502 staff 344817 Apr 23 08:17 mnist-svm.joblib drwxr-xr-x 3 root root 4096 Apr 23 08:23 mnist drwxr-xr-x 1 root root 4096 Apr 23 08:17 .. drwxrwxrwx 3 root root 4096 Apr 23 08:23 .
Implantar o serviço de inferência
-
Crie um arquivo chamado
tf-mnist.yamlcom o seguinte conteúdo:apiVersion: serving.kserve.io/v1beta1 kind: InferenceService metadata: name: tf-mnist namespace: modelmesh-serving annotations: serving.kserve.io/deploymentMode: ModelMesh spec: predictor: model: modelFormat: name: tensorflow storage: parameters: type: pvc name: my-models-pvc path: mnist -
Aplique o manifesto:
kubectl apply -f tf-mnist.yaml -
Aguarde o download da imagem e verifique se ambos os modelos estão prontos:
kubectl get isvc -n modelmesh-servingSaída esperada:
NAME URL READY sklearn-mnist grpc://modelmesh-serving.modelmesh-serving:8033 True tf-mnist grpc://modelmesh-serving.modelmesh-serving:8033 True
(Opcional) Etapa 2: Medir a latência de inferência antes da otimização
Use o fortio para medir a latência de base antes de ativar o balanceamento de carga por subconjunto dinâmico. Para obter o endereço IP do gateway de entrada do ASM, consulte Integrar o KServe com o ASM para implementar serviços de inferência baseados em modelos nativos da nuvem com IA.
-
Defina o IP do gateway e execute um teste de carga de 60 segundos no modelo tf-mnist:
ASM_GW_IP="<your-asm-gateway-ip>" fortio load -jitter=False -H 'model: tf-mnist' -c 1 -qps 100 -t 60s -payload '{"inputs": [{ "name": "inputs", "shape": [1, 784], "datatype": "FP32", "contents": { "fp32_contents": [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.01176471, 0.07058824, 0.07058824, 0.07058824, 0.49411765, 0.53333336, 0.6862745, 0.10196079, 0.6509804, 1.0, 0.96862745, 0.49803922, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.11764706, 0.14117648, 0.36862746, 0.6039216, 0.6666667, 0.99215686, 0.99215686, 0.99215686, 0.99215686, 0.99215686, 0.88235295, 0.6745098, 0.99215686, 0.9490196, 0.7647059, 0.2509804, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.19215687, 0.93333334, 0.99215686, 0.99215686, 0.99215686, 0.99215686, 0.99215686, 0.99215686, 0.99215686, 0.99215686, 0.9843137, 0.3647059, 0.32156864, 0.32156864, 0.21960784, 0.15294118, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.07058824, 0.85882354, 0.99215686, 0.99215686, 0.99215686, 0.99215686, 0.99215686, 0.7764706, 0.7137255, 0.96862745, 0.94509804, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.3137255, 0.6117647, 0.41960785, 0.99215686, 0.99215686, 0.8039216, 0.04313726, 0.0, 0.16862746, 0.6039216, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.05490196, 0.00392157, 0.6039216, 0.99215686, 0.3529412, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.54509807, 0.99215686, 0.74509805, 0.00784314, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.04313726, 0.74509805, 0.99215686, 0.27450982, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.13725491, 0.94509804, 0.88235295, 0.627451, 0.42352942, 0.00392157, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.31764707, 0.9411765, 0.99215686, 0.99215686, 0.46666667, 0.09803922, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1764706, 0.7294118, 0.99215686, 0.99215686, 0.5882353, 0.10588235, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0627451, 0.3647059, 0.9882353, 0.99215686, 0.73333335, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.9764706, 0.99215686, 0.9764706, 0.2509804, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.18039216, 0.50980395, 0.7176471, 0.99215686, 0.99215686, 0.8117647, 0.00784314, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.15294118, 0.5803922, 0.8980392, 0.99215686, 0.99215686, 0.99215686, 0.98039216, 0.7137255, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.09411765, 0.44705883, 0.8666667, 0.99215686, 0.99215686, 0.99215686, 0.99215686, 0.7882353, 0.30588236, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.09019608, 0.25882354, 0.8352941, 0.99215686, 0.99215686, 0.99215686, 0.99215686, 0.7764706, 0.31764707, 0.00784314, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.07058824, 0.67058825, 0.85882354, 0.99215686, 0.99215686, 0.99215686, 0.99215686, 0.7647059, 0.3137255, 0.03529412, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.21568628, 0.6745098, 0.8862745, 0.99215686, 0.99215686, 0.99215686, 0.99215686, 0.95686275, 0.52156866, 0.04313726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.53333336, 0.99215686, 0.99215686, 0.99215686, 0.83137256, 0.5294118, 0.5176471, 0.0627451, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] }}]}' -a ${ASM_GW_IP}:8008/v2/models/tf-mnist/inferSaída esperada:
-
Visualize os resultados do fortio em um navegador:
fortio serverAbra
localhost:8080, clique em saved results e selecione o arquivo JSON para visualizar a distribuição de latência.
Sem o balanceamento de carga por subconjunto dinâmico, algumas solicitações de inferência apresentam maior latência porque o Model Service Mesh as redireciona antes de alcançarem o runtime correto.
Etapa 3: Ative o balanceamento de carga por subconjunto dinâmico
As solicitações de inferência chegam ao Model Service Mesh através do serviço modelmesh-serving no namespace modelmesh-serving. Configure uma DestinationRule e uma VirtualService nesse serviço para rotear as solicitações diretamente ao runtime de serviço de modelo correto.
Crie a DestinationRule
Aplique a seguinte DestinationRule para agrupar dinamicamente os runtimes de serviço de modelo pelos modelos que hospedam. Para mais informações, consulte Gerencie regras de destino.
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: modelmesh-serving
namespace: modelmesh-serving
spec:
host: modelmesh-serving
trafficPolicy:
loadBalancer:
dynamicSubset:
subsetSelectors:
- fallbackPolicy: ANY_ENDPOINT
keys:
- modelmesh.asm.alibabacloud.com
Campos principais:
|
Campo |
Finalidade |
|
|
Permite o agrupamento dinâmico de endpoints com base em rótulos de runtime, em vez de definições estáticas de subconjuntos |
|
|
Chave de rótulo usada para agrupar os runtimes. O Model Service Mesh define o rótulo |
|
|
Quando nenhum subconjunto corresponde, roteia para qualquer runtime disponível em vez de rejeitar a solicitação |
Atualize a VirtualService
Aplique a seguinte VirtualService para mapear o cabeçalho de solicitação model para a chave do subconjunto dinâmico. Para mais informações, consulte Gerencie serviços virtuais.
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: vs-modelmesh-serving-service
namespace: modelmesh-serving
spec:
gateways:
- grpc-gateway
hosts:
- '*'
http:
- headerToDynamicSubsetKey:
- header: model
key: modelmesh.asm.alibabacloud.com
match:
- port: 8008
name: default
route:
- destination:
host: modelmesh-serving
port:
number: 8033
O campo headerToDynamicSubsetKey é uma extensão do ASM para a VirtualService padrão do Istio. Quando o gateway recebe uma solicitação com o cabeçalho model: tf-mnist, ele consulta o valor no rótulo modelmesh.asm.alibabacloud.com e roteia a solicitação para um runtime no subconjunto dinâmico correspondente.
(Opcional) Etapa 4: Medir a latência de inferência após a otimização
Execute o mesmo teste do fortio da Etapa 2 para comparar a latência.

Após ativar o balanceamento de carga por subconjunto dinâmico, todas as solicitações de inferência são roteadas diretamente para o runtime correto. A distribuição de latência torna-se significativamente mais concentrada, sem valores discrepantes causados por redirecionamentos internos.