Deploying MLflow models to Amazon SageMaker AI Hosting
Your model is logged in MLflow — now what? Three ways to get it onto a SageMaker AI endpoint: one MLflow-native, two governed by the Model Registry.
You trained the model. MLflow tracked every run, every parameter, every metric. The best candidate sits in the MLflow Model Registry with a version number and a signature. And then someone asks the question you were hoping to postpone: "Great — can we get that behind an endpoint?"
For many data scientists, this is where the comfortable part ends. Deployment sounds like somebody else's job: container images, AWS Identity and Access Management (IAM) roles, model tarballs with opinions about their internal layout. If you are using managed MLflow on Amazon SageMaker AI , however, the distance between "registered in MLflow" and "serving traffic on a SageMaker AI endpoint" is much shorter than it used to be. In particular, SageMaker AI can now automatically register your MLflow models in the SageMaker Model Registry , carrying your metrics, evaluation results, and lineage along for the ride.
There is more than one way to do it, though, and the differences are not obvious until you have tried them all. We have. In this post we walk through the three patterns, with working code for each, and give you a clear answer to the question that matters: which one should I use?
Everything below is available as executable notebooks in the companion repository .
What an endpoint actually needs
Before looking at the patterns, it helps to demystify what a SageMaker AI real-time endpoint requires. For the deployment patterns in this post, it is useful to think in terms of four ingredients:
- A container image that runs a model server.
- Model artifacts in Amazon Simple Storage Service (Amazon S3) — your trained model, in a format the container can read.
- Loading and prediction logic — the glue that tells the server how to deserialize your model and turn an HTTP payload into a prediction.
- An endpoint configuration — the compute the model serves from: instance type and instance count. (Auto scaling is configured separately, on the running endpoint, through Application Auto Scaling. An execution role and networking are table stakes in every pattern, so we leave them out of the comparison.)
The fourth ingredient is yours to specify in every pattern; you will see instance types and counts in every deployment call below. The first three are where the patterns genuinely differ: each one is just a different answer to the question "who provides these things?" Once you see it that way, choosing between them stops being mysterious.
Our running example is deliberately boring: a scikit-learn
RandomForestRegressor trained with a function that runs either inline or — by uncommenting a single @remote decorator — as a SageMaker Training Job, logged to managed MLflow with its signature, metrics, and an evaluation dataset. Two details in the logging code matter later, so they are worth pointing out now: we log one copy of the model per pattern (the reason follows below), and we serialize the model as plain pickle.1
2
3
4
5
6
7
8
9
10
for pattern in ("native", "modelbuilder", "infspec"):
model_info = mlflow.sklearn.log_model(
model,
name=f"sklearn-model-{pattern}",
signature=signature,
input_example=X_train[:3],
# Plain pickle (not skops) so the SageMaker SKLearn serving container
# can load the artifact without extra dependencies.
serialization_format="pickle",
)MLflow's default scikit-learn serialization produces a
model.skops file, which the SageMaker SKLearn serving container cannot read out of the box. A one-argument change at training time saves you a debugging session at deployment time. This is a recurring theme in ML deployment: most of the friction lives in exactly these small mismatches between what the training side writes and what the serving side expects.One design note about the walkthrough: the model is trained once, but we log it to MLflow three times — one logged model per pattern, under pattern-specific names — and each pattern registers its own. That isolation is deliberate, and we learned its value the hard way. The Model Registry sync fires at registration time, and pattern 3 attaches an inference specification to its logged model before registering — so if the patterns shared a single logged model, running pattern 3 first would make that specification ride along into every later registration, and pattern 2's starting point (a metadata-only package) would silently never materialize. Separate logged models keep the three patterns truly independent: run them in any order, or skip the ones you don't care about.

The MLflow UI showing the three logged models produced by the setup notebook — sklearn-model-native, sklearn-model-modelbuilder, and sklearn-model-infspec — all logged from the same training run
One training run, three logged models — one per deployment pattern, each carrying the same evaluation dataset.
One security note before moving on:
pickle.load() executes arbitrary code during deserialization. Only deserialize pickle artifacts produced by a training and registration path you trust — pickle is not safe for untrusted model files. Relatedly, keep the serving container's scikit-learn version compatible with the training version, so the artifact unpickles into the same estimator it was saved from.A note on versions before we start: all code in this post uses the SageMaker Python SDK v3 (
sagemaker>=3,<4, a breaking release compared to v2), mlflow>3.14,<4, and sagemaker-mlflow>=0.5.0,<1. The companion notebooks carry these constraints in their requirements.txt; the exact versions this walkthrough was tested with are sagemaker v3.17.1, mlflow v3.14.0, sagemaker-mlflow v0.5.0, and scikit-learn v1.4.2, on Python 3.12.Pattern 1: Let MLflow do everything
If you live entirely inside MLflow, the shortest path is the one MLflow itself provides: the SageMaker deployment target built into
mlflow.deployments. In terms of our ingredients, MLflow answers the first three: it ships a generic pyfunc serving container, it knows where your artifacts are, and its pyfunc abstraction already knows how to load and invoke any model flavor it logged. You supply the fourth (instance type and count) in the deployment config.There is a one-time setup step: building the serving container and pushing it to Amazon Elastic Container Registry (Amazon ECR) in your account.
1
mlflow sagemaker build-and-push-container --build --push -c mlflow-pyfunc --network sagemaker(The
--network sagemaker flag sets the Docker networking mode required when building inside a SageMaker Studio JupyterLab space; omit it when building elsewhere.)After that, deployment is a single call against the model URI in your MLflow registry:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from mlflow.deployments import get_deploy_client
deploy_client = get_deploy_client(f"sagemaker:/{region}")
deploy_client.create_deployment(
name=endpoint_name,
model_uri=f"models:/{registered_name}/{version}",
config={
"execution_role_arn": execution_role,
"image_url": mlflow_image_uri,
"instance_type": "ml.m5.xlarge",
"instance_count": 1,
"region_name": region,
# Wait at most 10 minutes for the endpoint to become InService.
"timeout_seconds": 600,
},
)Behind the scenes, MLflow creates the SageMaker AI model, endpoint configuration, and endpoint, and waits for it to come in service. Predictions go through the same client:
1
prediction = deploy_client.predict(endpoint_name, test_input.values)This is a genuinely good pattern for a single data science team with a single MLflow app and an informal promotion process. There is almost nothing to learn and almost nothing to maintain.
What you give up is everything that lives in the SageMaker Model Registry, because this pattern never uses it. (To be precise: if Model Registry sync is enabled on your MLflow app — as it is in the companion environment — the registration call still auto-creates a metadata-only Model Package. But the MLflow deployment client does not consume it, so it plays no part in the deployment.) That means no lineage connecting the endpoint back to the training job, no IAM-gated lifecycle stages separating who can propose a model for production from who can approve it, no cross-account sharing, and no Amazon EventBridge events for a CI/CD pipeline to react to when a model is approved. In a one-team setup you may not miss any of that. The moment a second team, an approval process, or a platform organization enters the picture, you will — and the next two patterns exist for exactly that moment.
The bridge: automatic model registration
Managed MLflow has an opt-in capability called Model Registry sync (
AutoModelRegistrationEnabled). With it enabled, every mlflow.register_model() call does double duty: alongside the MLflow registration, SageMaker AI automatically creates a Model Package Group and Model Package version in the SageMaker Model Registry, with your training metrics, your evaluation results surfaced as a model card, and lineage back to the run that produced the model. Your MLflow aliases even drive the registry's lifecycle stages, and IAM condition keys let an administrator control who can promote what.For you as a data scientist, the important part is what doesn't change: you keep working in MLflow. One registration call, and governance gets its registry entry for free.
There is a catch, and it is the reason this post has three patterns instead of two. The auto-created Model Package is metadata-only. It describes the model beautifully, but it cannot be deployed as-is: there is no container image and no serving code attached. Your artifacts exist, safely tracked in the MLflow artifact store, but the package doesn't yet know how to serve them. Patterns 2 and 3 are the two ways to close that gap.

The auto-created Model Package in SageMaker Studio: Train and Evaluate show Complete with the metrics carried over from MLflow, the Deploy stage shows Pending Approval, but the Containers and Instances sections are empty
The synced Model Package right after registration: training and evaluation results carried over from MLflow, but the Containers section is empty — this package cannot be deployed yet.
Pattern 2: Sync to the registry, let ModelBuilder write the serving code
The first way is to hand the problem to
ModelBuilder , the packaging utility in the SageMaker Python SDK. You give it the model artifacts (downloaded from MLflow once, at build time) plus an inference specification: a small class answering the two questions you already know how to answer — how do I load my model? and how do I predict with it? — and a schema with a sample input and output. ModelBuilder generates the serving code, resolves a compatible container, and repacks everything, model bytes included, into a deployable archive in Amazon S3. Because the model travels inside the archive, the endpoint never calls the MLflow app at runtime: instance launches and scale-out events depend only on Amazon S3.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import mlflow
from sagemaker.core import image_uris
from sagemaker.serve import ModelBuilder
from sagemaker.serve.spec.inference_spec import InferenceSpec
from sagemaker.serve.builder.schema_builder import SchemaBuilder
from sagemaker.serve.utils.types import ModelServer
# Download the MLflow model directory (MLmodel, model.pkl, env files) once,
# at build time — ModelBuilder packs these bytes into the archive.
local_model_dir = mlflow.artifacts.download_artifacts(
artifact_uri=model_uri, dst_path="mlflow_model_download"
)
class MLflowPyfuncSpec(InferenceSpec):
"""How to load the packaged MLflow model and how to predict with it."""
def load(self, model_dir):
import mlflow as _mlflow
# model_dir is /opt/ml/model inside the container — the repacked copy
# of the MLflow model directory. Local load, no tracking-server call.
return _mlflow.pyfunc.load_model(model_dir)
def invoke(self, input_object, model):
import numpy as np
return model.predict(np.array(input_object)).tolist()
model_builder = ModelBuilder(
# Always pin the serving container explicitly — resolved for the current
# region, no hardcoded ECR URIs.
image_uri=image_uris.retrieve(
framework="sklearn", region=region, version="1.4-2-py312",
image_scope="inference", instance_type="ml.m5.xlarge",
),
model_path=local_model_dir, # the downloaded MLflow model directory
inference_spec=MLflowPyfuncSpec(),
schema_builder=SchemaBuilder(
sample_input=[[0.5, -1.2, 0.3, 0.8]],
sample_output=[42.0],
),
model_server=ModelServer.TORCHSERVE,
role_arn=execution_role,
instance_type="ml.m5.xlarge",
# load() runs inside the serving container, so mlflow must be installed
# there (and the sagemaker SDK, which the generated inference.py imports).
dependencies={"auto": False, "custom": [
"mlflow<4",
"sagemaker>=3,<4",
"scikit-learn>=1.4,<1.5",
# Pins that keep the container's own serving stack alive — see below.
"protobuf<3.21",
"jinja2>=3.0,<3.1",
"markupsafe<3",
"setuptools<70",
]},
)
built_model = model_builder.build()
model_data_url = model_builder.s3_upload_path # the repacked archive
secret_key = model_builder.secret_key # signs the generated codeA note on
ModelServer.TORCHSERVE, because the name misleads: the enum selects the ModelBuilder packaging path that generates and stages the handler for an InferenceSpec. It does not mean your model is a PyTorch model, and the serving stack that actually runs is the one inside the SKLearn image we pinned. Notice also what is not in that code: no inference.py, no knowledge of how SageMaker containers locate model files, no request parsing. And because load() reads the packaged copy through mlflow.pyfunc (the MLmodel metadata travels with the artifacts), the structure generalizes to other MLflow flavors, although the serving image, dependencies, schema, and sizing will need to change with the framework.An alternative would be to skip the build-time download and have
load() pull from MLflow at runtime instead — mlflow.pyfunc.load_model("models:/...") works inside the container too. But that couples every instance launch, including auto-scaling events, to the availability of (and network access and credentials for) your MLflow app. Downloading at build time keeps endpoint startup deterministic and S3-only, and it makes the registry entry's artifacts complete: the archive the Model Package points at actually contains the model.A word about that block of version pins, because it is the price of admission for this pattern. Your dependencies are pip-installed into the serving container at startup, alongside the container's own serving stack — and the SKLearn container's stack has opinions: it needs
protobuf<3.21, a Jinja2 that still exports escape (3.0.x, not 3.1+), and a setuptools that neither shadows typing_extensions with a vendored copy (71+) nor drops pkg_resources (81+). Omit the pins and the serve process crashes on import, the endpoint fails every /ping health check, and the failure reason tells you nothing useful. This is the small-mismatches theme at its worst: the fix is four lines, but only the container's Amazon CloudWatch logs will lead you to them. Copy the pinned list from the companion notebook rather than re-deriving it.One step remains: connecting the repacked artifacts to the Model Package that the sync auto-created. Finding that package is easy — the sync writes its ARN back onto the MLflow model version as a
sagemaker.model_package_arn tag (the companion notebooks poll for it, since the sync runs asynchronously). We then update the existing package rather than registering a new one — that keeps a single governed registry entry per model version, with the lineage the sync established. While we are at it, we also record the MLflow model URI and run ID as customer metadata on the package, so anyone browsing the registry can trace the entry back to the experiment:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
sm_client.update_model_package(
ModelPackageArn=sm_model_package_arn,
InferenceSpecification={
"Containers": [{
"Image": model_builder.image_uri,
"ModelDataUrl": model_data_url,
"Environment": {
"SAGEMAKER_PROGRAM": "inference.py",
"SAGEMAKER_SUBMIT_DIRECTORY": "/opt/ml/model/code",
"SAGEMAKER_SERVE_SECRET_KEY": secret_key,
},
}],
"SupportedContentTypes": ["application/json"],
"SupportedResponseMIMETypes": ["application/json"],
"SupportedRealtimeInferenceInstanceTypes": ["ml.m5.xlarge"],
},
CustomerMetadataProperties={
"MlflowModelUri": model_uri,
"MlflowRunId": run_id,
},
)(The
SAGEMAKER_SERVE_SECRET_KEY is how the endpoint verifies the integrity of the code ModelBuilder generated — it comes paired with the archive, so carry it into the specification together with the ModelDataUrl.)
The same Model Package after update_model_package: the Containers section now lists the SKLearn serving image ECR URI, the repacked model location in Amazon S3, and the `SAGEMAKER_PROGRAM` and `SAGEMAKER_SUBMIT_DIRECTORY` environment variables
The same Model Package after attaching the repacked artifacts: serving container, model data location, and environment variables are now filled in — the package is deployable.
This pattern shines when registration happens inside an automated pipeline, and when your team would rather not own inference scripts at all.
The trade-off: the artifact that ends up serving traffic is a repacked copy of your model, living outside the MLflow artifact store. For most teams that is perfectly acceptable. If your compliance posture requires the served bytes to be exactly the bytes MLflow tracked, in the place MLflow tracked them, keep reading — that is precisely what pattern 3 is for.
Pattern 3: Sync to the registry, keep MLflow as the source of truth
The second way inverts the responsibility. Instead of repacking the model, you tell the registry how to serve it as it sits in the MLflow artifact store. Release
v0.5.0 of the sagemaker-mlflow plugin added log_inference_specification() for exactly this: you attach the container image, data location, and environment to the MLflow model, and when you register it, the sync creates a Model Package that is deployable from birth — no post-registration surgery, no artifact copies. The endpoint downloads the model directly from the MLflow artifact location.The sequencing matters and is worth stating plainly: log the specification before you register. The sync copies it onto the Model Package at registration time; log it afterwards and the package stays metadata-only.
The trade is that the specification is now your responsibility, and this is where a little SageMaker container knowledge pays off. The SKLearn framework serving container has no default model loader — it expects a user script, named by the
SAGEMAKER_PROGRAM environment variable, to provide a model_fn. Normally SKLearnModel.deploy() wires this up for you by repacking your tarball; since we are deliberately not repacking, we log a minimal script as an artifact of the logged model itself:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import os
import tempfile
client = mlflow.MlflowClient()
logged_model = client.get_logged_model(model_info.model_id)
INFERENCE_SCRIPT = """\
import os
import pickle
def model_fn(model_dir):
with open(os.path.join(model_dir, "model.pkl"), "rb") as f:
return pickle.load(f)
"""
# log_model_artifacts preserves the local directory structure, so code/inference.py
# lands at <artifact_location>/code/inference.py — inside the MLflow artifact store.
with tempfile.TemporaryDirectory() as tmp:
os.makedirs(os.path.join(tmp, "code"))
with open(os.path.join(tmp, "code", "inference.py"), "w") as f:
f.write(INFERENCE_SCRIPT)
client.log_model_artifacts(model_info.model_id, tmp)Note what we did not do: no raw
boto3 upload to Amazon S3, and no resumed run. In MLflow 3 a logged model owns its own artifact location, separate from the run's, and MlflowClient.log_model_artifacts() targets exactly that location through MLflow's own artifact access mechanism. Even the inference script stays inside the artifact store, visible in the MLflow UI next to the model it serves, so the provenance story stays intact.This works because the specification below uses an
S3Prefix data source, which tells the endpoint to download everything under the artifact prefix — so our script lands at /opt/ml/model/code/inference.py in the container, exactly where SAGEMAKER_SUBMIT_DIRECTORY points. Five lines of model_fn are enough because the model is a plain model.pkl, which is where the pickle serialization choice from the first code snippet in this post pays off.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import sagemaker_mlflow
inference_spec = {
"Containers": [{
"Image": sklearn_image, # resolved with sagemaker.core.image_uris
"ModelDataSource": {
"S3DataSource": {
"S3Uri": logged_model.artifact_location + "/",
"S3DataType": "S3Prefix",
"CompressionType": "None",
}
},
# Point the framework container at the inference script; without
# these, the container fails every /ping health check.
"Environment": {
"SAGEMAKER_PROGRAM": "inference.py",
"SAGEMAKER_SUBMIT_DIRECTORY": "/opt/ml/model/code",
},
}],
"SupportedRealtimeInferenceInstanceTypes": ["ml.m5.xlarge"],
}
sagemaker_mlflow.log_inference_specification(
model_info.model_id, inference_specification=inference_spec
)
mv = mlflow.register_model(f"models:/{model_info.model_id}", registered_name)One hard-won piece of advice: the two environment variables are the single most common failure point. Forget them and the endpoint will fail every
/ping health check and never reach InService, with no error message that points you anywhere near the actual cause.
The MLflow artifact browser for the logged model: the artifact tree shows `model.pkl`, a code folder containing `inference.py`, and `sagemaker_inference_specification.json`, with the specification JSON content displayed alongside
Everything in one place: the model, the inference script, and the logged inference specification, all inside the MLflow artifact store — the single source of truth the endpoint will serve from.
What you gain for that effort is a property the other patterns cannot offer: the MLflow artifact store remains the single source of truth for the served bytes. The registry entry, the lineage, and the running endpoint all point at one set of artifacts — the ones your experiment produced.
Deploying from the registry
Patterns 2 and 3 converge here, and this is the payoff of routing through the Model Registry at all: deployment becomes a governance event, not a data science task. The Model Package carries an approval status, and flipping it is the promotion signal:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
from sagemaker.core.resources import Endpoint, EndpointConfig, Model, ModelPackage
from sagemaker.core.shapes import ContainerDefinition, ProductionVariant
model_package = ModelPackage.get(model_package_name=sm_model_package_arn)
# DescribeModelPackage omits ModelPackageName for versioned packages; the API
# accepts the ARN in that field, so backfill it to keep update()/refresh() working.
model_package.model_package_name = model_package.model_package_arn
model_package.update(model_approval_status="Approved")
deployed_model = Model.create(
model_name=resource_name,
primary_container=ContainerDefinition(model_package_name=sm_model_package_arn),
execution_role_arn=execution_role,
)
endpoint_config = EndpointConfig.create(
endpoint_config_name=resource_name,
production_variants=[ProductionVariant(
variant_name="AllTraffic",
model_name=resource_name,
initial_instance_count=1,
instance_type="ml.m5.xlarge",
)],
)
endpoint = Endpoint.create(
endpoint_name=resource_name,
endpoint_config_name=resource_name,
)
# Poll describe_endpoint until EndpointStatus reaches "InService" (a "Failed"
# status carries the FailureReason) — see the companion notebooks for the loop.Three typed resources —
Model, EndpointConfig, Endpoint — mirroring the underlying API. This is the same flow the Deploy button in SageMaker Studio drives, and the same code a CI/CD pipeline runs when the approval event fires.
The Model Package in SageMaker Studio after approval: the Deploy stage shows Approved and the Deploy button is active
After flipping the approval status: the package shows Approved and the Deploy button lights up — the same signal a CI/CD pipeline would react to.
One caveat: approval status becomes a real gate only when your deployment workflow and IAM policies allow only approved packages to progress. In this walkthrough a single role performs both the approval and the deployment — that demonstrates the mechanics, not separation of duties; production environments should split those responsibilities across roles. (Approval status is also distinct from the registry's lifecycle stages, which sync from specially named MLflow aliases — two related governance levers, not the same field.)
So which one should you use?
If you have read this far, you probably already know which one fits your team. In short:
Choose pattern 1 when a single team owns the model end to end, MLflow is your registry of record, and promotion is a conversation rather than a process. It is the least code and the least AWS to learn.
Choose pattern 2 when models flow through the SageMaker Model Registry and you want the serving code generated for you. It fits naturally into pipeline register steps, and the
InferenceSpec class is the only piece you maintain — two methods any data scientist can write.Choose pattern 3 when the registry matters and artifact provenance matters: the endpoint downloads its artifacts directly from the MLflow artifact location, so what you tracked is literally what you run. You own a small inference script and two environment variables; in exchange, there is no repacked copy to account for — and no MLflow client in the serving container at all.
| Pattern 1: MLflow-native | Pattern 2: Sync + ModelBuilder | Pattern 3: Sync + inference spec | |
|---|---|---|---|
| SageMaker Model Registry entry | not used for deployment (sync may still create one) | yes (made deployable post-sync) | yes (born deployable) |
| Inference code | handled by pyfunc | generated for you | you provide model_fn |
| Served artifact | copy staged by MLflow in Amazon S3 | repacked copy (model + generated code) in Amazon S3 | downloaded from the MLflow artifact location |
| MLflow client in the serving container | baked into the pyfunc image | yes (loads the packaged MLmodel) | no |
| Governance (lifecycle, approvals, lineage, cross-account) | MLflow aliases only | full | full |
| Best for | single team, fast path | pipelines, no hand-written serving code | provenance-sensitive, platform-standardized teams |
One scope note: patterns 2 and 3 both extend to multi-account governance topologies — a central registry serving spoke accounts, hybrid approval flows, and cross-account sharing through AWS Resource Access Manager (AWS RAM). Those topologies deserve a post of their own, so we keep the focus here on the single-account mechanics.
Cleaning up
Real-time endpoints bill per instance-hour. The companion repository includes a cleanup notebook that removes the endpoints, endpoint configurations, models, Model Packages, and registered models created by the walkthrough — run it when you are done experimenting. Also remember to delete the Amazon S3 artifacts the walkthrough produced (the MLflow artifact store contents, the repacked archive from pattern 2, and, if you enabled
@remote, the training job outputs) and, if you provisioned the environment with the included AWS CloudFormation template, to delete that stack as well.Conclusion
Deploying a model does not have to be the moment your workflow leaves MLflow — or your comfort zone. If MLflow is your whole world, deploy from it directly. If your models need governance, let automatic model registration carry them into the SageMaker Model Registry with their metrics and lineage intact, then make them deployable either by generating the serving stack with
ModelBuilder or by logging an inference specification and serving straight from your artifact store. All three paths end in the same place: your model, behind a managed endpoint, answering requests.
The Endpoints view in SageMaker Studio showing three endpoints in service — one per deployment pattern
The end state of the walkthrough: the same model behind three endpoints, one per pattern. (Remember the cleanup notebook — these bill per instance-hour.)
The notebooks for all three patterns are in the companion repository — clone it, run them against your own MLflow app, and see which pattern fits the way your team works.
Further reading
- Managed MLflow on Amazon SageMaker AI
- Automatically register SageMaker AI models with SageMaker Model Registry
- Deploy MLflow Model to Amazon SageMaker (MLflow documentation)
- sagemaker-mlflow plugin, release v0.5.0
About the author
Paolo Di Francesco is a Senior Solutions Architect at AWS. He holds a PhD in Telecommunications Engineering and has experience in software engineering. He is passionate about machine learning and is currently focusing on using his experience to help customers reach their goals on AWS, in discussions around MLOps. Outside of work, he enjoys playing football and reading.
Enjoyed reading this content? Let the author know!
Your likes, comments, shares, and saves help creators reach more builders.
Loading recommendations
Loading article