基本的な使い方
ZenithTuneによるハイパーパラメータ自動チューニングは以下の4ステップから構成されます。
1. チューナーを選択する
チューニング対象を検討し、ZenithTuneが提供する4つのチューナーから1つを選択します。
- 関数の実行時間を最適化したい
- → FunctionRuntimeTuner
- コマンドの実行時間を最適化したい
- → CommandRuntimeTuner
- コマンド実行の標準出力内における特定の値を最適化したい
- → CommandOutputTuner
- 自分で定義した目的関数を最適化したい
- → GeneralTuner
それぞれのTunerは次のようにimportして使用します。
from zenith_tune import FunctionRuntimeTuner
tuner = FunctionRuntimeTuner()
2. 目的関数とチューニングパラメータを定義する
目的関数とチューニングパラメータをそのローカル変数として定義し、Tunerのoptimize関数に試行回数と共に与えます。 チューニングパラメータの定義には、目的関数の第1引数を介して与えられるOptuna Trial APIを使用します。 サポートされている型や範囲の定義方法はOptunaのAPI Referenceを参照してください。
def objective(trial, **kwargs):
x = trial.suggest_int("x", low=-10, high=10)
y = trial.suggest_int("y", low=-10, high=10)
# x,yに依存する処理
return {cost_value}
tuner = GeneralTuner()
tuner.optimize(objective, n_trials=10)
FunctionRuntimeTuner, CommandRuntimeTunerは実行時間を自動的に計測して最適化するため、明示的にコスト値を返す必要はありません。 一方、GeneralTunerはパラメータの定義からコスト値の決定まで、すべてユーザが記述します。 CommandOutputTunerは他のTunerと異なり、目的関数を(1)コマンド生成関数と(2)標準出力パース関数の組として定義します。 CommandOutputTunerが(1)と(2)から新たな目的関数を再構成することでチューニングが実行されます。 詳細は続く各Tunerの説明を参照してください。 また、目的関数のキーワード引数についてはチューニングTips: 目的関数から受け取れるメタデータを確認してください。
FunctionRuntimeTuner
FunctionRuntimeTunerは関数の実行時間を最適化します。 ユーザはハイパーパラメータに依存した関数を定義し、optimize関数の第1引数に渡します。
def func(trial, **kwargs):
# ハイパーパラメータの定義
t = trial.suggest_int("t", low=1, high=10)
# ハイパーパラメータに依存する処理
time.sleep(t)
tuner = FunctionRuntimeTuner()
tuner.optimize(func, n_trials=10)
CommandRuntimeTuner
CommandRuntimeTunerはコマンドの実行時間を最適化します。 ユーザはコマンド文字列を生成する関数を定義してoptimize関数の第1引数に渡します。 コマンドが異常終了した場合、その試行は評価から除外されます。
def command_generator(trial, **kwargs):
# ハイパーパラメータの定義
num_workers = trial.suggest_int("num_workers", low=1, high=10)
# ハイパーパラメータに依存するコマンド
command = f"python train.py --num-workers {num_workers}"
return command
tuner = CommandRuntimeTuner()
tuner.optimize(command_generator, n_trials=10)
CommandOutputTuner
CommandOutputTunerは与えられたコマンドを実行し、標準出力内の特定の値を最適化します。 ユーザはコマンド文字列を生成する関数と、標準出力から特定の値を抽出する関数の2つを定義してoptimize関数の第1、第2引数に渡します。 値を抽出する関数の第1引数にはコマンド実行結果の標準出力結果ファイルのパスが与えられるため、正規表現を用いた文字列操作やファイル処理を施してコスト値を抽出してください。
なお、コマンドが異常終了した場合や値の抽出に失敗した場合、その試行は評価から除外されます。
def command_generator(trial, **kwargs):
# ハイパーパラメータの定義
num_workers = trial.suggest_int("num_workers", low=1, high=10)
# ハイパーパラメータに依存するコマンド
command = f"python train.py --num-workers {num_workers}"
return command
def value_extractor(log_path):
# log_pathを開きコスト値を抽出する
with open(log_path, "r") as f:
for line in f:
if "epoch_time=" in line:
result = re.findall(
r"epoch_time=(\d+\.\d+)", line
)[0]
epoch_time = float(result[0])
return epoch_time
tuner = CommandOutputTuner()
tuner.optimize(command_generator, value_extractor, n_trials=10)
GeneralTuner
GeneralTunerはユーザ定義の目的関数を最適化します。
def objective(trial, **kwargs):
# ハイパーパラメータの定義
x = trial.suggest_int("x", low=-10, high=10)
# ハイパーパラメータに依存する処理
y = func(x)
# コスト値の決定
cost_value = y**2
return cost_value
tuner = GeneralTuner()
tuner.optimize(objective, n_trials=10)
3. チューニングを実行する
ZenithTuneを用いたチューニングスクリプト(optimize.pyとする)を実行すると、試行ごとのコスト値とパラメータが出力されます。 ユーザは最良値を得ることで、元のチューニング対象にフィードバックすることができます。
$ python optimize.py
2025-07-18 08:08:53,545 - zenith-tune - INFO - Using distributed launcher: None
[I 2025-07-18 08:08:54,103] A new study created in RDB with name: study_20250718_080853
[I 2025-07-18 08:08:54,185] Trial 0 finished with value: 41.0 and parameters: {'x': 4, 'y': -5}. Best is trial 0 with value: 41.0.
[I 2025-07-18 08:08:54,222] Trial 1 finished with value: 85.0 and parameters: {'x': -6, 'y': -7}. Best is trial 0 with value: 41.0.
[I 2025-07-18 08:08:54,258] Trial 2 finished with value: 5.0 and parameters: {'x': 2, 'y': -1}. Best is trial 2 with value: 5.0.
[I 2025-07-18 08:08:54,293] Trial 3 finished with value: 64.0 and parameters: {'x': 8, 'y': 0}. Best is trial 2 with value: 5.0.
[I 2025-07-18 08:08:54,328] Trial 4 finished with value: 5.0 and parameters: {'x': -1, 'y': -2}. Best is trial 2 with value: 5.0.
4. チューニング結果を分析する
チューニングが適切に収束したか、各ハイパーパラメータがコスト値に対してどの程度重要であるか、などチューニング結果の分析が大切です。 ZenithTuneでは、optimize関数実行後にanalyze関数を呼び出すことで、Optunaによる様々な分析手法を集約して出力します。
tuner = GeneralTuner()
tuner.optimize(objective, n_trials=10)
tuner.analyze()
analyze関数による標準出力からは、初期値・初期パラメータ、最適値・最適パラメータ、そして初期値からの改善率を確認することができます。
2025-07-18 08:18:30,076 - zenith-tune - INFO - First trial: value=117.0, params={'x': 9, 'y': 6}
2025-07-18 08:18:30,079 - zenith-tune - INFO - Best trial: trial_id=5, value=10.0, params={'x': -1, 'y': -3}
2025-07-18 08:18:30,079 - zenith-tune - INFO - Improvement rate from first: 11.7
また、チューニング結果が格納されている作業用ディレクトリ(デフォルトでは./outputs/以下)に以下の分析結果を出力します。
timeline.png
: 実時間上での各試行に費やした時間history.png
: 試行過程におけるコスト値の推移importances.png
: 各チューニングパラメータの重要度
各試行が適切に実行されているか、明らかにチューニングすべきでないパラメータが含まれていないかを確認し、必要に応じてチューニングスクリプトを修正します。 十分にチューニングが進行し、Best Value(最良値)が収束していればチューニングは完了です。