# ユーティリティのインポート

このページでは、`transformers`のユーティリティを通じて、オブジェクトの遅延かつ高速なインポートを可能にする仕組みについて説明します。最小限の依存関係を維持することを目標としていますが、一部のモデルには回避できない特定の依存関係の要件があります。そのため、`transformers`のすべてのユーザーが他のモデルを使用するためにこれらの依存関係をインストールする必要がないよう、それらをハードな依存関係ではなくソフトな依存関係としてマークしています。

Transformers ツールキットは、特定の依存関係を持つモデルのインポート時にエラーを発生させるようには設計されていません。代わりに、必要な依存関係が不足しているオブジェクトに対して、そのオブジェクトのメソッドを呼び出した際にエラーが発生します。例えば、`torchvision`がインストールされていない場合、高速な画像プロセッサは利用できません。

このオブジェクトは引き続きインポート可能です:

```python
>>> from transformers import DetrImageProcessor
>>> print(DetrImageProcessor)
<class 'transformers.models.detr.image_processing_detr.DetrImageProcessor'>
```

ただし、そのオブジェクトのメソッドは、呼び出された際にオプションの依存関係を確認します。例えば、`torchvision` が利用できない場合、この呼び出しは`ImportError`を発生させます。

```python
>>> DetrImageProcessor.from_pretrained("facebook/detr-resnet-50")
ImportError:
DetrImageProcessor requires the Torchvision library but it was not found in your environment. Check out the instructions on the
installation page: https://pytorch.org/get-started/locally/ and follow the ones that match your environment.
Please note that you may need to restart your runtime after installation.
```

特定のオブジェクトの依存関係を指定する方法を見てみましょう。

## オブジェクトの依存関係の指定

### ファイル名ベース

特定のファイル名配下のすべてのオブジェクトには、そのファイル名にリンクされたツールへの自動依存関係が設定されます。

**PyTorch**: `modeling_` で始まるすべてのファイルには、PyTorch への依存関係が自動的に付与されます

**Tokenizers**: `tokenization_` で始まり `_fast` で終わるすべてのファイルには、`tokenizers` が自動的な依存関係として含まれます

**Vision**: `image_processing_` で始まるすべてのファイルには、`vision` 依存関係グループへの自動依存関係が設定されます。執筆時点では、このグループには `pillow` 依存関係のみが含まれています。

**Vision + Torch + Torchvision**: `image_processing_` で始まり `_fast` で終わるすべてのファイルには、`vision`、`torch`、`torchvision` への自動依存関係があります。

これらの自動依存関係は、以下に詳述する明示的な依存関係の上に追加されます。

### 明示的なオブジェクト依存

`requires` というメソッドを追加し、特定のオブジェクトの依存関係を明示的に指定できるようにします。例えば、`Trainer` クラスには `torch` と `accelerate` という2つの必須依存関係があります。これらの必須依存関係を指定する方法は以下の通りです。

```python
from .utils.import_utils import requires

@requires(backends=("torch", "accelerate"))
class Trainer:
    ...
```

ここで追加できるバックエンドは、`import_utils.py` モジュールで利用可能なすべてのバックエンドです。

また、各バックエンドで特定のバージョンを指定できます。例えば、`Trainer`クラスでtorch>=2.6という要件を指定するには、次のようにします。

```python
from .utils.import_utils import requires

@requires(backends=("torch>=2.6", "accelerate"))
class Trainer:
    ...
```

以下の演算子を指定できます: `==`、`>`、`>=`、`<`、`<=`、`!=`。

## メソッド[[transformers.utils.import_utils.define_import_structure]]

#### transformers.utils.import_utils.define_import_structure[[transformers.utils.import_utils.define_import_structure]]

```python
transformers.utils.import_utils.define_import_structure(module_path: str, prefix: str | None = None)
```

このメソッドは、module_pathを入力として受け取り、_LazyModuleが処理可能なインポート構造を作成します。

src.transformers.models レベルでの出力インポート構造の例を以下に示します。

{ frozenset({'tokenizers'}): { 'albert.tokenization_albert_fast': {'AlbertTokenizer'} }, frozenset(): { 'albert.configuration_albert': {'AlbertConfig'}, 'align.processing_align': {'AlignProcessor'}, 'align.configuration_align': {'AlignConfig', 'AlignTextConfig', 'AlignVisionConfig'}, 'altclip.configuration_altclip': {'AltCLIPConfig', 'AltCLIPTextConfig', 'AltCLIPVisionConfig'}, 'altclip.processing_altclip': {'AltCLIPProcessor'} } }

インポート構造は、キーが frozenset で、値が文字列からオブジェクトのセットへの dict で定義された dict です。

`prefix`がNoneでない場合、返されるdictのすべてのキーにそのプレフィックスが追加されます。

#### transformers.utils.import_utils.requires[[transformers.utils.import_utils.requires]]

```python
transformers.utils.import_utils.requires(backends = ())
```

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

このデコレーターは、2つのことを可能にします。
- オブジェクトに`__backends`タプルを付与し、インスタンス化せずに正しく実行するために必要なバックエンドを確認します
- '@requires' 文字列は、オブジェクトを動的にインポートするために使用されます

#### transformers.requires_backends[[transformers.requires_backends]]

```python
transformers.requires_backends(obj, backends)
```

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

**パラメータ:**

obj : 確認対象のオブジェクト

backends : 確認するバックエンドのリストまたはタプル。

指定されたバックエンドが利用できない場合に自動的に例外を送出するメソッドです。クラス内で頻繁に使用されます

必要な依存関係がインストールされていることを確認するための初期化:

```py
requires_backends(self, ["torch"])
```

バックエンドは、`transformers.utils.import_utils` で定義されている `BACKEND_MAPPING` に定義される必要があります。

