# モジュラーなtransformersでモデルを追加する

Modular transformers は、[単一モデル、単一ファイル](https://huggingface.co/blog/transformers-design-philosophy)のポリシーとは対照的に、インポートと継承を許可することで、モデルを追加するために必要なコード量を削減します。モデルのコンポーネントをファイル間で繰り返す代わりに、モデルフォルダに *modular* ファイルを追加し、既存のクラスから継承します。

コンバーターは、モジュール化されたファイルからスタンドアロンファイルを生成します。ユーザーは、すでに慣れ親しんでいる単一ファイルのインターフェースをそのまま利用できます。

> [!NOTE]
> Modular transformersは、[レガシーなモデリングコード](./add_new_model)を置き換えることを目的としていません。既存のモデルをベースにしないモデルの場合は、`modeling.py`ファイルを手動で追加してください。同様に、類似のファイルからクリーンに継承できない設定、トークナイズ、またはプロセッシングのファイルにも、同じことが当てはまります。
>
> 唯一の正しい順序というものもありません。一部のコントリビューターはまずモジュラーファイルを作成し、そこから生成します。他のコントリビューターは手書きの`modeling.py`から始め、後でモジュラーファイルにリファクタリングします。どちらのアプローチでも機能します。

## モジュール化されたファイルの実装

まずは、Transformers で自分のモデルに似たものを探してください。[Mistral](./model_doc/mistral)、[Qwen2](./model_doc/qwen2)、[Cohere](./model_doc/cohere)、[Cohere2](./model_doc/cohere2)、[Llama](./model_doc/llama) が良い出発点です。以下の表は、一般的なコンポーネントを継承できるモデルに対応付けしています。

| コンポーネント | モデル |
|---|---|
| エキスパートの混合 | MixtralまたはQwen2-MoE |
| インターリーブ(および/または部分的)ローテーション埋め込み | GLM、Phi |
| 状態空間モデル | Jamba、Bamba、Zamba、Mamba2 |
| 再帰的隠れ状態 | Gemma2 |
| レイヤーごとのスライディングウィンドウアテンション/フルアテンションパターン | Gemma2、Cohere2 |
| QKVクリッピング | Olmo |
| QK正規化 | Olmo2、Cohere |
| Fused QKV（非推奨） | Phi3 |

> [!TIP]
> [modular-detector-v2](https://huggingface.co/spaces/Molbap/modular-detector-v2)ツールを使用して、継承元の既存実装を探します。コードスニペットを貼り付けると、Transformers内で最も類似したメソッドが返されるため、コーディングを開始する前に最適な親クラスを特定できます。

新しいモデルのために継承を機能させるという理由だけで、既存のモデルを変更しないでください。親クラスの名前変更やサブクラス化が不自然に感じる場合は、関連するコードを直接コピーする方が適切です。

`src/transformers/models/<name>/modular_<name>.py` を作成します。ここで `<name>` は、snake_case のモデルディレクトリ名と一致する必要があります。このセクションでは、モジュラーアプローチを用いて [Olmo](./model_doc/olmo) から [Olmo2](./model_doc/olmo2) を実装する方法を説明します（元の [modular_olmo2.py](https://github.com/huggingface/transformers/blob/main/src/transformers/models/olmo2/modular_olmo2.py) ファイルを参照してください）。

### 設定

[Olmo2Config](/docs/transformers/main/ja/model_doc/olmo2#transformers.Olmo2Config)と[OlmoConfig](/docs/transformers/main/ja/model_doc/olmo#transformers.OlmoConfig)には、2つの点で違いがあります。

1. 新しい引数 `rms_norm_eps` が追加されました。
2. `clip_qkv` 引数はもはや使用されません。

新しい引数は、デフォルト値を持つクラスレベルの型アノテーションとして宣言します。削除する引数については、生成されるファイル内で継承された属性を抑制するために、`AttributeError()`を代入します（[属性の削除](#removing-attributes)を参照）。

```diff
- @auto_docstring(checkpoint="allenai/OLMo-7B-hf")
+ @auto_docstring(checkpoint="allenai/Olmo2-7B-1124-hf")
+ @strict
- class OlmoConfig(PreTrainedConfig):
+ class Olmo2Config(OlmoConfig):
      ...
-     model_type = "olmo"
+     model_type = "olmo2"
      ...
+     rms_norm_eps: float = 1e-5
-     clip_qkv: float | None = None
+     clip_qkv = AttributeError()
```

`@auto_docstring` は標準的な引数のドキュメントを自動生成します（[@auto_docstring](./auto_docstring) ガイドを参照）。`@strict` はインスタンス化時に未知の kwargs を拒否し、タイポや古い引数を早期に検出します。デコレーターは親クラスから継承されないため、すべての設定クラスに両方を追加してください。親の設定クラスに既にこれらが存在する場合でも、明示的に宣言してください。

派生属性を設定したり、後方互換性のロジックを処理したりする場合は、`__init__` の代わりに `__post_init__` を使用します。例えば、Cohere2 は初期化時に `head_dim` を計算し、`layer_types` を導出します。

```py
def __post_init__(self, **kwargs):
    if self.num_key_value_heads is None:
        self.num_key_value_heads = self.num_attention_heads
    self.head_dim = self.hidden_size // self.num_attention_heads
    super().__post_init__(**kwargs)
```

テンソル並列またはパイプライン並列をサポートするモデルでは、`base_model_tp_plan` と `base_model_pp_plan` を config のクラスレベルの辞書として定義します。これらの辞書は、モデルをデバイス間でシャードする方法を定義します。例として、[Olmo2](https://github.com/huggingface/transformers/blob/main/src/transformers/models/olmo2/modular_olmo2.py) や [Cohere2](https://github.com/huggingface/transformers/blob/main/src/transformers/models/cohere2/modular_cohere2.py) などの既存の config を参照してください。

```py
class MyNewModelConfig(PreTrainedConfig):
    model_type = "my_new_model"

    # Tensor parallelism: maps layer name patterns to sharding strategies.
    # Use "colwise" / "rowwise" for standard sharding, or the "gather_output" /
    # "split_input" variants when an extra op (e.g. a QK norm) prevents fusing.
    base_model_tp_plan = {
        "layers.*.self_attn.q_proj": "colwise",
        "layers.*.self_attn.k_proj": "colwise",
        "layers.*.self_attn.v_proj": "colwise",
        "layers.*.self_attn.o_proj": "rowwise",
        "layers.*.mlp.gate_proj": "colwise",
        "layers.*.mlp.up_proj": "colwise",
        "layers.*.mlp.down_proj": "rowwise",
    }

    # Pipeline parallelism: maps submodule names to their (input, output) tensor names.
    base_model_pp_plan = {
        "embed_tokens": (["input_ids"], ["inputs_embeds"]),
        "layers": (["hidden_states", "attention_mask"], ["hidden_states"]),
        "norm": (["hidden_states"], ["hidden_states"]),
    }
```

### ノルム

変更を加えずに親クラスをコピーするには、`pass` を継承します。リンターは親クラスのコンテンツをコピーし、新しいモデルに合わせてすべての参照をリネームします。

```py
from ..olmo.modeling_olmo import OlmoRotaryEmbedding

class Olmo2RotaryEmbedding(OlmoRotaryEmbedding):
    pass
```

特定の動作を変更するには、異なる部分のみを継承してオーバーライドします。`Olmo2RMSNorm`は`LlamaRMSNorm`と1行だけ異なります。乗算は、入力dtypeへキャストし直す*前*に行われ、後に行われるわけではありません。

```diff
  from ..llama.modeling_llama import LlamaRMSNorm

  class Olmo2RMSNorm(LlamaRMSNorm):
      def forward(self, hidden_states):
          input_dtype = hidden_states.dtype
          hidden_states = hidden_states.to(torch.float32)
          variance = hidden_states.pow(2).mean(-1, keepdim=True)
          hidden_states = hidden_states * torch.rsqrt(variance + self.variance_epsilon)
-         return self.weight * hidden_states.to(input_dtype)
+         return (self.weight * hidden_states).to(input_dtype)
```

### アテンション

Olmo2のattentionはOlmoと同一ですが、クエリとキーに`RMSNorm`を適用し、qkvのクリッピングを削除しています。`super().__init__(...)`は親クラスの本体をコピーし、2つの新しいnorm行を追加します。`forward`は、クエリとキーがprojectionの前にnormを通過するようになったため、完全に再定義されています。リンターは、`apply_rotary_pos_emb`、`eager_attention_forward`およびそれらの依存関係を含む、インポートされた関数をすべて生成ファイルに引き込みます。

```diff
  class Olmo2Attention(OlmoAttention):
      def __init__(self, config: Olmo2Config, layer_idx: int | None = None):
          super().__init__(config, layer_idx=layer_idx)
+         self.q_norm = Olmo2RMSNorm(config.num_attention_heads * self.head_dim, config.rms_norm_eps)
+         self.k_norm = Olmo2RMSNorm(config.num_key_value_heads * self.head_dim, config.rms_norm_eps)

      def forward(self, ...):
          ...
-         query_states = self.q_proj(hidden_states)
-         key_states = self.k_proj(hidden_states)
+         query_states = self.q_norm(self.q_proj(hidden_states))
+         key_states = self.k_norm(self.k_proj(hidden_states))
          value_states = self.v_proj(hidden_states)

-         if self.config.clip_qkv is not None:
-             query_states.clamp_(min=-self.config.clip_qkv, max=self.config.clip_qkv)
-             key_states.clamp_(min=-self.config.clip_qkv, max=self.config.clip_qkv)
-             value_states.clamp_(min=-self.config.clip_qkv, max=self.config.clip_qkv)
-
          ...
```

### DecoderLayer

`super().__init__(...)` の後、norm 属性を `Olmo2RMSNorm` のインスタンスで上書きし、`self.self_attn` を新しい `Olmo2Attention` クラスに再代入します。`del self.input_layernorm` は、Olmo2 が attention の前ではなく *後* に norm を適用するため、親クラスの `input_layernorm` の代入を削除します。`del` が何を削除し、何を削除しないかについては、[属性の削除](#removing-attributes) を参照してください。

`forward` は、attention 後の norm の配置を反映するように書き換えられています。属性がリネームされる場合のみ `forward` の書き換えが必要であり、型だけが変更される場合は不要です。

```diff
  class Olmo2DecoderLayer(OlmoDecoderLayer):
      def __init__(self, config: Olmo2Config, layer_idx: int):
          super().__init__(config, layer_idx=layer_idx)
-         self.self_attn = OlmoAttention(config=config, layer_idx=layer_idx)
-         self.input_layernorm = OlmoLayerNorm(config.hidden_size)
-         self.post_attention_layernorm = OlmoLayerNorm(config.hidden_size)
+         self.self_attn = Olmo2Attention(config=config, layer_idx=layer_idx)
+         del self.input_layernorm
+         self.post_attention_layernorm = Olmo2RMSNorm(config.hidden_size, eps=config.rms_norm_eps)
+         self.post_feedforward_layernorm = Olmo2RMSNorm(config.hidden_size, eps=config.rms_norm_eps)

      def forward(self, ...):
          residual = hidden_states
-         hidden_states = self.input_layernorm(hidden_states)
          # Self Attention
          hidden_states, _ = self.self_attn(...)
-         hidden_states = residual + hidden_states
+         hidden_states = self.post_attention_layernorm(hidden_states)
+         hidden_states = residual + hidden_states

          # Fully Connected
          residual = hidden_states
-         hidden_states = self.post_attention_layernorm(hidden_states)
          hidden_states = self.mlp(hidden_states)
-         hidden_states = residual + hidden_states
+         hidden_states = self.post_feedforward_layernorm(hidden_states)
+         hidden_states = residual + hidden_states
          return hidden_states
```

### モデル

ここでは`self.norm`の型のみが変更されます。`forward`メソッドは親クラスと同一であるため、リンターが自動的に引き継ぎます。

```diff
  class Olmo2Model(OlmoModel):
      def __init__(self, config: Olmo2Config):
          super().__init__(config)
-         self.layers = nn.ModuleList(
-             [OlmoDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)]
-         )
-         self.norm = OlmoLayerNorm(config.hidden_size)
+         self.norm = Olmo2RMSNorm(config.hidden_size, eps=config.rms_norm_eps)
+         self.layers = nn.ModuleList(
+             [Olmo2DecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)]
+         )
```

### モデルヘッド

ロジックは[OlmoForCausalLM](/docs/transformers/main/ja/model_doc/olmo#transformers.OlmoForCausalLM)と同一であるため、変更は不要です。

```py
from ..olmo.modeling_olmo import OlmoForCausalLM

class Olmo2ForCausalLM(OlmoForCausalLM):
    pass
```

### その他のクラス

linter によって生成された [modeling_olmo2.py](https://github.com/huggingface/transformers/blob/main/src/transformers/models/olmo2/modeling_olmo2.py) には、`modular_olmo2.py` で明示的に定義されていないクラス（`Olmo2MLP`、`Olmo2RotaryEmbedding`、`Olmo2PreTrainedModel`）も含まれています。

linter は、明示的に再定義しない限り、継承クラスが依存するすべてのクラスを参照します。`apply_rotary_pos_emb` などのインポートされた関数も、同じルールに従います。

例えば、`OlmoDecoderLayer`には`self.mlp = OlmoMLP(config)`があります。`Olmo2MLP`はモジュラーファイル内で定義されていなかったため、リンターは`pass`を使用するのと同様に、これを自動的に作成します。

```py
from ..olmo.modeling_olmo import OlmoMLP

class Olmo2MLP(OlmoMLP):
    pass
```

`Olmo2MLP`が別のモデルを継承するようにしたい場合は、明示的に指定してください。

```py
# switch to Mistral definition
from ..mistral.modeling_mistral import MistralMLP

class Olmo2MLP(MistralMLP):
    pass
```

### ファイルの仕上げ

すべてのモジュールファイルでは、モジュールレベルで`logger`と`__all__`リストを宣言する必要があります。

```py
logger = logging.get_logger(__name__)

__all__ = [
    "Olmo2Config",
    "Olmo2ForCausalLM",
    "Olmo2Model",
    "Olmo2PreTrainedModel",
]
```

`__all__` には、ファイル内のすべての公開クラスを列挙する必要があります。コンバーターおよび下流のインポートがこれに依存しています。`__all__` に漏れているクラスは、正しくエクスポートされません。

## モデリングファイルの生成

`modular_model_converter.py` スクリプトは、モジュラーファイルから独立した `modeling.py`、`configuration.py` およびその他のファイルを生成します。継承された各クラスについて、親クラスの本体を子クラスにコピーし、すべての参照を新しいモデルに合わせて名前を変更し、これらの親クラスが依存するヘルパー関数やクラスを取り込みます。

出力ファイルには、モデル間のインポートや他のモデルディレクトリからの継承は含まれません。リンターは継承を1階層にフラット化します。`Olmo2Attention`が`OlmoAttention`を継承する場合、生成される`Olmo2Attention`は完全に自己完結型になります。ただし、`OlmoAttention`自体が別のものを継承していた場合、リンターはその祖クラスをインライン化しません。

以下のコマンドを実行して、モジュール化されたファイルからファイルを生成します。

```bash
python utils/modular_model_converter.py your_model
```

生成されたファイルを直接編集しないでください。次回の実行時に、すべての変更が上書きされるためです。

## モジュール化されたファイルのパターン

以下のセクションでは、モジュラーファイルで作業する際の一般的な使用パターン（属性の削除や、デコレータ付きメソッドのオーバーライドなど）について説明します。

### アトリビュートの削除

継承された属性を削除するかどうかは、`nn.Module`のサブクラスで作業しているのか、それともconfigクラスで作業しているのかによって異なります。

config クラスでは、クラスレベルで属性に `AttributeError()` を代入します。

```py
class MyNewConfig(ParentConfig):
    removed_attr = AttributeError()
```

linter は、生成された設定ファイルから属性の宣言を完全に削除します。設定クラスは `__init__` を持たない dataclass 形式のレイアウトを使用しているため、クラスレベルで `AttributeError()` を代入するのが正しいアプローチです。

`nn.Module` のサブクラスでは、`super().__init__(...)` の後に `del self.attribute` を使用します。

```py
class MyNewModel(ParentModel):
    def __init__(self, config: MyNewConfig):
        super().__init__(config)
        del self.attribute
```

`del self.attribute` は、コピーされた親クラスの本体から `self.attribute = ...` の代入行のみを削除します。`self.attribute` を参照する他の行は削除されません。親クラスの `forward` や他のメソッドもこの属性を参照している場合は、それらのメソッドもオーバーライドしてください。

```py
class DummyModel(nn.Module):
    def __init__(self, config: DummyConfig):
        super().__init__()
        self.attribute = config.attribute
        if self.attribute:
            # do more stuff with `self.attribute` here
            ...

class MyNewDummyModel(DummyModel):
    def __init__(self, config: MyNewDummyConfig):
        super().__init__(config)
        del self.attribute
        # 'self.attribute = config.attribute' is removed, but the 'if self.attribute:' block remains.
        # Override forward() or any other method that references self.attribute.
```

### `super()`の使い方

`super().__init__(config)` は、コンバーターに親の本体を子にコピーするよう指示します。この動作を上書きするには、2 つのパターンがあります。

- 生成された出力がモジュールの親クラスではなく、祖クラス（`nn.Module.__init__`）を呼び出す必要がある場合は、特定の親クラスを直接呼び出してください。
- `**super_kwargs` を使用すると、親メソッドの完全なシグネチャを継承しながら、カスタムのドキュメント文字列を追加したり、デコレーターを置き換えたりできます。

#### グランドパーセントクラスを直接呼び出す

Be explicit about which class you're calling when you need `super()` to target the generated class parent rather than the modular parent. The example below calls `nn.Module.__init__(self)` directly. `DummyModule` is itself an `nn.Module`, so the converter writes it as `super().__init__()` in the generated `MyNewDummyModule`.

```py
class MyNewDummyModule(DummyModule):                   |     class MyNewDummyModule(nn.Module):
                                                       |
  def __init__(self):                                  |       def __init__(self):
    nn.Module.__init__(self)                           |         super().__init__()
    self.foo = config.foo                              |         self.foo = config.foo
    ...                                                |         ...
```

#### super_kwargs

`**super_kwargs` を使用すると、親メソッドの完全なシグネチャを継承しつつ、カスタムのドキュメント文字列を追加したり、デコレーターを置き換えたりできます。オーバーライドされたシグネチャにおいて、この引数はリンターに、生成される出力で親のすべての引数を展開するよう指示します。

最も一般的な用途は、`labels`引数のドキュメント化など、モデル固有のdocstringを追加することであり、完全なシグネチャを書き直す必要はありません。

```py
# modular_gemma.py
class GemmaForCausalLM(LlamaForCausalLM):
    def forward(**super_kwargs):
        r"""
        Example:

        ```python
        >>> from transformers import AutoTokenizer, GemmaForCausalLM
        >>> model = GemmaForCausalLM.from_pretrained("google/gemma-7b")
        ...
        ```"""
        return super().forward(**super_kwargs)
```

生成された`GemmaForCausalLM.forward`には、手動でのコピーを必要としない完全な`LlamaForCausalLM`のシグネチャが含まれています。

`**super_kwargs` は、ニッチなケース向けのショートカットです。動作を変更する場合は、代わりに完全なシグネチャを記述してください。

### 未使用方法の削除

`raise AttributeError("")`ステートメントでオーバーライドすることにより、親クラスのメソッドを削除できます。リンターは、生成されたファイルからそのメソッドを削除します。

```py
class GemmaTokenizer(LlamaTokenizer):
    ...

    def get_spm_processor(self):
        raise AttributeError("Not needed for Gemma")

    def unk_token_length(self):
        raise AttributeError("Not needed for Gemma")
```

### デコレータ付きメソッドの上書き

装飾付きの親メソッドをオーバーライドする場合、親のデコレーターは自動的に引き継がれます。独自のデコレーターを追加すると、親のデコレーターを置き換えます。

このライブラリ全体では、[モデルの中間出力をキャプチャする](./model_output_tracing)ためのものと、[ドキュメント文字列を自動生成する](./auto_docstring)ためのもの、2つのデコレーターが登場します。

以下の例では、サブクラスがデコレータ付きの親クラスのメソッドをオーバーライドしていますが、独自のデコレータは追加していません。親クラスのデコレータが引き継がれます。

```py
class NewModel(DummyModel):       |   class NewModel(nn.Module):
  ...                             |     ...
                                  |
  def forward(...):               |     @decorator(...)
    ...                           |     def forward(...):
                                  |       ...
```

新しいデコレーターを追加すると、親のデコレーターが上書きされます。

```py
class NewModel(DummyModel):       |   class NewModel(nn.Module):
  ...                             |     ...
                                  |
  @my_new_decorator(...)          |     @my_new_decorator(...)
  def forward(...):               |     def forward(...):
    ...                           |       ...
```

### 特別な命名

linterは、クラスを継承する際に自動的にすべてをリネームします。同じファイル内のすべてのクラスで、同じクラス名のプレフィックスを使用してください。

以下の例のようにプレフィックスを混在させないでください。`MyModelIncredibleMLP` は命名規則に違反しており、上位の依存関係をリネームする際に、linter が `MyModelIncredible` を使うべきか `MyModel` を使うべきか判断できません。

```py
class MyModelIncredibleMLP(LlamaMLP):
    ...

class MyModelDecoderLayer(LlamaDecoderLayer):
    ...
```

[暗黙の依存関係](#other-classes)がないため、単一のクラスをローカルで名前変更できます。そのクラスへの他のすべての言及を、新しい名前パターンに合わせて明示的に再定義してください。そうしないと、リンターが`MyModelIncredibleMLP`の隣に不要な`MyModelMLP`クラスを追加してしまいます。

linterは、曖昧なプレフィックスを検出すると警告を出力します。

```text
We detected multiple prefix names when inheriting from transformers.models.llama.modeling_llama: ('Emu3Text', 'Emu3'). We will only use the most used 'Emu3' prefix when grabbing args and dependencies. Make sure to subclass the intermediate classes with the prefix you want (if different from 'Emu3') or use a single prefix in all the modular (best).
```

`Text` のようなモダリティ修飾子がクラス名に含まれるマルチモーダルモデルでは、曖昧なプレフィックスが最もよく見られます。依存関係に特定のプレフィックスを付与するには、`pass` を使用して明示的に名前を変更します。

```py
class Emu3TextMLP(LlamaMLP):
    pass
```

### 設定のドキュメント文字列

linterは、部分ドキュメント文字列の継承をまだサポートしていません。設定属性を追加または削除する場合は、クラス定義の下に、モジュラーファイル内で完全なドキュメント文字列を直接追加してください。

## チェックポイントの変換

モデルファイルの生成が完了したら、実際の重みが正しくロードされることを確認してください。アップストリームのチェックポイント形式をTransformers互換形式に変換するスクリプトを作成し、Hubに保存します。

### 変換スクリプトを作成する

`src/transformers/models/<model>/` に `convert_<model>_to_hf.py` ファイルを追加します。このスクリプトは、アップストリームの重みを読み込み、モジュールのパラメータ名に一致するようにキーの名前を変更し、形を変えたうえで、[save_pretrained()](/docs/transformers/main/ja/main_classes/model#transformers.PreTrainedModel.save_pretrained) を使用して結果を保存します。

> [!TIP]
> コピーして適応できる既存のスクリプトを探してください。`src/transformers/models/` 配下のモデルには、出発点として利用できる `convert_*_to_hf.py` が含まれています。

スクリプトの実行後、[from_pretrained()](/docs/transformers/main/ja/main_classes/model#transformers.PreTrainedModel.from_pretrained) で保存されたチェックポイントを読み込み、すべての期待される重みが正しく読み込まれたことを確認してください。未使用のチェックポイントキーは名前が一致していないことを示すため、問題を早期に検出するためにそれらを出力してください。

```py
model = YourModelForTask.from_pretrained("path/to/output/")
```

キーを反復処理する際、shapeとnameの一致を確認してください。shapeの不一致は、通常、config内のパラメータが誤っている、アーキテクチャがオリジナルと異なる、または重みを転置する必要があることを意味します。

```py
for key, tensor in original_state_dict.items():
    hf_tensor = hf_model.state_dict().get(mapped_key)
    assert hf_tensor.shape == tensor.shape, (
        f"Shape mismatch for {key}: expected {tensor.shape}, got {hf_tensor.shape}"
    )
```

モジュールファイル、生成されたモデリングファイル、変換スクリプトの間を反復して確認し、すべての重みが正常にロードされるまで問題を修正してください。

チェックポイントが正常に読み込まれたら、[push_to_hub()](/docs/transformers/main/ja/main_classes/model#transformers.utils.PushToHubMixin.push_to_hub) を使用して Hub にプッシュしてください。詳細については、[モデル共有](./model_sharing) ガイドを参照してください。

```py
model.push_to_hub("username/your-model-name")
```

### ランタイム変換マッピング

公開されている重みがモジュールのパラメータ構成と一致しない場合は、`src/transformers/conversion_mapping.py` にランタイムマッピングを追加してください。一般的なケースとしては、個別に保存されている融合された重みや、スタッキングが必要な MoE エキスパートテンソルなどが挙げられます。このマッピングにより、[from_pretrained()](/docs/transformers/main/ja/main_classes/model#transformers.PreTrainedModel.from_pretrained) が Hub のチェックポイントを、別途のエクスポート手順なしに読み込むようになります。

`WeightRenaming` と [WeightConverter](/docs/transformers/main/ja/internal/modeling_utils#transformers.WeightConverter) のルールを作成し、`model_type` に登録する方法については、[動的ウェイト読み込み](./weightconverter)ガイドを参照してください。

## 次のステップ

- [モデル構造のルール](./modeling_rules)は、すべての`modeling_*.py`、`modular_*.py`、`configuration_*.py`ファイルに適用される静的なルールです。PR を作成する前に、`make typing`を実行してこれらをチェックしてください。
- [ビジョン処理コンポーネントの追加](./add_vision_processing_components)では、マルチモーダルモデルに画像プロセッサ、動画プロセッサ、プロセッサを追加する手順を説明します。
- [ドキュメント文字列の自動生成](./auto_docstring)では、共有モデルAPIの引数ドキュメントを手動で記述する必要がないように、`@auto_docstring`の使用方法を示しています。
- [モデルのテストの作成](./testing)では、新しいモデルの統合テストを作成し、ローカルで実行する方法について説明します。
- [Pull request checks](./pr_checks) は、PR をマージする前にパスしなければならない CI チェック、およびそれらをローカルで再現・修正する方法を説明します。

