# Fusion mapping（実験的機能）

Fusion mapping は、元のチェックポイント形式を維持したまま、読み込み時にモデルのサブモジュールを置き換えるためのオプトイン方式を提供します。

以下に基づいています：

- モデルのインスタンス化前にモジュールのクラスを差し替えるための[Monkey patching](./monkey_patching)。
- 元のランタイムレイアウトと融合後のランタイムレイアウトの間で重みをマッピングするための[動的な重み読み込み](./weightconverter)。

> [!WARNING]
> Fusion mapping は実験的な読み込み機能です。ランタイムのモジュール構造を変更するため、モデルの動作に影響を与える可能性があります。明示的に融合されたランタイムレイアウトを使用したい場合にのみ使用してください。

## クイックスタート

[from_pretrained()](/docs/transformers/main/ja/main_classes/model#transformers.PreTrainedModel.from_pretrained) の `fusion_config` を使用して、Fusion を有効にできます。

```python
from transformers import AutoModelForImageTextToText

model = AutoModelForImageTextToText.from_pretrained(
    "Qwen/Qwen2-VL-2B-Instruct",
    fusion_config={"patch_embeddings": True},
)
```

デフォルトでは、フュージョンは適用されません。`fusion_config`がモデルのconfigに保存されている場合、`from_pretrained()`はそれを自動的に再利用します。

## 仕組み

Fusionの登録は、モデルがインスタンス化される前に実行されます:

1. [from_pretrained()](/docs/transformers/main/ja/main_classes/model#transformers.PreTrainedModel.from_pretrained) は明示的な `fusion_config` 引数を使用するか、`config.fusion_config` にフォールバックします。
2. フュージョンレジストリは、要求されたフュージョン名を検証します。
3. 各有効化されたfusionは、ターゲットのモデルクラスをメタ初期化し、必要に応じてモジュール名で候補モジュールをフィルタリングし、`is_fusable(...)`を使用して互換性のあるモジュールクラスを検出します。
4. Fused replacement classes are registered through [register_patch_mapping()](/docs/transformers/main/ja/monkey_patching#transformers.monkey_patching.register_patch_mapping).
5. 設定から`~WeightTransform`ルールが生成されるため、チェックポイントの読み込み時に、重みを融合ランタイムのレイアウトにマッピングできます。
6. デフォルトでは、[save_pretrained()](/docs/transformers/main/ja/main_classes/model#transformers.PreTrainedModel.save_pretrained)は逆変換パスを使用して元のチェックポイントのレイアウトを復元します。変換後のランタイムレイアウトを保持するには、`save_original_format=False`を渡します。

これにより、fusion は異なるランタイムモジュール構造を使用しながらも、元のチェックポイント形式から読み込み、デフォルトではその形式に保存することができます。

注: 現在のmonkey-patchingメカニズムでは、フュージョンの登録はクラスレベルです。1つの互換性のあるモジュールクラスが、1つのフュージョン済み代替クラスに対応します。

## 現在の融合ファミリー

現在、`fusion_config`は1つのフュージョンファミリーをサポートしています：

- `patch_embeddings` を有効にするには:

  ```python
  fusion_config = {"patch_embeddings": True}
  ```

  効果: 実行時に、互換性のある`nn.Conv3d`パッチ埋め込みの射影を、等価なフラット化された`nn.Linear`射置に置き換えます。

## フュージョンマッピングの拡張

新しい融合ファミリーを追加するには:

1. `is_fusable` 述語を追加します。これにより、発見されたモジュールがフュージョンと互換性があるかどうかを判定します。
2. 必要に応じて`target_modules_patterns`を追加します。これにより、`is_fusable(...)`の実行前に候補モジュール名を事前フィルタリングすることで、探索ステップがより明示的になります。
3. `make_fused_class` ファクトリを追加します。これは、互換性のあるモジュールクラスに対するランタイム置換クラスを返します。
4. 融合レイアウトにチェックポイントの変換が必要な場合は、`make_transforms` ファクトリを追加します。これは、指定された設定に対して、元のレイアウトと融合レイアウトの間で重みをマッピングする `~WeightTransform` ルールを返します。
5. `ModuleFusionSpec` の新しいものを [`fusion_mapping.py`](https://github.com/huggingface/transformers/blob/main/src/transformers/fusion_mapping.py) に登録します。

登録が完了すると、新しいフュージョンは`fusion_config`を通じて利用可能になります。

## 内部API[[transformers.fusion_mapping.ModuleFusionSpec]]

#### transformers.fusion_mapping.ModuleFusionSpec[[transformers.fusion_mapping.ModuleFusionSpec]]

```python
transformers.fusion_mapping.ModuleFusionSpec()
```

[ソース](https://github.com/huggingface/transformers/blob/main/src/transformers/fusion_mapping.py#L47)

フュージョンファミリーのベースレシピ。

fusion specは、どのモジュールが融合の対象となるか、ランタイム用の代替クラスをどのように構築するか、そして元のレイアウトと融合後のレイアウトの間でチェックポイントをマッピングするためにどの重みの変換が必要かを決定します。

#### get_empty_log[[transformers.fusion_mapping.ModuleFusionSpec.get_empty_log]]

```python
get_empty_log(model_name: str)
```

[ソース](https://github.com/huggingface/transformers/blob/main/src/transformers/fusion_mapping.py#L57)

互換性のあるモジュールが見つからない場合に出力されるログメッセージを返します。

#### is_fusable[[transformers.fusion_mapping.ModuleFusionSpec.is_fusable]]

```python
is_fusable(module: Module)
```

[ソース](https://github.com/huggingface/transformers/blob/main/src/transformers/fusion_mapping.py#L61)

`module`がこのフュージョンファミリーと互換性があるかどうかを返します。

#### make_fused_class[[transformers.fusion_mapping.ModuleFusionSpec.make_fused_class]]

```python
make_fused_class(original_cls: type)
```

[ソース](https://github.com/huggingface/transformers/blob/main/src/transformers/fusion_mapping.py#L65)

互換性のあるモジュールクラス用のランタイム置換クラスを構築します。

#### make_transforms[[transformers.fusion_mapping.ModuleFusionSpec.make_transforms]]

```python
make_transforms(config: PretrainedConfig)
```

[ソース](https://github.com/huggingface/transformers/blob/main/src/transformers/fusion_mapping.py#L69)

融合されたランタイムレイアウトを読み込み・保存するために必要な重みの変換を構築します。

#### transformers.fusion_mapping.PatchEmbeddingsFusionSpec[[transformers.fusion_mapping.PatchEmbeddingsFusionSpec]]

```python
transformers.fusion_mapping.PatchEmbeddingsFusionSpec()
```

[ソース](https://github.com/huggingface/transformers/blob/main/src/transformers/fusion_mapping.py#L97)

互換性のある Conv3d パッチ埋め込みを、フラット化された Linear 射影に融合します。

#### transformers.fusion_mapping._register_module_fusion[[transformers.fusion_mapping._register_module_fusion]]

```python
transformers.fusion_mapping._register_module_fusion(config: PretrainedConfig, fusion_name: str, spec: ModuleFusionSpec)
```

[ソース](https://github.com/huggingface/transformers/blob/main/src/transformers/fusion_mapping.py#L193)

`cls`用の1つの融合ファミリーを登録します。

この関数は、fused loading で使用される2つのグローバルレジストリを更新します。
- モンキーパッチングのレジストリにより、互換性のあるモジュールクラスが初期化前に置き換えられます
- チェックポイント変換のマッピングにより、融合されたランタイムモジュールは元のチェックポイントのレイアウトから引き続き読み込まれます

注:
- 競合するチェックポイント変換は早期に失敗します

#### transformers.fusion_mapping.register_fusion_patches[[transformers.fusion_mapping.register_fusion_patches]]

```python
transformers.fusion_mapping.register_fusion_patches(config, fusion_config: collections.abc.Mapping[str, bool | collections.abc.Mapping[str, typing.Any]] | None = None)
```

[ソース](https://github.com/huggingface/transformers/blob/main/src/transformers/fusion_mapping.py#L269)

`cls` に対して要求されたランタイム融合を登録します。

この関数は:
- `fusion_config` を `_FUSION_REGISTRY` に対して検証します
- ユーザーの指定した順序で、有効化された融合ファミリーを解決します
- モデルのインスタンス化の前に、モンキーパッチとチェックポイント変換を登録します

