ホーム » 「HuggingFace Transformers 4.17」タグがついた投稿 (ページ 2)

タグアーカイブ: HuggingFace Transformers 4.17

HuggingFace Transformers 4.17 : ガイド : カスタムモデルの作成

HuggingFace Transformers 4.17 : ガイド : カスタムモデルの作成 (翻訳/解説)

翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 04/23/2022 (v4.17.0)

* 本ページは、HuggingFace Transformers の以下のドキュメントを翻訳した上で適宜、補足説明したものです:

* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。

 

クラスキャット 人工知能 研究開発支援サービス

クラスキャット は人工知能・テレワークに関する各種サービスを提供しています。お気軽にご相談ください :

◆ 人工知能とビジネスをテーマに WEB セミナーを定期的に開催しています。スケジュール
  • お住まいの地域に関係なく 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 属性をモデルにロードします :

PyTorch
from transformers import DistilBertModel

my_config = DistilBertConfig.from_pretrained("./your_model_save_path/my_config.json")
model = DistilBertModel(my_config)
TensorFlow
from transformers import TFDistilBertModel

my_config = DistilBertConfig.from_pretrained("./your_model_save_path/my_config.json")
tf_model = TFDistilBertModel(my_config)

これは事前訓練済み重みの代わりにランダム値でモデルを作成します。それを訓練するまで、このモデルは何か有用なことのためには利用できません。訓練はコストも時間もかかるプロセスです。訓練に必要なリソースのほんの一部だけを使用しながら、より良い結果を素早く得るためには事前訓練済みモデルを利用するのが一般にベターです。

from_pretrained() で事前訓練済みモデルを作成します :

PyTorch
model = DistilBertModel.from_pretrained("distilbert-base-uncased")
TensorFlow
tf_model = TFDistilBertModel.from_pretrained("distilbert-base-uncased")

事前訓練済み重みをロードするとき、モデルが Transformers により提供される場合、デフォルトのモデル configuration が自動的にロードされます。けれども、必要であればデフォルトのモデル configuration 属性の一部または総てを貴方自身のもので置き換えることが依然としてできます :

PyTorch
model = DistilBertModel.from_pretrained("distilbert-base-uncased", config=my_config)
TensorFlow
tf_model = TFDistilBertModel.from_pretrained("distilbert-base-uncased", config=my_config)

 

モデルヘッド

この時点で、隠れ状態を出力するベース DistilBERT モデルを持ちます。隠れ状態は、最終的な出力を生成するためにモデルヘッドへの入力として渡されます。 Transformers は、モデルがタスクをサポートする限りは、各タスクに対する異なるモデルヘッドを提供します (i.e. DistilBERT を翻訳のような sequence-to-sequence のためには使用できません)。

例えば、DistilBertForSequenceClassification はシークエンス分類ヘッドを持つベース DistilBERT モデルです。シークエンス分類ヘッドはプーリングされた出力の上の線形層です。

PyTorch
from transformers import DistilBertForSequenceClassification

model = DistilBertForSequenceClassification.from_pretrained("distilbert-base-uncased")
TensorFlow
from transformers import TFDistilBertForSequenceClassification

tf_model = TFDistilBertForSequenceClassification.from_pretrained("distilbert-base-uncased")

別のモデルヘッドに切り替えることにより別のタスクのためにこのチェックポイントを容易に再利用できます。質問応答タスクのためには、DistilBertForQuestionAnswering モデルヘッドを利用できるでしょう。質問応答ヘッドは、それが隠れ状態出力の上の線形層であることを除けば、シークエンス分類ヘッドに類似しています。

PyTorch
from transformers import DistilBertForQuestionAnswering

model = DistilBertForQuestionAnswering.from_pretrained("distilbert-base-uncased")
TensorFlow
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 で、望む特定の属性を使用することを可能にします。訓練のためにモデルを簡単にセットアップしたり、再調整するために既存の事前訓練済みモデルを変更できます。

 

以上



HuggingFace Transformers 4.17 : Tutorials : モデルの共有

HuggingFace Transformers 4.17 : Tutorials : モデルの共有 (翻訳/解説)

翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 04/22/2022 (v4.17.0)

* 本ページは、HuggingFace Transformers の以下のドキュメントを翻訳した上で適宜、補足説明したものです:

* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。

 

クラスキャット 人工知能 研究開発支援サービス

クラスキャット は人工知能・テレワークに関する各種サービスを提供しています。お気軽にご相談ください :

◆ 人工知能とビジネスをテーマに WEB セミナーを定期的に開催しています。スケジュール
  • お住まいの地域に関係なく Web ブラウザからご参加頂けます。事前登録 が必要ですのでご注意ください。

お問合せ : 本件に関するお問い合わせ先は下記までお願いいたします。

  • 株式会社クラスキャット セールス・マーケティング本部 セールス・インフォメーション
  • sales-info@classcat.com  ;  Web: www.classcat.com  ;   ClassCatJP

 

 

HuggingFace Transformers : Tutorials : モデルの共有

最後の 2 つのチュートリアルでは PyTorch, Keras そして分散セットアップのための Accelerate でモデルを再調整する方法を示しました。次のステップは貴方のモデルをコミュニティで共有することです!Hugging Face では、人工知能を総ての人に対して民主化するためには知識とリソースをオープンに共有することが妥当であると信じています。他の人が時間とリソースを節約するのに役立つように、モデルをコミュニティと共有することを考えることを奨励します。

このチュートリアルでは、訓練された、あるいは再調整されたモデルを モデルハブ で共有する 2 つの方法を学習します :

  • プログラミング的にファイルをハブにプッシュする。
  • web インターフェイスでファイルをハブにドラッグ&ドロップする。

Note : モデルをコミュニティと共有するためには、huggingface.co のアカウントが必要です。既存の組織に参加したり新しいものを作成することもできます。

 

リポジトリの機能

モデルハブの各リポジトリは典型的な GitHub レポジトリのように動作します。リポジトリはバージョン管理, コミット履歴, そして差分を可視化する機能を提供しています。

モデルハブの組み込みバージョン管理は git と git-lfs に基づいています。換言すれば、一つのモデルを一つのリポジトリとして扱うことができて、より素晴らしいアクセス制御とスケーラビリティを可能にします。バージョン管理は、モデルの特定のバージョンをコミットハッシュ, タグやブランチでピン留め (固定) する方法である、リビジョン (の使用) を可能にします。

その結果、revision パラメータで特定のモデルバージョンをロードすることができます :

model = AutoModel.from_pretrained(
    "julien-c/EsperBERTo-small", revision="v2.0.1"  # tag name, or branch name, or commit hash
)

ファイルもまたリポジトリで容易に編集されます、そしてコミット履歴を差分に加えて閲覧することができます :

 

セットアップ

ハブにモデルを共有する前に、貴方の Hugging Face クレデンシャルが必要です。端末へのアクセスを持つ場合、 Transformers がインストールされた仮想環境で次のコマンドを実行してください。これは貴方のアクセストークンを Hugging Face キャッシュフォルダ (デフォルトで ~/.cache/ ) にストアします :

huggingface-cli login

Jupyter or Colaboratory のようなノートブックを使用している場合には、huggingface_hub ライブラリがインストールされていることを確認してください。このライブラリはプログラミング的にハブと相互作用します。

pip install huggingface_hub

それからハブにサインインするために notebook_login 使用し、そして次でログインするためのトークンを生成するために ここ のリンクに従ってください :

from huggingface_hub import notebook_login

notebook_login()

 

モデルを総てのフレームワークのために変換する

貴方のモデルが様々なフレームワークで作業する人により使用できることを確実にするため、モデルを PyTorch と TensorFlow の両者のチェックポイントでモデルを変換してアップロードすることを勧めます。このステップをスキップした場合、ユーザは依然として異なるフレームワークからモデルをロードできますが、 Transformers はチェックポイントを on-the-fly で変換する必要がありますので、それは遅くなります。

別のフレームワークへのチェックポイントの変換は容易です。PyTorch と TensorFlow がインストールされていることを確認し (インストール手順は こちら を参照)、そして他のフレームワークでタスクに対する特定のモデルを見つけてください。

例えば、PyTorch でシークエンス分類のために DistilBert を訓練し、それを TensorFlow の同等のものに変換することを望むとします。タスクに対するモデルの TensorFlow の同値をロードし、specify from_pt=True を指定します、すると
Transformers は PyTorch チェックポイントを TensorFlow チェックポイントに変換します :

tf_model = TFDistilBertForSequenceClassification.from_pretrained("path/to/awesome-name-you-picked", from_pt=True)

それから新しいチェックポイントと共に新しい TensorFlow モデルをセーブします :

tf_model.save_pretrained("path/to/awesome-name-you-picked")

同様に、チェックポイントを TensorFlow から PyTorch に変換するためには from_tf=True を指定します :

pt_model = DistilBertForSequenceClassification.from_pretrained("path/to/awesome-name-you-picked", from_tf=True)
pt_model.save_pretrained("path/to/awesome-name-you-picked")

モデルが Flax で利用可能であれば、チェックポイントを PyTorch から Flax に変換することも可能です :

flax_model = FlaxDistilBertForSequenceClassification.from_pretrained(
    "path/to/awesome-name-you-picked", from_pt=True
)

モデルへのハブへの共有は特別なパラメータやコールバックを追加するくらいに単純です。再調整チュートリアル を思い出してください、TrainingArguments クラスはハイパーパラメータと追加の訓練オプションを指定するところです。これらの訓練オプションの一つはモデルをハブに直接プッシュする機能を含みます。TrainingArguments で push_to_hub=True を設定します :

training_args = TrainingArguments(output_dir="my-awesome-model", push_to_hub=True)

通常のように訓練引数を Trainer に渡します :

trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=small_train_dataset,
    eval_dataset=small_eval_dataset,
    compute_metrics=compute_metrics,
)

モデルの再調整が終わあった後、訓練済みモデルをハブにプッシュするために Trainer の push_to_hub() を呼び出します。 Transformers は訓練ハイパーパラメータ, 訓練結果そしてフレームワークのバージョンをモデルカードに自動的に追加してくれさえします!

trainer.push_to_hub()

 

PushToHubCallback でモデルをプッシュする

TensorFlow ユーザは PushToHubCallback で同じ機能を可能にします。PushToHubCallback 関数では、以下を追加します :

  • モデルの出力先ディレクトリ。
  • トークナイザー。
  • hub_model_id, これはハブのユーザ名とモデル名です。
from transformers.keras.callbacks import PushToHubCallback

push_to_hub_callback = PushToHubCallback(
    output_dir="./your_model_save_path", tokenizer=tokenizer, hub_model_id="your-username/my-awesome-model"
)

fit にコールバックを追加します、すると Transformers は訓練済みモデルをハブにプッシュします :

model.fit(tf_train_dataset, validation_data=tf_validation_dataset, epochs=3, callbacks=push_to_hub_callback)

 

push_to_hub 関数の使用

モデルをハブにアップロードするためにその上で push_to_hub を直接呼び出すこともできます。

push_to_hub でモデル名を指定します :

pt_model.push_to_hub("my-awesome-model")

これは、モデル名 my-awesome-model で貴方のユーザ名のもとにリポジトリを作成します。ユーザはモデルを from_pretrained 関数でロードできるようになります :

from transformers import AutoModel

model = AutoModel.from_pretrained("your_username/my-awesome-model")

貴方が組織に属しておりモデルを代わりに組織名のもとにプッシュしたい場合には、organization パラメータを追加してください :

pt_model.push_to_hub("my-awesome-model", organization="my-awesome-org")

push_to_hub 関数はまた他のファイルをモデル・リポジトリに追加するためにも使用できます。例えば、トークナイザーをモデル・レポジトリに追加します :

tokenizer.push_to_hub("my-awesome-model")

あるいは多分、再調整された PyTorch モデルの TensorFlow バージョンを追加したいでしょう :

tf_model.push_to_hub("my-awesome-model")

今は貴方の Hugging Face プロファイルにナビゲートするとき、新しく作成されたモデル・リポジトリを見るはずです。Files タブをクリックするとレポジトリにアップロードした総てのファイルが表示されます。

ファイルを作成してレポジトリにアップロードする方法の詳細は、ここ のハブ・ドキュメントを参照してください。

 

web インターフェイスによるアップロード

コードを使わないアプローチを好むユーザはハブの web インターフェイスを通してモデルをアップロードできます。新しいリポジトリを作成するために huggingface.co/ にアクセスしてください :

ここから、モデルについての幾つかの情報を追加します :

  • レポジトリの オーナー を選択します。これは貴方自身か、所属する組織のどれでもかまいません。

  • モデルの名前を選択します、これはまたリポジトリ名にもなります。

  • モデルがパブリックかプライベートかを選択します。

  • モデルのライセンス使用方法を指定します。

次に新しいファイルをリポジトリにアップロードするためには Files タブをクリックして Add ファイル ボタンをクリックします。それからアップロードしてコミットメッセージを追加するためにファイルをドラッグ&ドロップします。

 

モデルカードの追加

ユーザがモデルの機能, 制限, 潜在的なバイアス, そして倫理規定を理解することを確実にするため、リポジトリにモデルカードを追加してください。モデルカードは README.md ファイルで定義されます。以下によりモデルカードを追加できます :

  • README.md ファイルを手動で作成してアップロードする。

  • モデルリポジトリで Edit モデルカード ボタンをクリックする。

モデルカードが含むべき情報の型の良いサンプルのために DistilBert モデルカード を見てください。モデルのカーボンフットプリントやウィジェット・サンプルのような README.md ファイルで制御可能な他のオプションの詳細については、ここ のドキュメントを参照してください。

 

以上



HuggingFace Transformers 4.17 : Tutorials : 多言語モデル

HuggingFace Transformers 4.17 : Tutorials : 多言語モデル (翻訳/解説)

翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 04/20/2022 (v4.17.0)

* 本ページは、HuggingFace Transformers の以下のドキュメントを翻訳した上で適宜、補足説明したものです:

* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。

 

クラスキャット 人工知能 研究開発支援サービス

クラスキャット は人工知能・テレワークに関する各種サービスを提供しています。お気軽にご相談ください :

◆ 人工知能とビジネスをテーマに WEB セミナーを定期的に開催しています。スケジュール
  • お住まいの地域に関係なく Web ブラウザからご参加頂けます。事前登録 が必要ですのでご注意ください。

お問合せ : 本件に関するお問い合わせ先は下記までお願いいたします。

  • 株式会社クラスキャット セールス・マーケティング本部 セールス・インフォメーション
  • sales-info@classcat.com  ;  Web: www.classcat.com  ;   ClassCatJP

 

HuggingFace Transformers : Tutorials : 多言語モデル

Transformers には幾つかの多言語 (= multilingual) モデルがあり、そしてそれらの推論使用方法は単一言語 (= monolingual) モデルとは異なります。総ての多言語モデルが異なるわけではありませんが。bert-base-multilingual-uncased のような幾つかのモデルはちょうど単一言語モデルのように利用できます。このガイドは、その推論のための使用方法が異なる多言語モデルの使用方法を示します。

 

XLM

XML は 10 個の異なるチェックポイントを持ち、その一つだけが単一言語です。残りの 9 個のモデルのチェックポイントは 2 つのカテゴリーに分けられます : 言語埋め込みを利用するチェックポイントと、そうでないものです。

 

言語埋め込みを持つ XLM

以下の XLM モデルは推論時に使用される言語を指定するために言語埋め込みを使用しています :

  • xlm-mlm-ende-1024 (Masked 言語モデリング, 英独)
  • xlm-mlm-enfr-1024 (Masked 言語モデリング, 英仏)
  • xlm-mlm-enro-1024 (Masked 言語モデリング、英語-ルーマニア語)
  • xlm-mlm-xnli15-1024 (Masked 言語モデリング、XNLI 言語)
  • xlm-mlm-tlm-xnli15-1024 (Masked 言語モデリング + 翻訳、XNLI 言語)
  • xlm-clm-enfr-1024 (因果言語モデリング、英仏)
  • xlm-clm-ende-1024 (因果言語モデリング、英独)

言語埋め込みは、モデルに渡される input_ids と同じ shape のテンソルとして表現されます。これらの tensor の値は使用される言語に依存していて、トークナイザーの lang2id と id2lang 属性により識別されます。

この例では、xlm-clm-enfr-1024 チェックポイントをロードしています (因果言語モデリング、英仏) :

import torch
from transformers import XLMTokenizer, XLMWithLMHeadModel

tokenizer = XLMTokenizer.from_pretrained("xlm-clm-enfr-1024")
model = XLMWithLMHeadModel.from_pretrained("xlm-clm-enfr-1024")

トークナイザーの lang2id 属性はモデルの言語とそれらの id を示します :

print(tokenizer.lang2id)
{'en': 0, 'fr': 1}

次に、サンプル入力を作成します :

input_ids = torch.tensor([tokenizer.encode("Wikipedia was used to")])  # batch size of 1
input_ids
tensor([[    0,  4018,  5545, 51104,    32,   308,    18,     1]])

language id を “en” として設定して言語埋め込みを定義するためにそれを使用します。言語埋め込みは 0 で満たされたテンソルです、何故ならそれは英語のための言語 id であるからです。このテンソルは input_ids と同じサイズである必要があります。

language_id = tokenizer.lang2id["en"]  # 0
langs = torch.tensor([language_id] * input_ids.shape[1])  # torch.tensor([0, 0, 0, ..., 0])

# We reshape it to be of size (batch_size, sequence_length)
langs = langs.view(1, -1)  # is now of shape [1, sequence_length] (we have a batch size of 1)
langs
tensor([[0, 0, 0, 0, 0, 0, 0, 0]])

そして input_ids と言語埋め込みをモデルに渡すことができます :

outputs = model(input_ids, langs=langs)
print(outputs)
MaskedLMOutput(loss=None, logits=tensor([[[ -6.3665,  10.7176,  -6.3753,  ...,  -6.1219,  -6.3775,  -6.0470],
         [-13.8973,  -3.1509, -13.8749,  ..., -14.6975, -12.9415, -13.8252],
         [ -9.2461,   4.8444,  -9.6047,  ..., -10.5616,  -8.2646,  -9.9838],
         ...,
         [-12.1487,   9.7573, -12.0884,  ..., -13.0167, -11.7700, -10.6408],
         [-11.5067,   4.1504, -11.6619,  ..., -12.0130, -11.2718, -10.8311],
         [ -8.4061,   6.6820,  -8.5521,  ...,  -8.2401,  -8.5305,  -8.3125]]],
       grad_fn=<AddBackward0>), hidden_states=None, attentions=None)

run_generation.py は、xlm-clm チェックポイントを使用して、言語埋め込みによりテキストを生成できます。

 

言語埋め込みなしの XLM

以下の XLM モデルは推論の間に言語埋め込みを必要としません :

  • xlm-mlm-17-1280 (Masked 言語モデリング、17 言語)
  • xlm-mlm-100-1280 (Masked 言語モデリング、100 言語)

これらのモデルは、前の XLM チェックポイントとは違って、一般的なセンテンス表現のために使用されます。

 

BERT

以下の BERT モデルは多言語タスクのために利用できます :

  • bert-base-multilingual-uncased (Masked 言語モデリング + 次文予測, 102 言語)
  • bert-base-multilingual-cased (Masked 言語モデリング + 次文予測, 104 言語)

これらはコンテキストから言語を識別してそれに従って推論するはずです。

 

XLM-RoBERTa

以下の XML-RoBERTa モデルは多言語タスクのために使用できます :

  • xlm-roberta-base (Masked 言語モデリング、100 言語)
  • xlm-roberta-large (Masked 言語モデリング、100 言語)

XLM-RoBERTa は 2.5TB の新たに作成されたクリーンな 100 言語の CommonCrawl データ上で訓練されました。それは、分類, シークエンス・ラベリングと質問応答のような下流タスク上で mBERT や XLM のような以前にリリースされた多言語モデルを越える強力な利点を提供します。

 

M2M100

以下の M2M100 モデルは多言語翻訳のために使用できます :

  • facebook/m2m100_418M (翻訳)
  • facebook/m2m100_1.2B (翻訳)

この例では、中国語から英語に翻訳するために facebook/m2m100_418M チェックポイントをロードしています。トークナイザーでソース言語を設定できます :

from transformers import M2M100ForConditionalGeneration, M2M100Tokenizer

en_text = "Do not meddle in the affairs of wizards, for they are subtle and quick to anger."
chinese_text = "不要插手巫師的事務, 因為他們是微妙的, 很快就會發怒."

tokenizer = M2M100Tokenizer.from_pretrained("facebook/m2m100_418M", src_lang="zh")
model = M2M100ForConditionalGeneration.from_pretrained("facebook/m2m100_418M")

テキストをトークン化します :

encoded_zh = tokenizer(chinese_text, return_tensors="pt")

M2M100 はターゲット言語に翻訳するために最初の生成されたトークンとしてターゲット言語 id を強制します。英語に翻訳するために generate メソッドでは forced_bos_token_id を en に設定します :

generated_tokens = model.generate(**encoded_zh, forced_bos_token_id=tokenizer.get_lang_id("en"))
tokenizer.batch_decode(generated_tokens, skip_special_tokens=True)
'Do not interfere with the matters of the witches, because they are delicate and will soon be angry.'

 

MBart

以下の MBart モデルは多言語翻訳のために利用できます :

  • facebook/mbart-large-50-one-to-many-mmt (1 対 多 ; 多言語機械翻訳, 50 言語)
  • facebook/mbart-large-50-many-to-many-mmt (多 対 多 ; 多言語機械翻訳, 50 言語)
  • facebook/mbart-large-50-many-to-one-mmt (多 対 1 ; 多言語機械翻訳, 50 言語)
  • facebook/mbart-large-50 (多言語翻訳, 50 言語)
  • facebook/mbart-large-cc25

この例では、フィンランド語を英語に翻訳するために facebook/mbart-large-50-many-to-many-mmt checkpoint チェックポイントをロードします。トークナイザーでソース言語を設定できます :

from transformers import AutoTokenizer, AutoModelForSeq2SeqLM

en_text = "Do not meddle in the affairs of wizards, for they are subtle and quick to anger."
fi_text = "Älä sekaannu velhojen asioihin, sillä ne ovat hienovaraisia ja nopeasti vihaisia."

tokenizer = AutoTokenizer.from_pretrained("facebook/mbart-large-50-many-to-many-mmt", src_lang="fi_FI")
model = AutoModelForSeq2SeqLM.from_pretrained("facebook/mbart-large-50-many-to-many-mmt")

テキストをトークン化します :

encoded_en = tokenizer(en_text, return_tensors="pt")

MBart はターゲット言語に翻訳するために最初の生成されたトークンとしてターゲット言語 id を強制します。英語に翻訳するために generate メソッドでは forced_bos_token_id を en に設定します :

generated_tokens = model.generate(**encoded_en, forced_bos_token_id=tokenizer.lang_code_to_id("en_XX"))
tokenizer.batch_decode(generated_tokens, skip_special_tokens=True)
"Don't interfere with the wizard's affairs, because they are subtle, will soon get angry."

facebook/mbart-large-50-many-to-one-mmt チェックポイントを使用している場合、最初の生成されたトークンとしてターゲット言語 id を強制する必要はありません、その他の点では使用方法は同じです。

 

以上



HuggingFace Transformers 4.17 : Tutorials : トークナイザーの概要

HuggingFace Transformers 4.17 : Tutorials : トークナイザーの概要 (翻訳/解説)

翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 04/19/2022 (v4.17.0)

* 本ページは、HuggingFace Transformers の以下のドキュメントを翻訳した上で適宜、補足説明したものです:

* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。

 

クラスキャット 人工知能 研究開発支援サービス

クラスキャット は人工知能・テレワークに関する各種サービスを提供しています。お気軽にご相談ください :

◆ 人工知能とビジネスをテーマに WEB セミナーを定期的に開催しています。スケジュール
  • お住まいの地域に関係なく Web ブラウザからご参加頂けます。事前登録 が必要ですのでご注意ください。

お問合せ : 本件に関するお問い合わせ先は下記までお願いいたします。

  • 株式会社クラスキャット セールス・マーケティング本部 セールス・インフォメーション
  • sales-info@classcat.com  ;  Web: www.classcat.com  ;   ClassCatJP

 

HuggingFace Transformers : Tutorials : トークナイザーの概要

このページでは、トークン化をより詳しく調べます。

前処理チュートリアル で見たように、テキストのトークン化はそれを単語やサブワードに分割します、これらはそれから検索テーブルを通して id に変換されます。単語やサブワードを id に変換することは簡単ですから、この概要では、テキストを単語やサブワードを分割することにフォーカスします (i.e. テキストのトークン化)。より具体的には、 Transformers で使用されるトークナイザーの 3 つの主要なタイプを見ます : Byte-Pair エンコーディング (BPE)WordPieceSentencePiece です、そしてどのトークナイザー型がどのモデルにより使用されるかの例を示します。

各モデルページでは、事前訓練済みモデルによりどのトークナイザー型が使用されたかを知るために関連するトークナイザーのドキュメントを見ることができることに注意してください。例えば、BertTokenizer を見れば、モデルが WordPiece を使用していることを分かります。

 

イントロダクション

テキストをより小さいチャンクに分割することは思うよりも困難なタスクで、それを行なうための複数の方法があります。例えば、センテンス “Don’t you love Transformers? We sure do.” を見てみましょう。

このテキストをトークン化する単純な方法はそれをスペース (空白) で分割することです、それは次を与えるでしょう :

["Don't", "you", "love", "🤗", "Transformers?", "We", "sure", "do."]

これは良識ある最初のステップですが、トークン “Transformers?” と “do.” を見れば、句読点が単語 “Transformer” と “do” に装着されていることに気付きます、これは最適とは言えません (= suboptimal)。モデルが単語の異なる表現とそれに続くかもしれない総ての可能な句読記号を学習しなくても良いように句読点を考慮に入れるべきです、それはモデルが学習しなければならない表現の数を爆発させます。句読点を考慮に入れれば、模範となるテキストのトークン化は次を与えます :

["Don", "'", "t", "you", "love", "🤗", "Transformers", "?", "We", "sure", "do", "."]

より良いです。けれども、トークン化が単語 “Don’t” を扱う方法は不都合です。”Don’t” は “do not” を表しますので、[“Do”, “n’t”] としてトークン化されるほうがより良いです。これは物事が複雑になり始めるところで、各モデルが自身のトークナイザー型を持つ理由の一部です。テキストのトークン化のために適用するルールに依存して、同じテキストに対して異なるトークン化された出力が生成されます。事前訓練済みモデルは、訓練データをトークン化するために使用されたものと同じルールでトークン化された入力を供給する場合に限り、正しく遂行します

spaCyMoses は 2 つのポピュラーなルールベースのトークナイザーです。それらをサンプルに適用すると、spaCy と Moses は次のようなものを出力します :

["Do", "n't", "you", "love", "🤗", "Transformers", "?", "We", "sure", "do", "."]

見て分かるように、スペースと句読点のトークン化に加えて、ルールベースのトークン化がここでは使用されています。スペースと句読点のトークン化とルールベースのトークン化は両者とも単語トークン化の例で、これはセンテンスを単語に分割するものとして緩く定義されます。テキストをより小さいチャンクに分割することは最も直観的な方法である一方で、このトークン化方法は大規模なテキストコーパスのためには問題に繋がる可能性があります。この場合、スペースと句読点 (ベースの) トークン化は通常は非常に大きな語彙 (使用される総ての一意の単語とトークンのセット) を生成します。E.g., Transformer XL はスペースと句読点トークン化を使用し、267,735 の語彙サイズという結果になります!

そのような大きな語彙サイズはモデルに入力と出力層として巨大な埋め込み行列を持つことを強制します、これは増大するメモリと時間コストの両者を引き起こします。一般に、transformer モデルは 50,000 より大きい語彙サイズは滅多に持ちません、特にそれらが単一の言語上で事前訓練される場合には。

 
◆ それでは単純なスペースと句読点トークン化が不十分であるならば、何故単純に文字上でトークン化しないのでしょう?

文字のトークン化が非常に単純であり、そしてメモリと時間コストを大きく削減する一方で、それはモデルが意味のある入力表現を学習することを遥かに困難にします。E.g. 文字 “t” のための意味のあるコンテキスト独立な表現を学習することは単語 “today” のためのコンテキスト独立な表現を学習することより遥かに困難です。従って、文字トークン化はしばしばパフォーマンスの損失を伴います。そのため、両者の長所を活かすため、transformers モデルは subword (サブワード) トークン化と呼ばれる単語レベルと文字レベルトークン化のハイブリッドを使用します。

 

サブワード・トークン化

サブワード・トークン化 アルゴリズムは、頻繁に使用される単語はより小さいサブワードに分割されるべきではないが、稀な単語は意味のあるサブワードに分解されるはずであるという原理に依存しています。例えば、”annoyingly” は稀な単語と考えられるかもしれず、そして “annoying” と “ly” に分解できるでしょう。スタンドアロンなサブワードとして “annoying” と “ly” の両者はより頻繁に現れる一方で、同時に “annoyingly” の意味は “annoying” と “ly” の合成的な意味により保持されます。これは特にトルコ語のような膠着語で有用です、そこではサブワードを一緒に繋ぐことにより任意に長い複雑な単語 (群) を (殆ど) 形成できます。

サブワード・トークン化はモデルに合理的な語彙サイズを持つことを可能にする一方で、意味のあるコンテキスト独立な表現を学習することができます。更に、サブワード・トークン化はモデルが前に見たことがない単語を、それらを既知のサブワードに分解することにより処理することを可能にします。例えば、BertTokenizer トークナイザーは “I have a new GPU!” を次のようにトークン化します :

from transformers import BertTokenizer

tokenizer = BertTokenizer.from_pretrained("bert-base-uncased")
tokenizer.tokenize("I have a new GPU!")
["i", "have", "a", "new", "gp", "##u", "!"]

uncased モデルを考えていますので、センテンスは最初に小文字にされています。単語群 [“i”, “have”, “a”, “new”] はトークナイザーの語彙に存在していますが、単語 “gpu” はそうでないことがわかります。その結果、トークナイザーは “gpu” を既知のサブワード : [“gp” と “##u”] に分割します。”##” は、(トークン化のデコードや反転のために) トークンの残りはスペースなしで前のものに装着されるべきであることを意味します。

別の例として、XLNetTokenizer トークナイザーは前の典型例としてのテキストを次のようにトークン化します :

from transformers import XLNetTokenizer

tokenizer = XLNetTokenizer.from_pretrained("xlnet-base-cased")
tokenizer.tokenize("Don't you love 🤗 Transformers? We sure do.")
["▁Don", "'", "t", "▁you", "▁love", "▁", "🤗", "▁", "Transform", "ers", "?", "▁We", "▁sure", "▁do", "."]

(後述する) SentencePiece を参照するときに、これらの “▁” の意味に戻ります。見て分かるように、稀な単語 “Transformers” はより頻度の高いサブワード “Transform” と “ers” に分割されています。

次に様々なサブワード・トークン化アルゴリズムがどのように動作するかを見ましょう。これらのトークン化アルゴリズムの総ては (通常は対応するモデルがその上で訓練されたコーパス上で成される) 訓練のある形式に依存していることに注意してください。

 

バイトペア・エンコーディング (BPE)

バイトペア・エンコーディング (BPE) は Neural Machine Translation of Rare Words with Subword Units (Sennrich et al., 2015) で導入されました。BPE は訓練データを単語に分割する 事前トークナイザー に依存しています。事前トークン化はスペース・トークン化のように単純であり得ます、e.g. GPT2, Roberta。より進んだ事前トークン化はルールベースのトークン化を含みます、e.g. XLM, FlauBERT、これは殆どの言語について Moses を使用しています、また GPT は訓練コーパスで各単語の頻度をカウントするために Spacy と ftfy を使用しています。

事前トークン化後、一意の単語のセットが作成されて訓練データで出現した各単語の頻度が決定されます。次に、BPE は一意の単語のセットに出現する総てのシンボルから成るベース語彙を作成します、そしてベース語彙の 2 つのシンボルから新しいシンボルを形成するためのマージルールを学習します。語彙が望まれる語彙サイズを獲得するまでそれを行ないます。望まれる語彙サイズはトークナイザーを訓練する前に定義するハイパーパラメータであることに注意してください。

例として、事前トークン化後、頻度を含む次の単語のセットが決定されたと仮定します :

("hug", 10), ("pug", 5), ("pun", 12), ("bun", 4), ("hugs", 5)

その結果、ベース語彙は [“b”, “g”, “h”, “n”, “p”, “s”, “u”] となります。総ての単語をベース語彙のシンボルに分割し、次を得ます :

("h" "u" "g", 10), ("p" "u" "g", 5), ("p" "u" "n", 12), ("b" "u" "n", 4), ("h" "u" "g" "s", 5)

そして BPE は各可能なシンボル・ペアの頻度をカウントして最も頻繁に出現するシンボル・ペアを選択します。上の例では、”u” が続く “h” は 10 + 5 = 15 回存在します (“hug” の 10 出現で 10 回、”hugs” の 5 出現で 5 回)。けれども、最も頻度の高いシンボル・ペアは “g” が続く “u” で、合計で 10 + 5 + 5 = 20 回出現します。こうして、トークナイザーが学習する最初のマージルールは “g” シンボルが続く “u” シンボル総てを一緒にグループ化することです。次に、”ug” は語彙に追加されます。そして単語のセットは次になります :

("h" "ug", 10), ("p" "ug", 5), ("p" "u" "n", 12), ("b" "u" "n", 4), ("h" "ug" "s", 5)

それから BPE は次の最も一般的なシンボル・ペアを識別します。それは “n” が続く “u” で、16 回出現します。”u”, “n” は “un” にマージされて語彙に追加されます。次に頻度の高いシンボル・ペアは “ug” が続く “h” で、15 回です。再度ペアがマージされて “hug” が語彙に追加できます。

この段階で、語彙は [“b”, “g”, “h”, “n”, “p”, “s”, “u”, “ug”, “un”, “hug”] でそして一意の単語のセットは次のように表されます :

("hug", 10), ("p" "ug", 5), ("p" "un", 12), ("b" "un", 4), ("hug" "s", 5)

バイトペア・エンコーディングがこの時点で停止すると仮定すると、学習されたマージルールが新しい単語に適用されます (それらの新しい単語がベース語彙にないシンボルを含まない限りは)。例えば、単語 “bug” は [“b”, “ug”] にトークン化されますが “mug” は [“<unk>”, “ug”] としてトークン化されます、何故ならばシンボル “m” はベース語彙にないからです。一般には、”m” のような単一文字は “<unk>” シンボルで置き換えられません、何故ならば訓練データは通常は各文字の出現を少なくとも一つは含むからですが、絵文字のような非常に特殊な文字については発生しがちです。

前に述べたように、語彙サイズ、i.e. ベース語彙サイズ + マージの数、は選択するハイパーパラメータです。例えば GPT は 40,478 の語彙サイズを持ちます、何故ならばそれらは 478 ベース文字を持ちそして 40,000 マージの後に訓練を停止することを選択したからです。

 

バイト・レベル BPE

総ての可能なベース文字を含むベース語彙は、総てのユニコード文字がベース文字として考えられる場合などには、非常に大規模になる可能性があります。より良いベース語彙を持つために、GPT-2 はベース語彙としてバイトを使用します、これは賢いトリックでベース語彙にサイズ 256 であることを強制する一方で、総てのベース文字がその語彙に含まれることを確かなものにします。句読点を扱うための幾つかの追加ルールにより、GPT2 のトークナイザーは <unk> シンボルを必要とすることなく総てのテキストをトークン化できます。GPT-2 は 50,257 の語彙サイズを持ちます、これは 256 バイトのベーストークン、特殊な end-of-text (テキスト終了) トークンと 50,000 マージで学習されたシンボルに相当します。

 

WordPiece

WordPiece は BERT, DistilBERT と Electra のために利用されるサブワード・トークン化アルゴリズムです。このアルゴリズムは Japanese and Korean Voice Search (Schuster et al., 2012) で概説され BPE に非常に良く似ています。WordPiece は最初に語彙を訓練データに存在する総ての文字を含めるように初期化して与えられた数のマージルールを漸進的に学習します。BPE とは対照的に、WordPiece は最も頻度の高いシンボルペアではなく、語彙に追加された訓練データの尤度を最大化するものを選択します。

さてこれは正確には何を意味するのでしょう?前の例を参照すれば、訓練データの尤度を最大化することは、2 番目のシンボルが続く最初のシンボルの確率により除算される (シンボルペアの) 確率が総てのシンボルペアの中で最大であるような、シンボルペアを見つけることと同値です。E.g. “g” が続く “u” は “u”, “g” により除算される “ug” の確率が任意の他のシンボルペアよりも大きい場合にだけマージされます。直観的には、WordPiece は 2 つのシンボルをマージすることにより (それに値するかを確かなものにするために) それが失うものを評価するという点で BPE と僅かに異なります。

 

Unigram

Unigram は Subword Regularization: Improving Neural Network Translation Models with Multiple Subword Candidates (Kudo, 2018) で導入されたサブワード・トークン化アルゴリズムです。BPE や WordPiece とは対照的に、Uniram はベース語彙をシンボルの大規模な数に初期化してより小さい語彙を得るために各シンボルを漸次的に切り捨てていきます。
ベース語彙は例えば総ての事前トークン化された単語と最も一般的な部分文字列に対応できるでしょう。Unigram は transformers のどのモデルについても直接使用されていませんが、SentencePiece とともに利用されています。

各訓練ステップで、現在の語彙と Unigram 言語モデルが与えられて Unigram アルゴリズムは訓練データに渡る損失 (多くの場合、対数尤度として定義されます) を定義します。それから、語彙の各シンボルについて、アルゴリズムはシンボルが語彙から除去されたとすると全体的な損失がどのくらい増加するかを計算します。それから Unigram は損失の増加がもっとも少ないシンボル、つまり訓練データに渡る全体的な損失にもっとも影響を与えないシンボルの p (p は通常は 10% or 20%) パーセントを除去します。このプロセスは語彙が望まれるサイズに達するまで繰り返されます。Unigram アルゴリズムは任意の単語がトークン化できるようにベース文字を常に保持します。

Unigram は (BPE と WordPiece とは対照的に) マージルールに基づかないので、アルゴリズムは訓練後に新しいテキストをトークン化する幾つかの方法を持ちます。例として、訓練された Unigram トークナイザーが以下の語彙を示す場合 :

["b", "g", "h", "n", "p", "s", "u", "ug", "un", "hug"],

“hugs” は [“hug”, “s”], [“h”, “ug”, “s”] or [“h”, “u”, “g”, “s”] の両者としてトークン化できるでしょう。それではどれを選択するのでしょう?Unigram は各可能なトークン化の確率を訓練後に計算できるように、語彙をセーブするのに加えて訓練コーパスの各トークンの確率をセーブします。アルゴリズムは実際い最も尤度の高いトークン化を単純に選択しますが、それらの確率に従って可能なトークン化をサンプリングする可能性も提供します。

これらの確率はその上でトークナイザーが訓練される損失により定義されます。訓練データが単語 $x_{1}, \dots, x_{N}$ から成り、そして単語 $x_{i}$ のための総ての可能なトークン化のセットが $S(x_{i})$ で定義されると仮定すると、全体的な損失は次で定義されます :

\[
\mathcal{L} = -\sum_{i=1}^{N} \log \left ( \sum_{x \in S(x_{i})} p(x) \right )
\]

 

SentencePiece

ここまで説明された総てのトークン化アルゴリズムは同じ問題を持ちます : 単語を分割するために入力テキストがスペースを使用していることが仮定されています。けれども、総ての言語が単語を分割するためにスペースを使用してはいません。一つの可能な解法は言語固有の事前トークナイザーを使用することです、例えば XML は固有の中国語、日本語、そしてタイ語の事前トークナイザーを使用しています。この問題をより一般的に解くため、SentencePiece : A simple and language independent subword tokenizer and detokenizer for Neural Text Processing (Kudo et al., 2018) は入力を raw 入力ストリームとして扱い、スペースを使用する文字のセット内に含めます。それから適切な語彙を構築するために BPE か unigram アルゴリズムを使用します。

XLNetTokenizer は例えば SentencePiece を使用しています、これはまた先の例で何故 “▁” 文字が語彙に含まれていたかです。SentencePiece によるデコードは非常に容易です、何故ならば総てのトークンは連結できて “▁” がスペースで置き換えられるだけからです。SentencePiece を使用するライブラリの総ての transformer モデルはそれを unigram との組合せで利用します。SentencePiece を使用するモデルの例は ALBERT, XLNet, Marian と T5 です。

 

以上



HuggingFace Transformers 4.17 : Tutorials : 事前訓練済みモデルの再調整

HuggingFace Transformers 4.17 : Tutorials : 事前訓練済みモデルの再調整 (翻訳/解説)

翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 04/18/2022 (v4.17.0)

* 本ページは、HuggingFace Transformers の以下のドキュメントを翻訳した上で適宜、補足説明したものです:

* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。

 

クラスキャット 人工知能 研究開発支援サービス

クラスキャット は人工知能・テレワークに関する各種サービスを提供しています。お気軽にご相談ください :

◆ 人工知能とビジネスをテーマに WEB セミナーを定期的に開催しています。スケジュール
  • お住まいの地域に関係なく Web ブラウザからご参加頂けます。事前登録 が必要ですのでご注意ください。

お問合せ : 本件に関するお問い合わせ先は下記までお願いいたします。

  • 株式会社クラスキャット セールス・マーケティング本部 セールス・インフォメーション
  • sales-info@classcat.com  ;  Web: www.classcat.com  ;   ClassCatJP

 

HuggingFace Transformers : Tutorials : 事前訓練済みモデルの再調整

事前訓練モデルの使用は大きな利点があります。それは計算コスト、カーボン・フットプリントを削減して、スクラッチから訓練する必要なく最先端のモデルを利用することを可能にします。 Transformers は広範囲のタスクに対して数千の事前訓練済みモデルへのアクセスを提供しています。事前訓練済みモデルを使用するとき、貴方のタスクに固有のデータセット上でそれを訓練します。これは再調整 (= fine-tuning, 微調整) として知られる、非常に強力な訓練テクニックです。このチュートリアルでは、事前訓練済みモデルを貴方の選択した深層学習フレームワークで再調整します。

  • Transformers Trainer で事前訓練済みモデルを再調整する。

  • TensorFlow with Keras で事前訓練済みモデルを再調整する。

  • native PyTorch で事前訓練済みモデルを再調整する。

 

データセットを準備する

事前訓練済みモデルを再調整できる前に、データセットをダウンロードしてそれを訓練のために準備します。前のチュートリアルは訓練のためにデータを処理する方法を紹介しましたが、今はそれらのスキルをテストする機会を得ています!

Yelp Reviews データセットをロードすることから始めます :

from datasets import load_dataset

dataset = load_dataset("yelp_review_full")
dataset.keys()
dict_keys(['train', 'test'])
len(dataset['train']), len(dataset['test'])
(650000, 50000)
dataset['train'][0]
{'label': 4,
 'text': "dr. goldberg offers everything i look for in a general practitioner.  he's nice and easy to talk to without being patronizing; he's always on time in seeing his patients; he's affiliated with a top-notch hospital (nyu) which my parents have explained to me is very important in case something happens and you need surgery; and you can get referrals to see specialists without having to see him first.  really, what more do you need?  i'm sitting here trying to think of any complaints i have about him, but i'm really drawing a blank."}
dataset['test'][0]
{'label': 0,
 'text': 'I got \'new\' tires from them and within two weeks got a flat. I took my car to a local mechanic to see if i could get the hole patched, but they said the reason I had a flat was because the previous patch had blown - WAIT, WHAT? I just got the tire and never needed to have it patched? This was supposed to be a new tire. \\nI took the tire over to Flynn\'s and they told me that someone punctured my tire, then tried to patch it. So there are resentful tire slashers? I find that very unlikely. After arguing with the guy and telling him that his logic was far fetched he said he\'d give me a new tire \\"this time\\". \\nI will never go back to Flynn\'s b/c of the way this guy treated me and the simple fact that they gave me a used tire!'}

今ではご存知のように、テキストを処理して、可変なシークエンス長を扱うためにパディングと truncation ストラテジーを含めるためにはトークナイザーが必要です。データセットを 1 ステップで処理するため、データセット全体に対して前処理関数を適用する Datasets map メソッドを使用します。

from transformers import AutoTokenizer

tokenizer = AutoTokenizer.from_pretrained("bert-base-cased")


def tokenize_function(examples):
    return tokenizer(examples["text"], padding="max_length", truncation=True)


tokenized_datasets = dataset.map(tokenize_function, batched=True)
tokenized_datasets['train'][0].keys()
dict_keys(['label', 'text', 'input_ids', 'token_type_ids', 'attention_mask'])
print(tokenized_datasets['train'][0])
{'label': 4, 'text': "dr. goldberg offers everything i look for in a general practitioner.  he's nice and easy to talk to without being patronizing; he's always on time in seeing his patients; he's affiliated with a top-notch hospital (nyu) which my parents have explained to me is very important in case something happens and you need surgery; and you can get referrals to see specialists without having to see him first.  really, what more do you need?  i'm sitting here trying to think of any complaints i have about him, but i'm really drawing a blank.",
'input_ids': [101, 173, 1197, 119, 2284, 2953, 3272, 1917, 178, 1440, 1111, 1107, 170, 1704, 22351, 119, 1119, 112, 188, 3505, 1105, 3123, 1106, 2037, 1106, 1443, 1217, 10063, 4404, 132, 1119, 112, 188, 1579, 1113, 1159, 1107, 3195, 1117, 4420, 132, 1119, 112, 188, 6559, 1114, 170, 1499, 118, 23555, 2704, 113, 183, 9379, 114, 1134, 1139, 2153, 1138, 3716, 1106, 1143, 1110, 1304, 1696, 1107, 1692, 1380, 5940, 1105, 1128, 1444, 6059, 132, 1105, 1128, 1169, 1243, 5991, 16179, 1106, 1267, 18137, 1443, 1515, 1106, 1267, 1140, 1148, 119, 1541, 117, 1184, 1167, 1202, 1128, 1444, 136, 178, 112, 182, 2807, 1303, 1774, 1106, 1341, 1104, 1251, 11344, 178, 1138, 1164, 1140, 117, 1133, 178, 112, 182, 1541, 4619, 170, 9153, 119, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
'token_type_ids': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}

望むのであれば、かかる時間を削減するために (その上で) 再調整する完全なデータセットの小さいサブセットを作成することができます :

small_train_dataset = tokenized_datasets["train"].shuffle(seed=42).select(range(1000))
small_eval_dataset = tokenized_datasets["test"].shuffle(seed=42).select(range(1000))
len(small_train_dataset), len(small_eval_dataset)
(1000, 1000)

 

Trainer による再調整

Transformers は Transformers モデルを訓練するために最適化された Trainer クラスを提供していて、貴方自身の訓練ループを手動で書くことなく訓練を開始することを容易にします。Trainer API はロギング, 勾配集積 (= accumulation), そして混合精度のような幅広い訓練オプションと機能をサポートします。

モデルをロードすることから始めて想定されるラベル数を指定します。Yelp Review dataset カード から、5 つのラベルがあることがわかります :

from transformers import AutoModelForSequenceClassification

model = AutoModelForSequenceClassification.from_pretrained("bert-base-cased", num_labels=5)

Note : 事前訓練済み重みの一部は使用されずに幾つかの重みはランダムに初期化されたことについて警告を見るでしょう。心配しないでください、これは完全に普通のことです!BERT の事前訓練済みヘッドが捨てられ、ランダムに初期化された分類ヘッドで置き換えられます。シークエンス分類タスクでこの新しいモデルヘッドを再調整し、事前訓練済みモデルの知識をそれに転送します。

 

訓練ハイパーパラメータ

次に、TrainingArguments クラスを作成します、これは調整可能な総てのハイパーパラメータと、異なる訓練オプションを有効にするフラグを含みます。このチュートリアルのためにはデフォルトの訓練 ハイパーパラメータ で開始できますが、最適な設定を見つけるためにこれらで自由に実験してください。

訓練からチェックポイントをどこにセーブするか指定します :

from transformers import TrainingArguments

training_args = TrainingArguments(output_dir="test_trainer")

 

メトリクス

Trainer は訓練の間に自動的にはモデル性能を評価しません。メトリクスを計算して報告する関数を Trainer に渡す必要があります。 Datasets ライブラリは load_metric (詳細はこの チュートリアル 参照) 関数でロード可能な単純な accuracy 関数を提供しています :

import numpy as np
from datasets import load_metric

metric = load_metric("accuracy")

予測の精度を計算するためにメトリックの compute を呼び出します。予測を compute に渡す前に、予測をロジットに変換する必要があります (総ての Transformers モデルはロジットを返すことを忘れないでください) :

def compute_metrics(eval_pred):
    logits, labels = eval_pred
    predictions = np.argmax(logits, axis=-1)
    return metric.compute(predictions=predictions, references=labels)

再調整の間に評価メトリックをモニタリングしたいのであれば、各エポックの最後に評価メトリックをレポートするために訓練引数で evaluation_strategy パラメータを指定します :

from transformers import TrainingArguments

training_args = TrainingArguments(output_dir="test_trainer", evaluation_strategy="epoch")

 

Trainer

モデル, 訓練引数, 訓練とテストデータセット, そして評価関数で Trainer オブジェクトを作成します :

from transformers import Trainer

trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=small_train_dataset,
    eval_dataset=small_eval_dataset,
    compute_metrics=compute_metrics,
)

そして train() を呼び出してモデルを再調整します :

trainer.train()

 

Keras で再調整

Transformers モデルはまた Keras API による TensorFlow での訓練もサポートしています。再調整できる前に幾つかの変更を行なう必要があるだけです。

 

データセットを TensorFlow 形式に変換する

DefaultDataCollator はモデルがその上で訓練するためにテンソルをバッチに集めます。TensorFlow テンソルを返すために return_tensors を指定することを確実にしてください :

from transformers import DefaultDataCollator

data_collator = DefaultDataCollator(return_tensors="tf")

Note : Trainer はデフォルトで DataCollatorWithPadding を使用しますので、データ collator (照合機) を明示的に指定する必要はありません。

次に、トークン化されたデータセットを to_tf_dataset メソッドで TensorFlow データセットに変換します。columns で入力を、label_cols でラベルを指定します :

tf_train_dataset = small_train_dataset.to_tf_dataset(
    columns=["attention_mask", "input_ids", "token_type_ids"],
    label_cols=["labels"],
    shuffle=True,
    collate_fn=data_collator,
    batch_size=8,
)

tf_validation_dataset = small_eval_dataset.to_tf_dataset(
    columns=["attention_mask", "input_ids", "token_type_ids"],
    label_cols=["labels"],
    shuffle=False,
    collate_fn=data_collator,
    batch_size=8,
)

 

Compile と fit

想定されるラベル数と共に TensorFlow モデルをロードします :

import tensorflow as tf
from transformers import TFAutoModelForSequenceClassification

model = TFAutoModelForSequenceClassification.from_pretrained("bert-base-cased", num_labels=5)

そして他の Keras モデルでそうするように compile してから fit でモデルを再調整します :

model.compile(
    optimizer=tf.keras.optimizers.Adam(learning_rate=5e-5),
    loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
    metrics=tf.metrics.SparseCategoricalAccuracy(),
)

model.fit(tf_train_dataset, validation_data=tf_validation_dataset, epochs=3)

 

native PyTorch で再調整

Trainer は訓練ループを処理してモデルを単一行のコードで再調整することを可能にします。独自の訓練ループを書くことを好むユーザについては、native PyTorch で Transformers モデルを再調整することもできます。

この時点で、ノートブックを再起動するか、あるいは何某かのメモリを解放するために以下のコードを実行する必要があるかもしれません :

del model
del pytorch_model
del trainer
torch.cuda.empty_cache()

 
次に、tokenized_dataset を訓練用に準備するため手動で後処理します。

  1. text カラムを削除します、モデルは入力として raw テキストを受け取らないからです :
    tokenized_datasets = tokenized_datasets.remove_columns(["text"])
    

  2. label カラムを labels に名前変更します、モデルは引数が labels と命名されていることを想定しているからです :
    tokenized_datasets = tokenized_datasets.rename_column("label", "labels")
    

  3. リストの代わりに PyTorch テンソルを返すようにデータセットの形式を設定します :
    tokenized_datasets.set_format("torch")
    

それから再調整をスピードアップするために前に示されたようにデータセットの小さいなサブセットを作成します :

small_train_dataset = tokenized_datasets["train"].shuffle(seed=42).select(range(1000))
small_eval_dataset = tokenized_datasets["test"].shuffle(seed=42).select(range(1000))

 

DataLoader

データのバッチに対してイテレートできるように、訓練とテストデータセットのために DataLoader を作成します :

from torch.utils.data import DataLoader

train_dataloader = DataLoader(small_train_dataset, shuffle=True, batch_size=8)
eval_dataloader = DataLoader(small_eval_dataset, batch_size=8)

想定されるラベルの数と共にモデルをロードします :

from transformers import AutoModelForSequenceClassification

model = AutoModelForSequenceClassification.from_pretrained("bert-base-cased", num_labels=5)

 

Optimizer と学習率スケジューラ

モデルを再調整するために optimizer と学習率スケジューラを作成します。PyTorch からの AdamW optimizer を使用しましょう :

from torch.optim import AdamW

optimizer = AdamW(model.parameters(), lr=5e-5)

Trainer からのデフォルトの学習率スケジューラを作成します :

from transformers import get_scheduler

num_epochs = 3
num_training_steps = num_epochs * len(train_dataloader)
lr_scheduler = get_scheduler(
    name="linear", optimizer=optimizer, num_warmup_steps=0, num_training_steps=num_training_steps
)

最後に、アクセス可能な GPU が持つならばそれを利用するように device を指定します。そうでないなら、CPU 上の訓練は数分ではなく数時間かかるかもしれません。

import torch

device = torch.device("cuda") if torch.cuda.is_available() else torch.device("cpu")
model.to(device)

Great, now you are ready to train!

 

訓練ループ

訓練進捗を追跡するため、訓練ステップ数に対してプログレスバーを追加する tqdm ライブラリを使用します :

from tqdm.auto import tqdm

progress_bar = tqdm(range(num_training_steps))

model.train()
for epoch in range(num_epochs):
    for batch in train_dataloader:
        batch = {k: v.to(device) for k, v in batch.items()}
        outputs = model(**batch)
        loss = outputs.loss
        loss.backward()

        optimizer.step()
        lr_scheduler.step()
        optimizer.zero_grad()
        progress_bar.update(1)

 

メトリクス

Trainer に評価関数を追加する必要があるのと同様に、貴方自身の訓練ループを書く時に同じことを行なう必要があります。しかし各エポックの最後にメトリックを計算してレポートする代わりに、今回は add_batch で総てのバッチを蓄積して最後の最後にメトリックを計算します。

metric = load_metric("accuracy")
model.eval()
for batch in eval_dataloader:
    batch = {k: v.to(device) for k, v in batch.items()}
    with torch.no_grad():
        outputs = model(**batch)

    logits = outputs.logits
    predictions = torch.argmax(logits, dim=-1)
    metric.add_batch(predictions=predictions, references=batch["labels"])

metric.compute()
 

以上



HuggingFace Transformers 4.17 : Tutorials : モデルの概要

HuggingFace Transformers 4.17 : Tutorials : モデルの概要 (翻訳/解説)

翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 04/17/2022 (v4.17.0)

* 本ページは、HuggingFace Transformers の以下のドキュメントを翻訳した上で適宜、補足説明したものです:

* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。

 

クラスキャット 人工知能 研究開発支援サービス

クラスキャット は人工知能・テレワークに関する各種サービスを提供しています。お気軽にご相談ください :

◆ 人工知能とビジネスをテーマに WEB セミナーを定期的に開催しています。スケジュール
  • お住まいの地域に関係なく Web ブラウザからご参加頂けます。事前登録 が必要ですのでご注意ください。

お問合せ : 本件に関するお問い合わせ先は下記までお願いいたします。

  • 株式会社クラスキャット セールス・マーケティング本部 セールス・インフォメーション
  • sales-info@classcat.com  ;  Web: www.classcat.com  ;   ClassCatJP

 

HuggingFace Transformers : Tutorials : モデルの概要

これは Transformers で利用可能なモデルの概要です。元の transformer モデル に馴染みがあることを仮定しています。優しいイントロダクションのためには annotated transformer を確認してください。ここではモデル間の高位な違いにフォーカスします。それぞれのドキュメントでそれらをより詳細に調べることができます。モデルハブ を確認することもできます、そこではモデルアーキテクチャによりチェックポイントをフィルタリングできます。

ライブラリのモデルの各一つは以下のカテゴリーの一つに分類されます :

  • 自己回帰モデル
  • オートエンコーダ・モデル
  • seq-to-seq モデル
  • マルチモーダル・モデル
  • 検索ベースの (= Retrieval-based) モデル

自己回帰 (= autoregressive) モデルは古典的な言語モデリング・タスク上で事前訓練されています : 前の総てのトークンを読んで次のトークンを推測します。それらは元の transformer モデルのデコーダに相当し、そして attention ヘッドが後に何があるかではなく前に何があったかだけを見ることができるように、マスクが full センテンスの上で使用されます。これらのモデルは多くのタスク上で再調整されて素晴らしい結果を獲得できますが、最も自然な応用はテキスト生成です。そのようなモデルの典型的な例は GPT です。

※ 訳注: 自己回帰モデルは一般には、ある時間ステップにおけるモデル出力がそれ以前のモデル出力に依存する確率過程です。

オートエンコーディング・モデルは入力トークンを何らかの方法で破損 (= corrupt) させて元のセンテンスを再構築することを試みて事前訓練されます。それらは、どのようなマスクもなしで完全な入力にアクセスするという意味で、元の transformer モデルのエンコーダに対応します。それらのモデルは通常はセンテンス全体の双方向表現を構築します。それらはテキスト生成のような多くのタスク上で再調整されて素晴らしい結果を獲得できますが、それらの最も自然な応用はセンテンス分類やトークン分類です。そのようなモデルの典型的な例は BERT です。

自己回帰モデルとオートエンコーディング・モデルの唯一の違いはモデルが事前訓練される方法にある ことに注意してください。
従って 自己回帰とオートエンコーディング・モデルの両者のために同じアーキテクチャが利用できます。与えられたモデルが両者のタイプの事前訓練のために使用されたとき、それが最初に紹介された記事に対応するカテゴリーにそれを入れます。

sequence-to-sequence モデルは、翻訳タスクのためや他のタスクを sequence-to-sequence 問題に変換することにより、元の transformer のエンコーダとデコーダの両者を利用します。それらは多くのタスクに対して再調整できますが、それらの最も自然な応用は翻訳、要約そして質問応答です。元の transformer モデルは (翻訳のためだけの) そのようなモデルの例で、T5 は他のタスク上で再調整できる例です。

マルチモーダル・モデルはテキスト入力を他の種類 (e.g. 画像) と混在させてそして与えられたタスクに対してより特有です。

 

デコーダ or 自己回帰モデル

前述のように、これらのモデルは元の transformer のデコーダ部に依存し、各位置でモデルが attention ヘッドの前のトークンだけを見れるように attention マスクを利用します。

 

Original GPT

transformer アーキテクチャに基づく最初の自己回帰モデルです、Book Corpus データセット上で事前訓練されました。

このライブラリは言語モデリングとマルチタスク言語モデリング/多肢選択式分類のためのモデルのバージョンを提供します。

 

GPT-2

GPT のより大きくてより良いバージョンです、WebText 上で事前訓練されました (3 karma 以上の Reddit の outgoing リンクからの web ページ)。

このライブラリは言語モデリングとマルチタスク言語モデリング/多肢選択式分類のためのモデルのバージョンを提供します。

 

CTRL

GPT モデルと同じですが、制御コードのアイデアを追加しています。テキストはプロンプト (empty であり得ます) とテキスト生成に影響を与えるために使用される制御コードの一つ (or 幾つか) から生成されます : wikipedia 記事、本や映画レビューのスタイルで生成します。

このライブラリは言語モデリングのためのモデルのバージョンだけを提供します。

 

Transformer-XL

通常の GPT モデルと同じですが、2 つの連続するセグメントに対してリカレンス機構を導入します (2 つの連続する入力を持つ通常の RNN に類似しています)。このコンテキストでは、セグメントは数多くの連続するトークン (例えば 512) で、これは複数のドキュメントに渡って広がるかもしれません、そしてセグメントは順番にモデルに供給されます。

基本的には、前のセグメントの隠れ状態は attention スコアを計算するために現在の入力に結合されます。これはモデルに現在のセグメントに加えて前のセグメント内の情報に注意を払うことを可能にします。マルチ attention 層をスタックすることにより、受容野 (= receptive field) は複数の前のセグメントに増加できます。

これは位置埋め込みを位置相対的 (= relative) 埋め込みに変更します、(何故ならば通常の位置埋め込みは与えられた位置で現在の入力と現在の隠れ状態の同じ結果を与えるからです) そして attention スコアが計算される方法で何某かの調整を行なう必要があります。

このライブラリは言語モデリングのためのモデルのバージョンだけを提供します。

 

Reformer

メモリ使用量と計算時間を削減するために多くのトリックを持つ自己回帰 transformer モデルです。これらのトリックは以下を含みます :

  • axial (軸の) 位置エンコーディング を使用します (より詳細は下を見てください)。それは (シークエンス長が非常に大きいとき) 巨大な位置エンコーディング行列を持つことをそれをより小さい行列に分解することにより回避する機構です。
  • 伝統的な attention を LSH (local-sensitive hashing) attention により置き換えます (より詳細は下を見てください)。それは attention 層で full 積 query-key を計算することを回避するテクニックです。
  • 各層の中間結果をストアすることを、backward パスの間にそれらを得るために可逆な (= reversible) transformer 層を使用するか (次の層の入力から残差を減算することはそれらを与え戻します)、与えられた層内で結果のためにそれらを再計算することにより (それらをストアするよりも非効率的ですがメモリを節約します) 回避します。
  • バッチ全体上ではなく chunks により feedforward 演算を計算します。

これらのトリックで、モデルは伝統的な transformer 自己回帰モデルよりも遥かに大きなセンテンスが供給できます。

Note: このモデルはオートエンコーディング設定で非常に上手く利用できるでしょう、けれどもそのような事前訓練のためのチェックポイントはまだありません。

このライブラリは言語モデリングのためのモデルのバージョンだけを提供します。

 

XLNet

XLNet は伝統的な自己回帰モデルではありませんが、その上で構築される訓練ストラテジーを利用します。それはセンテンスのトークンを並べ替えて (= permute) から、トークン n+1 を予測するために最後の n トークン(s) を使用することをモデルに許容します。これはマスクで成されますので、センテンスは実際には正しい順序でモデルに供給されますが、n+1 のために最初の n トークンをマスクする代わりに、XLNet は 1,…,シークエンス長のある与えられた並べ替え (= permutation) 内の前のトークンを隠すマスクを使用します。

XLNet はまた長期依存性を構築するために Transformer-XL と同じリカレンス機構も利用します。

このライブラリは言語モデリング、トークン分類、センテンス分類、マルチ選択分類と質問応答のためのモデルのバージョンを提供します。

 

エンコーダ or オートエンコーディング・モデル

前述したように、これらのモデルは元の transformer のエンコーダ部に依存していて、マスクは使用しませんのでモデルは attention ヘッドで総てのトークンを見ることができます。事前訓練については、ターゲットは元のセンテンスで入力はそれらの破損バージョンです。

 

BERT

ランダム・マスキングを使用して入力を破損させます、より正確には、事前訓練の間、トークンの与えられたパーセンテージ (通常は 15%) が以下によりマスクされます :

  • 確率 0.8 で特殊マスクトークン
  • 確率 0.1 でマスクされたものとは異なるランダムトークン
  • 確率 0.1 で同じトークン

モデルは元のセンテンスを予測しなければなりませんが、2 番目の目的を持ちます : 入力は 2 つのセンテンス A と B です (間には分離トークンを伴います)。確率 50% で、センテンスはコーパス内で連続的です、残りの 50% でそれらは関係ありません。モデルはセンテンスが連続的か否かを予測しなければなりません。

このライブラリは言語モデリング (伝統的 or マスク付き)、次文 (= next sentence) 予測、トークン分類、センテンス分類、多肢選択式分類と質問応答のためのモデルのバージョンを提供します。

 

ALBERT

BERT と同じですが 2, 3 の微調整を伴います :

  • 埋め込みサイズ E は理にかなった隠れサイズ H とは異なります、何故ならば埋め込みはコンテキスト独立である (一つの埋め込みベクトルは一つのトークンを表します) 一方で、隠れ状態はコンテキスト依存である (一つの隠れ状態はトークンのシークエンスを表します) からです、従って H >> E を持つことはより論理的です。また、埋め込み行列は巨大です、何故ならばそれは V x E (V は vocab サイズ) であるからです。E < H であれば、それはより少ないパラメータを持ちます。
  • 層は (メモリを節約するために) パラメータを共有するグループに分割されます。
  • 次文予測はセンテンス順序予測に置き換えられます : 入力では、2 つのセンテンス A と B を持ち (それらは連続的です) A に続いて B か B に続いて A のいずれかを供給します。モデルはそれらが交換されているか否かを予測しなければなりません。

このライブラリはマスク付き言語モデリング、トークン分類、センテンス分類、多肢選択式分類と質問応答のためのモデルのバージョンを提供します。

 

RoBERTa

BERT と同じですが以下のより良い事前訓練トリックを持ちます :

  • 動的マスキング : トークンは各エポックで異なってマスクされます、その一方で BERT はそれを一度限り行ないます。
  • NSP (次文予測) 損失はなくそして単に 2 センテンスを一緒に置く代わりに、512 トークンに達するまで連続するテキストのチャンクを一緒にまとめます (従ってセンテンスは幾つかのドキュメントに渡るかもしれない順番どおりです)。
  • より大規模なバッチで訓練します。
  • サブユニットとして文字ではなくバイトを持つ BPE を使用します (ユニコード文字ゆえに)。

このライブラリはマスク付き言語モデリング、トークン分類、センテンス分類、多肢選択式分類と質問応答のためのモデルのバージョンを提供します。

 

DistilBERT

BERT と同じですがより小さいです。事前訓練された BERT モデルの蒸留により訓練されます、より大きいモデルと同じ確率を予測するために訓練されたことを意味します。実際の目的は以下の組合せです :

  • 教師モデルと同じ確率を見つける
  • マスクされたトークンを正しく予測する (しかし次文目的ではない)
  • 生徒と教師モデルの隠れ状態の間の cos 類似度

このライブラリはマスク付き言語モデリング、トークン分類、センテンス分類と質問応答のためのモデルのバージョンを提供します。

 

ConvBERT

BERT とその変種のような事前訓練言語モデルは最近様々な自然言語理解タスクで印象的なパフォーマンスを獲得しています。けれども、 BERT はグローバル自己 attention ブロックに大きく依拠しているため大きなメモリ消費量と計算コストがかかります。総ての attention ヘッドはグローバル視点から attention マップを生成するために入力シークエンス全体の上で問い合わせをしますが、幾つかのヘッドはローカル依存性を学習する必要があるだけであることを観察します、これは計算の冗長性の存在を意味します。そこでローカル依存性を直接モデル化するためにこれらの自己 attention ヘッドを置き換える新しい span ベースの動的畳込みを提案します。新しい畳込みヘッドは、残りの自己 attention ヘッドと一緒に、新しい混合 attention ブロックを形成します、これはグローバルとローカル・コンテキスト学習の両者でより効率的です。この混合 attention 設計を BERT に装備して ConvBERT モデルを構築します。より低い訓練コストとより少ないモデルパラメータで、ConvBERT は様々な下流タスクで BERT とその変種のパフォーマンスを本質的に越えることを実験は示しました。驚くべきことに、ConvBERTbase モデルは ELECTRAbase より 0.7 高い、86.4 GLUE スコアを獲得する一方で、1/4 の訓練コスト未満を使用しています。

このライブラリはマスク付き言語モデリング、トークン分類、センテンス分類と質問応答のためのモデルのバージョンを提供します。

 

XLM

幾つかの言語上で訓練された transformer モデルです。このモデルのための 3 つの異なるタイプの訓練がありそしてライブラリはそれらの総てのためのチェックポイントを提供します :

  • 因果 (= Causal) 言語モデリング (CLM)、これは伝統的な自己回帰訓練です (従ってこのモデルは前のセクションにも入れるかもしれません)。各訓練サンプルのために言語の一つが選択され、そしてモデル入力は 256 トークンのセンテンスで、それらの言語の一つで幾つかのドキュメントに渡るかもしれません。

  • マスク付き言語モデリング (MLM)、これは RoBERTa のようなものです。各訓練サンプルのために言語の一つが選択され、そしてモデル入力は 256 トークンのセンテンスで、トークンの動的マスクを用い、それらの言語の一つで幾つかのドキュメントに渡るかもしれません。

  • MLM と翻訳言語モデリング (TLM) の組合せ。これはランダム・マスキングを伴い、 2 つの異なる言語のセンテンスを連結することから構成されます。マスクされたトークンの一つを予測するため、モデルは言語 1 の周囲のコンテキストと言語 2 で与えられるコンテキストの両者を利用できます。

チェックポイントはそれらの名前内で clm, mlm or mlm-tlm を持つことにより事前訓練のためにどの方法が利用されたかを参照します。位置埋め込みの上にモデルは言語埋め込みを持ちます。MLM/CLM を使用して訓練するとき、これは使用される言語の指示を、そして MLM+TLM を使用して訓練するとき、各パートのために使用される言語の指示をモデルに与えます。

このライブラリは言語モデリング、トークン分類、センテンス分類と質問応答のためのモデルのバージョンを提供します。

 

XLM-RoBERTa

XLM アプローチ上で RoBERTa トリックを利用しますが、翻訳言語モデリング目的は利用しません。それは一つの言語からのセンテンス上のマスク付き言語モデリングだけを使用します。けれども、モデルはより多くの言語 (100) 上で訓練されて言語埋め込みは使用しませんので、入力言語を自身で検出することができます。

このライブラリはマスク付き言語モデリング、トークン分類、センテンス分類、多肢選択式分類と質問応答のためのモデルのバージョンを提供します。

 

FlauBERT

RoBERTa のように、センテンス順序予測はありません (従って単に MLB 目的の上で訓練されます)。

このライブラリはマスク付き言語モデリングとセンテンス分類のためのモデルのバージョンを提供します。

 

ELECTRA

ELECTRA は別の (小さな) マスク付き言語モデルの使用で事前訓練される transformer モデルです。入力はその言語モデルにより破損されます、それはランダムにマスクされた入力テキストを取りそしてテキストを出力します、その (出力) テキストでは ELECTRA はどのトークンが元のものでありどれが置き換えられたかを予測しなければなりません。GAN 訓練のためのように、その小さい言語モデルは数ステップの間訓練されてから (しかし目的としての元のテキストで、伝統的な GAN 設定でのように ELECTRA モデルを騙したりはしません)、ELECTRA モデルが数ステップの間訓練されます。

このライブラリはマスク付き言語モデリング、トークン分類、センテンス分類のためのモデルのバージョンを提供します。

 

Funnel Transformer

Funnel Transformer は pooling を使用する transformer モデルで、少し ResNet モデルのようです : 層はブロックにグループ分けされ、そして (最初の一つを除いて) 各ブロックの最初で、隠れ状態はシークエンス次元内でプーリングされます。この方法で、それらの長さは 2 で除算され、これは次の隠れ状態の計算をスピードアップします。総ての事前訓練モデルは 3 つのブロックを持ち、これは最後の隠れ状態は元のシークエンス長の 4 分の 1 のシークエンス長を持つことを意味します。

分類のようなタスクについては、これは問題ではありませんが、マスク付き言語モデリングやトークン分類のようなタスクについては、元の入力と同じシークエンス長を持つ隠れ状態を必要とします。それらの場合には、最後の隠れ状態は入力シークエンス長にアップサンプリングされて 2 つの追加層を通り抜けます。それが各チェックポイントの 2 つのバージョンがある理由です。“-base” でサフィックスされるバージョンは 3 つのブロックだけを含む一方で、そのサフィックスがないバージョンは 3 つのブロックとその追加層を持つアップサンプリング・ヘッドを含みます。

利用可能な事前訓練モデルは ELECTRA と同じ事前訓練目的を使用しています。

このライブラリはマスク付き言語モデリング、トークン分類、センテンス分類、多肢選択式分類と質問応答のためのモデルのバージョンを提供します。

 

Longformer

高速にするために attention 行列をスパース行列に置き換えた transformer モデルです。しばしば、ローカル・コンテキスト (e.g. 左右の 2 つのトークンは何でしょう?) は与えられたトークンに対してアクションするために十分です。ある事前選択された入力トークンには依然として global attention が与えられますが、attention 行列はよりパラメータが少ない方法を持ち、スピードアップという結果になります。より多くの情報については ローカル attention セクション を見てください。

その他は RoBERTa と同じ方法で事前訓練されます。

Note: このモデルは自己回帰設定で非常に上手く利用できるでしょう、けれどもそのような事前訓練のためのチェックポイントはまだありません。

このライブラリはマスク付き言語モデリング、トークン分類、センテンス分類、多肢選択式分類と質問応答のためのモデルのバージョンを提供します。

 

Sequence-to-sequence モデル

前述のように、これらのモデルは元の transformer のエンコーダとデコーダの両者を保持しています。

 

BART

エンコーダとデコーダを持つ sequence-to-sequence モデル。エンコーダはトークンの破損バージョンが供給され、デコーダは元のトークンが供給されます (しかし通常の transformer デコーダのように未来の単語を隠すマスクを持ちます)。エンコーダについては、事前訓練タスク上、以下の変換の組合せが適用されます :

  • ランダムにトークンをマスクします (BERT のように)
  • ランダムにトークンを削除します
  • 単一のマスクトークンで k トークンの範囲をマスクします (0 トークンのスパンはマスクトークンの挿入です)
  • センテンスを並べ替える
  • 特定のトークンで開始されるようにドキュメントを rotate します

このライブラリは条件付き生成とシークエンス分類ためのモデルのバージョンを提供します。

 

Pegasus

BART と同じエンコーダ・デコーダモデルを持つ sequence-to-sequence モデルです。Pegasus は 2 つの自己教師あり目的関数上で同時に事前訓練されます : マスク付き言語モデリング (MLM) と Gap センテンス生成 (GSG, Gap Sentence Generation) と呼称される、新しい要約固有の事前訓練目的です。

  • MLM: エンコーダ入力トークンはマスクトークンによりランダムに置き換えられてエンコーダにより予測されなければなりません (BERT のように)。
  • GSG: エンコーダ入力センテンス全体が 2 番目のマスクトークンにより置き換えられてデコーダに供給されますが、それは通常の自己回帰 transformer デコーダのように未来の単語を隠すために因果マスクを持ちます。

BART と対照的に、Pegasus の事前訓練タスクは意図的に要約に類似しています : 重要なセンテンスはマスクされて残りのセンテンスから一つの出力センテンスとして一緒に生成されます、抽出型要約に類似しています。

このライブラリは要約のために使用されるべき条件付き生成のためのモデルのバージョンを提供します。

 

MarianMT

翻訳モデルのためのフレームワークです、BART と同じモデルを使用しています。

このライブラリは条件付き生成のためのモデルのバージョンを提供します。

 

T5

伝統的な transformer モデルを使用します (位置埋め込みで僅かな変更を伴います、これは各層で学習されます)。総ての NLP タスク上で動作できるように、それは特定のプレフィックスを使用することによりそれらをテキスト-to-テキスト問題に変換します : “summarize: ”, “question: ”, “translate English to German: ” 等々。

事前訓練は教師ありと自己教師あり訓練の両者を含みます。教師あり訓練は GLUE と SuperGLUE ベンチマークにより提供される下流タスク上で実行されます (それらを上で説明されたように text-to-text タスクに変換します)。

自己教師あり訓練はトークンの 15% をランダムに除去してそれらを個別の sentinel (見張り) トークンで置き換えることにより (もし幾つかの連続するトークンが除去のためにマークされる場合、グループ全体が単一の sentinel トークンで置き換えられます)、 破損トークンを利用します。エンコーダの入力は破損センテンスで、デコーダの入力は元のセンテンスでそれからターゲットは sentinel トークンで範囲が定められたドロップアウトされたトークンです。

例えば、センテンス “My dog is very cute .” を持ち、そしてトークン “dog”, “is” と “cute” を取り除くことを決めた場合、エンコーダ入力は “My <x> very <y> .” となりそしてターゲット入力は “<x> dog is <y> cute .<z>” になります。

このライブラリは条件付き生成のためのモデルのバージョンを提供します。

 

MT5

モデル・アーキテクチャは T5 と同じです。mT5 の事前訓練目的は T5 の自己教師あり訓練を含みますが、T5 の教師あり訓練は含みません。mT5 は 101 言語上で訓練されています。

このライブラリは条件付き生成のためのモデルのバージョンを提供します。

 

MBart

モデル・アーキテクチャと事前訓練目的は BART と同じですが、MBart は 25 言語上で訓練されてそして教師ありと教師なし機械翻訳が対象とされています。多言語の full テキストをノイズ除去することによる完全な sequence-to-sequence モデルを事前訓練するための最初の方法の一つです。

このライブラリは条件付き生成のためのモデルのバージョンを提供します。

mbart-large-en-ro チェックポイント は英語 -> ルーマニア語翻訳のために利用できます。

mbart-large-cc25 チェックポイントは `examples/seq2seq/` のコードを使用して、他の翻訳と要約タスクのために再調整できますが、再調整なしではそれほど有用ではありません。

 

ProphetNet

ProphetNet は未来 n-gram 予測と呼ばれる、新しい sequence-to-sequence 事前訓練目的を導入します。未来 n-gram 予測では、各時間ステップで前のコンテキスト・トークンに基づいてモデルは (単に単一の次のトークンの代わりに) 次の n トークンを同時に予測します。未来 n-gram 予測はモデルが未来のトークンのために計画して強い局所的な相関性の上で overfitting を回避することを促進します。モデル・アーキテクチャは元の Transformer に基づきますが、デコーダの「標準的な」自己 attention 機構を主要な自己 attention 機構と self と n-stream (predict) 自己attention 機構と置き換えます。

このライブラリは条件付き生成のためのモデルの事前訓練バージョンと要約のための再調整バージョンを提供します。

 

XLM-ProphetNet

XLM-ProphetNet のモデル・アーキテクチャと事前訓練目的 は ProphetNet と同じですが、XLM-ProphetNet は交差 lingual データセット XGLUE 上で事前訓練されました。

このライブラリは多言語条件付き生成のためのこのモデルの事前訓練バージョンとヘッドライン生成と質問生成のための再調整バージョンをそれぞれ提供します。

 

マルチモーダル・モデル

ライブラリには一つのマルチモーダル・モデルがあります、これは他のもののような自己教師あり流儀での事前訓練はされません。

 

MMBT

マルチモーダル設定で使用される transformers モデルは、予測を行なうためにテキストと画像を連結します。transformer モデルは入力としてトークン化されたテキストの埋め込みと、画像上で事前訓練された resnet の (resnet の最後の多くの特徴から transformer の隠れ状態次元へ通り抜けるための) 線形層を通り抜けた (最後のプーリング層の後の) 最後の活性を取ります。

異なる入力は連結されて、そして位置埋め込みの上に入力ベクトルのどの部分がテキストに対応してどれが画像に対応するかをモデルに知らせるためにセグメント埋め込みが追加されます。

事前訓練モデルは分類のためだけに動作します。

 

Retrieval-based (検索ベース) モデル

幾つかのモデルは、例えばオープンドメインの質問応答のために (事前) 訓練と推論の間にドキュメント検索を利用します。

 

DPR

Dense Passage Retrieval (DPR) – 最先端のオープンドメイン質問応答研究のためのツールとモデルのセットです。

DPR は 3 つのモデルにあります :

  • 質問エンコーダ : 質問をベクトルとしてエンコードする
  • コンテキスト・エンコーダ : コンテキストをベクトルとしてエンコードする
  • リーダー (= Reader) : 関連 (= relevance) スコア (推論された span が実際に質問に答える場合に高い) とともに、検索されたコンテキスト内から質問の答えを抽出する。

DPR のパイプラインはある質問が与えられたときに top k コンテキストを見つけるために検索ステップを使用し、それからそれは回答を得るために質問と検索されたドキュメントとともにリーダーを呼び出します。

 

RAG

  • All モデルページ : rag (8) ; モデル文書 : rag
  • Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks, Patrick Lewis, Ethan Perez, Aleksandara Piktus, Fabio Petroni, Vladimir Karpukhin, Naman Goyal, Heinrich Küttler, Mike Lewis, Wen-tau Yih, Tim Rocktäschel, Sebastian Riedel, Douwe Kiela
    (知識集約型 NLP タスクのための Retrieval-Augmented 生成)

Retrieval-augmented 生成 (“RAG”) モデルは事前訓練 dense retrieval (DPR) と Seq2Seq モデルのパワーを結合しています。RAG モデルは docs を取得し、それらを seq2seq モデルに渡してから、出力を生成するために周辺化します。下流タスクに適応するために取得と生成の両者を許容するために、retriever と seq2seq モジュールは事前訓練モデルから初期化され、同時に再調整されます。

2 つのモデル RAG-Token と RAG-Sequence は生成のために利用可能です。

 

以上



HuggingFace Transformers 4.17 : Tutorials : タスクの概要

HuggingFace Transformers 4.17 : Tutorials : タスクの概要 (翻訳/解説)

翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 04/15/2022 (v4.17.0)

* 本ページは、HuggingFace Transformers の以下のドキュメントを翻訳した上で適宜、補足説明したものです:

* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。

 

クラスキャット 人工知能 研究開発支援サービス

クラスキャット は人工知能・テレワークに関する各種サービスを提供しています。お気軽にご相談ください :

◆ 人工知能とビジネスをテーマに WEB セミナーを定期的に開催しています。スケジュール
  • お住まいの地域に関係なく Web ブラウザからご参加頂けます。事前登録 が必要ですのでご注意ください。

お問合せ : 本件に関するお問い合わせ先は下記までお願いいたします。

  • 株式会社クラスキャット セールス・マーケティング本部 セールス・インフォメーション
  • sales-info@classcat.com  ;  Web: www.classcat.com  ;   ClassCatJP

 

HuggingFace Transformers : Tutorials : タスクの概要

このページはライブラリを利用するとき最も頻度の高いユースケースを示します。利用可能なモデルはユースケースで多くの様々な configuration と素晴らしい多用途性を可能にします。最も単純なものはここで提示され、質問応答、シークエンス分類、固有表現認識 等のようなタスクのための使用方法を紹介します。

これらのサンプルは 自動モデル (= auto-models) を活用します、これらは与えられたチェックポイントに従ってモデルをインスタンス化するクラスで、正しいモデル・アーキテクチャを自動的に選択します。詳細については AutoModel ドキュメントを確認してください。より特定的にコードを自由に変更してそれを特定のユースケースに適応させてください。

モデルがタスク上で上手く動作するためには、それは タスクに対応するチェックポイントからロードされなければなりません。これらのチェックポイントは通常は大規模なデータのコーパス上で事前訓練されて特定のタスク上で再調整されます。これは以下を意味しています :

  • 総てのモデルが総てのタスク上で再調整されてはいません。特定のタスク上でモデルを再調整することを望む場合には、examples ディレクトリの run_$TASK.py スクリプトの一つを活用できます。

  • 再調整済みモデルは特定のデータセット上で再調整されました。このデータセットは貴方のユースケースとドメインと重なるかもしれないしそうでないかもしれません。前述のように、貴方のモデルを再調整するために examples スクリプトを利用しても良いですし、あるいは貴方自身の訓練スクリプトを作成しても良いです。

タスク上で推論を行なうため、幾つかのメカニズムがライブラリにより利用可能になっています :

  • Pipeline : 非常に利用しやすい抽象化で、これらは 2 行ほどの少ないコードを必要とするだけです。
  • 直接モデル利用 : 抽象度は低いですが、トークナイザー (PyTorch/TensorFlow) への直接アクセスと full 推論機能を通してより多くの柔軟性とパワーがあります。

両者のアプローチがここで紹介されます。

Note: ここで提示される総てのタスクは特定のタスク上で再調整された事前訓練済みチェックポイントを利用しています。特定のタスク上で再調整されていないチェックポイントのロードはそのタスクのために使用された追加のヘッドではなくベース transformer 層だけをロードして、ヘッドの重みをランダムに初期化します。
これはランダム出力を生成します。

 

シークエンス分類

シークエンス分類は与えられたクラス数に従ってシークエンスを分類するタスクです。シークエンス分類のサンプルは GLUE データセットで、これはそのタスクに完全に基づいています。GLUE 分類タスク上でモデルを再調整したいのであれば、run_glue.py, run_glue.py (for tensorflow), run_text_classification.py (for tensorflow) または run_xnli.py スクリプトを利用して良いです。

ここにセンチメント分析を行なうために pipeline を使用するサンプルがあります : シークエンスがポジティブかネガティブかを識別します。それは sst2 上で再調整されたモデルを利用します、これは GLUE タスクです。

これは次のように、スコアとともにラベル (“POSITIVE” or “NEGATIVE”) を返します :

from transformers import pipeline

classifier = pipeline("sentiment-analysis")

result = classifier("I hate you")[0]
print(f"label: {result['label']}, with score: {round(result['score'], 4)}")

result = classifier("I love you")[0]
print(f"label: {result['label']}, with score: {round(result['score'], 4)}")
label: NEGATIVE, with score: 0.9991
label: POSITIVE, with score: 0.9999

 
2 つのシークエンスが互いの言い換え (= paraphrase) であるかを決定するモデルを使用してシークエンス分類を行なうサンプルがここにあります。そのプロセスは以下です :

  1. チェックポイント名からトークナイザーとモデルをインスタンス化します。モデルは BERT モデルとして識別されてそれをチェックポイントにストアされた重みでロードします。

  2. 2 つのセンテンスから、正しいモデル固有の separator、トークン型 id と attention マスクを伴うシークエンスを構築します (これらはトークナイザーにより自動的に作成されます)。

  3. シークエンスをモデルに渡してその結果それは 2 つの利用可能なクラスの一つに分類されます : 0 (not a paraphrase) と 1 (is a paraphrase) 。

  4. クラスに渡る確率を得るために結果の softmax を計算します。

  5. 結果をプリントします。
PyTorch
from transformers import AutoTokenizer, AutoModelForSequenceClassification
import torch

tokenizer = AutoTokenizer.from_pretrained("bert-base-cased-finetuned-mrpc")
model = AutoModelForSequenceClassification.from_pretrained("bert-base-cased-finetuned-mrpc")

classes = ["not paraphrase", "is paraphrase"]

sequence_0 = "The company HuggingFace is based in New York City"
sequence_1 = "Apples are especially bad for your health"
sequence_2 = "HuggingFace's headquarters are situated in Manhattan"

# The tokenizer will automatically add any model specific separators (i.e.  and ) and tokens to
# the sequence, as well as compute the attention masks.
paraphrase = tokenizer(sequence_0, sequence_2, return_tensors="pt")
not_paraphrase = tokenizer(sequence_0, sequence_1, return_tensors="pt")

paraphrase_classification_logits = model(**paraphrase).logits
not_paraphrase_classification_logits = model(**not_paraphrase).logits

paraphrase_results = torch.softmax(paraphrase_classification_logits, dim=1).tolist()[0]
not_paraphrase_results = torch.softmax(not_paraphrase_classification_logits, dim=1).tolist()[0]

# Should be paraphrase
for i in range(len(classes)):
    print(f"{classes[i]}: {int(round(paraphrase_results[i] * 100))}%")
not paraphrase: 10%
is paraphrase: 90%
# Should not be paraphrase
for i in range(len(classes)):
    print(f"{classes[i]}: {int(round(not_paraphrase_results[i] * 100))}%")
not paraphrase: 94%
is paraphrase: 6%
TensorFlow
from transformers import AutoTokenizer, TFAutoModelForSequenceClassification
import tensorflow as tf

tokenizer = AutoTokenizer.from_pretrained("bert-base-cased-finetuned-mrpc")
model = TFAutoModelForSequenceClassification.from_pretrained("bert-base-cased-finetuned-mrpc")

classes = ["not paraphrase", "is paraphrase"]

sequence_0 = "The company HuggingFace is based in New York City"
sequence_1 = "Apples are especially bad for your health"
sequence_2 = "HuggingFace's headquarters are situated in Manhattan"

# The tokenizer will automatically add any model specific separators (i.e.  and ) and tokens to
# the sequence, as well as compute the attention masks.
paraphrase = tokenizer(sequence_0, sequence_2, return_tensors="tf")
not_paraphrase = tokenizer(sequence_0, sequence_1, return_tensors="tf")

paraphrase_classification_logits = model(paraphrase).logits
not_paraphrase_classification_logits = model(not_paraphrase).logits

paraphrase_results = tf.nn.softmax(paraphrase_classification_logits, axis=1).numpy()[0]
not_paraphrase_results = tf.nn.softmax(not_paraphrase_classification_logits, axis=1).numpy()[0]

# Should be paraphrase
for i in range(len(classes)):
    print(f"{classes[i]}: {int(round(paraphrase_results[i] * 100))}%")
not paraphrase: 10%
is paraphrase: 90%
# Should not be paraphrase
for i in range(len(classes)):
    print(f"{classes[i]}: {int(round(not_paraphrase_results[i] * 100))}%")
not paraphrase: 94%
is paraphrase: 6%

 

Extractive 質問応答

Extractive (抽出可能な) 質問応答は質問が与えられたときテキストから答えを抽出するタスクです。質問応答データセットの例は SQuAD データセットで、これはこのタスクに完全に基づいています。モデルを SQuAD タスク上で再調整したいのであれば、run_qa.pyrun_squad.py (for tensorflow) スクリプトを利用できます。

ここに質問応答を行なう pipeline を使用するサンプルがあります : 質問が与えられたときテキストから答えを抽出します。それは SQuAD 上で微調整されたモデルを利用します。

from transformers import pipeline

question_answerer = pipeline("question-answering")

context = r"""
Extractive Question Answering is the task of extracting an answer from a text given a question. An example of a
question answering dataset is the SQuAD dataset, which is entirely based on that task. If you would like to fine-tune
a model on a SQuAD task, you may leverage the examples/pytorch/question-answering/run_squad.py script.
"""

これはテキストから抽出された答え、信頼度スコアを、“start” と “end” 値と一緒に返します、これらはテキストの抽出された答えの位置です。

result = question_answerer(question="What is extractive question answering?", context=context)
print(
    f"Answer: '{result['answer']}', score: {round(result['score'], 4)}, start: {result['start']}, end: {result['end']}"
)

result = question_answerer(question="What is a good example of a question answering dataset?", context=context)
print(
    f"Answer: '{result['answer']}', score: {round(result['score'], 4)}, start: {result['start']}, end: {result['end']}"
)
Answer: 'the task of extracting an answer from a text given a question', score: 0.6177, start: 34, end: 95
Answer: 'SQuAD dataset', score: 0.5152, start: 147, end: 160

ここにモデルとトークナイザーを使用した質問応答のサンプルがあります。プロセスは以下のようなものです :

  1. チェックポイント名からトークナイザーとモデルをインスタンス化します。モデルは BERT モデルとして識別されそしてそれをチェックポイントにストアされた重みでロードします。

  2. テキストと幾つかの質問を定義します。

  3. 質問に渡り反復して、そして正しいモデル固有の separator、トークン型 id と attention マスクで、テキストと現在の質問からシークエンスを構築します。

  4. このシークエンスをモデルに渡します。これは開始と終了位置の両者に対して、シークエンス・トークン全体 (質問とテキスト) に渡るスコアの範囲を出力します。

  5. トークンに対する確率を得るために結果の softmax を計算します。

  6. 識別された開始と停止値からトークンを取得して、それらのトークンを文字列に変換します。

  7. 結果をプリントします。
PyTorch
from transformers import AutoTokenizer, AutoModelForQuestionAnswering
import torch

tokenizer = AutoTokenizer.from_pretrained("bert-large-uncased-whole-word-masking-finetuned-squad")
model = AutoModelForQuestionAnswering.from_pretrained("bert-large-uncased-whole-word-masking-finetuned-squad")

text = r"""
🤗 Transformers (formerly known as pytorch-transformers and pytorch-pretrained-bert) provides general-purpose
architectures (BERT, GPT-2, RoBERTa, XLM, DistilBert, XLNet…) for Natural Language Understanding (NLU) and Natural
Language Generation (NLG) with over 32+ pretrained models in 100+ languages and deep interoperability between
TensorFlow 2.0 and PyTorch.
"""

questions = [
    "How many pretrained models are available in 🤗 Transformers?",
    "What does 🤗 Transformers provide?",
    "🤗 Transformers provides interoperability between which frameworks?",
]

for question in questions:
    inputs = tokenizer(question, text, add_special_tokens=True, return_tensors="pt")
    input_ids = inputs["input_ids"].tolist()[0]

    outputs = model(**inputs)
    answer_start_scores = outputs.start_logits
    answer_end_scores = outputs.end_logits

    # Get the most likely beginning of answer with the argmax of the score
    answer_start = torch.argmax(answer_start_scores)
    # Get the most likely end of answer with the argmax of the score
    answer_end = torch.argmax(answer_end_scores) + 1

    answer = tokenizer.convert_tokens_to_string(
        tokenizer.convert_ids_to_tokens(input_ids[answer_start:answer_end])
    )

    print(f"Question: {question}")
    print(f"Answer: {answer}")
Question: How many pretrained models are available in 🤗 Transformers?
Answer: over 32 +
Question: What does 🤗 Transformers provide?
Answer: general - purpose architectures
Question: 🤗 Transformers provides interoperability between which frameworks?
Answer: tensorflow 2. 0 and pytorch
TensorFlow
from transformers import AutoTokenizer, TFAutoModelForQuestionAnswering
import tensorflow as tf

tokenizer = AutoTokenizer.from_pretrained("bert-large-uncased-whole-word-masking-finetuned-squad")
model = TFAutoModelForQuestionAnswering.from_pretrained("bert-large-uncased-whole-word-masking-finetuned-squad")

text = r"""
🤗 Transformers (formerly known as pytorch-transformers and pytorch-pretrained-bert) provides general-purpose
architectures (BERT, GPT-2, RoBERTa, XLM, DistilBert, XLNet…) for Natural Language Understanding (NLU) and Natural
Language Generation (NLG) with over 32+ pretrained models in 100+ languages and deep interoperability between
TensorFlow 2.0 and PyTorch.
"""

questions = [
    "How many pretrained models are available in 🤗 Transformers?",
    "What does 🤗 Transformers provide?",
    "🤗 Transformers provides interoperability between which frameworks?",
]

for question in questions:
    inputs = tokenizer(question, text, add_special_tokens=True, return_tensors="tf")
    input_ids = inputs["input_ids"].numpy()[0]

    outputs = model(inputs)
    answer_start_scores = outputs.start_logits
    answer_end_scores = outputs.end_logits

    # Get the most likely beginning of answer with the argmax of the score
    answer_start = tf.argmax(answer_start_scores, axis=1).numpy()[0]
    # Get the most likely end of answer with the argmax of the score
    answer_end = tf.argmax(answer_end_scores, axis=1).numpy()[0] + 1

    answer = tokenizer.convert_tokens_to_string(
        tokenizer.convert_ids_to_tokens(input_ids[answer_start:answer_end])
    )

    print(f"Question: {question}")
    print(f"Answer: {answer}")
Question: How many pretrained models are available in 🤗 Transformers?
Answer: over 32 +
Question: What does 🤗 Transformers provide?
Answer: general - purpose architectures
Question: 🤗 Transformers provides interoperability between which frameworks?
Answer: tensorflow 2. 0 and pytorch

 

言語モデリング

言語モデリングはモデルをコーパスに適合させるタスク で、ドメイン固有である可能性があります。総てのポピュラーな transformer ベースのモデルは言語モデリングの変種 (e.g. masked 言語モデリングによる BERT、casual 言語モデリングによる GPT-2) を使用して訓練されます。

言語モデリングは事前訓練以外でも有用である可能性があります、例えばモデル分布をドメイン固有にシフトするためです : 非常に大規模なコーパスに対して訓練された言語モデルを使用し、それを新しいニュース・データセットや科学論文 e.g. LysandreJik/arxiv-nlp に再調整します。

 

Masked 言語モデリング

masked 言語モデリングは masking トークンでシークエンスのトークンをマスクして、モデルに適切なトークンでそのマスクを埋めることを促すタスクです。これはモデルに右側のコンテキスト (マスクの右側のトークン) と左側のコンテキスト (マスクの左側のトークン) の両者に注意を払うことを可能にします。そのような訓練は、SQuAD のような (質問応答、Lewis, Lui, Goyal et al., part 4.2 参照) 双方向コンテキストを必要とするような下流タスクのための強力な基底を作成します。masked 言語モデリング・タスク上でモデルを再調整したい場合には、run_mlm.py スクリプトを活用できます。

ここにシークエンスからのマスクを置き換えるために pipeline を使用するサンプルがあります :

from transformers import pipeline

unmasker = pipeline("fill-mask")

これはマスクが埋められたシークエンス、信頼度スコア、そしてトークナイザー語彙のトークン id を出力します :

from pprint import pprint

pprint(
    unmasker(
        f"HuggingFace is creating a {unmasker.tokenizer.mask_token} that the community uses to solve NLP tasks."
    )
)
[{'score': 0.1793,
  'sequence': 'HuggingFace is creating a tool that the community uses to solve '
              'NLP tasks.',
  'token': 3944,
  'token_str': ' tool'},
 {'score': 0.1135,
  'sequence': 'HuggingFace is creating a framework that the community uses to '
              'solve NLP tasks.',
  'token': 7208,
  'token_str': ' framework'},
 {'score': 0.0524,
  'sequence': 'HuggingFace is creating a library that the community uses to '
              'solve NLP tasks.',
  'token': 5560,
  'token_str': ' library'},
 {'score': 0.0349,
  'sequence': 'HuggingFace is creating a database that the community uses to '
              'solve NLP tasks.',
  'token': 8503,
  'token_str': ' database'},
 {'score': 0.0286,
  'sequence': 'HuggingFace is creating a prototype that the community uses to '
              'solve NLP tasks.',
  'token': 17715,
  'token_str': ' prototype'}]

 
ここにモデルとトークナイザーを使用して masked 言語モデリングを行なうサンプルがあります。そのプロセスは以下です :

  1. チェックポイント名からトークナイザーとモデルをインスタンス化します。モデルは DistilBERT モデルとして識別されてチェックポイントにストアされている重みとともにそれをロードします。

  2. 単語の代わりに tokenizer.mask_token を配置して、マスクされたトークンを持つシークエンスを定義します。

  3. そのシークエンスを ID のリストにエンコードしてそのリスト内のマスクされたトークンの位置を見つけます。

  4. マスク・トークンのインデックスにおける予測を取得します : このテンソルは語彙と同じサイズを持ち、値は各トークンに帰するスコアです。モデルはそれがそのコンテキストで可能性が高いと判断するトークンに、より高いスコアを与えます。

  5. PyTorch topk or TensorFlow top_k メソッドを使用してトップ 5 のトークンを取得します。

  6. マスク・トークンをトークンで置き換えて、結果をプリントします。
PyTorch
from transformers import AutoModelForMaskedLM, AutoTokenizer
import torch

tokenizer = AutoTokenizer.from_pretrained("distilbert-base-cased")
model = AutoModelForMaskedLM.from_pretrained("distilbert-base-cased")

sequence = (
    "Distilled models are smaller than the models they mimic. Using them instead of the large "
    f"versions would help {tokenizer.mask_token} our carbon footprint."
)

inputs = tokenizer(sequence, return_tensors="pt")
mask_token_index = torch.where(inputs["input_ids"] == tokenizer.mask_token_id)[1]

token_logits = model(**inputs).logits
mask_token_logits = token_logits[0, mask_token_index, :]

top_5_tokens = torch.topk(mask_token_logits, 5, dim=1).indices[0].tolist()

for token in top_5_tokens:
    print(sequence.replace(tokenizer.mask_token, tokenizer.decode([token])))
Distilled models are smaller than the models they mimic. Using them instead of the large versions would help reduce our carbon footprint.
Distilled models are smaller than the models they mimic. Using them instead of the large versions would help increase our carbon footprint.
Distilled models are smaller than the models they mimic. Using them instead of the large versions would help decrease our carbon footprint.
Distilled models are smaller than the models they mimic. Using them instead of the large versions would help offset our carbon footprint.
Distilled models are smaller than the models they mimic. Using them instead of the large versions would help improve our carbon footprint.
TensorFlow
from transformers import TFAutoModelForMaskedLM, AutoTokenizer
import tensorflow as tf

tokenizer = AutoTokenizer.from_pretrained("distilbert-base-cased")
model = TFAutoModelForMaskedLM.from_pretrained("distilbert-base-cased")

sequence = (
    "Distilled models are smaller than the models they mimic. Using them instead of the large "
    f"versions would help {tokenizer.mask_token} our carbon footprint."
)

inputs = tokenizer(sequence, return_tensors="tf")
mask_token_index = tf.where(inputs["input_ids"] == tokenizer.mask_token_id)[0, 1]

token_logits = model(**inputs).logits
mask_token_logits = token_logits[0, mask_token_index, :]

top_5_tokens = tf.math.top_k(mask_token_logits, 5).indices.numpy()

for token in top_5_tokens:
    print(sequence.replace(tokenizer.mask_token, tokenizer.decode([token])))
Distilled models are smaller than the models they mimic. Using them instead of the large versions would help reduce our carbon footprint.
Distilled models are smaller than the models they mimic. Using them instead of the large versions would help increase our carbon footprint.
Distilled models are smaller than the models they mimic. Using them instead of the large versions would help decrease our carbon footprint.
Distilled models are smaller than the models they mimic. Using them instead of the large versions would help offset our carbon footprint.
Distilled models are smaller than the models they mimic. Using them instead of the large versions would help improve our carbon footprint.

これはモデルにより予測された top 5 トークンを伴う、5 つのシークエンスをプリントします。

 

Causal 言語モデリング

Causal (因果) 言語モデリングはトークンのシークエンスに続くトークンを予測するタスクです。この状況では、モデルは左側のコンテキスト (マスクの左側のトークン) にのみ注意を払います。そのような訓練は生成タスクのための特に興味深いです。causal 言語モデリング・タスク上でモデルを再調整したい場合、run_clm.py スクリプトを活用できます。

通常、次のトークンは (モデルが入力シークエンスから生成する) 最後の隠れ状態のロジットからサンプリングすることにより予測されます。

ここにトークナイザーとモデルを使用して (トークンの入力シークエンスに続く) 次のトークンをサンプリングするために PreTrainedModel.top_k_top_p_filtering メソッドを利用する例があります。

PyTorch
from transformers import AutoModelForCausalLM, AutoTokenizer, top_k_top_p_filtering
import torch
from torch import nn

tokenizer = AutoTokenizer.from_pretrained("gpt2")
model = AutoModelForCausalLM.from_pretrained("gpt2")

sequence = f"Hugging Face is based in DUMBO, New York City, and"

inputs = tokenizer(sequence, return_tensors="pt")
input_ids = inputs["input_ids"]

# get logits of last hidden state
next_token_logits = model(**inputs).logits[:, -1, :]

# filter
filtered_next_token_logits = top_k_top_p_filtering(next_token_logits, top_k=50, top_p=1.0)

# sample
probs = nn.functional.softmax(filtered_next_token_logits, dim=-1)
next_token = torch.multinomial(probs, num_samples=1)

generated = torch.cat([input_ids, next_token], dim=-1)

resulting_string = tokenizer.decode(generated.tolist()[0])
print(resulting_string)
Hugging Face is based in DUMBO, New York City, and ...
TensorFlow
from transformers import TFAutoModelForCausalLM, AutoTokenizer, tf_top_k_top_p_filtering
import tensorflow as tf

tokenizer = AutoTokenizer.from_pretrained("gpt2")
model = TFAutoModelForCausalLM.from_pretrained("gpt2")

sequence = f"Hugging Face is based in DUMBO, New York City, and"

inputs = tokenizer(sequence, return_tensors="tf")
input_ids = inputs["input_ids"]

# get logits of last hidden state
next_token_logits = model(**inputs).logits[:, -1, :]

# filter
filtered_next_token_logits = tf_top_k_top_p_filtering(next_token_logits, top_k=50, top_p=1.0)

# sample
next_token = tf.random.categorical(filtered_next_token_logits, dtype=tf.int32, num_samples=1)

generated = tf.concat([input_ids, next_token], axis=1)

resulting_string = tokenizer.decode(generated.numpy().tolist()[0])
print(resulting_string)
Hugging Face is based in DUMBO, New York City, and ...

これは元のシークエンスに続く (望ましくは) 首尾一貫した次のトークンを出力します、これは私達のケースでは単語 “is” or “features” です :

次のセクションでは、一度に一つのトークンの代わりに指定された長さまで複数のトークンを生成するために generation_utils.GenerationMixin.generate() を使用する方法を示します。

 

テキスト生成

テキスト生成 (a.k.a. open-ended テキスト生成) では、その目標は与えられたコンテキストからの継続であるテキストの首尾一貫した部分を作成することです。以下のサンプルは GPT-2 がテキストを生成するために pipeline でどのように使用されるかを示します。デフォルトでは総てのモデルはそれらに相当する configuration で設定されているように、pipeline で使用されるとき Top-K サンプリングを適用します (例えば gpt-2 config 参照)。

from transformers import pipeline

text_generator = pipeline("text-generation")
print(text_generator("As far as I am concerned, I will", max_length=50, do_sample=False))
[{'generated_text': 'As far as I am concerned, I will be the first to admit that I am not a fan of the idea of a
"free market." I think that the idea of a free market is a bit of a stretch. I think that the idea'}]

ここでは、コンテキスト “As far as I am concerned, I will” からモデルは 50 トークンの合計最大長を持つランダムテキストを生成します。内部的には、pipeline() オブジェクトはテキストを生成するためにメソッド PreTrainedModel.generate() を呼び出します。このメソッドに対するデフォルト引数は、引数 max_length and do_sample に対して上で示されたように、pipeline 内で override できます。

下は XLNet とそのトークナイザーを使用するテキスト生成のサンプルです、これは generate() の直接的な呼び出しを伴います :

PyTorch
from transformers import AutoModelForCausalLM, AutoTokenizer

model = AutoModelForCausalLM.from_pretrained("xlnet-base-cased")
tokenizer = AutoTokenizer.from_pretrained("xlnet-base-cased")

# Padding text helps XLNet with short prompts - proposed by Aman Rusia in https://github.com/rusiaaman/XLNet-gen#methodology
PADDING_TEXT = """In 1991, the remains of Russian Tsar Nicholas II and his family
(except for Alexei and Maria) are discovered.
The voice of Nicholas's young son, Tsarevich Alexei Nikolaevich, narrates the
remainder of the story. 1883 Western Siberia,
a young Grigori Rasputin is asked by his father and a group of men to perform magic.
Rasputin has a vision and denounces one of the men as a horse thief. Although his
father initially slaps him for making such an accusation, Rasputin watches as the
man is chased outside and beaten. Twenty years later, Rasputin sees a vision of
the Virgin Mary, prompting him to become a priest. Rasputin quickly becomes famous,
with people, even a bishop, begging for his blessing.   """

prompt = "Today the weather is really nice and I am planning on "
inputs = tokenizer(PADDING_TEXT + prompt, add_special_tokens=False, return_tensors="pt")["input_ids"]

prompt_length = len(tokenizer.decode(inputs[0]))
outputs = model.generate(inputs, max_length=250, do_sample=True, top_p=0.95, top_k=60)
generated = prompt + tokenizer.decode(outputs[0])[prompt_length + 1 :]

print(generated)
Today the weather is really nice and I am planning ...
TensorFlow
from transformers import TFAutoModelForCausalLM, AutoTokenizer

model = TFAutoModelForCausalLM.from_pretrained("xlnet-base-cased")
tokenizer = AutoTokenizer.from_pretrained("xlnet-base-cased")

# Padding text helps XLNet with short prompts - proposed by Aman Rusia in https://github.com/rusiaaman/XLNet-gen#methodology
PADDING_TEXT = """In 1991, the remains of Russian Tsar Nicholas II and his family
(except for Alexei and Maria) are discovered.
The voice of Nicholas's young son, Tsarevich Alexei Nikolaevich, narrates the
remainder of the story. 1883 Western Siberia,
a young Grigori Rasputin is asked by his father and a group of men to perform magic.
Rasputin has a vision and denounces one of the men as a horse thief. Although his
father initially slaps him for making such an accusation, Rasputin watches as the
man is chased outside and beaten. Twenty years later, Rasputin sees a vision of
the Virgin Mary, prompting him to become a priest. Rasputin quickly becomes famous,
with people, even a bishop, begging for his blessing.   """

prompt = "Today the weather is really nice and I am planning on "
inputs = tokenizer(PADDING_TEXT + prompt, add_special_tokens=False, return_tensors="tf")["input_ids"]

prompt_length = len(tokenizer.decode(inputs[0]))
outputs = model.generate(inputs, max_length=250, do_sample=True, top_p=0.95, top_k=60)
generated = prompt + tokenizer.decode(outputs[0])[prompt_length + 1 :]

print(generated)
Today the weather is really nice and I am planning ...

 
テキスト生成は現在 PyTorch で GPT-2, OpenAi-GPT, CTRL, XLNet, Transfo-XL と Reformer で、そして殆どのモデルについて TensorFlow でも可能です。上のサンプルで見られるように XLNet と Transfo-XL は上手く動作するためにはしばしばパッドされる必要があります。open-ended テキスト生成のためには GPT-2 は通常は良い選択です、何故ならばそれは causal 言語モデリング目的で数百万の web ページで訓練されたからです。

テキスト生成のための様々なデコーディング・ストラテジーをどのように適用するかの詳細については、ここ のテキスト生成ブログ投稿も参照してください。

 

固有表現認識

固有表現認識 (NER) は例えば人物、組織や位置としてトークンを識別するクラスに従ってトークンを分類するタスクです。固有表現認識データセットの例は CoNLL-2003 データセットで、これはそのタスクに完全に基づいています。NER タスク上でモデルを再調整したいのであれば、run_ner.py スクリプトを利用して良いです。

ここに固有表現認識を行なうために pipeline を使用するサンプルがあります、具体的には、トークンを 9 クラスの一つに属するものとして識別することを試みます :

  • O, 固有表現外 (= Outside of a named entity)
  • B-MIS, 別の雑多な (= miscellaneous) エンティティの直後の雑多なエンティティの開始
  • I-MIS, 種々雑多なエンティティ
  • B-PER, 別の人物名の直後の人物名の開始
  • I-PER, 人物名
  • B-ORG, 別の組織の直後の組織の開始
  • I-ORG, 組織
  • B-LOC, 別の場所の直後の場所の開始
  • I-LOC, 場所

それは dbmdz からの @stefan-it により再調整された、CoNLL-2003 上の再調整済みモデルを利用します。

from transformers import pipeline

ner_pipe = pipeline("ner")

sequence = """Hugging Face Inc. is a company based in New York City. Its headquarters are in DUMBO,
therefore very close to the Manhattan Bridge which is visible from the window."""

これは上で定義された 9 クラスからのエンティティの一つとして識別された総ての単語のリストを出力します。ここに期待される結果があります :

for entity in ner_pipe(sequence):
    print(entity)
{'entity': 'I-ORG', 'score': 0.9996, 'index': 1, 'word': 'Hu', 'start': 0, 'end': 2}
{'entity': 'I-ORG', 'score': 0.9910, 'index': 2, 'word': '##gging', 'start': 2, 'end': 7}
{'entity': 'I-ORG', 'score': 0.9982, 'index': 3, 'word': 'Face', 'start': 8, 'end': 12}
{'entity': 'I-ORG', 'score': 0.9995, 'index': 4, 'word': 'Inc', 'start': 13, 'end': 16}
{'entity': 'I-LOC', 'score': 0.9994, 'index': 11, 'word': 'New', 'start': 40, 'end': 43}
{'entity': 'I-LOC', 'score': 0.9993, 'index': 12, 'word': 'York', 'start': 44, 'end': 48}
{'entity': 'I-LOC', 'score': 0.9994, 'index': 13, 'word': 'City', 'start': 49, 'end': 53}
{'entity': 'I-LOC', 'score': 0.9863, 'index': 19, 'word': 'D', 'start': 79, 'end': 80}
{'entity': 'I-LOC', 'score': 0.9514, 'index': 20, 'word': '##UM', 'start': 80, 'end': 82}
{'entity': 'I-LOC', 'score': 0.9337, 'index': 21, 'word': '##BO', 'start': 82, 'end': 84}
{'entity': 'I-LOC', 'score': 0.9762, 'index': 28, 'word': 'Manhattan', 'start': 114, 'end': 123}
{'entity': 'I-LOC', 'score': 0.9915, 'index': 29, 'word': 'Bridge', 'start': 124, 'end': 130}

 
シークエンス “Hugging Face” のトークンがどのように組織として識別され、そして “New York City”, “DUMBO” と “Manhattan Bridge” が場所として識別されたかに注意してください。

モデルとトークナイザーを使用する、固有表現認識を行なうサンプルがここにあります。そのプロセスは以下です :

  1. チェックポイント名からトークナイザーとモデルをインスタンス化します。モデルは BERT モデルとして識別されてチェックポイントにストアされた重みでそれをロードします。

  2. “Hugging Face” を組織として “New York City” を場所とするような、既知のエンティティでシークエンスを定義します。

  3. 単語を予測にマップできるようにトークンに分解します。最初にシーケンスを完全にエンコードしてデコードすることにより小さいハックを利用します、その結果特殊トークンを含む文字列が残ります。

  4. そのシークエンスを ID にエンコードします (特殊トークンが自動的に追加されます)。

  5. 入力をモデルに渡して最初の出力を得ることにより予測を取得します。これは各トークンに対する 9 個の可能なクラスに渡る分布という結果になります。各トークンのための最尤クラスを得るために argmax を取ります。

  6. 各トークンをその予測と一緒に zip してそれをプリントします。
PyTorch
from transformers import AutoModelForTokenClassification, AutoTokenizer
import torch

model = AutoModelForTokenClassification.from_pretrained("dbmdz/bert-large-cased-finetuned-conll03-english")
tokenizer = AutoTokenizer.from_pretrained("bert-base-cased")

sequence = (
    "Hugging Face Inc. is a company based in New York City. Its headquarters are in DUMBO, "
    "therefore very close to the Manhattan Bridge."
)

inputs = tokenizer(sequence, return_tensors="pt")
tokens = inputs.tokens()

outputs = model(**inputs).logits
predictions = torch.argmax(outputs, dim=2)
TensorFlow
from transformers import TFAutoModelForTokenClassification, AutoTokenizer
import tensorflow as tf

model = TFAutoModelForTokenClassification.from_pretrained("dbmdz/bert-large-cased-finetuned-conll03-english")
tokenizer = AutoTokenizer.from_pretrained("bert-base-cased")

sequence = (
    "Hugging Face Inc. is a company based in New York City. Its headquarters are in DUMBO, "
    "therefore very close to the Manhattan Bridge."
)

inputs = tokenizer(sequence, return_tensors="tf")
tokens = inputs.tokens()

outputs = model(**inputs)[0]
predictions = tf.argmax(outputs, axis=2)

これは対応する予測にマップされた各トークンのリストを出力します。pipeline とは異なり、ここでは総てのトークンは予測を持ちます、何故ならばそのトークンで特定のエンティティが見つからなかったことを意味する “0” th クラスを削除しないからです。

上のサンプルでは、predictions は予測されたクラスに対応する整数値です。クラス番号に対応するクラス名を復元するために model.config.id2label プロパティを使用できます、これは下で示されます :

for token, prediction in zip(tokens, predictions[0].numpy()):
    print((token, model.config.id2label[prediction]))
('[CLS]', 'O')
('Hu', 'I-ORG')
('##gging', 'I-ORG')
('Face', 'I-ORG')
('Inc', 'I-ORG')
('.', 'O')
('is', 'O')
('a', 'O')
('company', 'O')
('based', 'O')
('in', 'O')
('New', 'I-LOC')
('York', 'I-LOC')
('City', 'I-LOC')
('.', 'O')
('Its', 'O')
('headquarters', 'O')
('are', 'O')
('in', 'O')
('D', 'I-LOC')
('##UM', 'I-LOC')
('##BO', 'I-LOC')
(',', 'O')
('therefore', 'O')
('very', 'O')
('close', 'O')
('to', 'O')
('the', 'O')
('Manhattan', 'I-LOC')
('Bridge', 'I-LOC')
('.', 'O')
('[SEP]', 'O')

 

要約

要約はドキュメントや記事をより短いテキストに要約するタスクです。要約タスク上でモデルを再調整したい場合には、run_summarization.py スクリプトを活用できます。

要約データセットの例は CNN / Daily Mail データセットで、これは長いニュース記事から成りそして要約タスクのために作成されました。モデルを要約タスクで再調整したい場合には、この ドキュメント で様々なアプローチが説明されています。

ここに要約を行なうためのパイプラインを使用する例があります。それは CNN / Daily Mail データセット上で再調整された Bart モデルを利用しています。

from transformers import pipeline

summarizer = pipeline("summarization")

ARTICLE = """ New York (CNN)When Liana Barrientos was 23 years old, she got married in Westchester County, New York.
A year later, she got married again in Westchester County, but to a different man and without divorcing her first husband.
Only 18 days after that marriage, she got hitched yet again. Then, Barrientos declared "I do" five more times, sometimes only within two weeks of each other.
In 2010, she married once more, this time in the Bronx. In an application for a marriage license, she stated it was her "first and only" marriage.
Barrientos, now 39, is facing two criminal counts of "offering a false instrument for filing in the first degree," referring to her false statements on the
2010 marriage license application, according to court documents.
Prosecutors said the marriages were part of an immigration scam.
On Friday, she pleaded not guilty at State Supreme Court in the Bronx, according to her attorney, Christopher Wright, who declined to comment further.
After leaving court, Barrientos was arrested and charged with theft of service and criminal trespass for allegedly sneaking into the New York subway through an emergency exit, said Detective
Annette Markowski, a police spokeswoman. In total, Barrientos has been married 10 times, with nine of her marriages occurring between 1999 and 2002.
All occurred either in Westchester County, Long Island, New Jersey or the Bronx. She is believed to still be married to four men, and at one time, she was married to eight men at once, prosecutors say.
Prosecutors said the immigration scam involved some of her husbands, who filed for permanent residence status shortly after the marriages.
Any divorces happened only after such filings were approved. It was unclear whether any of the men will be prosecuted.
The case was referred to the Bronx District Attorney\'s Office by Immigration and Customs Enforcement and the Department of Homeland Security\'s
Investigation Division. Seven of the men are from so-called "red-flagged" countries, including Egypt, Turkey, Georgia, Pakistan and Mali.
Her eighth husband, Rashid Rajput, was deported in 2006 to his native Pakistan after an investigation by the Joint Terrorism Task Force.
If convicted, Barrientos faces up to four years in prison.  Her next court appearance is scheduled for May 18.
"""

要約 pipeline は PretrainedModel.generate() メソッドに依存していますので、下で示されるように pipeline の PretrainedModel.generate() のデフォルト引数を max_length と min_length に対して直接 override することができます。これは次の要約を出力します :

print(summarizer(ARTICLE, max_length=130, min_length=30, do_sample=False))
[{'summary_text': ' Liana Barrientos, 39, is charged with two counts of "offering a false instrument for filing in
the first degree" In total, she has been married 10 times, with nine of her marriages occurring between 1999 and
2002 . At one time, she was married to eight men at once, prosecutors say .'}]

 
モデルとトークナイザーを使用する要約を行なうサンプルがここにあります。そのプロセスは以下です :

  1. チェックポイント名からトークナイザーとモデルをインスタンス化します。要約は通常は Bart or T5 のようなエンコーダ-デコーダ・モデルを使用して成されます。
  2. 要約されるべき記事を定義します。
  3. T5 固有の prefix “summarize: “ を追加します。
  4. 要約を生成するために PretrainedModel.generate() メソッドを使用します。

このサンプルでは Google の T5 モデルを利用しています。それは (CNN / Daily Mail を含む) マルチタスク混合データセット上でだけ事前訓練されていますが、それは非常に良い結果を生成します。

PyTorch
from transformers import AutoModelForSeq2SeqLM, AutoTokenizer

model = AutoModelForSeq2SeqLM.from_pretrained("t5-base")
tokenizer = AutoTokenizer.from_pretrained("t5-base")

# T5 uses a max_length of 512 so we cut the article to 512 tokens.
inputs = tokenizer("summarize: " + ARTICLE, return_tensors="pt", max_length=512, truncation=True)
outputs = model.generate(
    inputs["input_ids"], max_length=150, min_length=40, length_penalty=2.0, num_beams=4, early_stopping=True
)

print(tokenizer.decode(outputs[0]))
<pad> prosecutors say the marriages were part of an immigration scam. if convicted, barrientos faces two criminal
counts of "offering a false instrument for filing in the first degree" she has been married 10 times, nine of them
between 1999 and 2002.</s>
TensorFlow
from transformers import TFAutoModelForSeq2SeqLM, AutoTokenizer

model = TFAutoModelForSeq2SeqLM.from_pretrained("t5-base")
tokenizer = AutoTokenizer.from_pretrained("t5-base")

# T5 uses a max_length of 512 so we cut the article to 512 tokens.
inputs = tokenizer("summarize: " + ARTICLE, return_tensors="tf", max_length=512)
outputs = model.generate(
    inputs["input_ids"], max_length=150, min_length=40, length_penalty=2.0, num_beams=4, early_stopping=True
)

print(tokenizer.decode(outputs[0]))
<pad> prosecutors say the marriages were part of an immigration scam. if convicted, barrientos faces two criminal
counts of "offering a false instrument for filing in the first degree" she has been married 10 times, nine of them
between 1999 and 2002.

 

翻訳

翻訳は一つの言語から別の言語へテキストを変換するタスクです。翻訳タスク上でモデルを再調整したい場合には、run_translation.py を活用できます。

翻訳データセットの例は WMT 英独データセットです、これは入力データとして英語のセンテンスをそしてターゲットデータとして独語のセンテンスを持ちます。翻訳タスク上でモデルを再調整したい場合には、様々なアプローチがこの ドキュメント で説明されます。

ここに翻訳を行なうための pipeline を使用するサンプルがあります。それは T5 モデルを利用しています、これは (WMT を含む) マルチタスク混合データセット上でのみ事前訓練されましたが、印象的な翻訳結果を生成します。

from transformers import pipeline

translator = pipeline("translation_en_to_de")
print(translator("Hugging Face is a technology company based in New York and Paris", max_length=40))
[{'translation_text': 'Hugging Face ist ein Technologieunternehmen mit Sitz in New York und Paris.'}]

 
翻訳 pipeline は PretrainedModel.generate() メソッドに依存していますので、上で max_length に対して示されたように pipeline で PretrainedModel.generate() のデフォルト引数を直接 override できます。

ここにモデルとトークナイザーを使用して翻訳を行なうサンプルがあります。そのプロセスは以下です :

  1. チェックポイント名からトークナイザーとモデルをインスタンス化します。要約は通常は Bart or T5 のようなエンコーダ-デコーダ・モデルを使用して成されます。
  2. 翻訳されるべきセンテンスを定義します。
  3. T5 固有のプレフィックス “translate English to German: “ を追加します。
  4. 翻訳を遂行するために PretrainedModel.generate() メソッドを使用します。
PyTorch
from transformers import AutoModelForSeq2SeqLM, AutoTokenizer

model = AutoModelForSeq2SeqLM.from_pretrained("t5-base")
tokenizer = AutoTokenizer.from_pretrained("t5-base")

inputs = tokenizer(
    "translate English to German: Hugging Face is a technology company based in New York and Paris",
    return_tensors="pt",
)
outputs = model.generate(inputs["input_ids"], max_length=40, num_beams=4, early_stopping=True)

print(tokenizer.decode(outputs[0]))
<pad> Hugging Face ist ein Technologieunternehmen mit Sitz in New York und Paris.</s>
TensorFlow
from transformers import TFAutoModelForSeq2SeqLM, AutoTokenizer

model = TFAutoModelForSeq2SeqLM.from_pretrained("t5-base")
tokenizer = AutoTokenizer.from_pretrained("t5-base")

inputs = tokenizer(
    "translate English to German: Hugging Face is a technology company based in New York and Paris",
    return_tensors="tf",
)
outputs = model.generate(inputs["input_ids"], max_length=40, num_beams=4, early_stopping=True)

print(tokenizer.decode(outputs[0]))
<pad> Hugging Face ist ein Technologieunternehmen mit Sitz in New York und Paris.

pipeline サンプルでのように、同じ翻訳を得ます。

 

以上



HuggingFace Transformers 4.17 : Tutorials : 前処理

HuggingFace Transformers 4.17 : Tutorials : 前処理 (翻訳/解説)

翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 04/12/2022 (v4.17.0)

* 本ページは、HuggingFace Transformers の以下のドキュメントを翻訳した上で適宜、補足説明したものです:

* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。

 

クラスキャット 人工知能 研究開発支援サービス

クラスキャット は人工知能・テレワークに関する各種サービスを提供しています。お気軽にご相談ください :

◆ 人工知能とビジネスをテーマに WEB セミナーを定期的に開催しています。スケジュール
  • お住まいの地域に関係なく Web ブラウザからご参加頂けます。事前登録 が必要ですのでご注意ください。

お問合せ : 本件に関するお問い合わせ先は下記までお願いいたします。

  • 株式会社クラスキャット セールス・マーケティング本部 セールス・インフォメーション
  • sales-info@classcat.com  ;  Web: www.classcat.com  ;   ClassCatJP

 

 

HuggingFace Transformers : Tutorials : 前処理

貴方のデータをモデルで利用できる前に、データはモデルに対して受け取り可能な形式に処理される必要があります。モデルは生のテキスト, 画像や音声は理解できません。これらの入力は数値に変換されてテンソルに構築される必要があります。このチュートリアルでは、以下を行ないます :

  • トークナイザーでテキストデータを前処理する。
  • 特徴抽出器で画像や音声データを前処理する。
  • プロセッサでマルチモーダル・タスクのためのデータを前処理する。

 

NLP

テキストデータを処理する主要ツールは トークナイザー です。トークナイザーはルールのセットに従ってテキストをトークンに分割することから始めます。トークンは数値に変換されます、これはモデルへの入力としてテンソルを構築するために使用されます。モデルにより必要とされる任意の追加の入力もまたトークナイザーにより追加されます。

Note: 事前訓練モデルを使用する計画があれば、関連する事前訓練済みトークナイザーを使用することは重要です。これは、テキストが事前訓練済みコーパスと同じ方法で分割されて、訓練の間に同じ対応するトークン-to-インデックス (通常は語彙として参照) を使用することを保証します。

AutoTokenizer クラスで事前訓練済みトークナイザーをロードすることから素早く始めます。これはモデルが事前訓練されたときに使用された語彙をダウンロードします。

 

トークン化

AutoTokenizer.from_pretrained() で事前訓練済みトークナイザーをロードします :

from transformers import AutoTokenizer

tokenizer = AutoTokenizer.from_pretrained("bert-base-cased")

そしてセンテンスをトークナイザーに渡します :

encoded_input = tokenizer("Do not meddle in the affairs of wizards, for they are subtle and quick to anger.")
print(encoded_input)
{'input_ids': [101, 2079, 2025, 19960, 10362, 1999, 1996, 3821, 1997, 16657, 1010, 2005, 2027, 2024, 11259, 1998, 4248, 2000, 4963, 1012, 102], 
 'token_type_ids': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
 'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]}

トークナイザーは 3 つの重要な項目を持つ辞書を返します :

  • input_ids はセンテンスの各トークンに対応するインデックスです。

  • attention_mask はトークンが注意されるべきか否かを示します。

  • token_type_ids は複数のシークエンスがあるとき、トークンがどのシークエンスに属すかを示します。

元の入力を返すために input_ids をデコードできます :

tokenizer.decode(encoded_input["input_ids"])
'[CLS] Do not meddle in the affairs of wizards, for they are subtle and quick to anger. [SEP]'

見れるように、トークナイザーはセンテンスに 2 つの特殊トークン – CLS と SEP (classifier と separator) – を追加しました。総てのモデルが特殊トークンを必要とはしませんが、必要な場合には、トークナイザーはそれらを自動的に追加します。

処理したい幾つかのセンテンスがある場合には、(複数の) センテンスをリストとしてトークナイザーに渡します :

batch_sentences = [
    "But what about second breakfast?",
    "Don't think he knows about second breakfast, Pip.",
    "What about elevensies?",
]
encoded_inputs = tokenizer(batch_sentences)
print(encoded_inputs)
{'input_ids': [[101, 1252, 1184, 1164, 1248, 6462, 136, 102], 
               [101, 1790, 112, 189, 1341, 1119, 3520, 1164, 1248, 6462, 117, 21902, 1643, 119, 102], 
               [101, 1327, 1164, 5450, 23434, 136, 102]], 
 'token_type_ids': [[0, 0, 0, 0, 0, 0, 0, 0], 
                    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
                    [0, 0, 0, 0, 0, 0, 0]], 
 'attention_mask': [[1, 1, 1, 1, 1, 1, 1, 1], 
                    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], 
                    [1, 1, 1, 1, 1, 1, 1]]}

 

パッド

これは重要なトピックを提示します。センテンスのバッチを処理するとき、それらは常に同じ長さとは限りません。これは問題です、何故ならばテンソル、モデルへの入力、は均一の shape を持つことを必要とするからです。パディングは、少ないトークンを持つセンテンスに特殊なパディング・トークンを追加することによりテンソルが矩形であることを保証するストラテジーです。

最長のシークエンスに一致するようにバッチの短いシークエンスをパッドするためには padding パラメータを True に設定します :

batch_sentences = [
    "But what about second breakfast?",
    "Don't think he knows about second breakfast, Pip.",
    "What about elevensies?",
]
encoded_input = tokenizer(batch_sentences, padding=True)
print(encoded_input)
{'input_ids': [[101, 1252, 1184, 1164, 1248, 6462, 136, 102, 0, 0, 0, 0, 0, 0, 0], 
               [101, 1790, 112, 189, 1341, 1119, 3520, 1164, 1248, 6462, 117, 21902, 1643, 119, 102], 
               [101, 1327, 1164, 5450, 23434, 136, 102, 0, 0, 0, 0, 0, 0, 0, 0]], 
 'token_type_ids': [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
                    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
                    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], 
 'attention_mask': [[1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0], 
                    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], 
                    [1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]}

トークナイザーは最初と 3 番目のセンテンスをパッドしたことに気付いてください、それらは短いからです!

 

Truncation

対極的に、シークエンスがモデルが処理するには長すぎる場合も時々あるかもしれません。この場合、シークエンスを短い長さに切り詰める必要があります。

シークエンスをモデルが受け取れる最大長に切り詰めるには truncation パラメータを True に設定します :

batch_sentences = [
    "But what about second breakfast?",
    "Don't think he knows about second breakfast, Pip.",
    "What about elevensies?",
]
encoded_input = tokenizer(batch_sentences, padding=True, truncation=True)
print(encoded_input)
{'input_ids': [[101, 1252, 1184, 1164, 1248, 6462, 136, 102, 0, 0, 0, 0, 0, 0, 0], 
               [101, 1790, 112, 189, 1341, 1119, 3520, 1164, 1248, 6462, 117, 21902, 1643, 119, 102], 
               [101, 1327, 1164, 5450, 23434, 136, 102, 0, 0, 0, 0, 0, 0, 0, 0]], 
 'token_type_ids': [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
                    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
                    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], 
 'attention_mask': [[1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0], 
                    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], 
                    [1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]}

 

テンソルの構築

最後に、トークナイザーにモデルに供給される実際のテンソルを返すことを望みます。

return_tensors に PyTorch のために pt、あるいは TensorFlow のために tf を設定します :

PyTorch
batch_sentences = [
    "But what about second breakfast?",
    "Don't think he knows about second breakfast, Pip.",
    "What about elevensies?",
]
encoded_input = tokenizer(batch, padding=True, truncation=True, return_tensors="pt")
print(encoded_input)
{'input_ids': tensor([[  101,   153,  7719, 21490,  1122,  1114,  9582,  1623,   102],
                      [  101,  5226,  1122,  9649,  1199,  2610,  1236,   102,     0]]), 
 'token_type_ids': tensor([[0, 0, 0, 0, 0, 0, 0, 0, 0],
                           [0, 0, 0, 0, 0, 0, 0, 0, 0]]), 
 'attention_mask': tensor([[1, 1, 1, 1, 1, 1, 1, 1, 1],
                           [1, 1, 1, 1, 1, 1, 1, 1, 0]])}
TensorFlow
batch_sentences = [
    "But what about second breakfast?",
    "Don't think he knows about second breakfast, Pip.",
    "What about elevensies?",
]
encoded_input = tokenizer(batch, padding=True, truncation=True, return_tensors="tf")
print(encoded_input)
{'input_ids': , 
 'token_type_ids': , 
 'attention_mask': }

 

音声

音声入力はテキスト入力とは異なって前処理されますが、最終目標は同じままです : モデルが理解できる数値シークエンスを作成することです。特徴抽出器 は生の画像や音声データから特徴を抽出してそれらをテンソルに変換するという明確な目的のために設計されています。始める前に、実験するために以下で音声データセットをロードするために Datasets をインストールしてください :

pip install datasets

SUPERB ベンチマークからキーワードスポッティング・タスクをロードします (データセットをロードする方法の詳細は データセット・チュートリアル 参照) :

from datasets import load_dataset, Audio

dataset = load_dataset("superb", "ks")

入力を見るために音声カラムの最初の要素にアクセスします。音声カラムを呼び出すと音声ファイルを自動的にロードしてリサンプリングします :

dataset["train"][0]["audio"]
{'array': array([ 0.        ,  0.        ,  0.        , ..., -0.00592041,
        -0.00405884, -0.00253296], dtype=float32),
 'path': '/root/.cache/huggingface/datasets/downloads/extracted/05734a36d88019a09725c20cc024e1c4e7982e37d7d55c0c1ca1742ea1cdd47f/_background_noise_/doing_the_dishes.wav',
 'sampling_rate': 16000}

これは 3 つの項目を返します :

  • array は 1D 配列としてロードされて – そして潜在的にリサンプリングされた – 発話信号です。

  • path は音声ファイルの位置をポイントします。

  • sampling_rate は発話信号の幾つのデータポイントが毎秒測定されたかを示します。

 

リサンプリング

このチュートリアルについては、Wav2Vec2 モデルを使用します。モデルカードから分かるように、Wav2Vec2 は 16kHz でサンプリングされた発話音声で事前訓練されました。貴方の音声データのサンプリングレートがモデルを事前訓練するために使用されたデータセットのサンプリングレートに一致していることは重要です。もしデータのサンプリングレートが同じでないなら、音声データをリサンプリングする必要があります。

例えば、LJ Speech データセットをロードします、これは 22050Hz のサンプリングレートを持ちます。このデータセットで Wav2Vec2 モデルを使用するためには、サンプリングレートを 16kHz にダウンサンプリングします :

lj_speech = load_dataset("lj_speech", split="train")
lj_speech[0]["audio"]
{'array': array([-7.3242188e-04, -7.6293945e-04, -6.4086914e-04, ...,
         7.3242188e-04,  2.1362305e-04,  6.1035156e-05], dtype=float32),
 'path': '/root/.cache/huggingface/datasets/downloads/extracted/917ece08c95cf0c4115e45294e3cd0dee724a1165b7fc11798369308a465bd26/LJSpeech-1.1/wavs/LJ001-0001.wav',
 'sampling_rate': 22050}

 

  1. サンプリングレートを 16kHz にダウンサンプリングするために データセットの cast_column を使用します :
    lj_speech = lj_speech.cast_column("audio", Audio(sampling_rate=16_000))
    

  2. 音声ファイルをロードします :
    lj_speech[0]["audio"]
    
    {'array': array([-0.00064146, -0.00074657, -0.00068768, ...,  0.00068341,
             0.00014045,  0.        ], dtype=float32),
     'path': '/root/.cache/huggingface/datasets/downloads/extracted/917ece08c95cf0c4115e45294e3cd0dee724a1165b7fc11798369308a465bd26/LJSpeech-1.1/wavs/LJ001-0001.wav',
     'sampling_rate': 16000}
    

見て分かるように、sampling_rate は 16kHz にダウンサンプリングされました。リサンプリングがどのように動作するかを知ったので、SUPERB データセットによる前の例に戻りましょう!

 

特徴抽出器

次のステップは入力を正規化してパッドするために特徴抽出器をロードします。テキストデータをパッドするとき、短いシークエンスに 0 が追加されます。同じアイデアを音声データにも適用して、音声特徴抽出器は配列に 0 – 無音 (= silence) として解釈されます – を追加します。

AutoFeatureExtractor.from_pretrained() で特徴抽出器をロードします :

from transformers import AutoFeatureExtractor

feature_extractor = AutoFeatureExtractor.from_pretrained("facebook/wav2vec2-base")

音声配列を特徴抽出器に渡します。発生するかもしれない寡黙なエラーをより良くデバッグするために特徴抽出器に sampling_rate 引数を追加することも勧めます :

audio_input = [dataset["train"][0]["audio"]["array"]]
feature_extractor(audio_input, sampling_rate=16000)
{'input_values': [array([ 0.00045439,  0.00045439,  0.00045439, ..., -0.1578519 , -0.10807519, -0.06727459], dtype=float32)]}

 

パディングと truncate

トークナイザーのように、バッチの可変なシークエンスを処理するためにパディングと切り詰め (= truncattion) を適用できます。これら 2 つの音声サンプルのシークエンス長を見てみましょう :

dataset["train"][0]["audio"]["array"].shape
(1522930,)
dataset["train"][1]["audio"]["array"].shape
(988891,)

見て分かるように、最初のサンプルは 2 番目のサンプルよりも長いシークエンスを持ちます。データセットを前処理する関数を作成しましょう。最大サンプル長を指定すると、特徴抽出器はそれに一致するようにシークエンスをパッドするか切り詰めます :

def preprocess_function(examples):
    audio_arrays = [x["array"] for x in examples["audio"]]
    inputs = feature_extractor(
        audio_arrays,
        sampling_rate=16000,
        padding=True,
        max_length=1000000,
        truncation=True,
    )
    return inputs

データセットの最初の幾つかのサンプルに関数を適用します :

processed_dataset = preprocess_function(dataset["train"][:5])

そして処理されたサンプル長をもう一度見てみましょう :

processed_dataset["input_values"][0].shape
(1000000,)
processed_dataset["input_values"][1].shape
(1000000,)

最初の 2 つのサンプルの長さは今では指定した最大長に一致しています。

 

ビジョン

特徴抽出器はまたビジョンタスクのために画像を処理するためにも使用されます。再度、ゴールは raw 画像を入力としてテンソルのバッチに変換することです。

このチュートリアルのために food101 データセットをロードしましょう。データセットは非常に大きいので、訓練分割から小さいサンプルだけをロードするために データセットの split パラメータを使用します :

from datasets import load_dataset

dataset = load_dataset("food101", split="train[:100]")

次に、 データセットの Image 特徴で画像を見てみましょう :

dataset[0]["image"]

 

特徴抽出器

AutoFeatureExtractor.from_pretrained() で特徴抽出器をロードします :

from transformers import AutoFeatureExtractor

feature_extractor = AutoFeatureExtractor.from_pretrained("google/vit-base-patch16-224")

 

データ増強

ビジョンタスクについては、前処理も一部として画像にある種のデータ増強を追加することは一般的です。好みのライブラリで増強を追加できますが、このチュートリアルでは、torchvision の transforms モジュールを使用します。

  1. 画像を正規化して幾つかの transforms – RandomResizedCropColorJitter – をまとめて連鎖するために Compose を使用します :
    from torchvision.transforms import Compose, Normalize, RandomResizedCrop, ColorJitter, ToTensor
    
    normalize = Normalize(mean=feature_extractor.image_mean, std=feature_extractor.image_std)
    _transforms = Compose(
        [RandomResizedCrop(feature_extractor.size), ColorJitter(brightness=0.5, hue=0.5), ToTensor(), normalize]
    )
    

  2. モデルはその入力として pixel_values を受け取ります。値は特徴抽出器により生成されます。transforms から pixel_values を生成する関数を作成します :
    def transforms(examples):
        examples["pixel_values"] = [_transforms(image.convert("RGB")) for image in examples["image"]]
        return examples
    

  3. それから transforms を on-the-fly に適用するために データセットの set_transform を使用します :
    dataset.set_transform(transforms)
    

  4. そして画像にアクセスするとき、特徴抽出器がモデル入力に pixel_values を追加したことに気付くでしょう :
    dataset[0]["image"]
    
    {'image': ,
     'label': 6,
     'pixel_values': tensor([[[ 0.0353,  0.0745,  0.1216,  ..., -0.9922, -0.9922, -0.9922],
              [-0.0196,  0.0667,  0.1294,  ..., -0.9765, -0.9843, -0.9922],
              [ 0.0196,  0.0824,  0.1137,  ..., -0.9765, -0.9686, -0.8667],
              ...,
              [ 0.0275,  0.0745,  0.0510,  ..., -0.1137, -0.1216, -0.0824],
              [ 0.0667,  0.0824,  0.0667,  ..., -0.0588, -0.0745, -0.0980],
              [ 0.0353,  0.0353,  0.0431,  ..., -0.0039, -0.0039, -0.0588]],
     
             [[ 0.2078,  0.2471,  0.2863,  ..., -0.9451, -0.9373, -0.9451],
              [ 0.1608,  0.2471,  0.3098,  ..., -0.9373, -0.9451, -0.9373],
              [ 0.2078,  0.2706,  0.3020,  ..., -0.9608, -0.9373, -0.8275],
              ...,
              [-0.0353,  0.0118, -0.0039,  ..., -0.2392, -0.2471, -0.2078],
              [ 0.0196,  0.0353,  0.0196,  ..., -0.1843, -0.2000, -0.2235],
              [-0.0118, -0.0039, -0.0039,  ..., -0.0980, -0.0980, -0.1529]],
     
             [[ 0.3961,  0.4431,  0.4980,  ..., -0.9216, -0.9137, -0.9216],
              [ 0.3569,  0.4510,  0.5216,  ..., -0.9059, -0.9137, -0.9137],
              [ 0.4118,  0.4745,  0.5216,  ..., -0.9137, -0.8902, -0.7804],
              ...,
              [-0.2314, -0.1922, -0.2078,  ..., -0.4196, -0.4275, -0.3882],
              [-0.1843, -0.1686, -0.2000,  ..., -0.3647, -0.3804, -0.4039],
              [-0.1922, -0.1922, -0.1922,  ..., -0.2941, -0.2863, -0.3412]]])}
    

ここに画像が前処理した後どのように見えるかがあります。適用された transforms からちょうど想定されるように、画像はランダムにクロップされてそのカラー特性は異なっています。

import numpy as np
import matplotlib.pyplot as plt

img = dataset[0]["pixel_values"]
plt.imshow(img.permute(1, 2, 0))

 

マルチモーダル

マルチモーダル・タスクについては、ここまでに学習した総てを組合せて、自動発話認識タスク (ASR, automatic speech recognition) にスキルを適用していきます。これは以下を必要とすることを意味します :

  • 音声データを前処理する特徴抽出器。
  • テキストを処理するトークナイザー

LJ Speech データセットに戻りましょう :

from datasets import load_dataset

lj_speech = load_dataset("lj_speech", split="train")
lj_speech[0]
 {'audio': {'array': array([-7.3242188e-04, -7.6293945e-04, -6.4086914e-04, ...,
           7.3242188e-04,  2.1362305e-04,  6.1035156e-05], dtype=float32),
   'path': '/root/.cache/huggingface/datasets/downloads/extracted/917ece08c95cf0c4115e45294e3cd0dee724a1165b7fc11798369308a465bd26/LJSpeech-1.1/wavs/LJ001-0001.wav',
   'sampling_rate': 22050},
  'file': '/root/.cache/huggingface/datasets/downloads/extracted/917ece08c95cf0c4115e45294e3cd0dee724a1165b7fc11798369308a465bd26/LJSpeech-1.1/wavs/LJ001-0001.wav',
  'id': 'LJ001-0001',
  'normalized_text': 'Printing, in the only sense with which we are at present concerned, differs from most if not from all the arts and crafts represented in the Exhibition',
  'text': 'Printing, in the only sense with which we are at present concerned, differs from most if not from all the arts and crafts represented in the Exhibition'}

主として audio と text カラムに関心がありますので、他のカラムは削除します :

lj_speech = lj_speech.map(remove_columns=["file", "id", "normalized_text"])
lj_speech[0]
{'audio': {'array': array([-7.3242188e-04, -7.6293945e-04, -6.4086914e-04, ...,
          7.3242188e-04,  2.1362305e-04,  6.1035156e-05], dtype=float32),
  'path': '/root/.cache/huggingface/datasets/downloads/extracted/917ece08c95cf0c4115e45294e3cd0dee724a1165b7fc11798369308a465bd26/LJSpeech-1.1/wavs/LJ001-0001.wav',
  'sampling_rate': 22050},
 'text': 'Printing, in the only sense with which we are at present concerned, differs from most if not from all the arts and crafts represented in the Exhibition'}

そして audio と text カラムを見ましょう :

lj_speech[0]["audio"]
{'array': array([-7.3242188e-04, -7.6293945e-04, -6.4086914e-04, ...,
         7.3242188e-04,  2.1362305e-04,  6.1035156e-05], dtype=float32),
 'path': '/root/.cache/huggingface/datasets/downloads/extracted/917ece08c95cf0c4115e45294e3cd0dee724a1165b7fc11798369308a465bd26/LJSpeech-1.1/wavs/LJ001-0001.wav',
 'sampling_rate': 22050}
lj_speech[0]["text"]
'Printing, in the only sense with which we are at present concerned, differs from most if not from all the arts and crafts represented in the Exhibition'

音声データ処理の前のセクションを思い出してください、モデルを事前訓練するために使用されたデータセットのサンプリングレートに一致するように音声データのサンプリングレートで常にリサンプリングするべきです :

lj_speech = lj_speech.cast_column("audio", Audio(sampling_rate=16_000))
lj_speech[0]['audio']
{'array': array([-0.00064146, -0.00074657, -0.00068768, ...,  0.00068341,
         0.00014045,  0.        ], dtype=float32),
 'path': '/root/.cache/huggingface/datasets/downloads/extracted/917ece08c95cf0c4115e45294e3cd0dee724a1165b7fc11798369308a465bd26/LJSpeech-1.1/wavs/LJ001-0001.wav',
 'sampling_rate': 16000}

 

プロセッサ

プロセッサは特徴抽出器とトークナイザーを組合せています。AutoProcessor.from_pretrained でプロセッサをロードします :

from transformers import AutoProcessor

processor = AutoProcessor.from_pretrained("facebook/wav2vec2-base-960h")
  1. 音声データを input_values に処理して、テキストを labels にトークン化する関数を作成します。これらはモデルへの入力です :
    def prepare_dataset(example):
        audio = example["audio"]
    
        example["input_values"] = processor(audio["array"], sampling_rate=16000)
    
        with processor.as_target_processor():
            example["labels"] = processor(example["text"]).input_ids
        return example
    

  2. prepare_dataset をサンプルに適用します :
    prepare_dataset(lj_speech[0])
    
    {'audio': {'array': array([-0.00064146, -0.00074657, -0.00068768, ...,  0.00068341,
              0.00014045,  0.        ], dtype=float32),
      'path': '/root/.cache/huggingface/datasets/downloads/extracted/917ece08c95cf0c4115e45294e3cd0dee724a1165b7fc11798369308a465bd26/LJSpeech-1.1/wavs/LJ001-0001.wav',
      'sampling_rate': 16000},
     'input_values': {'input_values': [array([-6.7253257e-03, -7.8238761e-03, -7.2083874e-03, ...,
             7.1215569e-03,  1.4468388e-03, -2.1073874e-05], dtype=float32)]},
     'labels': [23, 3, 3, 3, 3, 3, 3, ..., 3, 3, 3, 3, 3],
     'text': 'Printing, in the only sense with which we are at present concerned, differs from most if not from all the arts and crafts represented in the Exhibition'}
    

    プロセッサは input_values と labels を追加したことに注意してください。sampling rate もまた 16kHz に正しくダウンサンプリングされています。

Awesome, you should now be able to preprocess data for any modality and even combine different modalities! In the next tutorial, learn how to fine-tune a model on your newly preprocessed data.

 

Everything you always wanted to know about padding and truncation

(訳注: 原文 参照)

 

以上



HuggingFace Transformers 4.17 : Tutorials : AutoClass による事前訓練済みインスタンスのロード

HuggingFace Transformers 4.17 : Tutorials : AutoClass による事前訓練済みインスタンスのロード (翻訳/解説)

翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 04/12/2022 (v4.17.0)

* 本ページは、HuggingFace Transformers の以下のドキュメントを翻訳した上で適宜、補足説明したものです:

* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。

 

クラスキャット 人工知能 研究開発支援サービス

クラスキャット は人工知能・テレワークに関する各種サービスを提供しています。お気軽にご相談ください :

◆ 人工知能とビジネスをテーマに WEB セミナーを定期的に開催しています。スケジュール
  • お住まいの地域に関係なく Web ブラウザからご参加頂けます。事前登録 が必要ですのでご注意ください。

お問合せ : 本件に関するお問い合わせ先は下記までお願いいたします。

  • 株式会社クラスキャット セールス・マーケティング本部 セールス・インフォメーション
  • sales-info@classcat.com  ;  Web: www.classcat.com  ;   ClassCatJP

 

HuggingFace Transformers : Tutorials : AutoClass による事前訓練済みインスタンスのロード

非常に多くの様々な Transformer アーキテクチャにより、貴方のチェックポイントのために一つを作成することは難しい可能性があります。ライブラリの利用を容易に、単純にそして柔軟にする Transformers 哲学の一部として、AutoClass は与えられたチェックポイントから正しいアーキテクチャを自動的に推測してロードします。from_pretrained メソッドは任意のアーキテクチャに対して事前訓練済みモデルを素早くロードさせますので、貴方はスクラッチからモデルを訓練する時間とリソースを割く必要はありません。このタイプのチェックポイント不可知なコードを生成することは、コードが一つのチェックポイントに対して動作すれば – 類似のタスクに対して訓練された限りでは – それは (アーキテクチャが異なる場合でさえ) 別のチェックポイントでも動作することを意味します。

忘れないでください、アーキテクチャはモデルのスケルトンを参照し、チェックポイントは与えられたアーキテクチャの重みです。例えば、BERT はアーキテクチャですが、bert-base-uncased はチェックポイントです。モデルはアーキテクチャかチェックポイントのいずれかを意味する一般的な用語です。

このチュートリアルでは、以下を学習します :

  • 事前訓練済みトークナイザーのロード。
  • 事前訓練済み特徴抽出器のロード。
  • 事前訓練済みプロセッサのロード。
  • 事前訓練済みモデルのロード。

 

AutoTokenizer

殆ど総ての NLP タスクはトークナイザーから始めます。トークナイザーは入力をモデルにより処理できる形式に変換します。

AutoTokenizer.from_pretrained() でトークナイザーをロードします :

from transformers import AutoTokenizer

tokenizer = AutoTokenizer.from_pretrained("bert-base-uncased")

それから下で示されるように入力をトークン化します :

sequence = "In a hole in the ground there lived a hobbit."
print(tokenizer(sequence))
{'input_ids': [101, 1999, 1037, 4920, 1999, 1996, 2598, 2045, 2973, 1037, 7570, 10322, 4183, 1012, 102], 
 'token_type_ids': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
 'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]}

 

AutoFeatureExtractor

音声とビジョンタスクについて、特徴抽出器は音声信号や画像を正しい入力形式に処理します。

AutoFeatureExtractor.from_pretrained() で特徴抽出器をロードします :

from transformers import AutoFeatureExtractor

feature_extractor = AutoFeatureExtractor.from_pretrained(
    "ehcalabres/wav2vec2-lg-xlsr-en-speech-emotion-recognition"
)

 

AutoProcessor

マルチモーダルなタスクは 2 つのタイプの前処理ツールを結合するプロセッサを必要とします。例えば、LayoutLMV2 モデルは画像を処理する特徴抽出器とテキストを処理するトークナイザーを必要とします ; プロセッサはそれらの両者を結合します。

プロセッサを AutoProcessor.from_pretrained() でロードします :

from transformers import AutoProcessor

processor = AutoProcessor.from_pretrained("microsoft/layoutlmv2-base-uncased")

 

AutoModel

最後に、AutoModelFor クラスは与えられたタスク (利用可能なタスクの完全なリストについては ここ を参照) に対する事前訓練済みモデルをロードさせます。例えば、AutoModelForSequenceClassification.from_pretrained() でシークエンス分類用のモデルをロードします。

PyTorch
from transformers import AutoModelForSequenceClassification

model = AutoModelForSequenceClassification.from_pretrained("distilbert-base-uncased")
TensorFlow
from transformers import TFAutoModelForSequenceClassification

model = TFAutoModelForSequenceClassification.from_pretrained("distilbert-base-uncased")

異なるタスクに対するアーキテクチャをロードするために同じチェックポイントを容易に再利用できます :

PyTorch
from transformers import AutoModelForTokenClassification

model = AutoModelForTokenClassification.from_pretrained("distilbert-base-uncased")
TensorFlow
from transformers import TFAutoModelForTokenClassification

model = TFAutoModelForTokenClassification.from_pretrained("distilbert-base-uncased")

一般に、モデルの事前訓練済みインスタンスをロードするためには AutoTokenizer クラスと AutoModelFor クラスを使用することを勧めます。これは毎回正しいアーキテクチャをロードすることを確実にします。次の チュートリアル では、再調整のためにデータセットを前処理するため新たにロードされたトークナイザー、特徴抽出器とプロセッサを使用する方法を学習します。

 

以上



HuggingFace Transformers 4.17 : Tutorials : 推論のためのパイプライン

HuggingFace Transformers 4.17 : Tutorials : 推論のためのパイプライン (翻訳/解説)

翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 04/11/2022 (v4.17.0)

* 本ページは、HuggingFace Transformers の以下のドキュメントを翻訳した上で適宜、補足説明したものです:

* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。

 

クラスキャット 人工知能 研究開発支援サービス

クラスキャット は人工知能・テレワークに関する各種サービスを提供しています。お気軽にご相談ください :

◆ 人工知能とビジネスをテーマに WEB セミナーを定期的に開催しています。スケジュール
  • お住まいの地域に関係なく Web ブラウザからご参加頂けます。事前登録 が必要ですのでご注意ください。

お問合せ : 本件に関するお問い合わせ先は下記までお願いいたします。

  • 株式会社クラスキャット セールス・マーケティング本部 セールス・インフォメーション
  • sales-info@classcat.com  ;  Web: www.classcat.com  ;   ClassCatJP

 

 

HuggingFace Transformers : Tutorials : 推論のためのパイプライン

pipeline() はテキスト生成, 画像セグメンテーション, そして音声分類のような様々なタスクに対して推論のためにモデルハブからの任意のモデルを使用することを単純にします。特定の様式での経験がなくてもあるいはモデルを駆動するコードを理解していなくても、依然として pipeline() でそれらを利用できます!このチュートリアルは以下を教えます :

  • 推論のために pipeline() を使用する。
  • 特定のトークナイザーやモデルを使用する。
  • 音声とビジョンタスクのために pipeline() を使用する。

サポートされるタスクの完全なリストについては pipeline() ドキュメントを見てください。

 

パイプラインの使用方法

各タスクが関連する pipeline() を持つ一方で、一般的な pipeline() 抽象化を使用するのがより簡単です、これは特定のタスクのパイプライン総てを含みます。pipeline() は、タスクのために推論可能なデフォルトのモデルとトークナイザーを自動的にロードします。

  1. pipeline() を作成することから始めて推論タスクを指定します :
    from transformers import pipeline
    
    generator = pipeline(task="text-generation")
    

  2. 入力テキストを pipeline() に渡します :
    generator("Three Rings for the Elven-kings under the sky, Seven for the Dwarf-lords in their halls of stone")
    
    [{'generated_text': 'Three Rings for the Elven-kings under the sky, Seven for the Dwarf-lords in their halls of stone, and Four for the Great-king for the Gods of darkness."\n\n"The first five ring is for the Elf-lords'}]
    

     
    1 つ以上の入力を持つ場合には、入力をリストとして渡します :

    generator(
        [
            "Three Rings for the Elven-kings under the sky, Seven for the Dwarf-lords in their halls of stone",
            "Nine for Mortal Men, doomed to die, One for the Dark Lord on his dark throne",
        ]
    )
    

     
    タスクのための任意の追加のパラメータも pipeline() に含めることができます。テキスト生成タスクは出力を制御するための幾つかのパラメータを持つ generate() メソッドを持ちます。例えば、1 つ以上の出力を生成したい場合には、num_return_sequences パラメータを設定します :

    [[{'generated_text': 'Three Rings for the Elven-kings under the sky, Seven for the Dwarf-lords in their halls of stone and Seven for the Elven-kings for the elves under the ground in the sky to create the great world of Elves.\n\n'}],
     [{'generated_text': "Nine for Mortal Men, doomed to die, One for the Dark Lord on his dark throne,\n\nThe Dark Lord's last gift.\n\nI love you, my Son!\n\nI love you, Lord\n\nLord, you will"}]]
    
    generator(
        "Three Rings for the Elven-kings under the sky, Seven for the Dwarf-lords in their halls of stone",
        num_return_sequences=2,
    )
    
    [{'generated_text': 'Three Rings for the Elven-kings under the sky, Seven for the Dwarf-lords in their halls of stone."\n\n"That\'s what I do," said Gandalf, placing a hand on his head as though to say, "you'},
     {'generated_text': 'Three Rings for the Elven-kings under the sky, Seven for the Dwarf-lords in their halls of stone and Seven for the Night Elves and so there are plenty of names that I can think of.\n\n"So this is where we'}]
    

 

モデルとトークナイザーを選択する

pipeline() は モデルハブ から任意のモデルを受け取ります。モデルハブにはタグがあります、これはタスクのために使用したいモデルをフィルタリングすることを可能にします。適切なモデルを選択すれば、対応する AutoModelFor と AutoTokenizer クラスでそれをロードします。例えば、因果言語モデリング・タスクのために AutoModelForCausalLM クラスをロードします :

from transformers import AutoTokenizer, AutoModelForCausalLM

tokenizer = AutoTokenizer.from_pretrained("distilgpt2")
model = AutoModelForCausalLM.from_pretrained("distilgpt2")

タスクのために pipeline() を作成して、ロードしたモデルとトークナイザーを指定します :

from transformers import pipeline

generator = pipeline(task="text-generation", model=model, tokenizer=tokenizer)

あるテキストを生成するために入力テキストを pipeline() に渡します :

generator("Three Rings for the Elven-kings under the sky, Seven for the Dwarf-lords in their halls of stone")
[{'generated_text': 'Three Rings for the Elven-kings under the sky, Seven for the Dwarf-lords in their halls of stone, and the Iron-crown-crown-godden of a few thousand feet. To see how many of them have'}]

 

音声パイプライン

pipeline() の柔軟性はつまりそれは音声タスクにも拡張できます。

例えば、 John F. Kennedy の有名な “We choose to go to the Moon” スピーチの短いクリップから感情を分類しましょう。モデルハブで感情認識のための 音声分類 モデルを見つけてそれを pipeline() でロードします :

from transformers import pipeline

audio_classifier = pipeline(
    task="audio-classification", model="ehcalabres/wav2vec2-lg-xlsr-en-speech-emotion-recognition"
)

音声ファイルを pipeline() に渡します :

audio_classifier("jfk_moon_speech.wav")
[{'label': 'calm', 'score': 0.13856211304664612},
 {'label': 'disgust', 'score': 0.13148026168346405},
 {'label': 'happy', 'score': 0.12635163962841034},
 {'label': 'angry', 'score': 0.12439591437578201},
 {'label': 'fearful', 'score': 0.12404385954141617}]

 

ビジョン・パイプライン

最後に、ビジョンタスクのために pipeline() を使用することは実際上、同じです。

ビジョンタスクを指定して画像を分類器に渡します。画像はリンクか画像へのローカルパスであり得ます。例えば、何の種の猫が下で示されるでしょう?

from transformers import pipeline

vision_classifier = pipeline(task="image-classification")
vision_classifier(
    images="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/pipeline-cat-chonk.jpeg"
)
[{'label': 'lynx, catamount', 'score': 0.4403027892112732},
 {'label': 'cougar, puma, catamount, mountain lion, painter, panther, Felis concolor',
  'score': 0.03433405980467796},
 {'label': 'snow leopard, ounce, Panthera uncia',
  'score': 0.032148055732250214},
 {'label': 'Egyptian cat', 'score': 0.02353910356760025},
 {'label': 'tiger cat', 'score': 0.023034192621707916}]
 

以上



ClassCat® Chatbot

人工知能開発支援
クラスキャットは 人工知能研究開発支援 サービスを提供しています :
  • テクニカルコンサルティングサービス
  • 実証実験 (プロトタイプ構築)
  • アプリケーションへの実装
  • 人工知能研修サービス
◆ お問合せ先 ◆
(株)クラスキャット
セールス・インフォメーション
E-Mail:sales-info@classcat.com

カテゴリー