1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【機械学習】Hydra × MLflow 最強の実験管理術

1
Last updated at Posted at 2026-02-17

この記事の要点(30秒版)

  • 実験管理の問題は1つではなく、再現性(同じ条件で動かせるか)と比較(どの条件が良かったか)の2つ
  • Hydra は「設定を整理して残す」、MLflow は「結果を並べて比べる」のが得意。役割を分けて組み合わせる
  • つなぐコツは3つ。Hydraの実行フォルダを実験の単位にする、確定後の設定をMLflowのartifactに保存する、paramsはフラット化する
  • 注意点: Hydra 1.2 以降は作業ディレクトリが出力フォルダに変わらない。出力フォルダは HydraConfig から取る

実験管理は、やり始めるとすぐ気づくのですが、問題は1つではありません。

  • 再現性: その実験、あとから同じ条件で動かせる?
  • 比較: どの条件が良くて、どこが効いたのか一目で分かる?

この2つは似ているようで、解決策が少し違います。

  • Hydra は「設定を整理して残す(再現性)」が得意
  • MLflow は「結果を並べて比べる(比較・可視化)」が得意

なので、役割を分けて組み合わせると、実験管理が一段安定します。それぞれの単体記事はこちらです。

この記事では、実験ごとの出力フォルダ(Hydra)と実験結果の比較UI(MLflow)を、同じ「実験単位」で揃えて管理する方法を、最小構成から紹介します。

想定読者: HydraとMLflowをそれぞれ触ったことがあり、2つをつなぎたい人

1. この記事でやること

最終的に、1回の実行で次の状態を作ります。

役割 何が残るか
Hydra が outputs/.../ を作る .hydra/config.yaml が残る(再現性)
同じ実行で MLflow にもRunが作られる パラメータ・スコアがUIで比較できる(比較)
Hydraの設定ファイル自体を MLflow にも保存する 「UIから見て、設定ファイルまで辿る」ができる

2. 組み合わせの基本方針

HydraとMLflowをきれいに繋ぐコツは、次の3点です。

  1. Hydraの実行単位(run dir)を「実験の粒度」にする
  2. MLflowのRunに、Hydraの設定(確定後のconfig)を保存する
  3. MLflowに入れるparamsは「フラット化」して管理する(ネスト対策)

この方針で作ると、あとから実験を見返すときに迷いません。

3. ディレクトリ構成(例)

Hydra側は普通に conf/ を切っておけばOKです。

.
├── conf/
│   ├── config.yaml
│   └── model/
│       └── lightgbm.yaml
├── train.py
└── README.md

4. 実装:Hydra × MLflow の最小構成

以下が、最小で回るコードです。ポイントは次の4つです。

  • mlflow.set_experiment(cfg.exp_name) で実験名を揃える
  • cfg はネストが深いので、params用にフラット化する
  • .hydra/config.yaml を artifactとして保存する(重要)
  • 出力フォルダは HydraConfig.get().runtime.output_dir で取る
from pathlib import Path

import hydra
import mlflow
from hydra.core.hydra_config import HydraConfig
from omegaconf import DictConfig, OmegaConf


def flatten_dict(d, prefix=""):
    """ネストしたdictを MLflow向けにフラット化する(a.b.c=...)"""
    items = {}
    for k, v in d.items():
        key = f"{prefix}{k}" if prefix == "" else f"{prefix}.{k}"
        if isinstance(v, dict):
            items.update(flatten_dict(v, key))
        else:
            items[key] = v
    return items


@hydra.main(config_path="conf", config_name="config", version_base=None)
def main(cfg: DictConfig):
    # Hydraの出力フォルダ(outputs/....)を取得
    run_dir = Path(HydraConfig.get().runtime.output_dir)

    # MLflowの実験名(Experiment)
    mlflow.set_experiment(cfg.exp_name)

    # 1実行 = 1Run
    with mlflow.start_run(run_name=run_dir.name):
        # 1) パラメータ記録(フラット化)
        cfg_dict = OmegaConf.to_container(cfg, resolve=True)
        flat_params = flatten_dict(cfg_dict)
        mlflow.log_params(flat_params)

        # 2) 設定ファイル自体も保存(artifact)
        #    Hydraが生成する確定config と、コマンドラインの上書き内容
        for name in ("config.yaml", "overrides.yaml"):
            path = run_dir / ".hydra" / name
            if path.exists():
                mlflow.log_artifact(str(path), artifact_path="hydra")

        # --- ここに学習処理を書く ---
        # 例:ダミー
        auc = 0.82

        # 3) 指標を記録(metric)
        mlflow.log_metric("auc", auc)

        # 4) Hydra run dir のパスも残す(相互参照しやすい)
        mlflow.set_tag("hydra.run_dir", str(run_dir))

    print(f"[done] run_dir={run_dir}")


if __name__ == "__main__":
    main()

os.getcwd() で出力フォルダは取れません。 Hydra 1.2 以降(version_base=None を含む)は、実行中も作業ディレクトリが出力フォルダに切り替わりません。os.getcwd() で取ったパスは実行した場所のままなので、.hydra/config.yaml が見つからず、exists() のチェックでエラーも出ないまま artifact が保存されないことになります。

5. 使い方

python train.py model.params.learning_rate=0.05

動作確認は Hydra 1.3.8 / MLflow 3.17.2 で行いました。実行すると、次のようになります。

Hydra側

  • outputs/yyyy-mm-dd/hh-mm-ss/ ができる
  • .hydra/config.yaml と .hydra/overrides.yaml が残る

MLflow側

mlflow ui

実行したフォルダで起動し、http://localhost:5000 を開くと次のように見えます。

  • Experiment = cfg.exp_name
  • Run = 実行ごとの記録
  • params / metrics が比較できる(上の例では model.params.learning_rate が 0.05 になる)

さらに artifact に hydra/config.yaml と hydra/overrides.yaml が付いてくるので、UI上から設定まで辿れます。

6. よくある詰まりどころと対処

6-1. mlflow.log_params(cfg_dict) がそのまま通らない

MLflowのparamsは、基本「key: value(文字列・数値)」を想定しています。Hydraのcfgはネストが深いので、フラット化が安定です(上の flatten_dict)。

例
OK model.params.learning_rate = 0.05
NG model.params = { ... } のように辞書丸ごと

6-2. mlflow.set_experiment に毎回別名を入れて散らかる

Experiment名は、最初は雑でもいいですが、散らかると見返しづらくなります。おすすめは次の分離です。

  • cfg.exp_name は「大枠の目的」(例: lgbm_baseline)
  • run_name に日付時刻やHydraの出力フォルダ名を使う(例: 22-00-00)

6-3. Hydraの出力フォルダが分からない

os.getcwd() ではなく、次のように取得します。

from hydra.core.hydra_config import HydraConfig

run_dir = Path(HydraConfig.get().runtime.output_dir)

6-4. MLflow UIに記録が出てこない

記録を実行したフォルダ以外で mlflow ui を起動していないか確認します。MLflow 3.17.2 では、実行したフォルダに mlflow.db と mlruns/ が作られました。

7. もう一段便利にする小ネタ

1. 重要なメトリクスは「比較しやすい名前」で揃える

MLflowの比較は「列名」が命です。たとえば次のように、列名を固定すると後で比較が楽です。

  • auc
  • logloss
  • cv_mean_auc

2. 学習済みモデルや特徴量重要度も artifact に入れる

LightGBMなら model.txt / model.pkl や feature_importance.csv を保存すると、実験の価値が上がります。

mlflow.log_artifact("feature_importance.csv", artifact_path="artifacts")

8. おわりに

HydraとMLflowは、別々に使うだけでも便利ですが、組み合わせると「実験の振り返り」がかなり楽になります。

  • Hydra: 実験条件が確実に残る(再現性)
  • MLflow: 結果を横並びで比べられる(比較)

設定ファイルを artifact に載せておけば、「UIで見て → 設定を確認して → 再現する」が自然に繋がります。まずはこの最小構成を動かして、必要になったタイミングで artifact(モデルや図)を増やしていくのが無理がないと思います。

見返し用チェック(自分用)

  • 出力フォルダは HydraConfig.get().runtime.output_dir で取る
  • paramsは flatten_dict でフラット化してから log_params
  • .hydra/config.yaml と overrides.yaml を artifact に保存する
  • mlflow ui は、記録したフォルダで起動する

参考

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?