Tous les produits
Search
Centre de documentation

Alibaba Cloud Service Mesh:Create a custom model serving runtime with ModelMesh

Dernière mise à jour :Aug 11, 2026

ModelMesh inclut des runtimes intégrés pour les frameworks d'inférence courants, mais certaines charges de travail nécessitent une logique de pré/post-traitement personnalisée, des frameworks non pris en charge ou un contrôle précis des ressources. Un ServingRuntime personnalisé vous permet de définir exactement comment les modèles sont chargés et servis, puis d'enregistrer ce runtime afin que ModelMesh planifie et mette à l'échelle les modèles automatiquement.

Ce guide explique comment créer un runtime personnalisé basé sur Python avec MLServer, l'empaqueter sous forme d'image conteneur, l'enregistrer en tant que ServingRuntime et déployer un modèle qui l'utilise.

Prérequis

Avant de commencer, assurez-vous de disposer des éléments suivants :

Runtimes intégrés

Avant de créer un runtime personnalisé, vérifiez si un runtime intégré prend déjà en charge le format de votre modèle.

Serveur de modèle Développeur Frameworks pris en charge Idéal pour
Triton Inference Server NVIDIA TensorFlow, PyTorch, TensorRT, ONNX Inférence haute performance, évolutive et à faible latence avec surveillance intégrée
MLServer Seldon SKLearn, XGBoost, LightGBM API unifiée pour plusieurs frameworks d'apprentissage automatique
OpenVINO Model Server Intel OpenVINO, ONNX Accélération matérielle Intel
TorchServe PyTorch PyTorch (y compris le mode eager) Service natif PyTorch léger

Si aucun de ces runtimes ne prend en charge votre framework, ou si votre pipeline d'inférence nécessite une logique personnalisée, créez un runtime de service personnalisé comme décrit ci-dessous.

Fonctionnement

Un ServingRuntime (limité à un namespace) ou ClusterServingRuntime (limité au cluster) définit le modèle de pod pour servir un ou plusieurs formats de modèle. Chaque ressource spécifie :

  • L'image conteneur qui exécute le serveur d'inférence

  • Une liste des formats de modèle pris en charge

  • Les variables d'environnement pour la configuration du runtime

ServingRuntime est une CustomResourceDefinition (CRD) Kubernetes. Vous pouvez donc créer des runtimes réutilisables sans modifier le contrôleur ModelMesh ni aucune ressource dans le namespace du contrôleur.

Pour les frameworks basés sur Python, la méthode la plus rapide consiste à étendre MLServer. MLServer fournit l'interface de service, vous fournissez la logique du modèle et ModelMesh gère la planification et la mise à l'échelle.

Le flux de travail comporte trois étapes :

  1. Implémentez la classe de modèle en étendant la classe MLModel de MLServer.

  2. Empaquetez la classe et ses dépendances dans une image conteneur.

  3. Enregistrez l'image en tant que ServingRuntime dans Kubernetes.

Étape 1 : Implémenter la classe MLModel

Créez une classe Python qui hérite de la classe MLModel de MLServer. Implémentez deux méthodes :

  • load() : initialisez le modèle (chargez les poids, préparez les caches).

  • predict() : exécutez l'inférence sur une requête entrante.

from typing import List
from mlserver import MLModel, types
from mlserver.utils import get_model_uri

# List the filenames your model uses so MLServer can locate them.
WELLKNOWN_MODEL_FILENAMES = ["model.json", "model.dat"]

class CustomMLModel(MLModel):

    async def load(self) -> bool:
        model_uri = await get_model_uri(
            self._settings, wellknown_filenames=WELLKNOWN_MODEL_FILENAMES
        )
        # TODO: Load the model from model_uri and store it as an instance attribute.
        #       Example: self._model = joblib.load(model_uri)
        self.ready = True
        return self.ready

    async def predict(
        self, payload: types.InferenceRequest
    ) -> types.InferenceResponse:
        payload = self._check_request(payload)
        return types.InferenceResponse(
            model_name=self.name,
            model_version=self.version,
            outputs=self._predict_outputs(payload),
        )

    def _check_request(self, payload):
        # TODO: Validate the request -- check input tensor names, shapes, and types.
        return payload

    def _predict_outputs(self, payload) -> List[types.ResponseOutput]:
        # TODO: Extract input data from payload.
        # TODO: Run the data through your model's prediction logic.
        # TODO: Construct and return a list of ResponseOutput objects.
        outputs = []
        return outputs

Pour plus d'exemples, consultez la documentation sur les runtimes personnalisés de MLServer.

Étape 2 : Empaqueter le runtime dans une image conteneur

Regroupez votre classe CustomMLModel, MLServer et toutes les dépendances dans une image conteneur.

Option A : Utiliser la CLI MLServer (recommandée)

MLServer fournit la commande mlserver build pour générer une image automatiquement. Pour plus de détails, consultez la section Création d'une image personnalisée.

Option B : Rédiger un Dockerfile

# Use a Python base image that matches your dependency requirements.
FROM python:3.8-slim-buster
RUN pip install mlserver

# Place your MLModel implementation on the Python path.
COPY --chown=${USER} ./custom_model.py /opt/custom_model.py
ENV PYTHONPATH=/opt/

# Set environment variables for ModelMesh compatibility.
# These can also be set in the ServingRuntime YAML, but embedding them here
# ensures consistent behavior during local 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=dummy-model

# Point MLServer to your class so the implementation field is optional
# in model settings.
ENV MLSERVER_MODEL_IMPLEMENTATION=custom_model.CustomMLModel

CMD ["mlserver", "start", "${MLSERVER_MODELS_DIR}"]

Construisez et poussez l'image :

docker build -t <your-registry>/<your-image-name>:<tag> .
docker push <your-registry>/<your-image-name>:<tag>

Remplacez les espaces réservés suivants par des valeurs réelles :

Espace réservé Description Exemple
<your-registry> Adresse du registre de conteneurs registry.cn-hangzhou.aliyuncs.com/my-namespace
<your-image-name> Nom de l'image custom-mlserver
<tag> Tag de version de l'image v1.0

Étape 3 : Créer le ServingRuntime

Définissez une ressource ServingRuntime qui pointe vers votre image conteneur et déclare les formats de modèle qu'elle prend en charge.

Afficher le fichier YAML

apiVersion: serving.kserve.io/v1alpha1
kind: ServingRuntime
metadata:
  name: <custom-runtime-name>          # Example: my-model-server-0.x
spec:
  supportedModelFormats:
    - name: <model-format-name>        # Example: my-model
      version: "1"
      autoSelect: true
  multiModel: true
  grpcDataEndpoint: port:8001
  grpcEndpoint: port:8085
  containers:
    - name: mlserver
      image: <your-image>              # The image built in Step 2
      env:
        - name: MLSERVER_MODELS_DIR
          value: "/models/_mlserver_models/"
        - name: MLSERVER_GRPC_PORT
          # Must match grpcDataEndpoint above.
          value: "8001"
        - name: MLSERVER_HTTP_PORT
          # Default is 8080, which conflicts with ModelMesh internal ports.
          value: "8002"
        - name: MLSERVER_LOAD_MODELS_AT_STARTUP
          # ModelMesh manages model loading; disable MLServer's built-in loader.
          value: "false"
        - name: MLSERVER_MODEL_NAME
          # Dummy name prevents MLServer from erroring when no models are loaded yet.
          value: dummy-model
        - name: MLSERVER_HOST
          # Bind to localhost so MLServer only listens inside the pod.
          value: "127.0.0.1"
        - name: MLSERVER_GRPC_MAX_MESSAGE_LENGTH
          # Unlimited (-1) because ModelMesh enforces its own message size limits.
          value: "-1"
      resources:
        requests:
          cpu: 500m
          memory: 1Gi
        limits:
          cpu: "5"
          memory: 1Gi
  builtInAdapter:
    serverType: mlserver
    runtimeManagementPort: 8001
    memBufferBytes: 134217728
    modelLoadingTimeoutMillis: 90000

Remplacez les espaces réservés suivants par des valeurs réelles :

Espace réservé Description Exemple
<custom-runtime-name> Un nom unique pour le runtime my-model-server-0.x
<model-format-name> Le format de modèle pris en charge par ce runtime. ModelMesh fait correspondre les modèles entrants à cette valeur. my-model
<your-image> L'image conteneur créée à l'étape 2 registry.cn-hangzhou.aliyuncs.com/my-namespace/custom-mlserver:v1.0

Appliquez la ressource :

kubectl apply -f <serving-runtime>.yaml

Une fois la ressource créée, le runtime personnalisé apparaît dans votre déploiement ModelMesh et est prêt à servir les modèles correspondant au format déclaré.

Étape 4 : Déployer un modèle

Créez un InferenceService pour déployer un modèle sur le runtime personnalisé. InferenceService est la ressource principale que KServe et ModelMesh utilisent pour gérer les endpoints de modèle.

Afficher le fichier YAML

apiVersion: serving.kserve.io/v1beta1
kind: InferenceService
metadata:
  name: my-model-sample
  namespace: modelmesh-serving
  annotations:
    serving.kserve.io/deploymentMode: ModelMesh
spec:
  predictor:
    model:
      modelFormat:
        name: my-model                 # Must match the format declared in the ServingRuntime
      runtime: my-model-server         # Optional: explicitly select the runtime
      storage:
        key: localMinIO
        path: sklearn/mnist-svm.joblib

Champs clés :

Champ Objectif
modelFormat.name Indique à ModelMesh quel runtime utiliser. Doit correspondre à une entrée supportedModelFormats de votre ServingRuntime.
runtime (Facultatif) Sélectionne explicitement un runtime par son nom. Si omis, ModelMesh sélectionne automatiquement en fonction de modelFormat.
storage.key Fait référence à un backend de stockage préconfiguré (par exemple, localMinIO du guide de démarrage rapide ModelMesh Serving).
storage.path Chemin vers l'artefact du modèle dans le backend de stockage.

Appliquez la ressource :

kubectl apply -f <inference-service>.yaml

Vérifiez que le modèle est prêt :

kubectl get inferenceservice my-model-sample -n modelmesh-serving

Résultat attendu :

NAME              URL   READY   AGE
my-model-sample         True    1m

La colonne READY affiche True une fois que ModelMesh a terminé le chargement du modèle dans le runtime personnalisé.

Débogage

Si le runtime personnalisé échoue à charger des modèles ou renvoie des erreurs d'inférence, activez la journalisation de débogage en ajoutant ces variables d'environnement au ServingRuntime :

env:
  - name: MLSERVER_DEBUG
    value: "true"
  - name: MLSERVER_MODEL_PARALLEL_WORKERS
    # Set to 0 to disable parallel workers, which simplifies log output.
    value: "0"

Consultez les journaux du pod du runtime pour obtenir des messages d'erreur détaillés :

kubectl logs -n modelmesh-serving <pod-name> -c mlserver

Étapes suivantes