liveBook · Manning

Model Serving

As explained in Machine Learning Platform Engineering

A model serving framework is software that packages, exposes, operates, and scales machine learning models for inference.

Model serving packages a trained model with its inference logic and exposes it as a dependable service. It turns a validated artifact into an API that applications can call, while addressing deployment repeatability, health checks, scaling, monitoring, and resource management. section 10.0 section 10.2

BentoML provides a practical implementation path: define a service, configure resources and request timeouts, package dependencies in a Bento, run the service locally, test its inference endpoint, and containerize the result. It abstracts custom API, health, liveness, batching, and device-handling work while retaining deployment controls. section 10.6 section 10.2

A production serving design commonly includes:

  • A model source such as an MLflow registry alias, allowing the service to retrieve the current production model rather than embedding a fixed artifact. section 10.6
  • A reproducible package containing service code, dependencies, labels, and configuration, followed by local validation before deployment. section 10.6
  • A deployment target ranging from local serving to Docker and Kubernetes, with monitoring, logging, version management, rollback, and scaling handled according to operational needs. section 10.7 section 10.2

BentoML with MLflow

A recommender service queries MLflow for the model version assigned the prod alias, imports that model into BentoML, builds a Bento, serves it locally, tests /predict, and containerizes the validated service. MLflow alone can provide a simpler alternative through /health and /invocations, while BentoML is preferable when fine-grained deployment options and monitoring are required. section 10.6 section 10.7

Listing 10.1 Using MLflow and BentoML in an inference service
import bentoml
import mlflow
import torch
import numpy as np
from mlflow import MlflowClient

@bentoml.service(
    resources={"cpu": "2"},
    traffic={"timeout": 10},
)
class RecommenderRunnable:
    def __init__(
        self, 
        registered_model_name = 'recommender_production', 
        device = 'cpu'): 
        mlflow.set_tracking_uri(uri="http://mlflow:8080")     #1
        client = MlflowClient()     #1
        current_prod = client.get_model_version_by_alias(
                            registered_model_name, 
                            "prod")  #1
        model_uri = f"runs:/{current_prod.run_id}/model"         #1
        bentoml.mlflow.import_model(
            "recommender", model_uri)     #1
        bento_model = bentoml.mlflow.get(
            "recommender:latest")     #1
        mlflow_model_path = bento_model.path_of(
                bentoml.mlflow.MLFLOW_MODEL_FOLDER) 
        self.model = mlflow.pytorch.load_model(mlflow_model_path) 
        self.device = device 
        self.model.to(self.device) 
        self.model.eval() 

    @bentoml.api     #2
    def predict(
        self, 
        user_id: int, 
        top_k: int=10, 
        ranked_movies:np.ndarray=None) -> np.ndarray: 

        user_id = torch.tensor(
                    [user_id], 
                    dtype=torch.long).to(self.device) 
        all_items = torch.arange(
                        1, 
                        self.model.n_items + 1, 
                        dtype=torch.long).to(self.device) 
        if ranked_movies is not None:     #1
            ranked_movies = torch.tensor(
                ranked_movies,
                dtype=torch.long).to(self.device)  
            unrated_items = all_items[
                    ~torch.isin(all_items, ranked_movies)] 
        else: 
            unrated_items = all_items
        user_ids = user_id.repeat(len(unrated_items)) 
        with torch.no_grad(): 
            predictions = self.model(
                            user_ids, 
                            unrated_items).squeeze()     #3
        top_n_indices = torch.topk(
            predictions, top_k).indices     #4
        recommended_items = unrated_items[top_n_indices].cpu().numpy() 
        return recommended_items

Inspect the service listing to see how resource limits, timeouts, MLflow model selection, and BentoML model loading fit together. section 10.6

How Machine Learning Platform Engineering covers it

How deep it goes
Builds a runnable service through packaging, local testing, containerization, and deployment choices, but defers infrastructure internals.
Examples
Uses recommender and object-detection services, MLflow production aliases, /predict requests, Bento files, Docker containers, and local inference servers.
What it assumes
Assumes a trained and validated model, then supplies the deployment steps needed to make it available as a service.
What you can do after
Apply it via BentoML or MLflow to package, expose, validate, and containerize deployable inference services.
How it connects
Connects model serving with MLflow, model registries, REST APIs, containerization, Kubernetes, monitoring, and data drift.

Also explained in

Compare how 5 books explain Model Serving →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Machine Learning Platform Engineering. The section links point to the parts of the book it draws on.