mcpField
S
shunk031-python-transformers-convert

shunk031-python-transformers-convert

github.com/shunk031開発058 回インストール1 週間前に更新
リポジトリ

shunk031-python-transformers-convert について

カスタム PyTorch モデルを Hugging Face Transformers 形式に変換するスキルです。実装、元モデルとの同等性検証、Hub への公開準備を支援します。

主な機能

  1. 01モデル値の設定への抽出
  2. 02モデルとプロセッサークラスの作成
  3. 03元モデルとの互換性テスト
  4. 04モデルカードと Hub 公開の準備

活用シーン

  1. 01カスタム画像・テキストモデルの移植
  2. 02置き換え前の出力同等性の検証
  3. 03Hub 公開用の変換モデルのパッケージ化

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/shunk031/skills --skill shunk031-python-transformers-convert

インストール後、Claude Code で/shunk031-python-transformers-convertを入力して読み込まれたか確認します。

同梱ファイルreferences/common-pitfalls.mdreferences/learnings.md

詳細

メモ

この SKILL.md を読んだ後、🤗 I read shunk031-python-transformers-convert. と言ってください。

Hugging Face Transformers モデル変換

カスタム PyTorch モデルを、元の実装との完全な互換性を維持しながら Hugging Face Transformers 形式に変換します。

概要

このスキルでは、Transformers への変換を体系的に進めるワークフローを提供します。

  • ハードコードされた値を PretrainedConfig に抽出する
  • PreTrainedModel ラッパーを作成する
  • ImageProcessor/Tokenizer を構築する
  • 同等性を徹底的にテストする
  • Hub へのアップロードに備える

重要:まず検証モード(並行実装)を使用して同等性を確認してから、元の実装を置き換えてください。

変換ワークフロー

ステップ 1:カスタムモデルを分析する

ユーザーに次の項目を指定してもらいます。

  • カスタムモデルの実装パス
  • モデルの種類(ビジョン、テキスト、マルチモーダル)
  • タスク(分類、セグメンテーション、生成など)
  • 検証モードまたは置換モード

次に、以下を特定します。

  • モデルのアーキテクチャとコンポーネント
  • 入力/出力の形式
  • 主要なハイパーパラメーターとハードコードされた値
  • 事前学習済みの重みの場所
  • 前処理パイプライン
  • カスタムレイヤーまたはモジュール
ステップ 2:PretrainedConfig クラスを作成する

重要な原則:モデル内のハードコードされた値をすべて、設定可能なパラメーターとして抽出します。

テンプレート:

from transformers import PretrainedConfig
from typing import List, Optional

class {ModelName}Config(PretrainedConfig):
    model_type = "{model_name}"

    def __init__(
        self,
        # Core architecture parameters
        hidden_dim: int = 128,
        num_layers: int = 4,

        # Input/output parameters
        image_size: int = 1024,
        num_channels: int = 3,
        num_labels: int = 1,

        # Component-specific parameters (extract from original)
        component_param: List[int] | None = None,

        **kwargs,
    ):
        super().__init__(**kwargs)

        self.hidden_dim = hidden_dim
        self.num_layers = num_layers
        self.image_size = image_size
        self.num_channels = num_channels
        self.num_labels = num_labels

        # Use default if not specified
        self.component_param = (
            component_param if component_param is not None else [1, 2, 4]
        )

重要:デフォルト値が事前学習済みの重みで想定されている値と一致していることを確認してください。

ステップ 3:PreTrainedModel クラスを作成する

テンプレート:

from transformers import PreTrainedModel
from transformers.modeling_outputs import SemanticSegmenterOutput

class {ModelName}ForTask(PreTrainedModel):
    config_class = {ModelName}Config

    def __init__(self, config: {ModelName}Config):
        super().__init__(config)
        self.config = config

        # Initialize layers using config parameters (no hardcoded values!)
        self.encoder = Encoder(
            hidden_dim=config.hidden_dim,
            num_layers=config.num_layers,
        )

    def forward(
        self,
        pixel_values: torch.FloatTensor,
        labels: Optional[torch.LongTensor] = None,
        output_hidden_states: Optional[bool] = None,
        return_dict: Optional[bool] = None,
    ) -> Union[Tuple, SemanticSegmenterOutput]:
        return_dict = return_dict if return_dict is not None else self.config.use_return_dict

        # Forward pass
        logits = self.encoder(pixel_values)

        # Calculate loss if needed
        loss = None
        if labels is not None:
            # Compute loss
            pass

        if not return_dict:
            output = (logits,)
            return ((loss,) + output) if loss is not None else output

        return SemanticSegmenterOutput(
            loss=loss,
            logits=logits,
            hidden_states=None,
            attentions=None,
        )
ステップ 4:ImageProcessor/Tokenizer を作成する

ビジョンモデルの場合 — ImageProcessor を作成します。

from transformers import BaseImageProcessor

class {ModelName}ImageProcessor(BaseImageProcessor):
    model_input_names = ["pixel_values"]

    def __init__(
        self,
        size: int = 1024,
        resample: str = "bilinear",
        do_normalize: bool = True,
        image_mean: List[float] | None = None,
        image_std: List[float] | None = None,
        **kwargs,
    ):
        super().__init__(**kwargs)
        self.size = size
        self.resample = resample
        self.do_normalize = do_normalize
        self.image_mean = image_mean if image_mean is not None else [0.485, 0.456, 0.406]
        self.image_std = image_std if image_std is not None else [0.229, 0.224, 0.225]

    def preprocess(
        self,
        images: ImageInput,
        return_tensors: Optional[Union[str, TensorType]] = None,
        **kwargs,
    ) -> BatchFeature:
        # Implement preprocessing matching original
        # Return BatchFeature with pixel_values

テキストモデルの場合 — トークナイザーの設定を作成します。

ステップ 5:互換性テストを作成する

重要:出力を比較する際は、両方のモデルで必ず同じ前処理済みテンソルを使用してください。

import pytest
import torch

def test_preprocessing_matches():
    """Test that preprocessing is equivalent."""
    old_tensor = old_preprocessing(image)
    new_tensor = processor(image, return_tensors="pt")["pixel_values"][0]
    assert torch.allclose(old_tensor, new_tensor, atol=1e-6)

def test_single_image_output_matches():
    """Test that model outputs match."""
    # Load models
    old_model = OldModel()
    new_model = NewModel(NewConfig())
    new_model.load_state_dict(old_model.state_dict())

    # Prepare SAME input
    preprocessed = preprocess(image)

    with torch.no_grad():
        old_output = old_model(preprocessed)
        new_output = new_model(pixel_values=preprocessed)

    # Use 0.5% tolerance for numerical differences
    assert torch.allclose(old_output, new_output.logits, atol=5e-3, rtol=1e-2)

def test_batch_output_matches():
    """Test batch processing."""
    # Test with batch of images

def test_state_dict_compatible():
    """Test that weights can be loaded."""
    new_model.load_state_dict(old_model.state_dict())
ステップ 6:MODEL_CARD.md を作成する

Hugging Face の標準に従って、包括的なモデルカードを作成します。次の項目を含めてください。

  • モデルの説明
  • 使用例
  • 学習の詳細
  • 評価指標
  • 引用情報

テンプレートについては、Hugging Face のモデルカードに関するドキュメントを参照してください。

ステップ 7:Hub へのプッシュスクリプトを作成する

重要:プッシュする前に、register_for_auto_class() でクラスを登録してください。

#!/usr/bin/env python3
from huggingface_hub import HfApi
from {module}.transformers import {ModelName}Config, {ModelName}ForTask, {ModelName}ImageProcessor

def main():
    # CRITICAL: Register for Auto* support
    {ModelName}Config.register_for_auto_class()
    {ModelName}ForTask.register_for_auto_class("AutoModel")
    {ModelName}ImageProcessor.register_for_auto_class("AutoImageProcessor")

    # Load original model
    original_model = OriginalModel()

    # Create transformers-compatible model
    config = {ModelName}Config()
    model = {ModelName}ForTask(config)
    model.load_state_dict(original_model.state_dict())

    # Save and push
    model.save_pretrained(local_dir)
    config.save_pretrained(local_dir)
    processor = {ModelName}ImageProcessor()
    processor.save_pretrained(local_dir)

    api = HfApi(token=token)
    api.create_repo(repo_id=repo_id, exist_ok=True)
    api.upload_folder(repo_id=repo_id, folder_path=local_dir)

実装方針

検証モード(最初に推奨)

並行実装を作成します。

{project}/
├── {module}/
│   ├── original_model.py           # Existing
│   └── transformers/               # NEW - for validation
│       ├── __init__.py
│       ├── configuration_{model}.py
│       ├── modeling_{model}.py
│       └── processing_{model}.py
└── tests/
    └── test_transformers_compatibility.py

ワークフロー:

  1. 元の実装と同じ階層に transformers/ パッケージを作成する
  2. 互換性テストを実行する
  3. 不一致があればデバッグする
  4. テストに合格したら → 置換に進む
置換モード(検証後)

同等性を確認したら、次のように進めます。

{project}/
└── {module}/
    ├── configuration_{model}.py    # Replaces original
    ├── modeling_{model}.py
    └── processing_{model}.py

ワークフロー:

  1. 元の実装を削除またはアーカイブする
  2. transformers/* ファイルを1つ上の階層に移動する
  3. すべてのインポートを更新する
  4. テストを更新する
  5. ドキュメントを更新する

よくある問題

詳しいトラブルシューティングについては、references/common-pitfalls.md を参照してください。

クイックリファレンス:

  • ハードコードされた値:一致するデフォルト値を設定して、config に抽出する
  • 前処理の不一致:まったく同じパイプラインとパラメーターを使用する
  • State dict のキー:レイヤー名を元の実装と一致させる
  • テストの許容誤差:数値の差異には 0.5% の許容誤差(5e-3)を使用する
  • デバイスの扱い:PreTrainedModel の self.device を使用する
  • 画像サイズの順序:post_process_semantic_segmentation() は (width, height) を想定する

デバッグ方針

出力が一致しない場合:

  1. 前処理で同一のテンソルが生成されることを確認する
  2. state dict が正しく読み込まれていることを確認する
  3. 各レイヤーを段階的に比較する
  4. デバイスの配置を確認する
  5. torch.manual_seed を使って決定性を確認する

詳しいデバッグ手順については、references/common-pitfalls.md を参照してください。

プロジェクトから得た知見

変換が完了したら、知見を references/learnings.md に追加してください。

各プロジェクトから知識を蓄積することで、同じミスを繰り返さないようにします。

チェックリスト

  • ステップ 1:モデルを分析する
    • アーキテクチャを特定する
    • ハイパーパラメーターを抽出する
    • 前処理を把握する
  • ステップ 2:設定クラスを作成する
    • すべてのハードコードされた値を設定に移す
    • デフォルト値を事前学習済み重みと一致させる
    • 型ヒントを追加する
  • ステップ 3:モデルクラスを作成する
    • PreTrainedModel を継承する
    • 設定パラメーターのみを使用する
    • forward のシグネチャを規約に合わせる
  • ステップ 4:プロセッサーを作成する
    • 前処理を元の実装と一致させる
    • 適切な形式で返す
  • ステップ 5:テストを作成する
    • 前処理テストに合格する
    • 単一画像テストに合格する
    • バッチテストに合格する
    • state dict テストに合格する
  • ステップ 6:MODEL_CARD.md を作成する
    • すべてのセクションを埋める
    • 使用例をテストする
    • 引用を含める
  • ステップ 7:プッシュスクリプトを作成する
    • register_for_auto_class() を呼び出す
    • スクリプトをローカルでテストする
    • Hub へのプッシュに成功する
  • クリーンアップ(置き換えを行う場合)
    • 元の実装を削除/アーカイブする
    • インポートを更新する
    • ドキュメントを更新する

コメント