Grade de serviço de modelo: gerenciamento de serviço de modelo sob nuvem nativa

Model Service Mesh é um padrão arquitetônico usado para implantar e gerenciar serviços de modelo de aprendizado de máquina em um ambiente distribuído. Ele fornece uma infraestrutura escalonável e de alto desempenho para gerenciar, implantar e agendar vários serviços de modelo para lidar melhor com a implantação de modelo, gerenciamento de versão, roteamento e balanceamento de carga de solicitações de inferência.

A ideia central da grade de serviço modelo é implantar modelos como serviços escaláveis ​​e gerenciar e rotear esses serviços através da grade, simplificando o gerenciamento e a operação dos serviços modelo. Ele facilita a implantação, a extensão e o controle de versão do modelo, abstraindo os serviços do modelo em unidades orquestradas e escaláveis. Ele também fornece algumas funções básicas, como balanceamento de carga, escalonamento automático, recuperação de falhas, etc., para garantir alta disponibilidade e confiabilidade dos serviços do modelo.

Os modelos podem ser automaticamente dimensionados e balanceados com base na carga real da solicitação de inferência, permitindo uma inferência eficiente do modelo. A grade de serviço de modelo também fornece algumas funções avançadas, como segmentação de tráfego, testes A/B, publicação em escala de cinza, etc., para melhor controlar e gerenciar o tráfego de serviços de modelo, e pode alternar e reverter facilmente diferentes versões de modelo. Ele também oferece suporte ao roteamento dinâmico, que pode rotear solicitações para o serviço de modelo apropriado com base nas propriedades da solicitação, como tipo de modelo, formato de dados ou outros metadados.

O Alibaba Cloud Service Grid ASM forneceu uma capacidade básica de grade de serviço de modelo escalonável e de alto desempenho para gerenciar, implantar e agendar vários serviços de modelo para lidar melhor com a implantação de modelo e gerenciamento de versão, roteamento e balanceamento de carga de solicitações de inferência. Ao usar uma malha de serviço de modelo, os desenvolvedores podem implantar, gerenciar e dimensionar modelos de aprendizado de máquina com mais facilidade, ao mesmo tempo que fornecem alta disponibilidade, resiliência e flexibilidade para atender às diversas necessidades de negócios.

01 Use grade de serviço de modelo para serviço de inferência multimodelo

O Model Service Grid é implementado com base no KServe ModelMesh e é otimizado para casos de uso de modelos de grande volume, alta densidade e mudanças frequentes. Ele pode carregar ou descarregar modelos de forma inteligente na memória para encontrar um equilíbrio entre capacidade de resposta e computação.

A malha de serviço modelo fornece os seguintes recursos:

  • Gerenciamento de cache
  • Os pods são gerenciados como um cache distribuído menos usado recentemente (LRU).
  • Carregue e descarregue cópias do modelo com base na frequência de uso e no volume de solicitações atual.
  • Posicionamento e carregamento inteligentes
  • O posicionamento do modelo é equilibrado pela idade do cache e pela carga de solicitação entre os pods.
  • Use filas para lidar com o carregamento simultâneo de modelos e minimizar o impacto no tráfego de tempo de execução.
  • elasticidade
  • O carregamento do modelo com falha é repetido automaticamente em pods diferentes.
  • De facil operação
  • Lide com atualizações contínuas de modelos de forma automática e contínua.

A seguir está um exemplo de modelo de implantação. Para pré-requisitos de uso, consulte [1].

1.1 Criar declaração de armazenamento PVC

No cluster ACK, crie a declaração de armazenamento my-models-pvc usando o seguinte YAML:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
 name: my-models-pvc
  namespace: modelmesh-serving
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 1Gi
  storageClassName: alibabacloud-cnfs-nas
  volumeMode: Filesystem

Em seguida, execute o seguinte comando:

kubectl get pvc -n modelmesh-serving

Você obterá resultados esperados semelhantes aos seguintes:

NAME STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS            AGE
my-models-pvc    Bound    nas-379c32e1-c0ef-43f3-8277-9eb4606b53f8   1Gi        RWX            alibabacloud-cnfs-nas   2h

1.2 Criar Pod para acessar o PVC

Para usar o novo PVC, precisamos montá-lo como um volume no Pod Kubernetes. Podemos então usar este pod para fazer upload dos arquivos de modelo para um volume persistente.

Vamos implantar um pod de acesso pvc e pedir ao controlador Kubernetes para declarar o PVC que solicitamos anteriormente, especificando "my-models-pvc":

kubectl apply  -n modelmesh-serving  -f - <<EOF
---
apiVersion: v1
kind: Pod
metadata:
  name: "pvc-access"
spec:
  containers:
    - name: main
      image: ubuntu
      command: ["/bin/sh", "-ec", "sleep 10000"]
      volumeMounts:
        - name: "my-pvc"
          mountPath: "/mnt/models"
  volumes:
    - name: "my-pvc"
      persistentVolumeClaim:
        claimName: "my-models-pvc"
EOF

Confirme se o pod pvc-access deve estar em execução:

kubectl get pods -n modelmesh-serving | grep pvc-access

Você obterá resultados esperados semelhantes aos seguintes:

pvc-access 1/1     Running

1.3 Armazene o modelo em um volume persistente

Agora, precisamos adicionar nosso modelo de IA ao volume de armazenamento, usaremos o modelo de reconhecimento de caracteres de dígitos manuscritos MNIST treinado pelo scikit-learn. Uma cópia do arquivo de modelo mnist-svm.joblib pode ser baixada do repositório kserve/modelmesh-minio-examples [2].

Copie o arquivo de modelo mnist-svm.joblib para a pasta /mnt/models no pod pvc-access com o seguinte comando:

kubectl -n modelmesh-serving cp mnist-svm.joblib pvc-access:/mnt/models/

Execute o seguinte comando para confirmar se o modelo foi carregado com sucesso:

kubectl -n modelmesh-serving exec -it pvc-access -- ls -alr /mnt/models/

Você deve obter algo assim:

-rw-r--r-- 1 501 staff 344817 Oct 30 11:23 mnist-svm.joblib

1.4 Implantar serviço de inferência

A seguir, precisamos implantar um serviço de inferência sklearn-mnist:

apiVersion: serving.kserve.io/v1beta1
kind: InferenceService
metadata:
  name: sklearn-mnist
  namespace: modelmesh-serving
  annotations:
    serving.kserve.io/deploymentMode: ModelMesh
spec:
  predictor:
    model:
      modelFormat:
        name: sklearn
      storage:
        parameters:
          type: pvc
          name: my-models-pvc
        path: mnist-svm.joblib

Após dezenas de segundos (dependendo da velocidade de extração da imagem), o novo serviço de inferência sklearn-mnist deverá estar pronto.

Execute o seguinte comando:

kubectl get isvc -n modelmesh-serving

Você obterá resultados esperados semelhantes aos seguintes:

NAME URL                  READY
sklearn-mnist   grpc://modelmesh-serving.modelmesh-serving:8033   True

1.5 Executando o serviço de inferência

Agora podemos usar curl para enviar solicitações de inferência ao nosso modelo sklearn-mnist. Os dados solicitados na forma de uma matriz representam os valores da escala de cinza de 64 pixels na digitalização da imagem digital a ser classificada.

MODEL_NAME="sklearn-mnist"
ASM_GW_IP="ASM网关IP地址"
curl -X POST -k "http://${ASM_GW_IP}:8008/v2/models/${MODEL_NAME}/infer" -d '{"inputs": [{"name": "predict", "shape": [1, 64], "datatype": "FP32", "contents": {"fp32_contents": [0.0, 0.0, 1.0, 11.0, 14.0, 15.0, 3.0, 0.0, 0.0, 1.0, 13.0, 16.0, 12.0, 16.0, 8.0, 0.0, 0.0, 8.0, 16.0, 4.0, 6.0, 16.0, 5.0, 0.0, 0.0, 5.0, 15.0, 11.0, 13.0, 14.0, 0.0, 0.0, 0.0, 0.0, 2.0, 12.0, 16.0, 13.0, 0.0, 0.0, 0.0, 0.0, 0.0, 13.0, 16.0, 16.0, 6.0, 0.0, 0.0, 0.0, 0.0, 16.0, 16.0, 16.0, 7.0, 0.0, 0.0, 0.0, 0.0, 11.0, 13.0, 12.0, 1.0, 0.0]}}]}'

A resposta JSON deve ficar assim, inferindo que o número digitalizado é "8":

{
"modelName": "sklearn-mnist__isvc-3c10c62d34",
 "outputs": [
  {
   "name": "predict",
   "datatype": "INT64",
   "shape": [
    "1",
    "1"
   ],
   "contents": {
    "int64Contents": [
     "8"
    ]
   }
  }
 ]
}

02 Personalize o tempo de execução do modelo usando a malha de serviço do modelo

Model Service Mesh (ModelMesh para abreviar) é otimizado para a implantação e operação de serviços de inferência de modelo de grande capacidade, alta densidade e mudanças frequentes. Ele pode carregar ou descarregar modelos de forma inteligente na memória para garantir que eles obtenham o melhor equilíbrio entre capacidade de resposta e computação.

ModelMesh integra os seguintes ambientes de execução de servidor modelo por padrão, como

  • O Triton Inference Server, servidor da NVIDIA, é adequado para estruturas como TensorFlow, PyTorch, TensorRT ou ONNX.
  • MLServer, servidor baseado em Python da Seldon, adequado para frameworks como SKLearn, XGBoost ou LightGBM.
  • OpenVINO Model Server, servidor da Intel para estruturas como Intel OpenVINO ou ONNX.
  • TorchServe, suporta modelos PyTorch, incluindo modo ansioso.

Se esses servidores modelo não puderem atender aos seus requisitos específicos, por exemplo, se você precisar manipular lógica customizada para inferência ou se seu modelo exigir uma estrutura que não esteja na lista de suporte acima, será possível customizar o tempo de execução do serviço para suporte estendido.

Para obter detalhes, consulte [3].

03 Fornecer serviços para modelo de linguagem grande LLM

Large Language Model (LLM) refere-se a um modelo de linguagem de rede neural com centenas de milhões de parâmetros, como GPT-3, GPT-4, PaLM, PaLM2, etc. A seguir descreve como fornecer serviços para o modelo de linguagem grande LLM.

Os pré-requisitos para uso podem ser consultados em [4] para detalhes.

3.1 Construindo um tempo de execução personalizado

Crie um tempo de execução personalizado que forneça ao HuggingFace LLM prompts para ajustar a configuração. As configurações padrão neste exemplo são nossa imagem de tempo de execução personalizada pré-construída e configuração de ajuste de prompt pré-construída.

3.1.1 Implementar uma classe que herda de MLServer MLModel

O arquivo peft_model_server.py no diretório kfp-tekton/samples/peft-modelmesh-pipeline [5] contém todo o código sobre como fornecer ao HuggingFace LLM configuração de ajuste imediato.

A função _load_model abaixo mostra que selecionaremos o modelo LLM pré-treinado para a configuração de ajuste de prompt PEFT. Os tokenizadores também são definidos como parte do modelo e podem, portanto, ser usados ​​para codificar e decodificar entradas de string brutas em solicitações de inferência, sem exigir que os usuários pré-processem suas entradas em bytes tensores.

from typing import List

from mlserver import MLModel, types
from mlserver.codecs import decode_args

from peft import PeftModel, PeftConfig
from transformers import AutoModelForCausalLM, AutoTokenizer
import torch
import os

class PeftModelServer(MLModel):
    async def load(self) -> bool:
        self._load_model()
        self.ready = True
        return self.ready

    @decode_args
    async def predict(self, content: List[str]) -> List[str]:
        return self._predict_outputs(content)

    def _load_model(self):
        model_name_or_path = os.environ.get("PRETRAINED_MODEL_PATH", "bigscience/bloomz-560m")
        peft_model_id = os.environ.get("PEFT_MODEL_ID", "aipipeline/bloomz-560m_PROMPT_TUNING_CAUSAL_LM")
        self.tokenizer = AutoTokenizer.from_pretrained(model_name_or_path, local_files_only=True)
        config = PeftConfig.from_pretrained(peft_model_id)
        self.model = AutoModelForCausalLM.from_pretrained(config.base_model_name_or_path)
        self.model = PeftModel.from_pretrained(self.model, peft_model_id)
        self.text_column = os.environ.get("DATASET_TEXT_COLUMN_NAME", "Tweet text")
        return

    def _predict_outputs(self, content: List[str]) -> List[str]:
        output_list = []
        for input in content:
            inputs = self.tokenizer(
                f'{self.text_column} : {input} Label : ',
                return_tensors="pt",
            )
            with torch.no_grad():
                inputs = {k: v for k, v in inputs.items()}
                outputs = self.model.generate(
                    input_ids=inputs["input_ids"], attention_mask=inputs["attention_mask"], max_new_tokens=10, eos_token_id=3
                )
                outputs = self.tokenizer.batch_decode(outputs.detach().cpu().numpy(), skip_special_tokens=True)
            output_list.append(outputs[0])
        return output_list

3.1.2 Construir imagem Docker

Depois de implementar a classe model, precisamos empacotar suas dependências (incluindo MLServer) em uma imagem que suporte o recurso ServingRuntime. Consulte o Dockerfile a seguir para construir a imagem.

# TODO: choose appropriate base image, install Python, MLServer, and
# dependencies of your MLModel implementation
FROM python:3.8-slim-buster
RUN pip install mlserver peft transformers datasets
# ...

# The custom `MLModel` implementation should be on the Python search path
# instead of relying on the working directory of the image. If using a
# single-file module, this can be accomplished with:
COPY --chown=${USER} ./peft_model_server.py /opt/peft_model_server.py
ENV PYTHONPATH=/opt/

# environment variables to be compatible with ModelMesh Serving
# these can also be set in the ServingRuntime, but this is recommended for
# consistency when building and testing
ENV MLSERVER_MODELS_DIR=/models/_mlserver_models \
 MLSERVER_GRPC_PORT=8001 \
    MLSERVER_HTTP_PORT=8002 \
    MLSERVER_LOAD_MODELS_AT_STARTUP=false \
    MLSERVER_MODEL_NAME=peft-model

# With this setting, the implementation field is not required in the model
# settings which eases integration by allowing the built-in adapter to generate
# a basic model settings file
ENV MLSERVER_MODEL_IMPLEMENTATION=peft_model_server.PeftModelServer

CMD mlserver start ${MLSERVER_MODELS_DIR}

3.1.3 Crie um novo recurso ServingRuntime

Você pode usar o modelo YAML no bloco de código a seguir para criar um novo recurso ServingRuntime e apontá-lo para a imagem que acabou de criar.

apiVersion: serving.kserve.io/v1alpha1
kind: ServingRuntime
metadata:
 name: peft-model-server
  namespace: modelmesh-serving
spec:
  supportedModelFormats:
    - name: peft-model
      version: "1"
      autoSelect: true
  multiModel: true
  grpcDataEndpoint: port:8001
  grpcEndpoint: port:8085
  containers:
    - name: mlserver
      image:  registry.cn-beijing.aliyuncs.com/test/peft-model-server:latest
      env:
        - name: MLSERVER_MODELS_DIR
          value: "/models/_mlserver_models/"
        - name: MLSERVER_GRPC_PORT
          value: "8001"
        - name: MLSERVER_HTTP_PORT
          value: "8002"
        - name: MLSERVER_LOAD_MODELS_AT_STARTUP
          value: "true"
        - name: MLSERVER_MODEL_NAME
          value: peft-model
        - name: MLSERVER_HOST
          value: "127.0.0.1"
        - name: MLSERVER_GRPC_MAX_MESSAGE_LENGTH
          value: "-1"
        - name: PRETRAINED_MODEL_PATH
          value: "bigscience/bloomz-560m"
        - name: PEFT_MODEL_ID
          value: "aipipeline/bloomz-560m_PROMPT_TUNING_CAUSAL_LM"
        # - name: "TRANSFORMERS_OFFLINE"
        #   value: "1" 
        # - name: "HF_DATASETS_OFFLINE"
        #   value: "1"   
      resources:
        requests:
          cpu: 500m
          memory: 4Gi
        limits:
          cpu: "5"
          memory: 5Gi
  builtInAdapter:
    serverType: mlserver
    runtimeManagementPort: 8001
    memBufferBytes: 134217728
    modelLoadingTimeoutMillis: 90000

Em seguida, use o comando kubectl apply para criar o recurso ServingRuntime e você verá seu novo tempo de execução personalizado na implantação do ModelMesh.

3.2 Implantar serviço LLM

Para implantar o modelo usando o tempo de execução recém-criado, você precisa criar um recurso InferenceService para servir o modelo. Este recurso é a principal interface usada pelo KServe e ModelMesh para gerenciar modelos e representa o ponto final lógico do modelo na inferência.

apiVersion: serving.kserve.io/v1beta1
kind: InferenceService
metadata:
  name: peft-demo
  namespace: modelmesh-serving
  annotations:
    serving.kserve.io/deploymentMode: ModelMesh
spec:
  predictor:
    model:
      modelFormat:
        name: peft-model
      runtime: peft-model-server
      storage:
        key: localMinIO
        path: sklearn/mnist-svm.joblib

No bloco de código anterior, o InferenceService é denominado peft-demo e seu formato de modelo é declarado como peft-model, o mesmo formato usado pelo exemplo de tempo de execução personalizado criado anteriormente. Um tempo de execução de campo opcional também é passado, informando explicitamente ao ModelMesh para usar o tempo de execução peft-model-server para implantar este modelo.

3.3 Executando o serviço de inferência

Agora podemos usar curl para enviar solicitações de inferência ao serviço de modelo LLM que implantamos acima.

MODEL_NAME="peft-demo"
ASM_GW_IP="ASM网关IP地址"
curl -X POST -k http://${ASM_GW_IP}:8008/v2/models/${MODEL_NAME}/infer -d @./input.json

Onde input.json representa os dados da solicitação:

{
 "inputs": [
        {
          "name": "content",
          "shape": [1],
          "datatype": "BYTES",
          "contents": {"bytes_contents": ["RXZlcnkgZGF5IGlzIGEgbmV3IGJpbm5pbmcsIGZpbGxlZCB3aXRoIG9wdGlvbnBpZW5pbmcgYW5kIGhvcGU="]}
        }
    ]
}

bytes_contents corresponde à codificação base64 da string “Cada dia é um novo começo, cheio de oportunidades e esperança”.

A resposta JSON deve ficar assim, inferindo que o número digitalizado é "8":

{
"modelName": "peft-demo__isvc-5c5315c302",
 "outputs": [
  {
   "name": "output-0",
   "datatype": "BYTES",
   "shape": [
    "1",
    "1"
   ],
   "parameters": {
    "content_type": {
     "stringParam": "str"
    }
   },
   "contents": {
    "bytesContents": [
     "VHdlZXQgdGV4dCA6IEV2ZXJ5IGRheSBpcyBhIG5ldyBiaW5uaW5nLCBmaWxsZWQgd2l0aCBvcHRpb25waWVuaW5nIGFuZCBob3BlIExhYmVsIDogbm8gY29tcGxhaW50"
    ]
   }
  }
 ]
}

O conteúdo decodificado em base64 de bytesContents é:

Tweet text : Every day is a new binning, filled with optionpiening and hope Label : no complaint

Até agora, mostra que a solicitação de serviço do modelo LLM de grande linguagem acima obteve os resultados esperados.

04 Resumo

O Alibaba Cloud Service Grid ASM forneceu uma capacidade básica de grade de serviço de modelo escalonável e de alto desempenho para gerenciar, implantar e agendar vários serviços de modelo para lidar melhor com a implantação de modelo e gerenciamento de versão, roteamento e balanceamento de carga de solicitações de inferência.

Bem-vindo a tentar: https://www.aliyun.com/product/servicemesh

Links Relacionados:

[1] A seguir está um exemplo de modelo de implantação. Consulte os pré-requisitos de uso.

https://help.aliyun.com/zh/asm/user-guide/multi-model-inference-service-using-model-service-mesh?spm=a2c4g.11186623.0.0.7c4e6561k1qyJV#213af6d078xu7

[2] armazém kserve/modelmesh-minio-examples

https://github.com/kserve/modelmesh-minio-examples/blob/main/sklearn/mnist-svm.joblib

[3] Para obter detalhes, consulte

https://help.aliyun.com/zh/asm/user-guide/customizing-the-model-runtime-using-the-model-service-mesh?spm=a2c4g.11186623.0.0.1db77614Vw96Eu

[4] Consulte os pré-requisitos de uso.

https://help.aliyun.com/zh/asm/user-guide/services-for-the-large-language-model-llm?spm=a2c4g.11186623.0.0.29777614EEBYWt#436fc73079euz

[5] arquivo kfp-tekton/samples/peft-modelmesh-pipeline

https://github.com/kubeflow/kfp-tekton

Autor: Wang Xining

Link original

Este artigo é conteúdo original do Alibaba Cloud e não pode ser reproduzido sem permissão.

O autor de um conhecido projeto de código aberto perdeu o emprego devido à mania - "Buscando dinheiro online" No Star, No Fix 2023 As dez maiores conquistas de engenharia do mundo são lançadas: ChatGPT, Sistema Operacional Hongmeng, Estação Espacial China e outros ByteDance selecionados foram "banidos" pela OpenAI. Google anuncia a extensão mais popular do Chrome em 2023 Acadêmico Ni Guangnan: Espero que o SSD doméstico substitua o HDD importado para desbloquear o celular Xiaomi BL? Primeiro, faça uma pergunta de entrevista para um programador Java. Arm demitiu mais de 70 engenheiros chineses e planeja reorganizar seu negócio de software chinês. OpenKylin 2.0 revela | UKUI 4.10 design de diamante duplo, bonito e de alta qualidade! Manjaro 23.1 lançado, codinome “Vulcan”
{{o.nome}}
{{m.nome}}

Acho que você gosta

Origin my.oschina.net/yunqi/blog/10324103
Recomendado
Clasificación