> For the complete documentation index, see [llms.txt](https://docs.roboflow.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.roboflow.com/workflows/ja/gaido/developer-guide/execution-engine-changelog.md).

# Execution Engine 変更履歴

Workflows Execution Engine のバージョンごとの変更点。

以下に Execution Engine の変更履歴があります。

## 未リリース

**変更点**

ユーザー向けのコンパイルまたは実行動作の変更はここに追加してください。リリース時には、保守担当者がこの見出しを Execution Engine と inference のバージョンに置き換えます。

***

## Execution Engine `v1.16.0` | inference `1.5.2`

**変更点**

* VLM が切り出し画像内でオブジェクトを見つけられない場合、ワークフロー出力で `PARENT` 座標を使用するものは、現在は元画像の寸法を報告します。 `OWN` 座標を使用する出力は、切り出し寸法を引き続き報告します。

***

## Execution Engine `v1.15.1` | inference `1.5.1`

**変更点**

* ローカルのワークフローモデルの読み込み中に発生したモデルアクセス失敗は、これまでの汎用 HTTP 500 エラーではなく、HTTP 402、403、423 のステータスを保持するようになりました。
* **ステップのワーカースレッドは、呼び出し元の完全な `contextvars` コンテキストを継承するようになりました。** 並列実行されるステップ（ `run_in_parallel`経由で生成されたネストされたブロックのワーカープールを含む）は、送信元スレッドのコンテキストの、タスクごとのスナップショット内で実行されます。ブロックコードと計測は、これまでステップ内でスレッド既定値を観測していた場合でも、今では各 `ContextVar`についてリクエストの値を観測します。これは、以前エグゼキュータが再バインドしていた固定セット（`execution_id`, `remote_processing_times`, `apply_duration_minimum`、デバッグコレクター、ストリームセッション ID）だけではありません。
* **ステップ内で設定されたコンテキストがリクエスト間で漏れなくなりました** 各タスクのスナップショットはタスク完了時に破棄されるため、共有スレッドプール内で再利用されたワーカースレッドが前回のリクエストの `ContextVar` 状態を保持することはできません。以前は、その後の `run(...)` が同じプール上で、前回のリクエストの値（例: 以前のリクエストのコレクターに蓄積されるリモート GPU タイミング項目）を観測する可能性がありました
* **Batch および list 形状のデータが、Modal のリモート実行境界をそのまま通過するようになりました** `Batch[...]` リモート実行される Custom Python ブロックへの入力と list 形状のステップ結果は、両方のリモート転送で、バッチインデックスを保持したまま正しくシリアライズ／デシリアライズされるようになりました（roboflow/inference#2870）。

***

## Execution Engine `v1.15.0` | inference `1.3.9`

* **リモート HTTP 501 エラーは内部 URL を公開せずにステータスを保持します** — リモート実行された Workflow ステップが HTTP 501 を返した場合、Execution Engine は内部の producer URL を含む汎用 HTTP 500 ではなく、同じステータスと API メッセージを持つクライアント起因の Workflow エラーとして現在は提示します。

## Execution Engine `v1.14.0` | inference `1.3.8`

**変更点**

* **出力シリアライズは文字列として宣言された kind を受け付けます** — 出力 kind が単なる文字列（例: `"string"`）の代わりに `Kind` オブジェクトではない場合、出力シリアライズはクラッシュし `TypeError: unhashable type: 'list'`、ワークフロー全体の実行が HTTP 500 になっていました。このような kind は名前で解決されるようになり、対応するシリアライザが適用されます（その kind に対してシリアライザが登録されていない場合は、生の値がそのまま通されます）。
* **ブロックは依存リソースを宣言できます** — `WorkflowBlockManifest` にインスタンスメソッド `discover_dependent_resources() -> Optional[List[DependentResource]]` が追加され、解析済みステップが実行で使用する外部リソースを宣言できるようになりました。これにより、呼び出し元（プラットフォーム、プレローディング、認証の事前確認ツール）は、ワークフロー定義からそれらを静的に列挙できます。エンベロープは Execution Engine によって管理されます。リソース種別は `roboflow_platform_model`, `roboflow_platform_project` および `third_party_model`で、それぞれ型付きでシリアライズ可能な（pydantic）メタデータエンティティを持ちます。プラットフォームモデルのエントリは、使用の性質も指定します: `required_action` (`access` — モデルエンティティはプラットフォーム上で到達可能である必要があるだけ、対して `execution` — モデルが実行される）であり、実行については `execution_location` (`local` / `remote` / `environment_defined` により実行時にローカルかリモートかが決定されるときです。 `WORKFLOWS_STEP_EXECUTION_MODE`）。独自の locality override を持つブロックは、その場でそれを指定します — SAM3 画像ブロックは、 `SAM3_EXEC_MODE=remote` のとき何も宣言せず（プロキシ実行は設定された model id を無視し、サーバー側で固定の SAM3 を実行します）、 `environment_defined` それ以外の場合も同様です。 `None`  を返す（既定）場合、そのブロックは依存関係を宣言しないことを意味します — これは、外部リソースが不要であることを宣言する `[]`とは異なります。ワークフローセレクタであるフィールド値（`$inputs.<name>` / `$steps.<name>.<property>`）はそのまま報告されます。各メタデータエンティティは `requires_runtime_resolution()` を公開し、こうした参照を具体的な識別子と区別できるようにします。最終的な id がフィールド値から合成される宣言（ `clip/<version>` のような family prefix、カタログ検索など）は、置換された入力値を実行時の id に変換する非シリアライズ可能な `model_id_resolver` callable を追加で付与します。この callable はシリアライズ、JSON スキーマ、等価性から除外されます。モデル、Roboflow プロジェクト、または第三者ホストのモデルを参照するすべてのコアブロックがこのメソッドを実装しており、各実装は `run()` が実際に読み込むモデル識別子（ `clip/<version>`）。プロジェクト宣言は、静的な manifest 値から決定される有効化制御に従います: Roboflow モデルブロックは、アクティブラーニングの対象を `disable_active_learning` が文字通り `True` （既定）のとき破棄し、dataset-upload ブロックは `disable_sink` が文字通り `True`のとき何も宣言しません。セレクタ由来の制御は、保守的な may-need 宣言を維持します。イントロスペクションは `active_learning_target_dataset` プロパティで停止します — 明示的なターゲットなしで active learning が有効な場合、モデル id からプロジェクトは導出されません。モデルマネージャーの外でモデル重みを読み込むブロック（ `AutoModel.from_pretrained`を使用する SAM2/SAM3 ビデオトラッカー）は、現時点では意図的にこのメソッドを実装しません — それらの依存関係は未宣言のままです（`None`).
* **動的（カスタム Python）ブロックは未知の依存関係を報告します** — 動的ブロック用に合成された manifest は `None` から `discover_dependent_resources()` に対して
* **を返します。Python 本体は静的解析に対して不透明なので、「未知」こそが唯一正直な答えです。** — `エンジン初期化時に宣言済み Roboflow モデルのオプトイン事前ロード` ExecutionEngine.init(...) `は新しいオプションパラメータ` dependencies\_pre\_init `None`を受け入れます（既定 `roboflow_platform_model` ）：依存リソース種別名のリストで、今のところサポートされる値は`のみです。有効にすると、エンジンはコンパイル済みのすべてのステップの宣言済み依存関係を推定し（` deduce\_blocks\_dependencies `コンパイラユーティリティ内）、実行用に宣言されたすべての具体的な Roboflow platform model を model manager に登録します（いずれも`init\_parameters `から取得され、API キーも同様です）を` init() `$inputs.<name>` では、実行前に行うため、初回推論のレイテンシを予測可能にします。参照を含む宣言は **first** `run()` 回目のみ — ランタイム入力検証の後に行われるため、無効なリクエストは単一の試行を消費せず、ダウンロードも引き起こしません — エンジンは提供されたランタイムパラメータ（入力デフォルト適用済み）に対してそれらを解決し、宣言の `model_id_resolver` が付いている場合はそれを適用し（たとえば置換された CLIP バージョンは `clip/<version>`を事前ロードし、実行が使うのとまったく同じ id になります）、識別子が具体化したモデルを登録します。resolver が `None` を返す場合、その置換値は静的に解決不能であると宣言します（例: ある他の入力に依存して最終 id が決まる Qwen の fine-tuned sentinel ラベル）— 依存関係はスキップされ、実行時に解決されます。resolver が扱えない送信済み入力値（例: 未知のカタログラベル）は `RuntimeInputError`を送出します。登録は各ブロックの実際のローダーを反映します: 宣言は非シリアライズ可能な `model_registration_kwargs` （例: `endpoint_type=CORE_MODEL` CLIP / OCR / SAM2 / YOLO-World 風のコアモデル向けで、 `load_core_model()`に対応します）を含めることができます。各事前ロード後、エンジンは登録済みモデルがまだ model manager に存在することを確認し、サイズ／メモリ制約付きのマネージャーがその一部を追い出していた場合は警告をログに出します（それらは実行時に遅延ロードされます）。事前ロードは、実効ステップ実行モード（明示的な `step_execution_mode` init パラメータ、または `WORKFLOWS_STEP_EXECUTION_MODE` 既定）に従います: `environment_defined` 宣言はステップがローカル実行される場合にのみ事前ロードされ、 `local` 宣言は常に事前ロードされ、アクセスのみの宣言（重みの取得なし）、リモート実行、そして `$steps.…`由来の識別子は事前ロードされません。 `InferencePipeline.init_with_workflow(...)` はこれをオプトインの `workflows_dependencies_pre_init` パラメータとして公開します（既定 `None` — 事前ロードなし）— 動画処理では予測可能な起動の恩恵が特に大きいです。

## Execution Engine `v1.13.0` | inference `v1.3.7`

**変更点**

* **オフラインモードはリモート Workflow ステップ実行を拒否します** — `OFFLINE_MODE` が有効な場合、コンパイラは `StepExecutionMode.REMOTE` をステップ初期化中に拒否し（`WorkflowEnvironmentConfigurationError`）、Workflows はネットワークアクセスなしでリモート推論クライアントを開けません。ローカルのステップ実行は、ウォーム済みキャッシュに対して引き続き動作します。
* **適切なモデルアクセス失敗ステータスコード** - ローカルのワークフローモデルの読み込み中に発生したモデルアクセス失敗は、これまでの汎用 HTTP 500 エラーではなく、HTTP 402、403、423 のステータスを保持するようになりました。

## Execution Engine `v1.12.0` | inference `v1.3.2`

**変更点**

**将来解決** - 一部のステップは、現在 `Future` オブジェクトを返すことがあり、これはクライアントが出力を必要とするまで出力解決を遅延させます。下流ブロックではこれらの future は [step\_input\_assembler](https://github.com/roboflow/inference/blob/main/workflows/roboflow_workflows/execution_engine/v1/executor/execution_data_manager/step_input_assembler.py) で解決され、出力構築では [output\_constructor](https://github.com/roboflow/inference/blob/main/workflows/roboflow_workflows/execution_engine/v1/executor/output_constructor.py) と座標変換も併せて行われます。

## Execution Engine `v1.11.0` | inference `v1.3.1`

**変更点**

* **dict ステップセレクタに対するケースごとの実行分岐** - フロー制御ブロックが `Dict[str, StepSelector]` プロパティ内にステップセレクタを宣言した場合（ `List[StepSelector]`ではなく）、コンパイラは辞書キーごとに個別の実行分岐を作成するようになりました。以前は単一プロパティ内のすべてのセレクタが 1 つの分岐を共有していたため、ブロックは各ターゲットへ独立にルーティングできませんでした。分岐名には現在辞書キーが含まれます（例: `Branch[$steps.switch -> cases[red]]`）。リストプロパティ（たとえば `next_steps`）に保持されたセレクタは、従来の共有分岐の挙動を維持するので、既存ブロックに影響はありません。この変更により新しい `roboflow_core/switch_case@v1` ブロック（`graph_constructor.establish_control_flow_edge`).
* **修正: 繰り返し分岐名を持つ非 SIMD フロー制御マスク** - 単一の list プロパティで 1 つ以上のターゲットを選択する非 SIMD フロー制御ステップが `execution branch 用のマスクを再登録しようとしました`。分岐マスクの登録では、登録前に分岐名を重複排除するようになり、クラッシュを修正しました（例: `ContinueIf`  が複数の `next_steps`; `execution_data_manager.manager._register_control_flow_output_for_non_simd_step`).

## Execution Engine `v1.10.1` | inference `v1.2.12`

**変更点**

* **ネストされた内側ワークフローの動的ブロック** - コンパイラは現在 `dynamic_blocks_definitions` をルートワークフローと、深さ優先でたどったすべてのネストされた `inner_workflow` の子から収集し、 `manifest.block_type` ごとに重複排除します（最初に現れたものが優先され、重複がスキップされた場合は警告をログに出します）。そして、マージされたリストを `compile_dynamic_blocks` とインライン化の前にルート定義へホストします。ネストされた workflow spec のみに定義された custom Python ブロック型を使う子ステップは、インライン化後に正しくコンパイルおよび実行されます。

## Execution Engine `v1.10.0` | inference `v1.2.10`

**変更点**

* 静的値とセレクタが混在する値を持つ辞書を認識する機能を追加しました。以前のバージョンでは、キーからセレクタへのマッピングのみが認識されていたため、いくつかのブロックが実行時に参照先値へ正しく配線されませんでした。この変更は後方互換ですが、過去に壊れていた特定のブロックを修正します。

## Execution Engine `v1.9.0` | inference `v1.2.0`

{% hint style="info" %}
**新機能: コンパイル時インライン化によるネストされたワークフロー**

このリリースでは **`roboflow_core/inner_workflow@v1`** ブロックが追加され、ワークフローが別のワークフロー定義を埋め込めるようになりました（インライン JSON、または `workflow_workspace_id` / `workflow_id` / 任意 `workflow_version_id`から解決）。子入力は **`parameter_bindings`** で親から配線されます（子 `inputs[].name` → 親セレクタ）。コンパイル時にエンジンは **インライン化し** 、ネストされたステップを親グラフに取り込みます。実行は通常のステップと同じ経路を使います（別個のネストされたランタイムはありません）。
{% endhint %}

**変更点**

* **Inner workflow ブロック** - 新しいフロー制御ブロック型 `roboflow_core/inner_workflow@v1` に登録された `roboflow_core`。親の出力は、インライン化がセレクタを書き換えるまで、子ワークフローの JsonField 出力を `$steps.<inner_step_name>.<child_output_name>` として参照できます。
* **コンパイルパイプライン** - ルート定義を解析する前に、コンパイラは: (1) **参照を正規化し** （既定: Roboflow API + `workflows_core.api_key`、またはカスタム `workflows_core.inner_workflow_spec_resolver`), (2) **で構成を検証し** （非巡回性、最大ネスティング深度、最大 inner-workflow 数）、(3) **インライン化し** すべての inner workflow ステップを通常のステップへインライン化し、その後 parse、workflow specification validation、execution graph construction を続けます。
* **制限（環境変数）** - `WORKFLOWS_MAX_INNER_WORKFLOW_DEPTH` dependencies\_pre\_init `4`) はルートからの包含深度を上限化します; `WORKFLOWS_MAX_INNER_WORKFLOW_COUNT` dependencies\_pre\_init `32`) はネストされた定義内の `inner_workflow` ステップの総数を上限化します。
* **ドキュメント** - 参照 [Inner workflows (nested definitions)](/workflows/ja/gaido/developer-guide/inner-workflows.md) を使用法、バインディング、制限、例について。

## Execution Engine `v1.8.0` | inference `v1.1.1`

{% hint style="info" %}
**加算的変更 + 最小限の影響が見込まれるバグ修正に起因する 1 つの破壊的変更**

このリリースでは Execution Engine を拡張し、フロー制御によってゲートされたステップ（例: ある `ContinueIf` ブロックの後のステップ）が、 **データ由来の lineage を持たない場合でも実行できるようにしました** — つまり、上流ステップからバッチ指向の入力を受け取らない場合です。lineage と実行次元は、フロー制御の前段ステップから導出できるようになりました。既存ワークフローに影響はありません。

導入された 1 つの破壊的変更は、 `Batch.remove_by_indices` がネストされた batch に対して影響するバグ修正によるものです（下記参照）。影響は最小限と見込まれます。
{% endhint %}

**変更点**

* **フロー制御 lineage** - コンパイラは現在、フロー制御ステップ（例: `ContinueIf`の後の分岐）から来る lineage を追跡します。新しい **フロー制御 lineage サポート** の概念は、ステップにバッチ指向のデータ入力がなく、かつフロー制御ステップが前段にある場合に使われます: ステップの実行スライスと batch 構造は、それらのフロー制御前段から取得されます。
* **互換性チェックの緩和** - 以前は、 `verify_compatibility_of_input_data_lineage_with_control_flow_lineage` が `ControlFlowDefinitionError` を、フロー制御前段はあるが data-derived lineage がない任意のステップに対して送出していたため、そのようなステップはコンパイルできませんでした。現在はそのチェックが緩和され、ステップに入力データ lineage がない場合は互換性が強制されず、代わりにステップの lineage はフロー制御前段ステップの lineage から導出されます。厳格なチェックは、ステップが *持つ* data-derived lineage の場合にのみ引き続き実行され、フロー制御とデータ lineage の互換性が保たれるようにします。
* **新しいステップパターン** - フロー制御だけでトリガーされ、バッチデータを消費しないステップが正しく実行されるようになりました。たとえば、 `ContinueIf` の後にメール通知（または他の副作用を持つステップ）を送れるようになり、 `message_parameters`のようなパラメータへデータを配線する必要はありません。ステップは制御ステップから取得した lineage と次元で、各フロー制御分岐ごとに 1 回実行されます。
* **`Batch.remove_by_indices` ネストされた batch あり（動作修正）** -  `Batch.remove_by_indices`を通じてインデックスを削除すると、ネストされた `Batch` 要素も同じインデックス集合で再帰的にフィルタされるようになりました。その結果、削除されたインデックスのエントリ（ `None` 値を含む）は、ネストされた batch からも正しく除去されます。以前はトップレベルの batch のみがフィルタされ、ネストされた batch は変更されませんでした。

  既定では `WorkflowBlock`, `accepts_empty_values()`は `False`です。これが迂回された場合、そのような入力を消費するブロックは、たとえば `StitchDetectionsBatchBlock`:

  ```python
  def run(
      self,
      images: Batch[WorkflowImageData],
      images_predictions: Batch[Batch[sv.Detections]],
  ) -> BlockResult:
      result = []
      for image, image_predictions in zip(images, images_predictions):
          image_predictions = [deepcopy(p) for p in image_predictions if len(p)]
          for p in image_predictions:
              coords = p["parent_coordinates"][0]
      ...
  ```

  この変更の影響を受ける唯一のコアブロックは `DimensionCollapseBlockV1` ブロックです。個々の入力を None 値でフィルタせずに batch に包んでいたためです。

  ```python
  class DimensionCollapseBlockV1(WorkflowBlock):

    @classmethod
    def get_manifest(cls) -> Type[WorkflowBlockManifest]:
        return BlockManifest

    def run(self, data: Batch[Any]) -> BlockResult:
        return {"output": [e for e in data]}
  ```

  このブロックの出力を下流のアプリケーションで使用すると、それらの値を自分でフィルタリングしない限り、アプリケーションが完全に失敗するか、None 値を黙って処理してしまう可能性があります。

  上記を踏まえると、影響は最小限だと考えています。

## Execution Engine `v1.7.0` | inference `v0.59.0`

{% hint style="warning" %}
**ワークフローにおけるステップエラーに関する破壊的変更**

における不正な HTTP レスポンスコードに関連するバグを修正するために `inference-server` Workflows の実行リクエストを処理する際、Execution Engine のエラー処理を担当するデフォルトのメカニズムを変更する必要がありました。この変更の結果、Roboflow Hosted Platform および `inference>=0.59.0`では、Roboflow プラットフォームと連携する Workflow ブロックが、クライアント設定の誤り（不正な Roboflow API キー、不正なモデル ID など）により失敗した場合、 `StepExecutionError` を送出する代わりに（サーバーからの HTTP 500 応答） `ClientCausedStepExecutionError` （および 400、401、403、404 などの該当する HTTP レスポンスコード）を送出するようになります。
{% endhint %}

この変更の影響を受けるシナリオの一覧:

* Roboflow モデルを使用するブロックが不正なモデル ID を定義している - 今後は `ClientCausedStepExecutionError` ステータスコード 400 で送出されます
* Roboflow モデルを使用するブロックが不正な API キーを定義している - 今後は `ClientCausedStepExecutionError` ステータスコード 401 で送出されます
* Roboflow モデルを使用するブロックが不正な API キーを定義している、またはリソースにアクセスするための有効なキーが scope 付きで不足している - 今後は `ClientCausedStepExecutionError` ステータスコード 403 で送出されます
* Roboflow モデルを使用するブロックが存在しないモデルを定義している - 今後は `ClientCausedStepExecutionError` ステータスコード 404 で送出されます

{% hint style="info" %}
**復活させる `レガシーな` エラー処理を**

必要に応じて、エラーハンドラのレガシーな挙動を復活させることが可能です。移行期間には役立つかもしれません。必要なのは環境変数を設定するだけです `DEFAULT_WORKFLOWS_STEP_ERROR_HANDLER=legacy`.
{% endhint %}

## Execution Engine `v1.6.0` | inference `v0.53.0`

{% hint style="info" %}
**変更に注意が必要な場合があります**

このリリースでは、 **既存のワークフローに変更を加える必要はありません** 。一部のブロックは、最新の Execution Engine の機能を活用するためにアップグレードが必要になる場合があります。
{% endhint %}

以前のバージョンの Execution Engine には、特定の種類のブロック、特に Single Instruction, Multiple Data (SIMD) モードで動作するブロックを扱う際に大きな制限がありました。これらのブロックは、入力のバッチを一度に処理し、各要素に同じ操作を適用し、バッチ全体の結果を返すように設計されています。

たとえば、 `run(...)` このようなブロックの method は次のようになります:

```python
def run(self, image: Batch[WorkflowImageData], confidence: float):
    pass
```

manifest では、 `image` フィールドはバッチを受け付けるものとして宣言されています。

問題は、入力画像がバッチで動作しないブロックから来た場合に発生しました。そのようなケースでは、Execution Engine は個々の画像からバッチを構築できず、次のような厄介なコンパイルエラーにつながることがよくありました:

```
step `$steps.model` の property `images` に無効な参照が接続されています - step property 
はバッチ指向の入力を厳密に必要としますが、input selector には非バッチ指向の入力が入っています - これは 
ワークフロー構築に関する問題を示しています - 通常、この問題は非バッチ指向の step inputs が 
非バッチ指向の step の出力や非バッチ指向の入力で埋められている場合に発生します。
```

Execution Engine では `v1.6.0`、この制限は削除され、次の動作が導入されました:

* ある入力がバッチ指向でなければならないと検出されると、 **Auto Batch Casting** と呼ばれる手順が適用されます。これにより入力は自動的に `Batch[T]`に変換されます。すべてのバッチモード入力は manifest ですでに明示的に示されているため、以下に記載する例外を除き、ほとんどのブロックは内部変更なしでこのアップグレードの恩恵を受けます。
* auto-batch cast されるパラメータの次元数（ネストのレベル）は、ワークフロー内の特定のブロックのコンテキストおよびその manifest に基づいて、コンパイル時に決定されます。ほかのバッチ指向の入力が存在する場合（ *lineage supports*と呼ばれます）、Execution Engine は auto-cast されたバッチを構築する際にそれらを参照として使用します。これにより、各バッチ次元の要素数が step に渡されるほかのデータと一致することが保証されます（実際のバッチ入力が与えられた場合にアサートされる内容を再現します）。 *lineage supports*が存在しない場合、またはブロック manifest でそれが必要とされる場合（たとえば入力次元オフセットが設定されている場合）、不足している次元は [`torch.unsqueeze(...)` 操作と同様に生成されます](https://docs.pytorch.org/docs/stable/generated/torch.unsqueeze.html).
* 。その後、step の出力は Auto Batch Casting のコンテキストの有無に照らして評価されます。評価に基づき、出力はバッチまたはスカラーとして保存され、キャストの影響がローカルに留まるようにします。唯一の例外は、ブロック自身によって導入される出力次元の変更です。その副作用として、次が可能になります:
  * **スカラーから出力バッチを作成する** （step が次元数を増やす場合）、および
  * **バッチをスカラーに縮小する** （ブロックが次元数を減らす場合）。
* 2つの潜在的な摩擦点があります。まず **バッチを受け付けないブロックが** （したがってバッチ受け入れの入力を明示しない） **出力次元を減少させる**場合です。以前のバージョンでは、Execution Engine は次元ラップを適用してこれに対応していました。すべてのバッチ指向入力は追加の `Batch[T]` 次元でラップされ、ブロックの `run(...)` method がリスト次元に対して reduce 操作を実行できるようになっていました。しかし Auto Batch Casting では、そのようなブロックは一部の入力がスカラーかバッチかについて Execution Engine に明確なシグナルを提供しなくなるため、キャストが非決定的になります。これに対処するため、新しい manifest method が導入されました: `get_parameters_enforcing_auto_batch_casting(...)`。この method は、次元が減少する際にバッチキャストを強制すべきパラメータの一覧を返さなければなりません。ほかの文脈で使用されることは想定されていません。

{% hint style="warning" %}
**新しい method が既存のブロックに与える影響**

上記のケースで Auto Batch Casting 機能を完全に利用するために `get_parameters_enforcing_auto_batch_casting(...)` method を定義する要件は厳格ではありません。ブロックが変更されない場合、唯一の影響は、以前は **失敗していた** ワークフローがコンパイルエラーではなく動作するか、あるいは **ランタイムエラー**で失敗するかのどちらかになることです。これはブロックの `run(...)` method 実装の詳細に依存します。
{% endhint %}

* 2つ目の摩擦点は、 `get_parameters_accepting_batches_and_scalars(...)` を使って、バッチとスカラーの両方をサポートする入力フィールドを宣言しているブロックがある場合に発生します。デフォルトでは、Execution Engine はそのようなパラメータに対する自動キャストをスキップします。なぜなら、この method は歴史的に **ブロック自体がスカラーをバッチへブロードキャストできることを宣言する手段でもあったからです**  - [の実装を参照してください `roboflow_core/detections_transformation@v1`](https://github.com/roboflow/inference/blob/main/workflows/roboflow_workflows/core_steps/transformations/detections_transformation/v1.py) ブロック。ある意味では、Auto Batch Casting は *冗長* です。そのため、これらのブロックはそのままにして、新しいバージョンでは `get_parameters_enforcing_auto_batch_casting(...)` ではなく `get_parameters_accepting_batches_and_scalars(...)` を使用するようにアップグレードすることを提案します。
* 以前のバージョンでは、厳しい制約がありました。次元の縮小はレベル 2 以上でのみ発生できる、つまりネストされたバッチでのみ可能でした。この制限は現在削除されています。次元縮小ブロックはスカラーでも動作できるようになり、出力次元はゼロの境界で「跳ね返る」ようになります。

出力の生成方法には1つ **重要な変更があります。** 以前の Execution Error では、ブロックが `Batch[X]` を最初の次元レベルで直接生成することは許可されていませんでした。その領域は入力バッチへのマッピング用に予約されていたためです。バージョン `v1.6.0`以降、この制限は削除されました。

以前は、出力は常に要素のリストとして返されていました:

* 入力バッチに対応しているか、または
* 入力がスカラーのみの場合は単一要素のリストでした。

ここで疑問が生じます。ブロックが最初の次元レベルでバッチを生成するようになった場合、どうすべきでしょうか？ この新しく生成されたバッチのサイズが入力要素数と一致しない可能性があるため、入力ベースの出力と単純に `zip(...)` することはできません。これでは操作が曖昧になります。

これを解決するため、次の規則を採用しました:

* 状況を、サイズ 1 の **「ダミー」入力バッチ**.
* が存在するかのように扱う
* 。これはブロードキャストの原則に従っており、そのような出力をすべての要素にわたって一貫して拡張できるようにします。
* 実行の結果として入力バッチが消えることがありますが、その際に新しい最初の次元が出現した場合でも、出力の整合性を保つために仮想的にネストされたままになります。

**例:**

```
(入力なし)    IMAGE FETCHER BLOCK --> image --> OD MODEL --> predictions --> CROPS --> 出力は次のようになります: ["crops": [<crop>, <crop>, ...]] 
```

重要なのは、 **以前に作成された有効なワークフローから生成された結果は同じであることです** 。この変更は、新しい機能を利用するために作成された新規ワークフローにのみ影響します。

### 移行ガイド

<details>

<summary>`get_parameters_enforcing_auto_batch_casting(...)` method の追加</summary>

出力次元を減少させ、バッチ指向の入力を定義しないブロックは、実装で `Batch[T]` でラップされることを想定しているすべての入力を宣言する必要があります `get_parameters_enforcing_auto_batch_casting(...)`

```python
from typing import List, Literal, Type, Union

import supervision as sv

from inference.core.utils.drawing import create_tiles
from inference.core.workflows.execution_engine.entities.base import (
    Batch,
    OutputDefinition,
    WorkflowImageData,
)
from inference.core.workflows.execution_engine.entities.types import (
    IMAGE_KIND,
    OBJECT_DETECTION_PREDICTION_KIND,
    Selector,
)
from inference.core.workflows.prototypes.block import (
    BlockResult,
    WorkflowBlock,
    WorkflowBlockManifest,
)

class BlockManifest(WorkflowBlockManifest):
    type: Literal["my_plugin/tile_detections@v1"]
    crops: Selector(kind=[IMAGE_KIND])
    crops_predictions: Selector(
        kind=[OBJECT_DETECTION_PREDICTION_KIND]
    )
    scalar_parameter: Union[float, Selector()]

    @classmethod
    def get_output_dimensionality_offset(cls) -> int:
        return -1

    @classmethod
    def get_parameters_enforcing_auto_batch_casting(cls) -> List[str]:
        return ["crops", "crops_predictions"]

    @classmethod
    def describe_outputs(cls) -> List[OutputDefinition]:
        return [
            OutputDefinition(name="visualisations", kind=[IMAGE_KIND]),
        ]

class TileDetectionsBlock(WorkflowBlock):

    @classmethod
    def get_manifest(cls) -> Type[WorkflowBlockManifest]:
        return BlockManifest

    def run(
        self,
        crops: Batch[WorkflowImageData],
        crops_predictions: Batch[sv.Detections],
        scalar_parameter: float,
    ) -> BlockResult:
        print("このパラメータは auto-batch cast されません!", scalar_parameter)
        annotator = sv.BoxAnnotator()
        visualisations = []
        for image, prediction in zip(crops, crops_predictions):
            annotated_image = annotator.annotate(
                image.numpy_image.copy(),
                prediction,
            )
            visualisations.append(annotated_image)
        tile = create_tiles(visualisations)
        return {"visualisations": tile}
```

* の行で `34-36` 強制的な auto-batch casting の対象となるフィールドの宣言を追加する必要があります
* 上記の結果、run method の入力パラメータ（行 `53-54`は `Batch[T]` Execution Engine によってラップされます。

</details>

## Execution Engine `v1.5.0` | inference `v0.38.0`

{% hint style="info" %}
**変更に対する対応は不要です**

この変更は Workflows のユーザーにとって変更を必要としません。これは単なるパフォーマンス最適化です。
{% endhint %}

* の init method に新しいパラメータを公開しました `BaseExecutionEngine` class - `executor` これは Python の `ThreadPoolExecutor` のインスタンスを受け取り、execution engine で使用できます。この変更により、各 `BaseExecutionEngine.run(...)` ごとに専用の `ThreadPoolExecutor` インスタンスが不要になるため、処理が高速になるはずです。さらに、スレッド生成を大幅に制限しているため、一部の環境ではそれも利点になる可能性があります。
* 変更にもかかわらず、Execution Engine は同時実行される step の上限を維持しています。これは、executor を通じて一度に実行される step 数を制限することで実現されています（Execution Engine はもはや `ThreadPoolExecutor` の作成を制御しておらず、pool により多くの worker を用意できる可能性があるため）。

<details>

<summary>ThreadPoolExecutor を Execution Engine に注入する方法</summary>

```python
from concurrent.futures import ThreadPoolExecutor
workflow_init_parameters = { ... }
with ThreadPoolExecutor(max_workers=...) as thread_pool_executor:
    execution_engine = ExecutionEngine.init(
        init_parameters=workflow_init_parameters,
        max_concurrent_steps=4,
        workflow_id="your-workflow-id",
        executor=thread_pool_executor,
    )
    runtime_parameters = {
      "image": cv2.imread("your-image-path")
    }
    results = execution_engine.run(runtime_parameters=runtime_parameters)
```

</details>

## Execution Engine `v1.4.0` | inference `v0.29.0`

* 新しい kind を追加 - [`secret`](/workflows/ja/gaido/developer-guide/kinds/secret.md) 資格情報を表すためのものです。 **既存のブロックで対応は不要ですが、今後はブロックがパラメータとして secret 値を受け取る場合、この kind を使用することが期待されます。** で導入された結果のシリアライズに関する問題を修正しました
* v1.3.0 `- 誤って、Execution Engine は非バッチ指向の出力をシリアライズしていませんでした。` ステップ用の入力準備に関する Execution Engine のバグを修正しました。以前は SIMD でない step の runtime 中の入力収集時に、
* WorkflowBlockManifest.accepts\_empty\_input() `method の結果が無視されていました。これにより、ある SIMD でない step が下流ブロックに空の値を渡すバグが発生していました。さらに、` で行われた変更に照らし、非 SIMD ブロックが下流の SIMD step の入力を容易に渡せるようになったため、上流の非 SIMD ブロックが空でない結果を返したかどうかを確認する必要がありました（SIMD ブロックは空の結果を受け付けない場合があるためです）。この確認が追加されました。 `- 誤って、Execution Engine は非バッチ指向の出力をシリアライズしていませんでした。`既存のブロックに対しては、しかしこの修正は以前壊れていた Workflows を修復する可能性があります。 **既存のブロックで対応は不要ですが、今後はブロックがパラメータとして secret 値を受け取る場合、この kind を使用することが期待されます。** v0.27.0

## Execution Engine `- 誤って、Execution Engine は非バッチ指向の出力をシリアライズしていませんでした。` | inference `各 kind に serializer と deserializer を定義できるようにする変更を導入しました。この変更により、Workflows プラグインと Execution Engine が分離され、ワイヤ経由でデータ転送を必要とする外部システムとエコシステムを統合できるようになります。`

* ブロックのバンドル [ページはその変更を反映するよう更新されました。](/workflows/ja/gaido/developer-guide/block-bundling.md) Kinds
* *で定義された* プラグインには適切な serializer と deserializer が提供されていました `roboflow_core` Workflows Compiler と Execution Engine は以下をサポートするよう強化されました
* 任意の **kind のバッチ指向入力を&#x20;*****kind***。これは以前のバージョンとは対照的で、 `- 誤って、Execution Engine は非バッチ指向の出力をシリアライズしていませんでした。`では `image` および `video_metadata` kind のみをバッチ指向入力として扱えました（これは Execution Engine レベルで導入された、kind と内部データ形式の不幸で不要な結合の結果です **Execution Engine のレベルで**）。この変更の結果:
  * **新しい入力型が導入されました:** `WorkflowBatchInput` は、バッチ指向入力を示すために今後使用すべきです（そしてそれらを `WorkflowParameters`). `WorkflowBatchInput` と明確に分離します [*kind*](/workflows/ja/gaido/developer-guide/kinds.md) データとその [*次元数*](/workflows/ja/gaido/developer-guide/workflow-execution.md#steps-interactions-with-data)の両方をユーザーが定義できるようにします。新しい入力型は、実質的に以前のすべてのバッチ指向入力のスーパーセットです: `WorkflowImage` および `WorkflowVideoMetadata`は **引き続きサポートされます**が、 **Execution Engine の `v2`**&#x3067;削除される予定です。新しい入力形式に調整することを推奨しますが、現時点では要件は厳格ではありません。Execution Engine は現在、データ deserializer を適切に選択するために入力データの明示的な定義を必要とします *kind* 。将来的には状況が変わる可能性があります。多くの場合、バッチ指向データは *kind* コンパイラによって推論できるかもしれません（ただし、この機能はまだ実装されていません）。
  * **新しい selector 型注釈が導入されました** - 単に `Selector(...)`. `Selector(...)` は `StepOutputSelector`, `WorkflowImageSelector`, `StepOutputImageSelector`, `WorkflowVideoMetadataSelector` および `WorkflowParameterSelector` を置き換えるものです。ブロック manifest では、開発者は特定の step manifest property が特定の *kind*の selector のいずれかを保持できることを表現できます。 **上記の古い注釈型は**を非推奨と見なすべきであり、 `Selector(...)`.
  * selectors の型注釈の簡素化の結果、古い selector は blocks のどのパラメータが `run(...)` method によって Execution Engine から ship されているかという情報を提供しなくなります [`Batch[X]` コンテナ](/workflows/ja/gaido/developer-guide/data-representations.md#batch)。古い selectors 型注釈と `block_manifest.accepts_batch_input()` method の代わりに、バッチ指向データで渡されることが期待されるパラメータ（`block_manifest.get_parameters_accepting_batches()`）と、両方を受け取れるパラメータを明示的に定義する 2 つの method への切り替えを提案します *バッチ* および *スカラー* 値（`block_manifest.get_parameters_accepting_batches_and_scalars()`）です。 `block_manifest.accepts_batch_input()` の戻り値は 2 つの新しい method の結果に基づいて構築されます。この変更は **破壊的ではありません**。なぜなら、バッチを処理できた既存のブロックはすべて `block_manifest.accepts_batch_input()` method を実装して `True` を返し、バッチ指向データを示す適切な selector 型注釈を使用していたはずだからです。
* これらの変更の結果、現在は **任意のワークフローを複数に分割して step のサブセットを実行することが可能になり**、デバッガーのようなツールを構築できるようになりました。

**予定されている破壊的変更 - Execution Engine `v2.0.0`**

* `WorkflowImage` および `WorkflowVideoMetadata` inputs は Workflows エコシステムから削除されます。
* `StepOutputSelector,` WorkflowImageSelector`,` StepOutputImageSelector`,` WorkflowVideoMetadataSelector`および`WorkflowParameterSelector\` 型注釈は Workflows エコシステムから削除されます。{% endhint %}

### 移行ガイド

<details>

<summary>Kinds の serializer と deserializer</summary>

Workflows プラグインを作成する際に、Workflows の *kind*向けのカスタム serializer と deserializer を導入できます。そのためには、プラグインのメインモジュール（ `load_blocks(...)` 関数を置くのと同じ場所）に次の辞書を配置するだけです:

```python
from typing import Any

def serialize_kind(value: Any) -> Any:
  # ここに、
  # Workflows の内部データ表現を 
  # 外部表現へ変換するためのコードを置きます（JSON でワイヤ経由で送信できる、
  # Python のデフォルト JSON エンコーダー）。
  pass

def deserialize_kind(parameter_name: str, value: Any) -> Any:
  # ここに、デコードに使用されるコードを配置する 
  # ワイヤー経由で Execution Engine に送られるデータ
  # そしてそれを適切な内部 Workflows データ表現に変換する
  # これはブロックによって理解される。
  pass

KINDS_SERIALIZERS = {
    "name_of_the_kind": serialize_kind,
}
KINDS_DESERIALIZERS = {
    "name_of_the_kind": deserialize_kind,
}
```

</details>

<details>

<summary>セレクタの新しい型注釈 - `Batch[X]` 入力を持たないブロック</summary>

ブロックのマニフェストは **任意で** 使用するように更新できます `Selector` 次のように:

```python
from typing import Union
from inference.core.workflows.prototypes.block import WorkflowBlockManifest
from inference.core.workflows.execution_engine.entities.types import (
    INSTANCE_SEGMENTATION_PREDICTION_KIND,
    OBJECT_DETECTION_PREDICTION_KIND,
    FLOAT_KIND,
    WorkflowImageSelector,
    StepOutputImageSelector,
    StepOutputSelector,
    WorkflowParameterSelector,
)

class BlockManifest(WorkflowBlockManifest):

    reference_image: Union[WorkflowImageSelector, StepOutputImageSelector]
    predictions: StepOutputSelector(
        kind=[
            OBJECT_DETECTION_PREDICTION_KIND,
            INSTANCE_SEGMENTATION_PREDICTION_KIND,
        ]
    )
    confidence: WorkflowParameterSelector(kind=[FLOAT_KIND]) 
```

は単純に次のように変更されるべきです:

```python
from inference.core.workflows.prototypes.block import WorkflowBlockManifest
from inference.core.workflows.execution_engine.entities.types import (
    INSTANCE_SEGMENTATION_PREDICTION_KIND,
    OBJECT_DETECTION_PREDICTION_KIND,
    FLOAT_KIND,
    IMAGE_KIND,
    Selector,
)

class BlockManifest(WorkflowBlockManifest):
    reference_image: Selector(kind=[IMAGE_KIND])
    predictions: Selector(
        kind=[
            OBJECT_DETECTION_PREDICTION_KIND,
            INSTANCE_SEGMENTATION_PREDICTION_KIND,
        ]
    )
    confidence: Selector(kind=[FLOAT_KIND]) 
```

</details>

<details>

<summary>セレクタの新しい型注釈 - `Batch[X]` 入力を持つブロック</summary>

ブロックのマニフェストは **任意で** 使用するように更新できます `Selector` 次のように:

```python
from typing import Union
from inference.core.workflows.prototypes.block import WorkflowBlockManifest
from inference.core.workflows.execution_engine.entities.types import (
    INSTANCE_SEGMENTATION_PREDICTION_KIND,
    OBJECT_DETECTION_PREDICTION_KIND,
    FLOAT_KIND,
    WorkflowImageSelector,
    StepOutputImageSelector,
    StepOutputSelector,
    WorkflowParameterSelector,
)

class BlockManifest(WorkflowBlockManifest):

    reference_image: Union[WorkflowImageSelector, StepOutputImageSelector]
    predictions: StepOutputSelector(
        kind=[
            OBJECT_DETECTION_PREDICTION_KIND,
            INSTANCE_SEGMENTATION_PREDICTION_KIND,
        ]
    )
    data: Dict[str, Union[StepOutputSelector(), WorkflowParameterSelector()]]
    confidence: WorkflowParameterSelector(kind=[FLOAT_KIND]) 

    @classmethod
    def accepts_batch_input(cls) -> bool:
        return True
```

は次のように変更されるべきです:

```python
from inference.core.workflows.prototypes.block import WorkflowBlockManifest
from inference.core.workflows.execution_engine.entities.types import (
    INSTANCE_SEGMENTATION_PREDICTION_KIND,
    OBJECT_DETECTION_PREDICTION_KIND,
    FLOAT_KIND,
    IMAGE_KIND,
    Selector,
)

class BlockManifest(WorkflowBlockManifest):
    reference_image: Selector(kind=[IMAGE_KIND])
    predictions: Selector(
        kind=[
            OBJECT_DETECTION_PREDICTION_KIND,
            INSTANCE_SEGMENTATION_PREDICTION_KIND,
        ]
    )
    data: Dict[str, Selector()]
    confidence: Selector(kind=[FLOAT_KIND]) 

    @classmethod
    def get_parameters_accepting_batches(cls)W -> List[str]:
        return ["predictions"]

    @classmethod
    def get_parameters_accepting_batches_and_scalars(cls) -> List[str]:
        return ["data"]
```

次の点に注意してください:

* 元の例の `data` プロパティは、両方を受け入れることができました **バッチ** のデータと **スカラー** 値。これは、バッチ指向データのセレクタ（`StepOutputSelector`）と *スカラー* data（`WorkflowParameterSelector`）。現在では同じことが `Selector(...)` 型注釈と、 `get_parameters_accepting_batches_and_scalars(...)` メソッドの戻り値によって表されています。

</details>

<details>

<summary>Workflows 定義における新しい入力</summary>

どちらかを `WorkflowImage` または `WorkflowVideoMetadata` Workflows 定義の入力を **任意で** へ移行できます。 `WorkflowBatchInput`。その移行は以下に示します:

```json
{
  "inputs": [
    {"type": "WorkflowImage", "name": "image"},
    {"type": "WorkflowVideoMetadata", "name": "video_metadata"}
  ]
}
```

は次のように変更されるべきです:

```json
{
  "inputs": [
    {
      "type": "WorkflowBatchInput",
      "name": "image",
      "kind": ["image"]
    },
    {
      "type": "WorkflowBatchInput",
      "name": "video_metadata",
      "kind": ["video_metadata"]
    }
  ]
}
```

**空欄のままにしておくと `kind` フィールドを空のままにすると、画像のような一部のデータが正しくデシリアライズされない可能性があります。**

**注意**

でデータがシリアライズされる方法が気に入らない場合は `roboflow_core` プラグイン内のシリアライズ方法を自由に変更できます *kind*、関数をプラグインに登録して Execution Engine に読み込むだけで、最後に定義された serializer/deserializer が使用されます。

</details>

## Execution Engine `v1.2.0` | inference `v0.23.0`

* この [`video_metadata` kind](/workflows/ja/gaido/developer-guide/kinds/video-metadata.md) は非推奨となっており、私たちは **今後のブロック作成では使用をやめることを強く推奨します**。代替として、 [`image` kind](/workflows/ja/gaido/developer-guide/kinds/image.md) は、と同じメタデータをサポートするよう拡張されました [`video_metadata` kind](/workflows/ja/gaido/developer-guide/kinds/video-metadata.md)。これは任意で提供できるようになりました。この更新は **破壊的ではありません** 既存のブロックには **一部の古いブロック** 画像を生成する **が互換性を失う可能性があります** と **将来の** 動画処理ブロック。

<details>

<summary>ブロック間の互換性の可能性</summary>

前述のとおり、 `video_metadata` を内部表現の任意フィールドとして追加することは、 [`image` kind](/workflows/ja/gaido/developer-guide/kinds/image.md) (`WorkflowImageData` クラス）に追加すると、出力が次のものである既存ブロックと [`image` kind](/workflows/ja/gaido/developer-guide/kinds/image.md) との間で摩擦が生じる可能性があります。将来の動画処理ブロックは `video_metadata` が一部であることに `image` 表現。

問題は、私たちが提供できる一方で **デフォルトの** 値を `video_metadata` に対して `image` 入力から明示的にコピーしなくても、上流で追加されたデフォルト以外のメタデータが失われる可能性があることです。これにより、〜に依存する下流ブロックが `video_metadata` 期待どおりに動作しなくなることがあります。

既存のすべての `roboflow_core` ブロックはこれに対応するよう更新しましたが、この変更以前に外部リポジトリで作成されたブロックは、出力画像が動画処理ブロックで使用されるワークフローで問題を引き起こす可能性があります。

</details>

* 非推奨となった [`video_metadata` kind](/workflows/ja/gaido/developer-guide/kinds/video-metadata.md) は引き続き使用できますが、Execution Engine バージョンで完全に削除されます `v2.0.0`.

{% hint style="warning" %}
**予定されている破壊的変更 - Execution Engine `v2.0.0`**

[`video_metadata` kind](/workflows/ja/gaido/developer-guide/kinds/video-metadata.md) は非推奨となり、で削除される予定です `v2.0.0`
{% endhint %}

* 上記の変更の結果、の内部表現は [`image` kind](/workflows/ja/gaido/developer-guide/kinds/image.md) 新しい `video_metadata` プロパティを含むよう更新されました。このプロパティはコンストラクタで任意に設定できます。指定されない場合は、適切なデフォルト値を持つ既定値が使用されます。ブロック内でのメタデータ操作を簡単にするため、2つの新しいクラスメソッドを導入しました: `WorkflowImageData.copy_and_replace(...)` および `WorkflowImageData.create_crop(...)`。詳細は更新された [`WoorkflowImageData` 使用ガイド](/workflows/ja/gaido/developer-guide/data-representations.md#workflowimagedata).
