Todos los productos
Search
Centro de documentos

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

Última actualización: Sep 05, 2026

ModelMesh incluye runtimes integrados para frameworks de inference comunes, pero algunas cargas de trabajo requieren lógica personalizada de preprocesamiento o posprocesamiento, frameworks no compatibles o un control detallado de recursos. Un ServingRuntime personalizado le permite definir exactamente cómo se cargan y sirven los modelos, y luego registrar ese runtime para que ModelMesh programe y escale los modelos sobre él automáticamente.

Esta guía explica cómo construir un runtime personalizado basado en Python sobre MLServer, empaquetarlo como una imagen de contenedor, registrarlo como ServingRuntime y desplegar un modelo sobre él.

Requisitos previos

Antes de empezar, asegúrese de contar con lo siguiente:

Runtimes integrados

Antes de construir un runtime personalizado, compruebe si algún runtime integrado ya es compatible con el formato de su modelo.

Servidor de modelos

Desarrollador

Frameworks compatibles

Recomendado para

Triton Inference Server

NVIDIA

TensorFlow, PyTorch, TensorRT, ONNX

Inference de alto rendimiento, escalable y baja latencia con monitoreo integrado

MLServer

Seldon

SKLearn, XGBoost, LightGBM

API unificada para varios frameworks de ML

OpenVINO Model Server

Intel

OpenVINO, ONNX

Aceleración por hardware de Intel

TorchServe

PyTorch

PyTorch (incluido modo eager)

Servicio nativo ligero para PyTorch

Si ninguno de estos runtimes admite su framework, o si su pipeline de inference requiere lógica personalizada, cree un runtime de servicio personalizado como se describe a continuación.

Cómo funciona

Un ServingRuntime (con alcance de namespace) o ClusterServingRuntime (con alcance de clúster) define la plantilla de pod para servir uno o más formatos de modelo. Cada recurso especifica:

  • La imagen de contenedor que ejecuta el servidor de inference

  • Una lista de formatos de modelo compatibles

  • Variables de entorno para la configuración del runtime

ServingRuntime es un CustomResourceDefinition (CRD) de Kubernetes, por lo que puede crear runtimes reutilizables sin modificar el controlador de ModelMesh ni ningún recurso en el namespace del controlador.

Para frameworks basados en Python, la opción más rápida es extender MLServer. MLServer proporciona la interfaz de servicio, usted aporta la lógica del modelo y ModelMesh se encarga de la programación y el escalado.

El flujo de trabajo consta de tres pasos:

  1. Implementar la clase del modelo mediante la extensión de la clase MLModel de MLServer.

  2. Empaquetar la clase y sus dependencias en una imagen de contenedor.

  3. Registrar la imagen como ServingRuntime en Kubernetes.

Paso 1: Implementar la clase MLModel

Cree una clase de Python que herede de la clase MLModel de MLServer. Implemente dos métodos:

  • load() -- Inicializa el modelo (carga pesos, prepara cachés).

  • predict() -- Ejecuta la inference sobre una solicitud 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

Para consultar más ejemplos, revise la documentación de runtimes personalizados de MLServer.

Paso 2: Empaquetar el runtime en una imagen de contenedor

Agrupe su clase CustomMLModel, MLServer y todas las dependencias en una imagen de contenedor.

Opción A: Usar la CLI de MLServer (recomendado)

MLServer ofrece el comando mlserver build para generar una imagen automáticamente. Para más detalles, consulte Building a custom image.

Opción B: Escribir 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}"]

Compile y envíe la imagen:

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

Reemplace los siguientes marcadores de posición con valores reales:

Marcador

Descripción

Ejemplo

<your-registry>

Dirección del registro de contenedores

registry.cn-hangzhou.aliyuncs.com/my-namespace

<your-image-name>

Nombre de la imagen

custom-mlserver

<tag>

Etiqueta de versión de la imagen

v1.0

Paso 3: Crear el ServingRuntime

Defina un recurso ServingRuntime que apunte a su imagen de contenedor y declare los formatos de modelo que admite.

Show the YAML file

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

Reemplace los siguientes marcadores de posición con valores reales:

Marcador

Descripción

Ejemplo

<custom-runtime-name>

Un nombre único para el runtime

my-model-server-0.x

<model-format-name>

El formato de modelo que admite este runtime. ModelMesh compara los modelos entrantes con este valor.

my-model

<your-image>

La imagen de contenedor del paso 2

registry.cn-hangzhou.aliyuncs.com/my-namespace/custom-mlserver:v1.0

Aplique el recurso:

kubectl apply -f <serving-runtime>.yaml

Una vez creado el recurso, el runtime personalizado aparece en su despliegue de ModelMesh y queda listo para servir modelos que coincidan con el formato declarado.

Paso 4: Desplegar un modelo

Cree un InferenceService para desplegar un modelo en el runtime personalizado. InferenceService es el recurso principal que KServe y ModelMesh utilizan para gestionar endpoints de modelos.

Show the YAML file

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

Campos clave:

Campo

Propósito

modelFormat.name

Indica a ModelMesh qué runtime usar. Debe coincidir con una entrada de supportedModelFormats en su ServingRuntime.

runtime

(Opcional) Selecciona explícitamente un runtime por nombre. Si se omite, ModelMesh realiza la selección automática según modelFormat.

storage.key

Hace referencia a un backend de almacenamiento preconfigurado (por ejemplo, localMinIO del inicio rápido de ModelMesh Serving).

storage.path

Ruta al artefacto del modelo dentro del backend de almacenamiento.

Aplique el recurso:

kubectl apply -f <inference-service>.yaml

Compruebe que el modelo esté listo:

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

Salida esperada:

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

La columna READY muestra True después de que ModelMesh termina de cargar el modelo en el runtime personalizado.

Depuración

Si el runtime personalizado no logra cargar modelos o devuelve errores de inference, habilite el registro de depuración agregando estas variables de entorno al 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"

Revise los registros del pod del runtime para ver mensajes de error detallados:

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

Pasos siguientes