MLflow 3 u Pythonu: Vodič za praćenje ML eksperimenata i Model Registry (2026)

Praktični vodič kroz MLflow 3 u Pythonu: instalacija tracking servera, autologging za sklearn i XGBoost, Model Registry s aliasima i posluživanje modela u produkciji uz konkretne primjere koda.

Ažurirano: 15. kolovoza 2026.

MLflow 3 je open-source platforma za praćenje ML eksperimenata, verzioniranje modela i posluživanje u produkciji, s prvi put uvedenim konceptom LoggedModel kao entitetom prvog reda te proširenom podrškom za GenAI aplikacije. U ovom vodiču pokazujem kako MLflow 3 postaviti u Pythonu, integrirati u scikit-learn i XGBoost trening kod, upravljati verzijama modela kroz Model Registry i posluživati modele iza HTTP endpointa, onako kako to zaista radim kad model treba izdržati produkcijski promet, a ne samo demo bilježnicu.

  • MLflow 3.10 (ožujak 2026.) uvodi LoggedModel kao samostalan entitet s vlastitim ID-om, odvojen od trening runa.
  • Autologging za scikit-learn, PyTorch, XGBoost i LightGBM snima parametre, metrike i model bez ijedne dodatne linije koda.
  • Model Registry podržava aliase (npr. @champion, @challenger) umjesto zastarjelih stage-ova.
  • MLflow 3 uklanja mlflow.recipes i stari Deployment Server, migracija ide na mlflow models serve.
  • Za timski rad postavite MLFLOW_TRACKING_URI na centralni server s Postgres backendom i S3 artifact storeom.
  • MLflow je besplatan i self-hosted; W&B i Neptune su SaaS, bira se prema tome čije podatke i cijenu možete progutati.

Što je MLflow i zašto ga koristiti u produkciji?

MLflow je open-source platforma, izvorno iz Databricksa, danas s više od 30 milijuna mjesečnih preuzimanja, koja pokriva četiri odvojena ali povezana dijela ML lifecycle-a: Tracking (log parametara, metrika i artefakata), Models (jedinstveni format pakiranja modela), Model Registry (verzioniranje i promocija) te Projects (reproducibilno pokretanje koda). U verziji 3, koja je stigla sredinom 2025., dodan je i sloj za GenAI aplikacije: tracing LLM poziva, evaluacija po LLM-as-a-judge principu i registar promptova.

U mojoj svakodnevici, MLflow rješava tri konkretna produkcijska bola. Prvo, kad model padne u proizvodnji u tri ujutro i pager zazvoni (i vjerujte mi, to se dogodi baš onda kad ne treba), moram za manje od pet minuta znati koji run je proizveo baš tu verziju modela, s kojim seedom, kojim skupom podataka i kojim hiperparametrima. Bez centralnog tracking servera to znači kopanje po Git commitovima, Slack porukama i CSV-ovima po tuđim laptopima. Drugo, kad product manager kaže „vratimo prošlotjedni model, ovaj gubi 3 % preciznosti“, treba mi mehanizam za instant rollback bez novog treninga. Treće, kad audit dođe i pita „kako je ovaj model treniran i tko ga je odobrio“, treba mi zapis koji stoji izvan bilježnica podatkovnih znanstvenika. Sve tri stvari MLflow rješava u default konfiguraciji.

Iskreno, skeptičan sam prema frameworkovima koji zvuče dobro na konferencijama, a raspadaju se kod prvog HTTP 500 u produkciji. MLflow nije bez mana (do njih ću doći kasnije), ali vjerojatno je najzreliji open-source alat u prostoru MLOps-a i platforma koju je danas teško preskočiti kad procjenjujete novi ML stack.

Instalacija MLflow 3 i pokretanje tracking servera

Za lokalni razvoj instalacija je trivijalna:

# Preporučam Python 3.10+ i virtualno okruženje
python -m venv .venv
source .venv/bin/activate
pip install "mlflow>=3.10"

# Provjeri instaliranu verziju
mlflow --version

Za same eksperimente na lokalu (bez servera) sve završi u lokalnoj mapi mlruns/. To je dobro za istraživanje, katastrofa za timove: kolega ne vidi tvoje runove, backup ne postoji, model registry je samo lokalni SQLite. Za bilo što ozbiljno pokrećem centralni tracking server u Dockeru na malenoj EC2 instanci ili GKE podu:

# Pokretanje tracking servera s Postgresom kao backend storeom
# i S3 bucketom za artefakte
mlflow server \
    --backend-store-uri postgresql://mlflow:[email protected]:5432/mlflow \
    --default-artifact-root s3://ml-artifacts-prod/mlflow \
    --host 0.0.0.0 \
    --port 5000 \
    --workers 4

Klijentski kod se veže na taj server preko varijable okruženja ili direktnim pozivom:

import os
import mlflow

os.environ["MLFLOW_TRACKING_URI"] = "https://mlflow.internal:5000"
# Ili u kodu:
mlflow.set_tracking_uri("https://mlflow.internal:5000")
mlflow.set_experiment("kreditni-rizik-v2")

Kako pratiti ML eksperimente s Tracking API-jem?

Osnovna jedinica u MLflowu je run, jedno izvršavanje trening skripte. Runove grupiramo u experiment (npr. „kreditni-rizik-v2“). Unutar runa logiramo parametre (ulaz), metrike (izlaz) i artefakte (fajlove, model, plotove).

import mlflow
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import roc_auc_score, f1_score
import pandas as pd

df = pd.read_parquet("s3://data-lake/credit/train_2026q3.parquet")
X = df.drop(columns=["defaulted"])
y = df["defaulted"]
X_train, X_val, y_train, y_val = train_test_split(
    X, y, test_size=0.2, random_state=42, stratify=y
)

mlflow.set_experiment("kreditni-rizik-v2")

with mlflow.start_run(run_name="gbm-depth4-lr01") as run:
    params = {"n_estimators": 300, "max_depth": 4,
              "learning_rate": 0.1, "random_state": 42}
    mlflow.log_params(params)

    model = GradientBoostingClassifier(**params).fit(X_train, y_train)
    probs = model.predict_proba(X_val)[:, 1]

    mlflow.log_metric("val_auc", roc_auc_score(y_val, probs))
    mlflow.log_metric("val_f1", f1_score(y_val, probs > 0.5))

    signature = mlflow.models.infer_signature(X_train.head(5), probs[:5])
    mlflow.sklearn.log_model(
        model, name="model",
        signature=signature,
        input_example=X_train.head(3),
    )

    print(f"MLflow run: {run.info.run_id}")

Nekoliko produkcijskih navika koje sam skupio, uglavnom boleći ih:

  • Uvijek postavite random_state i logirajte ga. „Reproducibilan“ eksperiment bez seeda je fikcija.
  • Logirajte i hash ulaznog dataseta, ne samo putanju. Putanja s3://data/train.parquet u tri tjedna više nije isti file.
  • Koristite signature i input_example. To je prva linija obrane kad frontend počne slati null u polju koje očekuje float64. Točno na tome sam se opekao u prvom kvartalu ove godine.
  • Ne logirajte cijele podatke kao artefakt. Reference (hash + putanja) su dovoljne; artifact store ne bi trebao rasti brzinom ML tima.

Model Registry: verzije, aliasi i promocija modela

Tracking odgovara na pitanje „kako je nastao ovaj model“. Model Registry odgovara na „koji je model trenutno u produkciji“. To su različiti problemi i različiti slojevi svijesti u MLOps stacku.

U verziji 3 stage-ovi (Staging, Production) su formalno deprecirani u korist fleksibilnijih aliasa:

from mlflow import MlflowClient

client = MlflowClient()

# Registriraj novu verziju iz prethodnog runa
result = mlflow.register_model(
    model_uri=f"runs:/{run_id}/model",
    name="kreditni-rizik",
)

# Dodijeli alias @challenger za A/B testiranje
client.set_registered_model_alias(
    name="kreditni-rizik",
    alias="challenger",
    version=result.version,
)

# Kad se dokaže, promoviraj u @champion
client.set_registered_model_alias(
    name="kreditni-rizik",
    alias="champion",
    version=result.version,
)

Servis onda uvijek učita „daj mi models:/kreditni-rizik@champion“, bez tvrdo kodiranih verzija:

import mlflow.pyfunc

model = mlflow.pyfunc.load_model("models:/kreditni-rizik@champion")
predictions = model.predict(features_df)

Rollback je jedan alias flip: prebacite @champion na prethodnu verziju i sljedeći request u servisu čita novi (stari) model. Bez redeploya, bez novog treninga, bez panike. Ako vam ovakav tijek zvuči poznato iz svijeta scikit-learn cjevovoda, pogledajte i moj raniji vodič scikit-learn Pipeline i ColumnTransformer za produkcijski ML. Registry se prirodno slaže s tim pattern-om, jer Pipeline objekt već sadrži i preprocessing i estimator, pa je registrirani „model“ zapravo cijeli inference graf.

Autologging: manje koda, više uhvaćenih parametara

Za većinu standardnih frameworkova, MLflow može automatski uhvatiti parametre, metrike i model jednim pozivom prije treninga:

import mlflow
import xgboost as xgb

mlflow.xgboost.autolog(log_input_examples=True, log_model_signatures=True)

model = xgb.XGBClassifier(n_estimators=500, max_depth=6, learning_rate=0.05)
model.fit(X_train, y_train, eval_set=[(X_val, y_val)])
# Sve je već logirano: parametri, per-iter metrike,
# feature importance, model, requirements

Podržani frameworkovi u 3.10 uključuju sklearn, xgboost, lightgbm, pytorch, keras, tensorflow, transformers, langchain, openai i još 15-ak GenAI biblioteka. Za brzo istraživanje ovo je čisto zlato: pokrenete grid search, u MLflow UI dobijete tablicu sa svim runovima, sortirate po val_auc, kliknete najbolji i imate model spreman za registraciju.

Postoji jedna zamka. Autolog neće uhvatiti kontekst koji framework ne zna, poput sheme vaših ulaznih podataka, verzije feature transformacija ili imena data snapshota. Za produkciju obično kombiniram autolog s ručnim log_param pozivima za taj metadata:

mlflow.sklearn.autolog()

with mlflow.start_run():
    mlflow.log_param("dataset_snapshot", "train_2026q3_v2")
    mlflow.log_param("feature_transform_version", "v1.4")
    mlflow.log_param("data_row_hash", compute_hash(X_train))

    pipeline.fit(X_train, y_train)  # sve ostalo autolog uhvati

Posluživanje modela s mlflow models serve i Dockerom

MLflow ne pretendira biti Kubernetes ili SageMaker, ali za manje servise (do nekoliko stotina rps-a) njegov ugrađeni server je više nego dovoljan. Iza scene je Flask ili MLServer wrapper koji učita pyfunc model i eksponira /invocations endpoint.

# Lokalno posluživanje modela iz registryja
mlflow models serve \
    -m "models:/kreditni-rizik@champion" \
    -p 5001 \
    --env-manager local

# Test request
curl -X POST http://localhost:5001/invocations \
    -H "Content-Type: application/json" \
    -d '{"dataframe_records": [{"income": 45000, "age": 34, "loans_open": 2}]}'

Za produkciju obično buildam Docker sliku direktno iz modela:

mlflow models build-docker \
    -m "models:/kreditni-rizik@champion" \
    -n kreditni-rizik:v42 \
    --enable-mlserver

# Push u registry, deploy u k8s
docker push registry.internal/ml/kreditni-rizik:v42

Flag --enable-mlserver koristi Seldon MLServer umjesto Flaska i vrijedi svake sekunde koja vam s 40 ms padne na 12 ms po pozivu, jer koristi V2 inference protokol i async workere.

MLflow za GenAI: praćenje LLM aplikacija i promptova

MLflow 3 nije više samo za klasične ML modele. Sloj mlflow.tracing instrumentira 20+ GenAI frameworkova (OpenAI, Anthropic, LangChain, LlamaIndex, PydanticAI, smolagents) i automatski snima svaki LLM poziv (prompt, response, latency, cost, tool calls) u istu Tracking bazu kao i klasične runove.

import mlflow
from openai import OpenAI

mlflow.openai.autolog()
mlflow.set_experiment("rag-chatbot-prod")

client = OpenAI()
response = client.chat.completions.create(
    model="gpt-4o-mini",
    messages=[{"role": "user", "content": "Objasni što je cross-validation."}],
)
# Trace se automatski pojavi u MLflow UI s cijelim requestom i responseom

Prompt Registry drži verzionirane prompte, s search_prompts API-jem za pretragu i A/B testiranje. U kombinaciji s ugrađenom LLM-as-a-judge evaluacijom, ovo zamjenjuje pola custom skripti koje su timovi pisali 2024. godine. Za robusni RAG pipeline još uvijek treba pravi feature store (MLflow tu nije nadomjestak), ali za observability sloj čini teško nadmašivu tehničku bazu, s uzročno-posljedičnim linkom između runa treninga, evaluacijskog runa i produkcijskog tracea.

MLflow vs Weights & Biases vs Neptune: usporedba

Tri platforme dominiraju prostor experiment trackinga u 2026: MLflow, Weights & Biases (W&B) i Neptune.ai. Nisu iste. Svaka optimizira za drugačiju stvar, pa izbor ovisi o tome što vas najviše boli.

KriterijMLflow 3Weights & BiasesNeptune.ai
LicencaOpen source (Apache 2.0)Free tier + Pro od ~60 USD/mjFree tier + Team od ~150 USD/mj
Self-hostedDa, sve funkcijeSamo Enterprise (skupo)Samo Enterprise
Model RegistryUgrađen, s aliasimaWeave (odvojen proizvod)Model registry uključen
UI i vizualizacijaFunkcionalna, čitljivaNajbolja u klasiOdlična, skalira na tisuće runova
GenAI/LLM tracingUgrađen u 3.xWeave (dodatni proizvod)Fokus na foundation modele
Hyperparam sweepsPreko Optuna/HyperoptUgrađen W&B SweepsPreko integracija
Idealno zaSelf-hosted i regulirane industrijeResearch timove, kompetitivnu vizualizacijuFoundation model trening, veliki metadata

Moja heuristika: ako trebate držati sve podatke unutar VPC-a (finance, healthcare, government) i imate DevOps kapaciteta, MLflow je jedini razuman izbor. Ako ste research tim gdje UX i kolaboracija odlučuju, W&B pobjeđuje. Njegov Sweeps je bolji od bilo čega što ćete lakonski složiti nad MLflowom. Ako trenirate foundation modele s tisućama runova i trebate ozbiljno pretraživanje metadata, Neptune ima najbolju priču. Za sličnu odluku između alata za obradu podataka pročitajte i Polars vs Pandas usporedbu za 2026.

Produkcijske zamke koje sam vidio na dežurstvu

Nekoliko stvari na koje sam se opekao (ili gledao kolege kako se opekle) u produkciji s MLflow-om:

1. Artifact storage koji šuti dok ne pukne

MLflow zapisuje modele kao artefakte na filesystem, S3 ili Azure Blob. Ako S3 IAM policy nema PutObject permission za MLflow servis, klijent će vam veselo javiti „run završen“, a model neće biti nigdje. Uključite smoke test koji nakon svakog runa poziva MlflowClient.list_artifacts() i failaju CI ako je lista prazna. Jeftina zaštita, spašava dane.

2. Serialization drift između trening i serving okoline

Modeli su pickle-ani. Ako trenirate sa scikit-learn 1.5, a servis vrti 1.3, dobit ćete tihe (ili glasne) greške pri unpickle-u. Uvijek pinajte verzije u conda.yaml ili requirements.txt koje MLflow automatski logira uz model. Za ETL cjevovode koji hrane te modele, DuckDB kao lokalna ETL alatka može drastično smanjiti trošak reprodukcije feature pipelinea kada trebate ponovno stvoriti trening set.

3. Backend baza koja postane bottleneck

Postgres backend s neindeksiranom tags tablicom postaje spor nakon 50k runova. Prvo iskoristite ugrađene indekse iz MLflow backend store dokumentacije i pokrenite mlflow db upgrade nakon svakog major upgrade-a, a onda dodajte GIN indeks na JSON kolone ako filtrirate po tagovima.

4. Ne prati što nije rekao da će pratiti

Autolog neće snimiti train/val split logic. Ako netko odjednom počne dijeliti podatke drugačije, metrika ide gore, model se promovira, a u produkciji, iznenađenje. Uvijek imajte barem hash validacijskog seta u parametrima.

5. GDPR i pravo na zaborav

Ako logirate input_example s pravim korisničkim podacima, ti podaci ostaju u artifact storeu godinama. Za osobne podatke koristite sintetizirane primjere ili maskirajte. Ovo je već koštalo poduzeća skupih odvjetničkih računa i kompletnog re-runnanja svih historijskih eksperimenata.

Sljedeći koraci

Instalirajte MLflow 3, pokrenite lokalno mlflow ui i logirajte prvi eksperiment za pet minuta. Zatim postavite centralni tracking server s Postgres backendom, prebacite tim, i integrirajte s CI cjevovodom kroz mlflow.set_tag("git_sha", os.getenv("GITHUB_SHA")) u trening skripti. Za sve tehničke detalje pogledajte službene MLflow 3 release notes i MLflow 3 migration guide.

Često postavljana pitanja

Za što se koristi MLflow?

MLflow se koristi za praćenje ML eksperimenata (parametara, metrika, artefakata), verzioniranje i promociju modela kroz Model Registry, pakiranje reproducibilnih trening projekata te posluživanje modela iza HTTP endpointa. U verziji 3 pokriva i observability GenAI aplikacija, LLM tracing, Prompt Registry i LLM-as-a-judge evaluacije.

Je li MLflow besplatan?

Da, MLflow je open source pod Apache 2.0 licencom i besplatan za komercijalnu upotrebu. Ako ga hostate sami, jedini trošak je infrastruktura (compute, baza, storage). Databricks nudi upravljanu verziju kao dio svoje platforme, ali sama biblioteka i self-hosted tracking server nemaju licencne troškove.

Kako pratiti hiperparametre i metrike u MLflowu?

Unutar mlflow.start_run() bloka koristite mlflow.log_params({...}) za hiperparametre, mlflow.log_metric(name, value, step=...) za per-iteration metrike i mlflow.log_artifact(path) za fajlove. Za standardne frameworke mlflow.sklearn.autolog() (ili ekvivalent za XGBoost, PyTorch itd.) sve radi automatski.

Koja je razlika između MLflow i Weights & Biases?

MLflow je open source i self-hosted, s ugrađenim Model Registry-jem i minimalnim vendor lock-inom. W&B je SaaS s boljim UI-jem, ugrađenim hyperparameter sweep-om i naprednom kolaboracijom, ali od Pro plana košta oko 60 USD mjesečno po korisniku. Za regulirane industrije i on-prem MLflow pobjeđuje; za brzu team velocity u istraživanju W&B pobjeđuje.

Kako deployati model u produkciju s MLflowom?

Najbrži put je mlflow models serve -m "models:/ime@champion" koji podigne lokalni HTTP endpoint. Za produkciju koristite mlflow models build-docker s flagom --enable-mlserver koji buildaju sliku sa Seldon MLServer runtimeom (V2 inference protokol), pa je pushajte u container registry i deployajte u Kubernetes iza svog uobičajenog ingressa.

Arjun Krishnamurthy
O Autoru Arjun Krishnamurthy

ML engineer focused on getting models out of notebooks and into production. Has war stories about every serving framework.