HuggingFace Transformers 4.17 : ガイド : カスタムモデルの作成 (翻訳/解説)
翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 04/23/2022 (v4.17.0)
* 本ページは、HuggingFace Transformers の以下のドキュメントを翻訳した上で適宜、補足説明したものです:
* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。
- 人工知能研究開発支援
- 人工知能研修サービス(経営者層向けオンサイト研修)
- テクニカルコンサルティングサービス
- 実証実験(プロトタイプ構築)
- アプリケーションへの実装
- 人工知能研修サービス
- PoC(概念実証)を失敗させないための支援
- お住まいの地域に関係なく Web ブラウザからご参加頂けます。事前登録 が必要ですのでご注意ください。
◆ お問合せ : 本件に関するお問い合わせ先は下記までお願いいたします。
- 株式会社クラスキャット セールス・マーケティング本部 セールス・インフォメーション
- sales-info@classcat.com ; Web: www.classcat.com ; ClassCatJP
HuggingFace Transformers : ガイド : カスタムモデルの作成
AutoClass は自動的にモデルアーキテクチャを推測して事前訓練済み configuration と重みをダウンロードします。一般には、チェックポイント不可知なコードを作成するためには AutoClass を使用することを勧めます。しかし特定のパラメータに対してより制御を望むユーザは幾つかの基底クラスからカスタム Transformers モデルを作成することができます。これは
Transformers モデルで研究、訓練あるいは実験をすることに関心がある人に対して特に役立てるでしょう。このガイドでは、AutoClass なしでカスタムモデルを作成することを深く掘り下げます。以下の方法を学習します :
- モデル configuration をロードしてカスタマイズする。
- モデル・アーキテクチャを作成する。
- テキストのための slow と fast なトークナイザーを作成する。
- 音声または画像タスクのための特徴抽出器を作成する。
- マルチモーダル・タスクのためのプロセッサを作成する。
Configuration
configuration はモデルの特定の属性を参照します。各モデル configuration は様々な属性を持ちます ; 例えば、総ての NLP モデルは hidden_size, num_attention_heads, num_hidden_layers と vocab_size を共通に持ちます。これらの属性はそれでモデルを構築するための attention ヘッドや隠れ層の数を指定します。
その属性を調べるために DistilBertConfig にアクセスすることにより DistilBERT を詳しく見ます。
from transformers import DistilBertConfig
config = DistilBertConfig()
print(config)
DistilBertConfig { "activation": "gelu", "attention_dropout": 0.1, "dim": 768, "dropout": 0.1, "hidden_dim": 3072, "initializer_range": 0.02, "max_position_embeddings": 512, "model_type": "distilbert", "n_heads": 12, "n_layers": 6, "pad_token_id": 0, "qa_dropout": 0.1, "seq_classif_dropout": 0.2, "sinusoidal_pos_embds": false, "transformers_version": "4.16.2", "vocab_size": 30522 }
DistilBertConfig はベース DistilBertModel を構築するために使用される総てのデフォルト属性を表示します。総ての属性はカスタマイズ可能で、実験のための空間を作成します。例えば、デフォルトモデルを次のようにカスタマイズできます :
- activation パラメータで異なる活性化関数を試す。
- attention_dropout パラメータで attentioin 確率のより高い dropout 率を使用する。
my_config = DistilBertConfig(activation="relu", attention_dropout=0.4)
print(my_config)
DistilBertConfig { "activation": "relu", "attention_dropout": 0.4, "dim": 768, "dropout": 0.1, "hidden_dim": 3072, "initializer_range": 0.02, "max_position_embeddings": 512, "model_type": "distilbert", "n_heads": 12, "n_layers": 6, "pad_token_id": 0, "qa_dropout": 0.1, "seq_classif_dropout": 0.2, "sinusoidal_pos_embds": false, "transformers_version": "4.16.2", "vocab_size": 30522 }
事前訓練済みモデルの属性は from_pretrained() 関数で変更できます :
my_config = DistilBertConfig.from_pretrained("distilbert-base-uncased", activation="relu", attention_dropout=0.4)
貴方のモデル configuration に満足すれば、それを save_pretrained() でセーブできます。configuration ファイルは指定された save directory に JSON ファイルとしてストアされます :
my_config.save_pretrained(save_directory="./your_model_save_path")
configuration ファイルを再利用するには、それを from_pretrained() でロードします :
my_config = DistilBertConfig.from_pretrained("./your_model_save_path/my_config.json")
Note : configuration ファイルを辞書として、あるいはカスタム configuration 属性とデフォルト configuration 属性の間の差分だけをセーブすることもできます!詳細は configuration ドキュメントを見てください。
モデル
次のステップは モデル を作成することです。モデル – 緩くアーキテクチャとしても参照されます – は各層が何をするか、どんな演算が発生するかを定義しています。configuration からの num_hidden_layers のような属性はアーキテクチャを定義するために使用されます。総てのモデルは基底クラス PreTrainedModel と入力埋め込みのリサイズと self-attention ヘッドの pruning のような幾つかの共通のメソッドを共有します。更に、総てのモデルはまた torch.nn.Module, tf.keras.Model or flax.linen.Module サブクラスのいずれかです。これは、モデルがそれぞれのフレームワークの使用方法と互換であることを意味します。
貴方のカスタム configuration 属性をモデルにロードします :
from transformers import DistilBertModel
my_config = DistilBertConfig.from_pretrained("./your_model_save_path/my_config.json")
model = DistilBertModel(my_config)
from transformers import TFDistilBertModel
my_config = DistilBertConfig.from_pretrained("./your_model_save_path/my_config.json")
tf_model = TFDistilBertModel(my_config)
これは事前訓練済み重みの代わりにランダム値でモデルを作成します。それを訓練するまで、このモデルは何か有用なことのためには利用できません。訓練はコストも時間もかかるプロセスです。訓練に必要なリソースのほんの一部だけを使用しながら、より良い結果を素早く得るためには事前訓練済みモデルを利用するのが一般にベターです。
from_pretrained() で事前訓練済みモデルを作成します :
model = DistilBertModel.from_pretrained("distilbert-base-uncased")
tf_model = TFDistilBertModel.from_pretrained("distilbert-base-uncased")
事前訓練済み重みをロードするとき、モデルが Transformers により提供される場合、デフォルトのモデル configuration が自動的にロードされます。けれども、必要であればデフォルトのモデル configuration 属性の一部または総てを貴方自身のもので置き換えることが依然としてできます :
model = DistilBertModel.from_pretrained("distilbert-base-uncased", config=my_config)
tf_model = TFDistilBertModel.from_pretrained("distilbert-base-uncased", config=my_config)
モデルヘッド
この時点で、隠れ状態を出力するベース DistilBERT モデルを持ちます。隠れ状態は、最終的な出力を生成するためにモデルヘッドへの入力として渡されます。 Transformers は、モデルがタスクをサポートする限りは、各タスクに対する異なるモデルヘッドを提供します (i.e. DistilBERT を翻訳のような sequence-to-sequence のためには使用できません)。
例えば、DistilBertForSequenceClassification はシークエンス分類ヘッドを持つベース DistilBERT モデルです。シークエンス分類ヘッドはプーリングされた出力の上の線形層です。
from transformers import DistilBertForSequenceClassification
model = DistilBertForSequenceClassification.from_pretrained("distilbert-base-uncased")
from transformers import TFDistilBertForSequenceClassification
tf_model = TFDistilBertForSequenceClassification.from_pretrained("distilbert-base-uncased")
別のモデルヘッドに切り替えることにより別のタスクのためにこのチェックポイントを容易に再利用できます。質問応答タスクのためには、DistilBertForQuestionAnswering モデルヘッドを利用できるでしょう。質問応答ヘッドは、それが隠れ状態出力の上の線形層であることを除けば、シークエンス分類ヘッドに類似しています。
from transformers import DistilBertForQuestionAnswering
model = DistilBertForQuestionAnswering.from_pretrained("distilbert-base-uncased")
from transformers import TFDistilBertForQuestionAnswering
tf_model = TFDistilBertForQuestionAnswering.from_pretrained("distilbert-base-uncased")
トークナイザー
テキストデータに対してモデルを使用する前に必要な最後のベースクラスは、raw テキストをテンソルに変換する トークナイザー です。 Transformers で使用できる 2 つのタイプのトークナイザーがあります。
- PreTrainedTokenizer : トークナイザーの Python 実装。
- PreTrainedTokenizerFast : Rust ベースの
Tokenizer ライブラリからのトークナイザー。このトークナイザー型はその Rust 実装により、特にバッチトークン化のときに非常に高速です。高速トークナイザーはまた、トークンをその元の単語や文字にマップする、オフセットマッピングのような追加のメソッドも提供します。
トークナイザーは両方ともエンコードとデコード, 新しいトークンの追加, そして特殊トークンの管理のような共通メソッドをサポートしています。
Note : 総てのモデルが高速トークナイザーをサポートはしているわけではありません。モデルが高速トークナイザーのサポートを持つか確認するにはこの テーブル を見てください。
貴方自身のトークナイザーを訓練した場合、貴方の語彙ファイルから作成できます :
from transformers import DistilBertTokenizer
my_tokenizer = DistilBertTokenizer(vocab_file="my_vocab_file.txt", do_lower_case=False, padding_side="left")
カスタム・トークナイザーの語彙は、事前訓練済みモデルのトークナイザーにより生成された語彙とは異なることを覚えておくことは重要です。事前訓練済みモデルを使用している場合、事前訓練済みモデルの語彙を使用する必要があります、そうでなければ入力は意味を持ちません。DistilBertTokenizer で事前訓練済みモデルの語彙を持つトークンナイザーを作成します :
from transformers import DistilBertTokenizer
slow_tokenizer = DistilBertTokenizer.from_pretrained("distilbert-base-uncased")
DistilBertTokenizerFast クラスで高速トークナイザーを作成します :
from transformers import DistilBertTokenizerFast
fast_tokenizer = DistilBertTokenizerFast.from_pretrained("distilbert-base-uncased")
Note : デフォルトでは、AutoTokenizer は高速トークナイザーをロードしようとします。from_pretrained で use_fast=False を設定することによりこの動作を無効にできます。
特徴抽出器
特徴抽出器は音声や画像入力を処理します。それは基底 FeatureExtractionMixin クラスを継承し、そしてまた画像特徴を処理するためには ImageFeatureExtractionMixin クラスを、あるいは音声入力を処理するためには SequenceFeatureExtractor を継承しても良いです。
音声かビジョンタスクで作業しているかに依存して、使用しているモデルに関連する特徴抽出器を作成します。例えば、画像分類のために ViT を使用している場合、デフォルトの ViTFeatureExtractor を作成します。
from transformers import ViTFeatureExtractor
vit_extractor = ViTFeatureExtractor()
print(vit_extractor)
ViTFeatureExtractor { "do_normalize": true, "do_resize": true, "feature_extractor_type": "ViTFeatureExtractor", "image_mean": [ 0.5, 0.5, 0.5 ], "image_std": [ 0.5, 0.5, 0.5 ], "resample": 2, "size": 224 }
Note : カスタマイズを求めていないのであれば、モデルのデフォルトの特徴抽出器のパラメータをロードするために単に from_pretrained メソッドを使用してください。
カスタム特徴抽出器を作成するために任意の ViTFeatureExtractor パラメータを変更できます :
from transformers import ViTFeatureExtractor
my_vit_extractor = ViTFeatureExtractor(resample="PIL.Image.BOX", do_normalize=False, image_mean=[0.3, 0.3, 0.3])
print(my_vit_extractor)
ViTFeatureExtractor { "do_normalize": false, "do_resize": true, "feature_extractor_type": "ViTFeatureExtractor", "image_mean": [ 0.3, 0.3, 0.3 ], "image_std": [ 0.5, 0.5, 0.5 ], "resample": "PIL.Image.BOX", "size": 224 }
音声入力に対しては、Wav2Vec2FeatureExtractor を作成して同様にパラメータをカスタマイズできます :
from transformers import Wav2Vec2FeatureExtractor
w2v2_extractor = Wav2Vec2FeatureExtractor()
print(w2v2_extractor)
Wav2Vec2FeatureExtractor { "do_normalize": true, "feature_extractor_type": "Wav2Vec2FeatureExtractor", "feature_size": 1, "padding_side": "right", "padding_value": 0.0, "return_attention_mask": false, "sampling_rate": 16000 }
プロセッサ
マルチモーダル・タスクをサポートするモデルについては、 Transformers は特徴抽出器とトークナイザーを単一オブジェクトに便利にラップするプロセッサクラスを提供しています。例えば、自動発話認識タスク (ASR) のための Wav2Vec2Processor を使用しましょう。ASR は音声をテキストに文字起こししますので、特徴抽出器とトークンナイザーを必要とします。
音声入力を処理する特徴抽出器を作成します :
from transformers import Wav2Vec2FeatureExtractor
feature_extractor = Wav2Vec2FeatureExtractor(padding_value=1.0, do_normalize=True)
テキスト入力を処理するトークナイザーを作成する :
from transformers import Wav2Vec2CTCTokenizer
tokenizer = Wav2Vec2CTCTokenizer(vocab_file="my_vocab_file.txt")
Wav2Vec2Processor に特徴抽出器とトークナイザーを結合します :
from transformers import Wav2Vec2Processor
processor = Wav2Vec2Processor(feature_extractor=feature_extractor, tokenizer=tokenizer)
2 つの基本クラス – configuration とモデル – と追加の前処理クラスで、 Transformers によりサポートされる任意のモデルを作成できます。これらの基底クラスの各々は configurable で、望む特定の属性を使用することを可能にします。訓練のためにモデルを簡単にセットアップしたり、再調整するために既存の事前訓練済みモデルを変更できます。
以上