모델 서비스 그리드: 클라우드 네이티브에서의 모델 서비스 관리

Model Service Mesh는 분산 환경에서 기계 학습 모델 서비스를 배포하고 관리하는 데 사용되는 아키텍처 패턴입니다. 추론 요청의 모델 배포, 버전 관리, 라우팅 및 로드 밸런싱을 더 잘 처리하기 위해 여러 모델 서비스를 관리, 배포 및 예약하기 위한 확장 가능한 고성능 인프라를 제공합니다.

모델 서비스 그리드의 핵심 아이디어는 모델을 확장 가능한 서비스로 배포하고 이러한 서비스를 그리드를 통해 관리 및 라우팅하여 모델 서비스의 관리 및 운영을 단순화하는 것입니다. 모델 서비스를 조정되고 확장 가능한 단위로 추상화하여 모델 배포, 확장 및 버전 제어를 더 쉽게 만듭니다. 또한 모델 서비스의 고가용성과 안정성을 보장하기 위해 로드 밸런싱, 자동 확장, 장애 복구 등과 같은 일부 핵심 기능을 제공합니다.

실제 추론 요청 로드를 기반으로 모델의 크기를 자동으로 조정하고 로드 밸런싱을 수행하여 효율적인 모델 추론을 가능하게 합니다. 모델 서비스 그리드는 또한 모델 서비스의 트래픽을 더 잘 제어하고 관리하기 위해 트래픽 분할, A/B 테스트, 그레이스케일 게시 등과 같은 일부 고급 기능을 제공하며 다양한 모델 버전을 쉽게 전환하고 롤백할 수 있습니다. 또한 모델 유형, 데이터 형식 또는 기타 메타데이터와 같은 요청 속성을 기반으로 요청을 적절한 모델 서비스로 라우팅할 수 있는 동적 라우팅을 지원합니다.

Alibaba Cloud Service Grid ASM은 모델 배포 및 버전 관리를 더 잘 처리하기 위해 여러 모델 서비스를 관리, 배포 및 예약할 수 있는 확장 가능한 고성능 모델 서비스 그리드 기본 기능, 추론 요청의 라우팅 및 로드 밸런싱을 제공했습니다. 모델 서비스 메시를 사용하면 개발자는 기계 학습 모델을 보다 쉽게 ​​배포, 관리 및 확장하는 동시에 다양한 비즈니스 요구 사항을 충족하는 고가용성, 탄력성 및 유연성을 제공할 수 있습니다.

01 다중 모델 추론 서비스를 위한 모델 서비스 그리드 활용

Model Service Grid는 KServe ModelMesh를 기반으로 구현되며 대용량, 고밀도, 자주 변경되는 모델 사용 사례에 최적화되어 있으며 모델을 메모리에 지능적으로 로드하거나 언로드하여 응답성과 계산 간의 균형을 유지할 수 있습니다.

모델 서비스 메시는 다음 기능을 제공합니다.

  • 캐시 관리
  • 포드는 분산 LRU(최근 사용) 캐시로 관리됩니다.
  • 사용 빈도와 현재 요청량에 따라 모델의 복사본을 로드 및 언로드합니다.
  • 스마트 배치 및 로딩
  • 모델 배치는 Pod 간의 캐시 수명과 요청 로드에 따라 균형을 이룹니다.
  • 대기열을 사용하여 동시 모델 로드를 처리하고 런타임 트래픽에 대한 영향을 최소화합니다.
  • 탄력
  • 실패한 모델 로드는 다른 Pod에서 자동으로 재시도됩니다.
  • 작동 용이성
  • 롤링 모델 업데이트를 자동으로 원활하게 처리합니다.

다음은 배포 모델의 예시이며, 사용 전제조건은 [1]을 참고하시기 바랍니다.

1.1 스토리지 선언 PVC 생성

ACK 클러스터에서 다음 YAML을 사용하여 스토리지 선언 my-models-pvc를 생성합니다.

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

그런 다음 다음 명령을 실행하십시오.

kubectl get pvc -n modelmesh-serving

다음과 유사한 예상 결과를 얻게 됩니다.

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 PVC에 액세스하기 위한 포드 생성

새 PVC를 사용하려면 이를 Kubernetes Pod에 볼륨으로 마운트해야 합니다. 그런 다음 이 포드를 사용하여 모델 파일을 영구 볼륨에 업로드할 수 있습니다.

PVC 액세스 포드를 배포하고 Kubernetes 컨트롤러에 "my-models-pvc"를 지정하여 이전에 요청한 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

PVC-access 포드가 실행 중인지 확인합니다.

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

다음과 유사한 예상 결과를 얻게 됩니다.

pvc-access 1/1     Running

1.3 영구 볼륨에 모델 저장

이제 AI 모델을 스토리지 볼륨에 추가해야 하며, scikit-learn으로 훈련된 MNIST 필기 숫자 문자 인식 모델을 사용하겠습니다. mnist-svm.joblib 모델 파일의 복사본은 kserve/modelmesh-minio-examples 저장소[2]에서 다운로드할 수 있습니다.

다음 명령을 사용하여 mnist-svm.joblib 모델 파일을 pvc-access 포드의 /mnt/models 폴더에 복사합니다.

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

다음 명령을 실행하여 모델이 성공적으로 로드되었는지 확인합니다.

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

다음과 같은 결과를 얻어야 합니다:

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

1.4 추론 서비스 배포

다음으로 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

수십 초 후에(이미지 가져오기 속도에 따라) 새로운 추론 서비스 sklearn-mnist가 준비되어야 합니다.

다음 명령을 실행하십시오.

kubectl get isvc -n modelmesh-serving

다음과 유사한 예상 결과를 얻게 됩니다.

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

1.5 추론 서비스 실행

이제 컬을 사용하여 sklearn-mnist 모델에 추론 요청을 보낼 수 있습니다. 배열 형태로 요청된 데이터는 분류할 디지털 이미지 스캔에서 64픽셀의 계조 값을 나타냅니다.

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]}}]}'

JSON 응답은 다음과 같아야 하며 스캔된 숫자가 "8"임을 추론합니다.

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

02 모델 서비스 메시를 사용하여 모델 런타임 사용자 정의

Model Service Mesh(줄여서 ModelMesh)는 대용량, 고밀도, 자주 변경되는 모델 추론 서비스의 배포 및 운영에 최적화되어 있으며, 모델을 메모리에 지능적으로 로드/언로드하여 모델 간의 최상의 균형을 유지합니다. 반응성과 컴퓨팅.

ModelMesh는 기본적으로 다음과 같은 모델 서버 실행 환경을 통합합니다.

  • NVIDIA의 서버인 Triton Inference Server는 TensorFlow, PyTorch, TensorRT 또는 ONNX와 같은 프레임워크에 적합합니다.
  • MLServer는 Seldon의 Python 기반 서버로 SKLearn, XGBoost 또는 LightGBM과 같은 프레임워크에 적합합니다.
  • OpenVINO 모델 서버, Intel OpenVINO 또는 ONNX와 같은 프레임워크용 Intel 서버입니다.
  • TorchServe는 Eager 모드를 포함한 PyTorch 모델을 지원합니다.

이러한 모델 서버가 특정 요구 사항을 충족할 수 없는 경우(예: 추론을 위해 사용자 지정 논리를 처리해야 하는 경우 또는 모델에 위 지원 목록에 없는 프레임워크가 필요한 경우) 확장 지원을 위해 서비스 런타임을 사용자 지정할 수 있습니다.

자세한 내용은 [3]을 참조하세요.

03 대형언어모델 LLM 서비스 제공

LLM(Large Language Model)은 GPT-3, GPT-4, PaLM, PaLM2 등과 같이 수억 개의 매개변수를 가진 신경망 언어 모델을 말합니다. 다음은 대형 언어 모델 LLM에 대한 서비스 제공 방법에 대해 설명합니다.

자세한 사용 조건은 [4]를 참고하세요.

3.1 사용자 정의 런타임 구축

HuggingFace LLM에 구성 조정 프롬프트를 제공하는 사용자 정의 런타임을 구축합니다. 이 예의 기본 설정은 사전 구축된 사용자 정의 런타임 이미지와 사전 구축된 프롬프트 조정 구성입니다.

3.1.1 MLServer MLModel을 상속하는 클래스 구현

kfp-tekton/samples/peft-modelmesh-pipeline 디렉터리[5]에 있는 peft_model_server.py 파일에는 HuggingFace LLM에 프롬프트 조정 구성을 제공하는 방법에 대한 모든 코드가 포함되어 있습니다.

아래 _load_model 함수는 PEFT 프롬프트 튜닝 구성을 위해 사전 훈련된 LLM 모델을 선택함을 보여줍니다. 토크나이저는 모델의 일부로 정의되므로 사용자가 입력을 텐서 바이트로 전처리하지 않고도 추론 요청에서 원시 문자열 입력을 인코딩 및 디코딩하는 데 사용할 수 있습니다.

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 도커 이미지 빌드

모델 클래스를 구현한 후 해당 종속성(MLServer 포함)을 ServingRuntime 리소스를 지원하는 이미지로 패키징해야 합니다. 이미지를 빌드하려면 다음 Dockerfile을 참조하세요.

# 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 새로운 ServingRuntime 리소스 생성

다음 코드 블록에서 YAML 템플릿을 사용하여 새 ServingRuntime 리소스를 생성하고 방금 생성한 이미지를 가리킬 수 있습니다.

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

그런 다음 kubectl apply 명령을 사용하여 ServingRuntime 리소스를 생성하면 ModelMesh 배포에 새로운 사용자 정의 런타임이 표시됩니다.

3.2 LLM 서비스 배포

새로 생성된 런타임을 사용하여 모델을 배포하려면 모델을 제공할 InferenceService 리소스를 생성해야 합니다. 이 리소스는 KServe 및 ModelMesh가 모델을 관리하는 데 사용하는 기본 인터페이스이며 추론에서 모델의 논리적 끝점을 나타냅니다.

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

이전 코드 블록에서 InferenceService의 이름은 peft-demo이고 해당 모델 형식은 이전에 생성된 사용자 지정 런타임 예제에서 사용된 것과 동일한 형식인 peft-model로 선언됩니다. 선택적 필드 런타임도 전달되어 ModelMesh에게 이 모델을 배포하기 위해 peft-model-server 런타임을 사용하도록 명시적으로 지시합니다.

3.3 추론 서비스 실행

이제 컬을 사용하여 위에서 배포한 LLM 모델 서비스에 추론 요청을 보낼 수 있습니다.

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

input.json은 요청 데이터를 나타냅니다.

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

bytes_contents는 "매일이 기회와 희망으로 가득 찬 새로운 시작입니다"라는 문자열의 base64 인코딩에 해당합니다.

JSON 응답은 다음과 같아야 하며 스캔된 숫자가 "8"임을 추론합니다.

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

bytesContents의 base64 디코딩 콘텐츠는 다음과 같습니다.

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

지금까지 위의 대규모 언어 모델 LLM의 모델 서비스 요청이 예상한 결과를 얻었음을 보여줍니다.

04 요약

Alibaba Cloud Service Grid ASM은 모델 배포 및 버전 관리를 더 잘 처리하기 위해 여러 모델 서비스를 관리, 배포 및 예약할 수 있는 확장 가능한 고성능 모델 서비스 그리드 기본 기능, 추론 요청의 라우팅 및 로드 밸런싱을 제공했습니다.

시도에 오신 것을 환영합니다: https://www.aliyun.com/product/servicemesh

관련된 링크들:

[1] 다음은 배포 모델의 예시로, 사용 전제조건을 참고하시기 바랍니다.

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

[2] kserve/modelmesh-minio-예제 창고

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

[3] 자세한 내용은 다음을 참조하세요.

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

[4] 이용을 위한 전제조건을 참고하시기 바랍니다.

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

[5] kfp-tekton/samples/peft-modelmesh-pipeline 目录

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

저자: 왕시닝

원본 링크

이 기사는 Alibaba Cloud의 원본 콘텐츠이므로 허가 없이 복제할 수 없습니다.

잘 알려진 오픈 소스 프로젝트의 저자는 열광으로 인해 직장을 잃었습니다 - "온라인에서 돈을 구하다" No Star, No Fix 2023 세계 10대 엔지니어링 성과 발표: ChatGPT, Hongmeng 운영 체제, 중국 우주 정거장 및 기타 엄선된 ByteDance OpenAI에서 '금지' Google, 2023년 가장 인기 있는 Chrome 확장 프로그램 발표 Ni Guangnan 학자: 샤오미 휴대폰 BL 잠금 해제를 위해 국산 SSD가 수입 HDD를 대체하길 바라나요 ? 먼저 Java 프로그래머 인터뷰 질문을 해보세요. Arm은 70명 이상의 중국 엔지니어를 해고하고 중국 소프트웨어 사업을 재편할 계획입니다. OpenKylin 2.0 공개 | UKUI 4.10 더블 다이아몬드 디자인, 아름답고 고품질! Manjaro 23.1 출시, 코드명 "Vulcan"
{{o.이름}}
{{이름}}

추천

출처my.oschina.net/yunqi/blog/10324103