Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Rustuna: Rustによる高速なOptuna実装

Rustuna: Rustによる高速なOptuna実装

2026/10/16 Optuna Meetup #3 発表資料。2026年9月に新たに公開した「Rustuna」の開発背景や設計に関する詳細についてご紹介します。

イベントサイト: https://optuna.connpass.com/event/406648/

Avatar for Preferred Networks

Preferred Networks PRO

October 16, 2026

More Decks by Preferred Networks

Other Decks in Technology

Transcript

  1. 開発背景 Optunaのユースケースが広がるにつれ、いくつかのユースケースで課題が生まれる 評価回数の多い最適化への活用 Pythonエコシステムの Rust化 • ハイパーパラメータ最適化に加え、材料探索な どの領域でも活用が拡大 • Ruff・Polars・Pydantic

    V2 などがRustで大幅 な高速化を実現 • 結晶構造探索などの事例では数十万回規模の 大規模な探索が行われるように • Optunaでも同様のアプローチが有効ではない か? • 一方、OptunaのTPEで推奨される規模は1,000 Trials程度(公式ドキュメントを参照) • 第三者がコーディングエージェントを使って先 に公開する可能性も十分にある • → Rust実装の Rustuna を開発 4
  2. Rustunaとは? Rustで実装された Optuna互換 のハイパーパラメータ最適化ライブラリ 高速 省メモリ 依存最小 TPEで約14倍、 CMA-ES・NSGA-IIでは700倍 以上高速

    (Optuna比) 試行履歴の破棄機能で、長時 間の最適化でもメモリ消費を抑 制 NumPyを含め必須のランタイム 依存なし。高速なimportやサプ ライチェーン攻撃のリスク緩和 $ pip install rustuna GitHub: github.com/optuna/rustuna Docs: rustuna.readthedocs.io ※ 現時点ではPythonライブラリのみを公開 5
  3. Rustunaの基本的な使い方 1 目的関数を定義 2 サジェストAPI経由でハイパー パラメータをサンプル 3 最適化の状態を管理する Studyオブジェクトを作成 4

    試行回数を指定して最適化開始 5 結果の表示 import rustuna def objective(trial: rustuna.Trial) -> float: x1 = trial.suggest_float("x1", -10, 10) x2 = trial.suggest_float("x2", -10, 10) return (x1 - 2)**2 + (x2 + 5)**2 study = rustuna.create_study( study_name="optimize-quadratic-function" ) study.optimize(objective, n_trials=100) print(f"Best value: {study.best_value}") print(f"Best params: {study.best_params}") ※ 基本的な使い方はOptunaと同じ。こちらの例では1行目を import optuna as rustuna に置き換えても動作 6
  4. Rustunaが重視している点 1 2 例: Optunaの可視化機能で分析 Optunaとの高い互換性 create_study・suggest_*・optimize など同じAPI。新 たに覚え直す必要なし 高速な動作

    rustuna_study = rustuna.load_study(...) optuna_study = ToOptunaStudy(rustuna_study) fig = plot_optimization_history(optuna_study) 速度に大幅な改善がなければ Rustunaは存在 意義を失います。 互換性を重視しすぎると高速化に限界が生じる ため、一部機能の導入は慎重に判断。 3 from optuna.visualization import ( plot_optimization_history ) from rustuna.converter import ToOptunaStudy 例: Optuna Dashboardの利用 from rustuna.storages import SQLite3Storage from optuna_dashboard import run_server Optunaやエコシステムとの協調 完全な置き換えではなく併用が前提。 storage = SQLite3Storage(...) run_server(storage, host="localhost”, port=8080) 足りない機能はOptunaを呼び出して補う。 7
  5. Rustunaが向いているケース Rustunaが向いているケース Optunaを使うべきケース • 目的関数の評価が軽く、大量のTrialを実行し たい • モデルの学習時間が大半を占める (高速化の 恩恵が小さい)

    • 基本的な機能しか必要ないので依存関係を最 小限にしたい (バージョン衝突・サプライチェー ン攻撃のリスク緩和) • 本番運用での成熟度・安定性を重視する • GPSampler・AutoSampler などの高度なサン プラーが必要 • RustやTypeScriptなどPython以外の言語から 使いたい(今後提供を予定) 用途に応じて使い分け・併用 することを想定 8
  6. 高速化を達成した要因 最適化アルゴリズムによってボトルネックおよび高速化を達成した要因が異なる。 TPE / MOTPE 約14倍 CMA-ES / NSGA-II 700〜1000倍

    • 全試行履歴から分布を推定するため、計算量 はTrial数に応じて増える • 直近の世代だけを参照するため、本来の計算 量はTrial数によらず一定 • サンプリング処理をRustで実装し、Pythonオブ ジェクト処理などのオーバーヘッドを削減 • Optunaでは設計上の理由から、履歴が増える ほど処理時間が増加 • 1万Trialsを1分以内に実行可能に • Storage APIやTrialQueueの設計見直しで、 Trial数によらずほぼ一定に 11
  7. マルチスレッドでのスケール スレッド数 Optuna Rustuna 高速化 1 8.670 秒 0.649 秒

    13.4倍 2 7.280 秒 0.326 秒 22.3倍 4 7.449 秒 0.238 秒 31.3倍 単目的TPE / 1,000 Trials / 探索空間40次元 / M4 Pro MacBookで計測 12 4スレッドで 31倍 Optunaはスレッドを増やしても 速くならないが、Rustunaはス レッド数に応じて短縮
  8. 探索中に必要な試行履歴 これまでの課題 • • package main Optunaは全ての試行履歴をメモリ上に保持するため、評 価回数に比例してメモリ消費が増加 一方、CMA-ES・NSGA-II等のアルゴリズムが探索に使う のは履歴の一部だけ

    Goptuna BlackHoleStorageの紹介 • GoptunaはOptunaの非公式Go言語実装 • MySQLのBLACKHOLEストレージエンジンにインスパイ アされたストレージ実装を提供 • 最新N件のTrialだけを残すことにより高速化 14 func objective(trial goptuna.Trial) (float64, error) { x1, _ := trial.SuggestFloat("x1", -10, 10) x2, _ := trial.SuggestFloat("x2", -10, 10) return ... } func main() { relativeSampler := cmaes.NewSampler( cmaes.SamplerOptionNStartupTrials(5)) storage := goptuna.NewBlackholeStorage(20) study, _ := goptuna.CreateStudy(...) study.Optimize(objective, 100000); }
  9. Rustunaにおける試行履歴の破棄機能 Rustunaでの設計方針 • import rustuna StorageにTrialを破棄するAPIである discard_trials(trial_ids: list[int]) を 追加

    • 各サンプラーが discard_trials を呼び出すた め、対応しているストレージを利用する 使い方 • 各ストレージが提供する apply_discard=True により、不要になった試行履歴をメモリから破棄可 能 • ファイルには全履歴が残るため、分析時は apply_discard なしで読み込めば復元できる 15 def objective(trial): x = trial.suggest_float("x", -10, 10) trial.set_user_attr("large_text", "a" * 10000) return (x - 2) ** 2 storage = rustuna.storages.JournalFileStorage( "./rustuna-journal.db", apply_discard=True ) sampler = rustuna.samplers.CmaEsSampler() study = rustuna.create_study( sampler=sampler, storage=storage ) study.optimize(objective, n_trials=100000)
  10. 実サービスにおける試行履歴破棄機能の検証 Matlantis CSP • Matlantis株式会社が提供する結晶構造探索 サービス • Optunaを活用したNSGA-IIベースの手法を独 自に設計・実装 消費メモリの課題

    • 大規模な探索における消費メモリの増加が課題 の1つ • 探索に不要な試行履歴を破棄することで消費メ モリを大幅に抑制 16
  11. 今後の開発計画 1 2 Optuna本体へのフィードバック 安定性の向上 バグ修正・改善を継続 Rustunaで得られた知見を、Optunaの将来バー ジョンの性能改善にも活かす予定 Optunaとの連携強化 •

    Optunaの機能をシームレスに利用 3 Bulk Insert型のStorage API Storageへの書き込みをまとめて実行 • 多言語サポート TrialQueue enqueue_trialのキューをStorageから分離 Node.jsなど他言語への展開 • 試行履歴の破棄機能 不要になった履歴をメモリから破棄 19
  12. おわりに 1 Optuna互換のAPIで、すぐに使い始められる 2 TPEで約14倍、CMA-ES・NSGA-IIで700倍以上高速 3 基本的なユースケースでは importを変えるだけ。 Optunaの可視化などとも併用可能。 1万TrialsをTPEで1分以内に実行し、マルチスレッドによりさらにスケール可能

    試行履歴の破棄機能で省メモリ Matlantis CSPでメモリ消費を約 6割削減 ぜひお試しください! $ pip install rustuna GitHubのStarやIssue報告等をお待ちしております! github.com/optuna/rustuna rustuna.readthedocs.io 21
  13. 付録A: Optunaとの主な違い PersistedTrial / PersistedStudy TrialQueue FrozenTrial / FrozenStudy に相当。機能は同等

    で名前のみ異なる enqueue_trial のキューをStorageから分離。デ フォルトはインメモリ 属性値は文字列のみ Prunerは未サポート user_attrs などは文字列に限定。辞書などは json.dumps() で文字列化 多目的最適化などを優先しており、現時点では枝 刈り機能なし サンプラー : Random / TPE (デフォルト) / NSGA-II / CMA-ES ストレージ : InMemory / SQLite3Storage / JournalFileStorage 23