Kamu latih model, dapat akurasi 0.87, dan menyimpan hasilnya di spreadsheet. Besok kamu ganti learning rate, akurasi naik ke 0.91, tapi kamu lupa learning rate kemarin pakai angka berapa. Dua minggu kemudian spreadsheet itu sudah berisi 40 baris dan kamu tak ingat lagi model mana yang dilatih dengan dataset versi mana.

MLflow menutup celah itu. Ia mencatat parameter, metrik, dan file model dari setiap eksperimen ke satu tempat yang bisa kamu cari dan bandingkan. Kita pakai scikit-learn dan dataset breast cancer bawaan, jadi tidak perlu mengunduh data apa pun. Kalau belum pernah menyentuh scikit-learn, baca dulu tutorial klasifikasi dasarnya supaya kode di bawah terasa familier.

Install MLflow dan siapkan proyek

Buat virtual environment supaya dependensi tidak berantakan, lalu install tiga paket: mlflow, scikit-learn, dan pandas.

bash
python -m venv venv
source venv/bin/activate
pip install mlflow scikit-learn pandas

Dataset breast cancer sudah ikut scikit-learn. Kamu tinggal memanggil load_breast_cancer() — 569 sampel, 30 fitur numerik, dan label biner (ganas atau jinak). Kalau kamu lebih nyaman bereksplorasi lewat DataFrame, pandas bisa dipakai untuk melihat ringkasan data, tapi untuk tutorial ini array NumPy sudah cukup.

Log parameter, metrik, dan model

Inti MLflow adalah konsep run. Satu run mewakili satu kali eksperimen: satu kombinasi parameter, satu model hasil latih. Semua yang kamu log di dalam blok mlflow.start_run() otomatis tersimpan ke folder mlruns/ di proyekmu.

import mlflow
import mlflow.sklearn
from sklearn.datasets import load_breast_cancer
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, f1_score

data = load_breast_cancer()
X_train, X_test, y_train, y_test = train_test_split(
    data.data, data.target, test_size=0.2, random_state=42
)

mlflow.set_experiment("klasifikasi-kanker")

with mlflow.start_run():
    n_estimators = 100
    max_depth = 5

    mlflow.log_params({
        "n_estimators": n_estimators,
        "max_depth": max_depth,
    })

    model = RandomForestClassifier(
        n_estimators=n_estimators,
        max_depth=max_depth,
        random_state=42,
    )
    model.fit(X_train, y_train)

    y_pred = model.predict(X_test)
    mlflow.log_metrics({
        "accuracy": accuracy_score(y_test, y_pred),
        "f1_score": f1_score(y_test, y_pred),
    })

    mlflow.sklearn.log_model(model, "model")

Jalankan skrip itu beberapa kali sambil mengubah n_estimators dan max_depth — misalnya 100/5, 200/10, dan 50/None. Tiap eksekusi menghasilkan satu run baru. Perhatikan tiga fungsi log: log_params untuk input, log_metrics untuk output, dan log_model untuk menyimpan artifact yang bisa dipakai ulang nanti.

Jangan cuma log akurasi. Catat juga f1_score atau precision dan recall. Akurasi 0.95 bisa menyesatkan kalau kelasmu timpang — misalnya 95% data ternyata kelas mayoritas, jadi model yang asal nebak pun kelihatan bagus.

Buka dashboard MLflow

MLflow punya UI lokal. Dari folder proyek yang sama, jalankan:

bash
mlflow ui

Buka http://127.0.0.1:5000 di browser. Kamu akan melihat daftar experiment; klik klasifikasi-kanker untuk melihat semua run beserta parameter dan metriknya. Ada fitur chart juga — plot akurasi terhadap n_estimators untuk melihat kapan penambahan pohon berhenti memberi keuntungan.

Bandingkan run tanpa membuka UI

UI bagus untuk eksplorasi manual, tapi kadang kamu butuh hasilnya di dalam kode — misalnya untuk otomatisasi pipeline. MlflowClient bisa mencari run terbaik berdasarkan metrik tertentu.

python
import mlflow

client = mlflow.MlflowClient()
experiment = client.get_experiment_by_name("klasifikasi-kanker")

runs = client.search_runs(
    experiment_ids=[experiment.experiment_id],
    order_by=["metrics.accuracy DESC"],
    max_results=3,
)

for r in runs:
    m = r.data.metrics
    print(f"{r.info.run_id[:8]}  acc={m['accuracy']:.4f}  f1={m['f1_score']:.4f}")

Kode itu mengambil tiga run dengan akurasi tertinggi. Dari sini kamu bisa memilih run terbaik, lalu mendaftarkannya ke model registry supaya versinya terkontrol.

Model registry dan deployment

Model registry memberi nama dan versi pada model yang kamu anggap layak. Beda dengan mlruns/ yang mencatat semua percobaan, registry hanya berisi model yang kamu pilih secara sadar.

python
import mlflow

client = mlflow.MlflowClient()
experiment = client.get_experiment_by_name("klasifikasi-kanker")

best = client.search_runs(
    experiment_ids=[experiment.experiment_id],
    order_by=["metrics.accuracy DESC"],
    max_results=1,
)[0]

result = mlflow.register_model(
    f"runs:/{best.info.run_id}/model",
    "klasifikasi-kanker",
)
print(f"Registered version {result.version}")

Sekarang model punya versi tetap yang bisa dipanggil ulang kapan saja, bahkan dari proyek lain. Muat dan prediksi seperti ini:

python
import mlflow.sklearn
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split

data = load_breast_cancer()
_, X_test, _, y_test = train_test_split(
    data.data, data.target, test_size=0.2, random_state=42
)

model = mlflow.sklearn.load_model("models:/klasifikasi-kanker/1")
prediksi = model.predict(X_test[:5])
print(prediksi)

Kalau kamu mau menyajikannya sebagai endpoint HTTP, MLflow bisa langsung menjalankan server REST dari model di registry:

bash
mlflow models serve -m "models:/klasifikasi-kanker/1" -p 5000

# di terminal lain, cek server sudah hidup
curl http://127.0.0.1:5000/ping

mlflow ui dan mlflow models serve sama-sama memakai port 5000 secara default. Jangan jalankan keduanya bersamaan, atau beri port berbeda lewat flag --port.

Langkah berikutnya: arahkan MLflow ke tracking server terpusat supaya seluruh tim menulis ke satu database, bukan ke folder mlruns/ masing-masing. Caranya cukup jalankan mlflow server --backend-store-uri sqlite:///mlflow.db lalu set variabel environment MLFLOW_TRACKING_URI ke alamatnya. Kalau kamu masih menyusun arah belajar di bidang ini, roadmap AI engineer bisa membantu mengurutkan materinya.