拡張ガイドライン#
このページは、既存コンポーネントの軽量な差し替えと互換性用Pipelineの構成を扱います。 拡張は、既存コンポーネントの差し替えとフレームワークの拡張に分かれます。
既存の契約にコンポーネントを追加する場合は 独自Componentを実装する を参照してください。
契約、探索空間、Graph、Runtimeを追加する場合は フレームワーク拡張 を参照してください。
import経路の規則は Canonical Imports にまとめています。
拡張点を選ぶ#
変更したい責務に対応する最も浅い境界を選びます。 新しい実行契約が必要な場合だけFrameworkへ進み、既存の契約で表現できる差し替えはチュートリアルの手順で実装します。
変更したいこと |
主な境界 |
概念 |
APIリファレンス |
|---|---|---|---|
候補生成や個体更新を変更する |
|
||
交叉、突然変異、選択を変更する |
演算子 |
||
予測モデルや学習データを変更する |
|
||
候補の選択や評価順序を変更する |
|
||
外部ライブラリを接続する |
明示的なAdapter |
||
候補表現や変数制約を追加する |
|
||
入出力、状態、ライフサイクルを宣言する |
|
||
接続や互換性検査を変更する |
|
||
実行、再開、非同期待機の意味を変更する |
|
フレームワーク契約は saealib.core から取得し、実装モジュールを安定した拡張APIとして扱いません。
Algorithm、OptimizationStrategy、Surrogate、AcquisitionFunction、SurrogateManagerには、それぞれ差し替え可能な契約があります。 独自の探索や予測を実装するときは、対象のドメインコンポーネントを実装して Optimizer.set_*() から登録します。 既存コンポーネントの一部だけを変更する場合は、次の軽量な拡張手段を使えます。
with_post / with_post_fitによる後処理#
Crossover/Mutation の with_post(fn) と Surrogate の with_post_fit(fn) は、サブクラス化せずに既存インスタンスへ後処理を追加します。元のインスタンスは変更せず、フックを追加したコピーを返します。
用例は、Crossover/Mutationへの修復関数の追加や、Surrogateのフィット後処理です。 各コンポーネントページの「拡張フック」節に、コンポーネントごとの具体例があります。
PipelineとStage#
Stage と Pipeline には、互換性用の実行経路と構造化DSLの二つの境界があります。 Stageは OptimizationState を受け取り、更新した状態を返す互換性用の実行単位です。 一方、構造化Pipelineはgraph-native component、入れ子のPipeline、Repeat、Loop、Branchを保持し、状態を直接実行しません。
構造化PipelineへStageを入れるときは、stage_component(stage) で互換性境界を明示します。 Optimizerは内部でこのDSLをGraphへlowerし、構造化Runtimeで実行できる計画へ変換します。 通常の利用者がCompilerを直接呼び出す必要はありません。
pipeline.replace("name", entry) は構造上のエントリを置き換え、pipeline.find("name", recursive=False) は名前でエントリを検索します。
from saealib import Pipeline, Stage
from saealib.stages import stage_component
from saealib.stages import CountGenerationStage
class DoubleCountStage(Stage):
name = "count_generation"
def execute(self, state):
return state.replace(gen=state.gen + 2)
pipeline = Pipeline(
steps=[
stage_component(CountGenerationStage()),
# Add a graph-native component or another Stage adapter next.
]
)
pipeline.replace("count_generation", stage_component(DoubleCountStage()))
Stage はStageの契約、組み込みStage、互換性用のカスタムStageを説明します。 このページでは、既存の構成を置き換えるときにどの境界を選ぶかを説明します。
CallbackManager#
CallbackManager はEvent発火時にハンドラを呼び出す観測機構です。 candidates などのEventフィールドは観測用であり、再代入してもPipelineの入力は変わりません。 データフローの後処理には with_post() / with_post_fit()、実行単位の置換には Stage、実行構成の変更には Runtime を選びます。
iterate() / run() のステップ境界で optimizer.set_*() やコンポーネント属性を変更すると、実行環境が変化を検出してplanを再コンパイルし、次世代から反映します。 この手順はStage互換経路とgraph-native経路のどちらでも利用できます。 Component側から再コンパイルを要求する経路については OptimizationStrategy の「Behavior of runtime swapping」を参照してください。 Callbackは観測専用で、ハンドラから RuntimeCommand を返すことはできません。 Callbackのクロージャで optimizer.set_*() を呼ぶ変更は上記の経路として反映されますが、構成変更は iterate() 側の手順として案内します。
レジストリ#
saealib.registryは、名前(文字列)またはspec({"type": "Name", "params": {...}})から実インスタンスを構築する仕組みです。 with_post/Pipeline-Stage/CallbackManagerが「実行時の挙動を変える」ための機構であるのに対し、Registryは「コンポーネントを文字列や設定ファイルから組み立てる」ための機構であり、目的が異なります。 プリセットYAML経由の設定駆動構築(Optimizer.set_preset())やチェックポイント再開のように、クラスを直接importしない場面で使います。
register(name=None)(デコレータ):クラスや関数をレジストリへ登録します。 独自のAlgorithm/Surrogate等のサブクラスに@register()を付けるだけで、組み込みコンポーネントと同じように短い名前で参照できるようになります。
from saealib import register
from saealib.surrogate import Surrogate
@register()
class MyCustomSurrogate(Surrogate):
def __init__(self, alpha: float = 1.0):
self.alpha = alpha
...
get/build/to_specはsaealibのトップレベルからは公開されておらず、saealib.registryから直接importします。
get(name):登録名、または未登録なら"module.submodule.ClassName"形式のドットパスとして解決します。
build(spec):specを再帰的に実インスタンスへ構築します。 spec内の値がさらに入れ子のspecであれば再帰的に構築されます。 {"callable": "dotted.path"}という形式は、関数や組み込み関数そのものを(呼び出さずに)解決します。
to_spec(obj):build()の逆操作。 コンストラクタシグネチャを反映し、同名属性を読んでspecへ再帰的にシリアライズします。 _registry_spec属性を持つクラス(TerminationConditionなど)はこの汎用リフレクションを使わず、その属性を直接返します。 Optimizer.save_preset()が使う経路です。
from saealib.registry import build, get, to_spec
obj = build({"type": "MyCustomSurrogate", "params": {"alpha": 2.0}})
get("MyCustomSurrogate") # -> the MyCustomSurrogate class
to_spec(obj) # -> {"type": "MyCustomSurrogate", "params": {"alpha": 2.0}}
各コンポーネントページで「◯◯クラスは@register()未登録」という注記が複数箇所にありますが、いずれもRegistry経由でクラス名から解決する使い方をする場合にのみ影響します。
使い分けの指針#
やりたいこと |
使う機構 |
|---|---|
既存の演算子やサロゲートに後処理を足すだけ |
|
ステージの並び自体を変えたい |
|
外部観測、ログ、条件判断 |
|
設定ファイルやプリセットから組み立てたい |
|
関連コンポーネント#
Stage:
Pipelineが組み合わせる各ステージの契約CallbackManager:イベント一覧と観測の仕組み
strategies:パイプラインの再構築タイミング