ModelMesh Serving

repository·main·Indexed 42 days ago

https://github.com/kserve/modelmesh-serving

A Kubernetes controller for managing ModelMesh, a routing and management layer for model serving. It orchestrates model placement and integrates with model servers such as Triton, MLServer, OpenVINO, and TorchServe via runtime adapters. It utilizes ServingRuntime and InferenceService CRDs to manage the lifecycle of model deployments, providing features like ScaleToZero, REST and gRPC inferencing, and flexible model server integration patterns.

Tokens
44.4K
Snippets
104
Records
175
Agent score
53%

What's inside ModelMesh Serving

  1. What is ModelMesh Serving?

    main

    ModelMesh Serving is a Kubernetes-based platform designed for high-volume, high-density realtime serving of ML/DL models. It maximizes system resource utilization by intelligently managing in-memory model data across clusters of deployed Pods based on historical usage patterns.

    Key features include:

    • Multi-format support: Out-of-the-box support for TensorFlow, PyTorch ScriptModule, ONNX, scikit-learn, XGBoost, LightGBM, and OpenVINO IR.
    • Extensibility: Support for custom runtimes to handle arbitrary model formats.
    • Standardized API: Uses the KServe v2 data plane API for both gRPC and REST (REST is limited to built-in runtimes; custom runtimes must use gRPC).
    • Storage: Pulls model data from external S3-based object storage (configured via Kubernetes Secrets).
  2. What is ModelMesh Serving

    main
    ModelMesh Serving is the Controller responsible for managing ModelMesh, which acts as a general-purpose model serving management and routing layer. It orchestrates how models are placed and routed across a serving infrastructure.
  3. Supported Model Formats and Serving Runtimes

    main

    ModelMesh Serving supports various standard ML model formats by leveraging third-party model servers via ServingRuntime. The following table maps model types and frameworks to their supported runtimes:

    Model TypeFrameworkSupported via ServingRuntime
    kerasTensorFlowTriton (C++)
    lightgbmLightGBMMLServer (python), Triton (C++)
    onnxONNXTriton (C++), OVMS (C++)
    openvino_irIntel OpenVINO*OVMS (C++)
    pytorchPyTorchTriton (C++)
    sklearnscikit-learnMLServer (python), Triton (C++)
    tensorflowTensorFlowTriton (C++)
    xgboostXGBoostMLServer (python), Triton (C++)
    anyCustomCustom (any)

    *Note: Many ML frameworks (Caffe, TensorFlow, MXNet, PaddlePaddle, and ONNX) can be converted to the OpenVINO IR format for use with OVMS.

  4. Overview of ModelMesh Metrics

    main

    ModelMesh Serving runtime pods expose metrics via an HTTPS endpoint on port 2112 at /metrics.

    Most metrics are pod-specific and should be aggregated by a monitoring framework like Prometheus. However, some metrics have a Deployment scope and are published by only one pod at a time to represent service-wide state.

    To track the IPs of the pods for scraping, use the endpoints associated with the ModelMesh Serving service (default name: modelmesh-serving).

    Configuration: You can override the default metrics port and scheme by setting metrics.port and metrics.scheme in the model-serving-config ConfigMap.

  5. Core Kubernetes Custom Resources in ModelMesh Serving

    main

    ModelMesh Serving operates using two primary Kubernetes Custom Resource (CR) types:

    ServingRuntime

    Acts as a template for Pods that serve specific model formats.

    • Built-in runtimes: Triton, MLServer, and OpenVINO Model Server (OVMS).
    • Custom runtimes: Users can define additional ServingRuntime objects to support new formats.
    • Lifecycle: Pods associated with a ServingRuntime are only started when there are InferenceService resources requiring them.

    InferenceService

    The primary interface for managing models. An InferenceService represents a logical endpoint for predictions.

    • Predictor Spec: Defines the model format, storage location, and optional configurations.
    • Stability: Endpoints remain stable even when transitioning between different model versions or types.
    • Limitations: When using deploymentMode: ModelMesh, certain features like transformers, explainers, canary rollouts, and PodSpec fields in the predictor spec are currently not supported or will be ignored.
  6. Supported TensorFlow model formats

    main

    ModelMesh supports both TensorFlow v1 and v2 models in two formats:

    1. SavedModel: The default and preferred format for TF2.x. It includes model weights and configuration, allowing inputs and outputs to be inferred automatically without a manual model schema.
    2. GraphDef: A serialized protocol buffer message. When using this format, you must provide a model schema file to specify the inputs and outputs.

    For advanced runtime-specific configurations that cannot be inferred, refer to the Triton Server advanced configuration options.

  7. Configure and use the Storage Helper

    main

    The Storage Helper automatically downloads models from an S3 bucket using the storage-config secret and places them in a local path.

    • Enabled (Default): The model server receives a loadModel call where modelPath is the local filesystem path where the helper placed the model. The modelKey contains serialized metadata including disk_size_bytes.
    • Disabled: Set storageHelper.disabled: true in the ServingRuntime. When disabled, the custom runtime is responsible for accessing and pulling model data from storage. In this mode, the modelPath provided in the loadModel call will be the same as the path provided in the InferenceService predictor storage spec, and the modelKey metadata will not include disk_size_bytes.
    // Example loadModel metadata when Storage Helper is ENABLED
    {
      "modelId": "my-mnist-isvc-<suffix>",
      "modelType": "my_model_format",
      "modelPath": "/models/my-mnist-isvc-<suffix>/",
      "modelKey": "{\"bucket\":\"my_bucket\",\"disk_size_bytes\":2415,\"model_type\":{\"name\":\"my_model_format\",\"version\":\"1\"},\"storage_key\":\"my_storage\"}"
    }
  8. Configure XGBoost model inputs and outputs

    main

    For standard XGBoost models, inputs and outputs are automatically inferred from the model data. A formal model schema is not required.

    If the inferred configuration is insufficient for your use case, you may need to provide runtime-specific configuration. Refer to the advanced configuration documentation for specific options related to the chosen runtime (e.g., MLServer).

  9. Implement a custom MLModel using MLServer

    main

    Extend MLServer by implementing the MLModel class. The core lifecycle involves:

    • load(): An asynchronous method used to locate model data (using get_model_uri), parse/process files, and instantiate the model. Set self.ready = True when loading is complete.
    • predict(): An asynchronous method that receives an InferenceRequest payload, validates it, and returns an InferenceResponse containing the model's outputs.

    Use mlserver.errors.InferenceError to signal errors during request validation.

    from typing import List
    from mlserver import MLModel, types
    from mlserver.errors import InferenceError
    from mlserver.utils import get_model_uri
    
    WELLKNOWN_MODEL_FILENAMES = ["model.json", "model.dat"]
    
    class CustomMLModel(MLModel):
        async def load(self) -> bool:
            # get URI to model data
            model_uri = await get_model_uri(self._settings, wellknown_filenames=WELLKNOWN_MODEL_FILENAMES)
    
            # parse/process file and instantiate the model
            self._load_model_from_file(model_uri)
    
            # set ready to signal that model is loaded
            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 _load_model_from_file(self, file_uri):
            # TODO: load model from file and instantiate class data
            return
    
        def _check_request(self, payload: types.InferenceRequest) -> types.InferenceRequest:
            # TODO: validate request and raise InferenceError on error
            return payload
    
        def _predict_outputs(self, payload: types.InferenceRequest) -> List[types.ResponseOutput]:
            inputs = payload.inputs
            # TODO: transform inputs and run prediction logic
            outputs = []
            return outputs
  10. Understand data type mapping for LightGBM, Sklearn, and XGBoost

    main
    Models served via Seldon MLServer (such as LightGBM, Sklearn, and XGBoost) are fully compliant with the KServe V2 Dataplane specification. To ensure correct inference, use the KServe V2 Tensor data types when constructing your requests. The supported types and their formats are defined in the KServe V2 Predict API specification.