Skip to content

feat: Hardware EP 自動選択 + PIPER_EXECUTION_PROVIDER env var 対応 (全5ランタイム) - #386

Draft
ayutaz wants to merge 37 commits into
devfrom
feat/hardware-ep
Draft

feat: Hardware EP 自動選択 + PIPER_EXECUTION_PROVIDER env var 対応 (全5ランタイム)#386
ayutaz wants to merge 37 commits into
devfrom
feat/hardware-ep

Conversation

@ayutaz

@ayutaz ayutaz commented May 4, 2026

Copy link
Copy Markdown
Owner

概要

ONNX Runtime の Execution Provider (EP) 自動選択と PIPER_EXECUTION_PROVIDER 環境変数による明示的 EP 指定を全 5 ネイティブランタイム (Python / Rust / Go / C# / C++) に実装します。

自動検出優先順: CUDA → CoreML → DirectML → OpenVINO → CPU
TensorRT は明示指定のみ (PIPER_EXECUTION_PROVIDER=tensorrt)

変更内容

コア実装

  • Python (ort_utils.py): get_providers() / _get_device_label() を全 EP 対応に拡張、"gpu" エイリアス追加
  • Python runtime (voice.py): device="auto" パラメータ追加、use_cuda=True 後方互換を維持
  • Rust (gpu.rs): resolve_device_string() 追加、env var を parse_device_string() の前段で処理
  • Go (device.go): selectDeviceWithEnv() 追加、configureSessionOptions() の先頭で env var 参照
  • C# (SessionFactory.cs): ResolveDevice() / AutoDetectAndConfigureEP() 追加、EP 失敗時フォールバック対応
  • C++ (piper.cpp / main.cpp): auto EP ブロック追加、PIPER_EXECUTION_PROVIDER env var 対応

パッケージ

  • setup.py: directml / openvino extras_require グループを追加

ドキュメント

  • ort-session-contract.toml: EP 選択仕様と device_label フォーマットを追記
  • ort-versions.md: EP 対応状況マトリクスを追加

その他

  • pyproject.toml: workspace = true + editable = true 同時指定の TOML エラーを修正
  • tools/benchmark_ep.py: CPU スレッド数別推論速度ベンチマークスクリプトを追加

テスト結果(ローカル確認済み)

ランタイム テスト 結果
Python uv run pytest src/python/tests/test_ort_utils.py 81 passed
Rust cargo test --features onnx test_resolve_device_string -- --test-threads=1 6 passed
Go go test ./piperplus/ -run "TestSelectDeviceWithEnv|TestConfigureSessionOptionsEnvVar" 7 passed
C# dotnet test --filter FullyQualifiedName~SessionFactory (.NET 10.0.203 / macOS arm64) 41 passed

ベンチマーク(Apple Silicon M系 8コア、ORT 1.24.1)

設定 100 phonemes 推論時間 RTF 高速化
CPU-1thread 120.1ms 0.095 基準
CPU-2thread 71.8ms 0.057 1.67x
CPU-4thread 50.2ms 0.040 2.40x
CPU-8thread 74.4ms 0.059 1.61x

Note: CoreML EP はこの VITS モデル (Duration Predictor の NonZero op + ゼロ要素動的形状) が非対応のため CPU で計測。CUDA 環境での CoreML/CUDA 高速化は未検証。

TODO

  • Windows (CUDA EP): PIPER_EXECUTION_PROVIDER=cuda で GPU 推論が動作することを確認
  • Windows (DirectML EP): PIPER_EXECUTION_PROVIDER=directml で DirectML 推論が動作することを確認
  • Linux (CUDA EP): NVIDIA GPU 環境で device="auto" が CUDA を自動検出することを確認
  • Linux (OpenVINO EP): Python の PIPER_EXECUTION_PROVIDER=openvino で OpenVINO 推論が動作することを確認
  • macOS CoreML: ModelFormat=MLProgram + _probe_session() で推論失敗を検出し CPU へ自動フォールバック。ort-session-contract.toml に既知制限を文書化済み
  • C# テスト: .NET 10.0.203 / macOS arm64 で SessionFactoryTests 含む 41 tests passed。AppendExecutionProvider_CoreML / OrtEnv.Instance() の API 非互換を修正
  • C++ ビルド: Windows / Linux で CMake ビルドと PIPER_EXECUTION_PROVIDER env var の動作を確認

関連

  • Spec: docs/superpowers/specs/2026-05-04-hardware-ep-design.md
  • Plan: docs/superpowers/plans/2026-05-04-hardware-ep.md

ayutaz added 30 commits May 4, 2026 23:34
全5ネイティブランタイム(Python/Rust/C#/C++/Go)向けに
CoreML / CUDA / DirectML / OpenVINO / TensorRT の
EP 自動選択ロジックと実装方針を記述。
Critical:
- TensorRT を auto-detect 対象外に変更(明示指定のみ)
- Rust 擬似コードを gpu.rs の実際の型・関数に修正
- C++ に ORT 1.17 C-API (GetAvailableProviders) によるプローブ手順を明記
- TOML は既存 flat key 構造に倣い device_label_* キーで拡張

Important:
- voice.py: use_cuda を deprecated にし device: str = "auto" を追加
- Rust/Go: 既存実装を流用、差分は env var 対応のみと明記
- C# OpenVINO をスコープ外と明記
- CoreML キャッシュ矛盾を解消(.opt.onnx は通常通り生成)
- windows-2025 → windows-2022 に修正
- ort バージョンを 2.0.0-rc.12 に固定
- PIPER_GPU_DEVICE_ID との互換ルールを明記

Minor:
- 統合テスト閾値を RMS>0 + NaN なし(smoke test)に変更
- pyproject.toml に optional deps グループ例を追記
- C# コードスニペットに疑似コード注記を追加
- env_vars.implementation_status への追記を TOML セクションに含める
10タスク構成。Python/Rust/C#/C++/Go の全5ランタイムへの
PIPER_EXECUTION_PROVIDER env var 対応と EP 自動選択を TDD で実装。
T-07 のスコープ外(将来 Issue)のため `cpp` を除去し
コメントで明記する。
DeviceConfig.Resolve() に後方互換ロジックを追加。
PIPER_EXECUTION_PROVIDER → PIPER_GPU_DEVICE_ID → requested の
優先度で解決する設計を明示した。
std::function を生関数ポインタ (bool(*)(Ort::SessionOptions&, int)) に変更。
auto& ラムダ引数を Ort::SessionOptions& に明示して関数ポインタへの
暗黙変換を保証。constexpr の誤記を inline static const に訂正。
PEP 685 は extra 名の正規化を定めるもので Conflicts メタデータとは無関係。
Python 標準パッケージングに Conflicts 機能は存在しないことを明記し、
pip check による検証を代替手段として示した。
PiperVoice.load() は @staticmethod が正しい。実装計画が
T-03 チケットの仕様と矛盾していたため修正。
env var を書き換える並列テストは cargo の並列実行で競合する。
Done 基準のテストコマンドに -- --test-threads=1 を明記し、
実装者が競合なしでテストを実行できるよう修正。
RunConfig 構造体に provider フィールドを追加するには
piper.hpp の変更が必要。変更ファイルリストから漏れていたため追加。
「実装者判断」のままでは T-03 との不整合が生じる。
外部 CLI が --device gpu を渡すケースを考慮し、
_EP_KEY_TO_ORT_NAME["gpu"] = "CUDAExecutionProvider" の
別名登録を採用することを明記。T-03 でも同方針を踏襲する旨を追記。
TryAppend* が void を返す現設計では EP 初期化失敗を検知できず、
失敗した EP のラベルを返すバグが起きる。設計仕様書 §2.1 の
「初期化失敗時は次の EP に降格」要件を満たすため、
TryAppend* を bool 返値に変更する設計方針をチケットに追記。
…#382)

- CoreML/DirectML/OpenVINO/TensorRT を含む全 EP に get_providers() と _get_device_label() を拡張
- PIPER_EXECUTION_PROVIDER 環境変数によるオーバーライド対応
- 'gpu' を 'cuda' の後方互換別名として _EP_KEY_TO_ORT_NAME に登録
- auto モードでは TensorRT を除く優先順位付き EP 自動検出
- 新規テスト 26 件追加 (TestGetProviders: 14 件, TestGetDeviceLabel: 12 件)
- _INLINE_EP_AUTO_PRIORITY / _INLINE_EP_KEY_MAP を追加(ort_utils.py と同期)
- _inline_get_providers() / _inline_get_device_label() を追加
- _load_session_inline() のシグネチャに device: str="auto" を追加、use_cuda を非推奨化
- PiperVoice.load() に device: str="auto" を追加
- _HAS_SHARED_ORT_UTILS 分岐で use_cuda 条件を削除し、device を透過渡し
- "gpu" を "cuda" の後方互換別名として登録
- use_cuda=True は device="auto" 時のみ "cuda" に変換(明示的 device 指定を優先)
…_PROVIDER 対応を追加 (#382)

- ResolveDevice(): PIPER_EXECUTION_PROVIDER env var を優先、fallback は device パラメータ
- GetDeviceLabel(): "cuda:1" → "cuda1" など EP 文字列をキャッシュファイルラベルに変換
- TryAppendCoreML(): CoreML EP の try/catch ラッパー (bool 返値)
- TryAppendDirectML(): DirectML EP の try/catch ラッパー (bool 返値)
- AutoDetectAndConfigureEP(): CUDA → CoreML → DirectML → CPU の順に自動検出
- TryAppendCudaProvider を void → bool に変更 (AutoDetect での降格処理用)
- Create() 内の deviceLabel 計算を GetDeviceLabel() に切り替え
- 7 件のテストを SessionFactoryTests.cs に追加
…ER env var を追加 (#382)

- piper.cpp loadModel(): provider=="auto" (デフォルト) で CUDA→CoreML→DirectML→CPU を順次試みる自動検出モードを追加
- main.cpp RunConfig: provider フィールド (std::string, デフォルト "auto") を追加
- main.cpp parseArgs(): PIPER_EXECUTION_PROVIDER env var を読み込み、CLI フラグより優先して provider を設定
- main.cpp: --use-cuda フラグで useCuda=true と同時に provider="cuda" も設定 (後方互換維持)
- piper.hpp: loadVoice() のデフォルト provider を "cpu" → "auto" に変更
- printUsage(): PIPER_EXECUTION_PROVIDER の説明を環境変数セクションに追加
ayutaz added 3 commits May 5, 2026 00:54
workspace = true と editable = true は同時指定不可なため、
editable = true を削除。workspace メンバーは自動的に editable 扱いになる。
CPU-1/2/4/8 スレッドで 30/100/200 phonemes の推論時間を計測し
RTF と高速化倍率を出力する。CoreML EP の非対応モデル向け注記も含む。
@ayutaz ayutaz self-assigned this May 4, 2026
ayutaz added 4 commits May 5, 2026 09:04
- get_providers() で CoreML EP に ModelFormat=MLProgram を付加することで
  推論失敗時に SIGSEGV ではなく Python 例外が発生するよう変更
- _probe_session() を追加: 複数の phoneme 長 (6, 100) でダミー推論し
  EP が正常動作するかを確認。失敗時は False を返す
- create_session_with_cache(): 非 CPU EP でプローブ失敗時に
  CPUExecutionProvider で自動再作成するフォールバックを追加
- 非 CPU EP では ORT cache (optimized_model_filepath) を無効化
  (CoreML などはコンパイル済みノードをシリアライズ不可)
- ort-session-contract.toml に CoreML + VITS SDP NonZero の既知制限を文書化
- test_ort_utils.py に TestEpProbeAndFallback (4件) を追加: 81 passed
- AppendExecutionProviderCoreML(0) → AppendExecutionProvider_CoreML((CoreMLFlags)0)
  正しいメソッド名はアンダースコアあり、引数は CoreMLFlags enum
- OrtEnv.Instance.GetAvailableProviders() → OrtEnv.Instance().GetAvailableProviders()
  Instance はプロパティではなくメソッド (CS0119 修正)

dotnet test SessionFactory: 41 passed on .NET 10.0.203 / macOS arm64
- pyproject.toml: PLR0911 (too many return statements) を ignore に追加
  (PLR0912/PLR0913/PLR0915 と同様の扱いで EP 選択ロジック向け)
- voice.py: 未使用の `typing.Any` import を削除 (F401)
- benchmark_ep.py: import ブロック整列・onnxruntime をトップレベルへ移動 (I001/PLC0415)
- SessionFactory.cs: switch 式のアライメント空白を dotnet format で修正 (WHITESPACE)
@ayutaz

ayutaz commented May 14, 2026

Copy link
Copy Markdown
Owner Author

現状メモ (2026-05-14)

  • 実装中の Draft PR として認識・継続
  • 他の進行中 PR がマージ完了次第、CI レビューに着手予定

@ayutaz

ayutaz commented May 14, 2026

Copy link
Copy Markdown
Owner Author

トリアージ (2026-05-14)

CI: 94/94 checks passing ✅
MergeState: DIRTY (dev へのリベースが必要)

対応方針

このPRは Hardware EP 自動選択の完全な実装が含まれており、コードレビュー可能な状態です。ただし dev の最近のマージ(#477/#479/#480/#481/#482)によりコンフリクトが発生しています。

推奨アクション: dev への rebase 後、Ready for Review に昇格。実装は完成しており、学習等の追加作業は不要です。

リベース対象コンフリクト箇所 (推定)

次の dev マージが落ち着いたタイミングでリベース・昇格を進めます。

@github-actions

Copy link
Copy Markdown
Contributor

この PR は 90 日間 activity がないため stale label を付与しました。
7 日以内に進展がなければ自動 close されます。 rebase / push / コメント
のいずれかで stale clear。

@github-actions github-actions Bot added the stale label Aug 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant