Skip to content

MLflow 3から記録する ​

[プロジェクト設定]の「SDK・MLflow 3から接続」

公式のmlflow Python SDK(MLflow 3)から、mado ML TrackingのProjectへ記録できます。接続先とtokenを環境変数で指定するだけで、既存のMLflowのコードを変えずに使えます。記録したRun・metrics・Artifact・登録モデルは、画面から記録したものと同じデータとして扱います。

MLflowの全機能を提供するサーバーではありません。対応している機能は対応範囲の表で確認してください。

こんなときに向いています ​

  • 今あるMLflowの学習コードを、そのまま社内のサーバーへ記録したい
  • mlflow.sklearn.autolog()などの自動記録を使いたい
  • mlflow.register_model()で登録したモデルを、そのまま自動推論・自動評価につなげたい

接続する ​

  1. [プロジェクト設定]を開き、「SDK・MLflow 3から接続」の[MLflow 3]を確認します(実験の画面の[SDKで記録]からも開けます。そこではset_experimentの例に開いている実験の名前が入ります)。MLFLOW_TRACKING_URIとMLFLOW_REGISTRY_URIには同じURL(https://<サーバー>/api/mlflow/projects/<ProjectのID>)が表示されます
  2. [このProject用のAPI tokenを発行]を選びます。scopeにread・runs:write・registry:write・artifacts:writeが選ばれた状態で発行画面が開くので、名前と期限を入力して発行します。tokenはこのときだけ表示されるので控えておきます(ボタンはeditor以上にだけ表示されます)
  3. 学習を実行するマシンのターミナルで、MLflowをインストールして環境変数を設定します
bash
python3 -m pip install 'mlflow>=3,<4'
export MLFLOW_TRACKING_URI='https://tracking.example.internal/api/mlflow/projects/PROJECT_ID'
export MLFLOW_REGISTRY_URI="$MLFLOW_TRACKING_URI"
printf 'API token: '; read -r -s MLFLOW_TRACKING_TOKEN; echo
export MLFLOW_TRACKING_TOKEN

画面の[環境変数(tokenは実行時に入力)]の右の[コピー]で、このProjectのURLが入った設定例をコピーできます。tokenはソースコードやGitで管理するファイルに書かず、コンテナには環境変数として渡してください。

用途必要なscope
Experiment・Run・モデル・Artifactの読み出しread
Experiment・Run・params・metrics・tagsの記録runs:write
入力Datasetの新規登録runs:writeとregistry:write
Artifactのアップロードartifacts:write
Logged Model・モデルバージョン・aliasの登録や変更registry:write

記録するユーザーには、そのProjectのeditor以上の役割が必要です。Workerや自動処理のように長く動かすものには、人ではなくService Accountのtokenを使ってください。SSOでログインするユーザーのtokenは、グループの確認から7日を過ぎると止まります(API token)。

接続を確かめる ​

次のコードを実行し、画面の[Experiments]にconnection-checkのExperimentとRunが出れば接続できています。

python
import mlflow

mlflow.set_experiment("connection-check")
with mlflow.start_run(run_name="hello"):
    mlflow.log_param("learning_rate", 0.01)
    mlflow.log_metric("loss", 0.5, step=1)

うまくいかないときは、エラー文に直す所が書いてあります。

エラー直す所
ENDPOINT_NOT_FOUND: MLFLOW_TRACKING_URIにProjectのIDが入っていませんMLFLOW_TRACKING_URIをサイトや/api/mlflowで止めず、/api/mlflow/projects/<ProjectのID>まで入れる
UNAUTHENTICATED: API tokenが送られていませんMLFLOW_TRACKING_TOKEN(Basic認証ならMLFLOW_TRACKING_PASSWORD)にtokenを入れる
UNAUTHENTICATED(tokenが無効または失効)tokenの値か期限を確かめ、必要なら発行し直す
PERMISSION_DENIED: API tokenのscopeが不足しています足りないscopeが書いてある。用途「SDK・MLflow 3から記録する」でtokenを発行し直す
PERMISSION_DENIED: API tokenのprojectが一致しませんtokenがどのProject用かが書いてある。URIのProject IDか、使うtokenを合わせる

Basic認証で接続する ​

ユーザー名とパスワードしか設定できない社内ツールでは、Basic認証も使えます。パスワードにAPI tokenを入れます。ユーザー名は照合しないので、任意の値で構いません。

bash
export MLFLOW_TRACKING_URI='https://tracking.example.internal/api/mlflow/projects/PROJECT_ID'
export MLFLOW_TRACKING_USERNAME=mado
printf 'API token: '; read -r -s MLFLOW_TRACKING_PASSWORD; echo
export MLFLOW_TRACKING_PASSWORD
  • Basic認証を使えるのは、MLflow互換の接続先(/api/mlflow/...)だけです
  • ローカルアカウントのパスワードを入れても接続できません
  • 失効・期限・scope・Projectの役割の確認は、MLFLOW_TRACKING_TOKENのときと同じです

設定例は、画面の[Service Accountのtoken・Basic認証]を開くと表示されます。

RunとArtifactを記録する ​

python
from pathlib import Path
import mlflow

mlflow.set_experiment("qwen3-finetuning")
with mlflow.start_run(run_name="learning-rate-2e-5"):
    mlflow.log_params({"learning_rate": 2e-5, "epochs": 3})
    mlflow.set_tags({"model_family": "qwen3", "dataset": "training-v1"})
    mlflow.log_metric("train.loss", 0.42, step=100)
    mlflow.log_metric("train.loss", 0.31, step=200)
    Path("predictions.json").write_text('{"text": "sample"}')
    mlflow.log_artifact("predictions.json", artifact_path="evaluation")
  • 同じparamに違う値を記録するとエラーになります。条件を変えた実験は新しいRunにしてください
  • metricsの最新の値は、届いた順ではなくstepと時刻で決まります。NaNも保存できます
  • Runの終わりにSDKが表示するView run・View experimentのリンクを開くと、このアプリのRunの画面・[Experiments]の画面が開きます
  • Artifactは管理者が選んだ保存先(ファイルシステムかS3互換ストレージ)に保存します。SDKにストレージの認証情報を渡す必要はありません
  • mlflow.start_run(run_id="RUN_ID")で、終わったRunを開き直して続きを記録できます。WorkerのJobで動いたRunは開き直せません

大きいファイルは、MLflowのmultipart uploadで分割して送れます。MLflow 3.17以降のSDKは自動で使います。3.0〜3.16ではMLFLOW_ENABLE_PROXY_MULTIPART_UPLOAD=trueを設定してください。既定ではSDKは500MiB以上のファイルを10MiBずつに分けて送ります。partの大きさ(MLFLOW_MULTIPART_UPLOAD_CHUNK_SIZE)は5MiB以上にし、part数は10,000までなので、200GiBのファイルなら21MiB以上にします。詳しくは大きなファイルのアップロードを参照してください。

autologを使う ​

scikit-learnでは、次のようにparams・metrics・入力Dataset・モデルを自動で記録できます。

python
import mlflow
import mlflow.sklearn

mlflow.set_experiment("automatic-training")
mlflow.sklearn.autolog(log_models=True, log_datasets=True)
model.fit(features, targets)

確認済みのautologはscikit-learnだけです。ほかのライブラリのautologは使うAPIやモデル形式が違うため、動作を確かめていません。

モデルを登録する ​

python
import mlflow
import mlflow.sklearn
import numpy as np
from sklearn.linear_model import LinearRegression

features = np.array([[0.0], [1.0], [2.0]])
targets = np.array([1.0, 3.0, 5.0])
with mlflow.start_run():
    mlflow.log_input(mlflow.data.from_numpy(features, targets=targets, name="training-v1"), context="training")
    model = LinearRegression().fit(features, targets)
    recorded = mlflow.sklearn.log_model(model, name="regression")

version = mlflow.register_model(recorded.model_uri, "regression")
mlflow.MlflowClient().set_registered_model_alias("regression", "candidate", version.version)
loaded = mlflow.pyfunc.load_model("models:/regression@candidate")
  • バージョンの番号は1、2、3…と自動で付きます。画面から登録したバージョンと同じ系列で数え、削除したバージョンの番号は再利用しません
  • 登録したバージョンは、モデル一式のファイルをバージョンごとに固定します。元のRunのファイルを上書きしても、バージョンの内容は変わりません
  • 読み込みにはmodels:/名前/バージョンかmodels:/名前@aliasを使います
  • 入力Dataset、生成元のRun、登録したバージョンの関係は[Lineage]に表示します

save_model()で保存したディレクトリをlog_artifacts()でRunに上げた場合も、そのまま登録できます。

python
mlflow.sklearn.save_model(model, "saved")
with mlflow.start_run() as run:
    mlflow.log_artifacts("saved", "model")
version = mlflow.register_model(f"runs:/{run.info.run_id}/model", "regression")
  • 登録のときにディレクトリのMLmodelを読み、そこに書かれたファイルをモデル本体(Modelsの画面の重み)にします。生成元のRunもバージョンに結び付きます
  • 戻り値のsourceは、登録時に固定したファイル一式の場所(mlflow-artifacts:/model-versions/…)です。MLflowのサーバーと違い、指定したruns:/…ではありません

登録をきっかけに推論・評価を自動で動かすには、登録モデルのtag mmt.model_familyに系列名を指定し、その系列の自動実行ルールをProjectに用意します。

python
mlflow.MlflowClient().create_registered_model("qwen3", tags={"mmt.model_family": "qwen3"})

ルールの作り方はモデルと自動実行を参照してください。

表・画像・音声を記録する ​

  • log_table・log_image・log_dict・log_text・log_figureで記録したものは、Artifactとして一覧・ダウンロードできます
  • log_image(image, key=..., step=...)の画像とlog_tableの表は、Runの[Media]タブにも出ます(メディアの記録と聴き比べ)。MLflow 3.0.0では、keyに/を含めないでください(SDKがファイル名を切ってしまいます)。3.17.0以降は問題ありません
  • 音声はmlflow.log_artifactで保存します。wav・flacは画面でそのまま再生できます

対応範囲 ​

MLflow 3.0.0(scikit-learn 1.6.1)と3.17.0(scikit-learn 1.9.1)で動作を確かめた範囲です。この表に無い機能は確かめていません。

機能状態
Run・nested Run・params・metrics・tags、検索、削除と復元対応
Artifactのアップロード・ダウンロード、multipart upload対応
Logged Model、Model Registry、alias対応
scikit-learnのautolog対応
mlflow.models.evaluate(結果はRunとLogged Modelに記録)対応
log_table・log_image・log_dict・log_text・log_figure対応
wav・flacの音声Artifact対応
自作のpyfuncモデル、複数ファイルのモデル対応
save_model()で保存しlog_artifacts()で上げたモデルのregister_model("runs:/…")対応
最初のRunの前のmlflow.search_runs()・get_experiment("0")対応(0件、空のDefault Experimentを返します)
mlflow.search_runsのpandas出力対応
登録モデル・バージョンの検索(search_registered_models、search_model_versions)対応(1回に返すのは最大1000件。下の説明を参照)
SDKが表示するView run・View experimentのリンク対応(このアプリの画面が開きます)
webhooks未対応(ENDPOINT_NOT_FOUNDのエラー)
Tracing(search_traces、@mlflow.trace)未対応。@mlflow.traceを付けた関数は動き、Runも正常に終わります
GenAI評価、AI Gateway、Prompt Registry未対応

検索の条件はANDでつなぎます。ORと括弧は使えません。IN/NOT INはrun_idなどの一部の属性で使えます。

  • tagの条件は、MLflowと同じくtags.名前とtag.名前のどちらでも書けます
  • バージョンの番号はversion_numberで指定します(例: version_number > 2、order_by=["version_number DESC"])
  • 登録モデル・バージョン・Logged Modelの検索は、1回に最大1000件を返し、残りがあれば続きのページの印(next_page_token)を付けます。mlflow.search_model_versions()などのmlflow.で始まる関数は、続きを自動でたどって全件を返します
  • MlflowClient().search_model_versions()は1ページ分(1000件まで)だけを返します。MLflowのサーバーは10000件まで1回で返すので、ここだけ違います。1000件を超えるときは、戻り値のtokenをpage_tokenに渡して続きを取ってください

Workerの中で使う ​

Workerで動くJobには、MLflowの接続先・token・Experiment・Runが環境変数で渡されます。コードのmlflow.start_run()は新しいRunを作らず、Jobに割り当てられたRunに記録します。tokenはそのRunだけを書けるJob限定のものです。Jobの環境にMLflow 3を入れておいてください(Worker)。