Skip to content

Instantly share code, notes, and snippets.

@sile

sile/0_memo.md Secret

Last active July 27, 2020 07:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sile/d9158d618a8d8e3544a251a8fd4607c4 to your computer and use it in GitHub Desktop.
Save sile/d9158d618a8d8e3544a251a8fd4607c4 to your computer and use it in GitHub Desktop.
optjournal共有メモ

optjournal共有メモ

https://github.com/sile/optjournal

Optunaのアクセスパターンの特徴

  • 基本的に対象study内の全trial情報を要する (sampler/pruner/visualization/pandas)
  • 削除や上書きがほぼない
  • => optjournalの仕組みと相性が良い

基本的な仕組み

操作ログ

  • ワーカ毎のステートマシンとグローバルな操作履歴

DBモデル

Databaseのインタフェース

RDBDatabase

  • リトライ
  • 追記時にロック

FileSystemDatabase

  • 追記時にファイルロック
    • NFS

ベンチマーク

  • 内容: bench.shbench.py を参照
  • 結果 (oputna=v2.0.0-rc1):
    • InMemoryStorage: 17.26s
    • RDBStorage: 41.44s
    • optjournal.RDBDatabase: 41.31s
    • optjournal.FileSystemDatabase: 20.55s

既知の問題

初回ロードが若干遅い(かも)

属性の上書き時に無駄が発生

対処:

  • GC
  • スナップショット

StudySummary

最適化

DONE: 複数オペレーションログの集約

  • 典型的にはset_trial_param
  • ベンチマークでは所要時間が1/2程度になった

エンコーディング方法見直し

  • JSON: Dict => List
  • Other encoding (e.g., protobuf)

スナップショット

  • StudySummary
  • Trials

複雑さに見合うメリットがあるかどうかは不明

sync

  • 常にsync
    • Storage.set_user_attr
    • Storage.user_attrs
    • Storage.set_trial_state
    • Study.*
  • each trial:
    • 開始前にread_sync
    • 終了前にwrite_sync
  • Pruner.prune:
    • 呼び出し前にread_sync
    • 呼び出し後にwrite_sync

ストレージレイヤではflushpollを提供し、同期タイミングは完全に呼び出しもとに任せた方がシンプルになるかもしれない? (ストレージの使用側の負担は増える)

import argparse
import math
import optuna
import optjournal
optuna.logging.set_verbosity(optuna.logging.WARNING)
def objective(trial):
return sum(
math.sin(trial.suggest_uniform("param-{}".format(i), 0, math.pi * 2)) for i in range(30)
)
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("study_name")
parser.add_argument("n_trial", type=int)
args = parser.parse_args()
# storage = optuna.storages.InMemoryStorage()
# storage = optuna.storages.RDBStorage("mysql+pymysql://root:password@localhost:3306/db")
# storage = optjournal.JournalStorage("mysql+pymysql://root:password@localhost:3306/db")
storage = optjournal.JournalStorage(optjournal.FileSystemDatabase("/tmp/ojfs/"))
study = optuna.create_study(study_name=args.study_name, storage=storage, load_if_exists=True)
study.optimize(objective, n_trials=args.n_trial, gc_after_trial=False)
print("# {}".format(len(study.trials)))
#!/bin/bash
#
# docker run --rm -e MYSQL_ROOT_PASSWORD=password -e MYSQL_DATABASE=db -p 3306:3306 mysql
NAME=`optuna create-study --storage sqlite:///:memory:`
echo $NAME
python3 bench.py $NAME 100 &
python3 bench.py $NAME 100 &
python3 bench.py $NAME 100 &
python3 bench.py $NAME 100 &
python3 bench.py $NAME 100 &
python3 bench.py $NAME 100 &
wait
@sile
Copy link
Author

sile commented Jul 27, 2020

メモ:

  • JSONだとfloatの精度が落ちる
  • SutdySummaryのスナップショットは良さそう

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment