mrkeyoor.com_
Sat 19 Sept 21:39 UTC
PyPIAI / MLupdated 19 Sept 2026

mlflow review

MLflow 3.15.2 is a self-hostable tracking server, Python SDK, web interface, artifact system, and model registry for machine-learning and generative-AI teams. It records experiments, parameters, metrics, models, traces, evaluations, prompts, and deployment metadata, then makes them searchable through APIs and a UI. The current patch adds immutable evaluation-dataset versions and a `scorer_ensemble` primitive, while fixing a Databricks telemetry deadlock and two evaluation or tracking defects. Our v3.15.1 Python 3.12 install imported successfully and shipped typing metadata, but it occupied 608 MB, pulled 90 packages, and contained 1 known vulnerability. Treat it as operational infrastructure with a client library.

Verdict

MLflow 3.15.1 took 14.3 seconds, installed 90 packages using 608 MB, imported in 3.79 seconds, and produced 1 pip-audit finding in our sandbox. Adopt 3.15.2 when a team will use the shared tracking and registry system enough to justify operating it; do not add the full package for a few local charts.

We installed it

Lab card: what happened when we installed mlflowScreenshot of mlflow documentation
Install✓ · 14.3s90 packages on disk · 608 MB
Importimport mlflow in 3.79s · pure Python · py.typed · requires Python >=3.10
Known vulns1(pip-audit)

Answers from our run

Does mlflow install cleanly?

Yes. In a fresh container with an empty cache, pip install mlflow finished in 14 seconds, leaving 90 packages and 608 MB on disk. pip-audit reported 1 known vulnerability.

What does mlflow need to run?

Python >=3.10, and nothing compiled: it is pure Python. In our run import mlflow succeeded in 3.79s, and the package ships py.typed for type checkers.

mlflow or wandb: which should you use?

wandb: Use it when a managed experiment service and collaborative UI matter more than operating the tracking stack yourself. MLflow 3.15.1 took 14.3 seconds, installed 90 packages using 608 MB, imported in 3.79 seconds, and produced 1 pip-audit finding in our sandbox.

When should you not use mlflow?

You only need local loss curves or a few scalar charts. TensorBoard or plain artifacts avoid a service and our measured 608 MB environment.

API stability3/5Core run calls such as `start_run`, `log_param`, `log_metric`, `log_artifact`, and `search_runs` remain recognizable across the 3.x line. Platform edges move faster. Version 3.13 replaced the legacy permission tables and client methods with role-based access control, removed an MLServer serving option, and changed local file-store defaults. Version 3.15.2 adds new evaluation primitives. Pin versions and test server, SDK, permission, and model-loading paths together.
Docs4/5The official site separates model-training material from GenAI material and then documents tracking, registry, deployment, tracing, evaluation, prompts, gateway, self-hosting, security, and integrations. API references and quick starts are extensive. Breadth is now the main problem: old 2.x search results still show model stages and file-store assumptions, while current 3.x pages use aliases, workspaces, and newer authorization. Check the version and product area before copying an example.
Maintenance5/5PyPI published 3.15.2 on August 26, 2026, and GitHub showed a push later that day, 27,687 stars, 2,075 open issues and pull requests, and an unarchived repository. The patch includes two evaluation features plus fixes for tracking metadata and a Databricks telemetry deadlock. Release activity is high enough to address defects quickly, though the size of the issue and PR queue matches a platform with many independently moving subsystems.
Ecosystem5/5MLflow records 9,993,245 weekly downloads and connects to common training libraries, model flavors, cloud artifact stores, serving targets, OpenTelemetry, LLM providers, and agent frameworks. Databricks integrates it directly while the open server keeps tracking and registry APIs available elsewhere. The same breadth creates dependency and version coupling: framework autologging, model environments, database drivers, object-store SDKs, and gateway providers can all extend the already large base installation.

Use it if

  • A team needs a shared history of training parameters, metrics, datasets, artifacts, model versions, and promotion aliases.
  • Model-serving code should load a registry alias while operators change the selected version without editing the application.
  • One self-hosted system must cover conventional ML experiments plus LLM traces, prompts, scorers, and evaluations.
  • Supported framework autologging can replace repeated tracking calls, and the captured data has passed a privacy review.
Skip it if

Setup reality

Our lab installed MLflow 3.15.1 in a clean Python 3.12 Bookworm sandbox in 14.3 seconds. The environment contained 90 packages and occupied 608 MB. pip-audit reported 1 known vulnerability. The distribution declares 59 direct dependencies, requires Python 3.10 or newer, is pure Python, and ships py.typed. import mlflow succeeded in 3.79 seconds. These measurements apply to 3.15.1; PyPI now serves 3.15.2.

Without a tracking URI, a script can create local run data where it was launched. Shared use needs a stable tracking URI, a database for tracking and registry records, and an artifact store reachable by either clients or the server's artifact proxy. Back up the database before mlflow db upgrade. Decide which process owns S3, Azure, GCS, or other artifact credentials. Notebook code should not carry production storage secrets just because it logs a model.

A tracking server holds experiment metadata and downloadable model artifacts, so bind and expose it deliberately. Configure authentication, TLS, allowed origins, and resource permissions before team access. SQLite may work for one local user; concurrent services call for a server database and tested connection limits. MLflow 3.13 replaced legacy per-resource permissions with role-based access control, which makes an upgrade from older self-hosted authorization a migration project rather than a package bump.

Autologging can capture model artifacts, dataset details, input examples, prompts, responses, tags, and traces beyond the metric you meant to chart. Review personal data and secret exposure before enabling each integration. Framework flavors add their own environments on top of the 608 MB base we measured. mlflow-skinny can reduce client weight when only tracking APIs are needed, but verify required commands and flavors. Version 3.15.2's immutable evaluation datasets help reproducibility only when callers consistently log and reference those versions.

Patterns

Record parameters and metric steps log-training-run

import mlflow

mlflow.set_tracking_uri('http://127.0.0.1:5000')
mlflow.set_experiment('invoice-risk')

with mlflow.start_run(run_name='depth-8'):
    mlflow.log_param('max_depth', 8)
    for step, loss in enumerate(losses):
        mlflow.log_metric('loss', loss, step=step)

Set the tracking URI before `start_run`. Otherwise the run can land in a local store tied to the process working directory.

Capture a scikit-learn fit enable-sklearn-autolog

import mlflow
from sklearn.ensemble import RandomForestClassifier

mlflow.sklearn.autolog(log_models=True)
with mlflow.start_run():
    model = RandomForestClassifier(n_estimators=200)
    model.fit(X_train, y_train)

Autologging may save the estimator, signature, example, parameters, and metrics. Review the captured input before using sensitive training data.

Load the URI returned by model logging log-and-load-model

with mlflow.start_run():
    info = mlflow.sklearn.log_model(
        sk_model=model,
        name='risk-classifier',
        input_example=X_train[:2],
    )

loaded = mlflow.pyfunc.load_model(info.model_uri)
predictions = loaded.predict(X_test)

Current 3.x examples use `name`. Keep the returned URI instead of reconstructing a run-relative artifact path.

Point an alias at a tested version promote-model-alias

import mlflow
from mlflow import MlflowClient

client = MlflowClient()
client.set_registered_model_alias(
    name='invoice-risk',
    alias='champion',
    version='12',
)
model = mlflow.pyfunc.load_model('models:/invoice-risk@champion')

Alias readers can resolve version 12 immediately after the update. Finish validation before moving `champion`.

Order runs by a metric search-best-runs

runs = mlflow.search_runs(
    experiment_names=['invoice-risk'],
    filter_string='metrics.auc >= 0.90',
    order_by=['metrics.auc DESC'],
    max_results=20,
)
print(runs[['run_id', 'metrics.auc']])

The filter uses MLflow's search syntax. Prefix metrics, parameters, and tags instead of writing database SQL.

Associate a dataset with a run log-dataset-input

import mlflow

dataset = mlflow.data.from_pandas(
    training_frame,
    source='s3://ml-data/invoices/train.parquet',
    name='invoice-training',
)
with mlflow.start_run():
    mlflow.log_input(dataset, context='training')

A source URI and name improve lineage, but access control for the underlying data remains outside MLflow's run record.

Create nested retrieval spans trace-python-functions

import mlflow

@mlflow.trace
def retrieve(question: str) -> list[str]:
    return index.search(question)

@mlflow.trace
def answer(question: str) -> str:
    context = retrieve(question)
    return generate(question, context)

Decorated arguments and return values can enter the trace store. Redact boundaries that carry private prompts or credentials.

Turn on OpenAI autologging trace-openai-client

import mlflow

mlflow.set_tracking_uri('http://127.0.0.1:5000')
mlflow.set_experiment('support-agent')
mlflow.openai.autolog()

# OpenAI client calls made after this line can be traced.

Set the experiment before the first request and review prompt, response, and token data retention before production use.

Separate metadata and artifacts start-tracking-server

mlflow server \
  --backend-store-uri postgresql://mlflow@db/mlflow \
  --artifacts-destination s3://team-mlflow/artifacts \
  --host 127.0.0.1 \
  --port 5000

PostgreSQL stores tracking and registry rows; S3 stores files. Put authenticated TLS access in front of port 5000.

Apply schema migrations before startup upgrade-database-schema

mlflow db upgrade postgresql://mlflow@db/mlflow

Back up the database and test the same version jump first. Do not let several new server instances race a schema migration.

Evaluate a prediction function evaluate-model-output

import mlflow

result = mlflow.genai.evaluate(
    data=evaluation_rows,
    predict_fn=answer,
    scorers=[correctness_scorer],
)
print(result.metrics)

Scorers can call external models and create cost or data exposure. Pin scorer definitions and dataset versions with the result.

Use a tracking-only client environment load-skinny-client

from mlflow import MlflowClient

client = MlflowClient(tracking_uri='https://mlflow.example.com')
runs = client.search_runs(
    experiment_ids=['1'],
    max_results=10,
)

`mlflow-skinny` can suit this client pattern, but it omits parts of the full package. Verify every flavor and command before replacing the 608 MB environment we measured.

Alternatives

PackageRegistryPick it when
wandbPyPIUse it when a managed experiment service and collaborative UI matter more than operating the tracking stack yourself.
neptunePyPIUse it when a hosted metadata store fits the team's governance and experiment-comparison workflow.
aimPyPIUse it for a narrower open-source experiment tracker when model registry, serving, and GenAI gateway features are unnecessary.
tensorboardPyPIUse it for local scalar, histogram, and graph visualization without running a registry service.

More ai / ml guides

openai · mcp · huggingface-hub · @modelcontextprotocol/sdk · scikit-learn · tiktoken · the whole shelf →

How this guide is made: grounded in the library's documentation, release notes, changelog, and issue history, on a fixed rubric — not a hands-on install of every release. The 50 most-downloaded entries are additionally install-verified in clean containers. Corrections: contact the desk.