Model Deployment · Topic 2 of 2

Model Serving Endpoints and Traffic Splitting

Databricks ML Associate: deploy a custom pyfunc model to a Model Serving endpoint, query it over REST, and split traffic between served models.

  • 5 min
In a nutshell
  • Any MLflow model can be served, including custom pyfunc models with a predict method.
  • Logging to Unity Catalog needs a signature; an input example lets MLflow infer it.
  • Query with POST /serving-endpoints/<name>/invocations and a body such as dataframe_split or dataframe_records.

What it is

Mosaic AI Model Serving puts a registered MLflow model behind a REST API for real time inference. You create an endpoint, attach one or more served entities (model versions), and callers send JSON requests that return predictions in milliseconds.

The exam asks how a custom model gets onto an endpoint, how the endpoint is queried, and how requests are divided between two served models, for example a champion and a challenger.

Log modelpyfunc with signatureRegistercatalog.schema.modelEndpointserved entitiesClientPOST invocationsPrediction

How it works

Deploying a custom model

Model Serving accepts any model logged in MLflow format, either a built in flavor (scikit-learn, XGBoost, PyTorch) or pyfunc for arbitrary Python code. A custom model subclasses mlflow.pyfunc.PythonModel and implements predict.

import mlflow
class ScoreTo100(mlflow.pyfunc.PythonModel):
    def predict(self, context, model_input):
        return model_input["score"] * 100
mlflow.set_registry_uri("databricks-uc")
mlflow.pyfunc.log_model("model", python_model=ScoreTo100(),
    input_example=sample_pdf, registered_model_name="main.ml.score_to_100")

Logging to Unity Catalog requires a model signature; passing an input example lets MLflow infer it. Custom logic such as pre processing, post processing or calling several models can all live inside predict.

Creating the endpoint

You can create an endpoint from the Serving page in the UI, the REST API or the MLflow Deployments client.

from mlflow.deployments import get_deploy_client
client = get_deploy_client("databricks")
client.create_endpoint(name="score-endpoint", config={"served_entities": [{
    "entity_name": "main.ml.score_to_100", "entity_version": "1",
    "workload_size": "Small", "scale_to_zero_enabled": True}]})
SettingWhat it controls
entity_name, entity_versionWhich registered model version is served
workload_sizeHow much concurrency the served entity gets
scale_to_zero_enabledScales compute down to zero when idle; the next request has a cold start

Scale to zero saves cost on development endpoints. Databricks advises against it for production endpoints that need consistent response times.

Querying for real time inference

Every endpoint exposes one URL: POST https://<workspace>/serving-endpoints/<endpoint-name>/invocations, authenticated with a Databricks token. For tabular models, the body holds a pandas style DataFrame.

JSON keyShape
dataframe_splitColumns list plus data rows (recommended)
dataframe_recordsA list of row objects
instancesTensor input, row format
inputsTensor input, columnar format
resp = client.predict(endpoint="score-endpoint",
    inputs={"dataframe_records": [{"score": 0.42}, {"score": 0.91}]})

The same request can be sent with any HTTP client, and SQL users can call an endpoint with the ai_query function.

Splitting traffic between served models

One endpoint can hold several served entities. Its traffic_config lists routes, each naming a served entity and a traffic_percentage; the percentages sum to 100 and each request goes to exactly one entity. Each served entity has a name, and the route refers to it by that name.

client.update_endpoint_config(endpoint="score-endpoint", config={
    "served_entities": [champion_entity, challenger_entity],
    "traffic_config": {"routes": [
        {"served_model_name": "champion", "traffic_percentage": 90},
        {"served_model_name": "challenger", "traffic_percentage": 10}]}})
Client requestEndpointtraffic config90 percentChampionversion 3Client requestEndpointtraffic config10 percentChallengerversion 4

To test one entity directly, call /serving-endpoints/<endpoint-name>/served-models/<served-model-name>/invocations; traffic settings are ignored on that path. All served entities on one endpoint must be the same model type.

Worked example

An endpoint routes 90 percent to the champion and 10 percent to the challenger and receives 50,000 requests a day. About 45,000 go to the champion and 5,000 to the challenger, enough to compare live metrics before moving the challenger to 50 percent and then 100 percent.

Changing the split is a config update on the same endpoint, so callers keep using the same URL throughout.

How the exam asks about this

  • "A model needs custom pre processing before predicting and must be served." Wrap it in an mlflow.pyfunc.PythonModel with predict, log and register it, then serve it.
  • "A web app needs a prediction per user request in milliseconds." Deploy to a Model Serving endpoint and POST to its invocations URL.
  • "Send 20 percent of live requests to a new version without changing the client." Add the version as a second served entity and set traffic_config routes to 80 and 20.

What to remember for the exam

  • Any MLflow model can be served, including custom pyfunc models with a predict method.
  • Logging to Unity Catalog needs a signature; an input example lets MLflow infer it.
  • Query with POST /serving-endpoints/<name>/invocations and a body such as dataframe_split or dataframe_records.
  • traffic_config routes split requests by traffic_percentage, which must total 100.
  • The served-models/<name>/invocations path targets one entity and ignores the split.
  • Scale to zero cuts idle cost but adds a cold start, so avoid it for latency sensitive production use.
Watch out

A traffic split is not a duplicate. Each request goes to one served entity only, so a 90/10 split does not score every request with both models.

Common mistakes

Creating a second endpoint for the challenger. Two endpoints mean two URLs and client changes. One endpoint with two served entities and a traffic split is the intended way to compare versions.

Forgetting the signature. Registering to Unity Catalog fails without a signature. Supply an input example or an explicit signature when logging.

Picking real time for nightly scoring. An endpoint is the right tool only when a caller waits for each answer. Bulk scheduled scoring belongs in a batch job.

Check yourself

  • How do you serve a model that needs custom Python logic around predict?

    Subclass mlflow.pyfunc.PythonModel, implement predict, log and register the model in Unity Catalog, then add it as a served entity on an endpoint.

  • Which URL does a client POST to for real time predictions?

    The endpoint's /serving-endpoints/<endpoint-name>/invocations URL, with a JSON body such as dataframe_split or dataframe_records.

  • How do you send 10 percent of requests to a challenger on the same endpoint?

    Serve both versions on one endpoint and set traffic_config routes to 90 for the champion and 10 for the challenger.

Topic 2 of 2 in Model Deployment

Test yourself on Model Deployment

The full Databricks Machine Learning Associate question bank has 600 questions, with timed practice exams and an explanation for every answer.

This study guide is independent and is not affiliated with, endorsed by, or sponsored by Databricks. Vendor names, certification names and exam codes are trademarks of their respective owners and are used for identification only.