6. トラブルシューティングと最適化
EvoXを使用する際、問題に遭遇したり、アルゴリズムを微調整したくなることがあるかもしれません。本章では、一般的な問題とその解決策、デバッグ戦略、およびパフォーマンスチューニングのヒントを概説し、問題の解決とエクスペリエンスの最適化を支援します。
6.1 一般的な問題と解決策
以下は、頻繁に遭遇する問題とその対処法です。
(1) インストールまたはインポートのエラー:
- 症状:
import evoxを実行するとエラーが発生する。 - 解決策:
- インストールの確認:
pip show evoxを実行して確認してください。インストールされていない場合は、仮想環境を確認して再インストールしてください。 - 依存関係の欠落:
ModuleNotFoundError: No module named 'torch'が表示される場合は、第2章の説明に従ってPyTorchをインストールしてください。 - CUDAの不一致: PyTorchのバージョンがインストールされているCUDAドライバーと一致していることを確認してください。
- インストールの確認:
(2) GPUが使用されていない:
- 症状: EvoXがGPUではなくCPUで実行されている。
- 解決策:
torch.cuda.is_available()で確認してください。Falseの場合、GPU互換のPyTorchを再インストールし、CUDAのインストールを確認してください。TrueであるにもかかわらずEvoXがCPUを使用している場合は、テンソルがGPUに移動されていることを確認してください(設定については第3章を参照)。
(3) メモリ不足 (RAM/VRAM):
- 症状:
OutOfMemoryErrorが表示される。 - 解決策:
- 個体群サイズ(population size)、問題の次元数、または評価頻度を減らしてください。
- float16(半精度)を使用するか、バッチ評価を分割してください。
- PyTorchのデバッグモードや決定論的モードをオフにしてください。
- (多目的最適化の場合)完全なパレートフロントではなく、統計情報のみを保存してください。
- ハードウェアのアップグレードが、メモリボトルネックに対する究極の解決策です。
(4) 収束の停滞:
- 症状: アルゴリズムが局所最適解(local optimum)に陥っている。
- 解決策:
- 個体群の多様性を高めてください(例:突然変異率を上げる)。
- 異なるアルゴリズムやパラメータを試してください。
- 目的関数が適切に定義されていることを確認してください(ノイズが多すぎたり、平坦すぎたりしないか)。
- 複数回の試行を実行して最良の結果を選んでください。EvoXでは並列実行が容易に行えます。
(5) 最適化結果が悪い:
- 症状: 最終結果が期待を下回っている。
- 解決策:
- 問題定義の確認: 適応度(fitness)が正しく計算されているか確認してください(例:符号、スケーリング)。
- アルゴリズムの適合性: 他のアルゴリズムを試すか、ハイパーパラメータを調整してください。
- 収束曲線の利用:
- 早期に平坦化 → 早すぎる収束(premature convergence)。
- 振動している → ランダム性が高すぎる。
- アルゴリズムの設定を調整し、経時的な挙動を分析してください。
(6) バックエンドの競合 (JAX vs PyTorch):
- 症状: PyTorchの例を使用しているのに、誤ってJAX版のEvoXをインストールしてしまった。
- 解決策: デフォルトの
pip install evoxではPyTorch版がインストールされます。JAX版をインストールしてしまった場合は、PyTorchの手順に従って再インストールしてください(第2章を参照)。JAXの機能については別途ドキュメント化されています。
(7) バージョンの不一致:
- 症状: API呼び出しがインストールされているバージョンと一致しない。
- 解決策:
- EvoXのアップデートにより、メソッド名が変更される場合があります(例:
ask/tell→step)。 - 最新の安定版を使用し、そのドキュメントを参照してください。
- コードをEvoXのバージョンに合わせるか、アップグレードを検討してください。
- EvoXのアップデートにより、メソッド名が変更される場合があります(例:
6.2 デバッグのヒント
進化計算アルゴリズムは確率的な性質を持つため、デバッグが難しい場合があります。以下に実践的なヒントを挙げます。
(1) 小規模なテストを行う:
- 個体群サイズと反復回数を減らして、デバッグを簡素化してください。
- 例:
pop_size=5,iterations=20。 - 個体群の挙動を追跡し、問題を特定しやすくなります。
(2) Print文を挿入する:
- 個体群の適応度、最良個体、および中間値を出力してください。
- 大きなテンソルの場合は形状(shape)を出力するか、小さいものの場合は
.tolist()を使用してください。 - 収束状況や演算子の効果を理解するのに役立ちます。
(3) IDEのブレークポイントを使用する:
- PyCharmやVS Codeを使用して、アルゴリズムの
step()や評価ロジック内にブレークポイントを設定してください。 - 変数の値、テンソルの内容、または状態遷移を検査します。
- 大きなテンソルには注意してください。クラッシュを避けるため、検査する内容を制限してください。
(4) カスタムコンポーネントの単体テスト:
- 交叉(crossover)や突然変異(mutation)関数を個別にテストしてください。
- 完全な統合を行う前に、合成入力を使用して出力形状とロジックを検証してください。
(5) 実行のプロファイリング:
torch.autograd.profiler.profileやtime.time()を使用して、ステップのタイミングを計測してください。- ボトルネックや無限ループを特定するのに役立ちます。
- 速度低下の原因が評価にあるのか、アルゴリズムのロジックにあるのかを特定します。
(6) 出力をファイルにログ記録する:
- 長時間実行する場合は、ログを
.csvファイルに書き込んでください。 - 世代ごとの最良適応度、多様性の統計情報などを含めます。
- クラッシュによってコンソール出力が見られなくなった場合に役立ちます。
全体として、EvoXプロジェクトのデバッグには、正確性のチェックと結果分析のバランスが必要です。まずはアルゴリズムが正しく動作することを確認し、その後に有効性を最適化することに集中してください。
6.3 パフォーマンスチューニングガイド
以下のヒントは、EvoXからさらなる速度と品質を引き出すのに役立ちます。
(1) 段階的なスケーリング:
- 小さく始める: 小さな入力でロジックをテストします。
- スケールアップ: 徐々に規模を拡大し、実行時間がどのように増加するかを観察します。
- 非効率性の特定: スケーリングが非線形である場合(例:個体群が10倍になると時間が10倍以上になる)、非効率な部分を特定します。
(2) ハードウェア使用率の監視:
- GPUには
nvidia-smi、CPUにはhtopを使用してください。 - 高いGPU使用率(>50%)が理想的です。
- GPU使用率が低い場合、データがGPU上にないか、頻繁なCPU-GPU間の転送が処理を遅らせている可能性があります。
(3) 並列処理の調整:
- CPUスレッドの設定:
torch.set_num_threads(n)。 - マルチスレッド評価ツールを使用している場合は、スレッドの過剰割り当て(oversubscription)を避けてください。
- GPUの場合、バッチ環境やデータセットを使用しているなら、
DataLoaderのスレッドを最適化してください。
(4) バッチ評価の活用:
- バッチ評価は、個体ごとの評価よりも高速です。
- 常に
Problem.evaluate()をベクトル化し、個体群全体を処理するようにしてください。
(5) Pythonのオーバーヘッド削減:
- 重いロジックは
AlgorithmやProblemの内部に移動し、メインループ内での複雑なPythonコードは避けてください。 - ほとんどの操作には
workflow.step()を使用してください。 - 世代ごとの診断処理が実行を遅くしている場合は、最小限に抑えてください。
(6) アルゴリズム選択の調整:
- CMA-ES、GA、PSO、RVEAなどを試してください。すべての問題に最適な単一のアルゴリズムは存在しません。
- 収束の遅いアルゴリズムを細かく最適化するよりも、収束の速いアルゴリズムを使用する方が時間を節約できる場合があります。
パフォーマンスチューニングは反復的なプロセスです。根気よく行えば、数時間の実行時間を数分に短縮できることもあります。EvoXには多くの「調整つまみ(knobs)」が用意されています。それらを賢く使い、速度と解の品質のバランスをとってください。