python3 機械学習・ディープラーニング

bert-base-japanese-v2の使い方!MASKされた日本語を推測する

記事内に広告が含まれています。

ふゅか
bert-base-japanese-v2の話をするんだって!楽しみ~♪ どんなモデルか知ってる?
はるか
うん、東北大学が開発した日本語に対応したBERT。

BERTとは

  • Encoderタイプのモデル
  • 日本語対応
  • 日本語のwikiを学習
  • 12層のレイヤー
  • 768次元の隠れ層
  • アテンションヘッドが12個

BERT(Bidirectional Encoder Representations from Transformers)はencoderのみのモデルです。bert-base-japanese-v2 はbertの一種で、日本語でMLMができます。東北大学によって開発されました。

bert-base-japanese-v2でできること

MLM(Masked Language Modeling)と呼ばれるマスクされた位置に何の単語が入るべきかを予測します。

MLMの流れ

  1. 単語のマスキング
    • 選ばれた単語はマスクトークン(通常は [MASK] トークン)に置き換えられます。例えば、「ある日、友人が砂糖と塩を間違えてコーヒーに入れました。飲んだ瞬間の反応が忘れられません!」という文があった場合、「ある日、友人が砂糖と塩を間違えてコーヒーに入れました。飲んだ瞬間の[MASK]が忘れられません!」のように一部の単語がマスクされます。
  2. マスクされた文をモデルに入力
    • マスクされた文がBERTモデルに入力されます。モデルはこのマスクされた文を通して、マスクされた単語を予測します。
  3. マスクされた単語の予測
    • モデルは、マスクされた位置に何の単語が入るべきかを予測します。例えば、マスクされた位置に「反応」が元々入っていたことを予測します。

ふゅか
このコードを使えば、文中の[MASK]が何か予測できるのね!

はるか
うん、モデルが予測結果を返してくれる。

pythonコード

実行環境

  • RTX 4070ti super VRAM 16GB
  • Windows11
  • memory 64GB
  • Python 3.11.9

ライブラリのinstall

次のコマンドで、ライブラリをインストールする必要があります。

pip install transformers
pip install fugashi
pip install unidic-lite

pipelineのコード

次のプログラムは、Hugging FaceのTransformersライブラリを使用して、BERTモデルでマスク化言語モデリング(Masked Language Modeling, MLM)を実行しています。具体的には、指定された文中のマスクされた部分を予測します。

from transformers import pipeline

pipe = pipeline("fill-mask", model="tohoku-nlp/bert-base-japanese-v2",device=0)
out=pipe("ある日、友人が砂糖と塩を間違えてコーヒーに入れました。飲んだ瞬間の[MASK]が忘れられません!")

入力文 "ある日、友人が砂糖と塩を間違えてコーヒーに入れました。飲んだ瞬間の[MASK]が忘れられません!" をモデルに渡します。文中の [MASK] トークンが予測対象となります。モデルはこのマスクされた単語を予測します。

[{'score': 0.21244759857654572,
  'token': 13385,
  'token_str': '記憶',
  'sequence': 'ある 日 、 友人 が 砂糖 と 塩 を 間違え て コーヒー に 入れ まし た 。 飲ん だ 瞬間 の 記憶 が 忘れ られ ませ ん!'},
 {'score': 0.09215220808982849,
  'token': 12824,
  'token_str': '反応',
  'sequence': 'ある 日 、 友人 が 砂糖 と 塩 を 間違え て コーヒー に 入れ まし た 。 飲ん だ 瞬間 の 反応 が 忘れ られ ませ ん!'},
 {'score': 0.06483859568834305,
  'token': 15911,
  'token_str': '衝撃',
  'sequence': 'ある 日 、 友人 が 砂糖 と 塩 を 間違え て コーヒー に 入れ まし た 。 飲ん だ 瞬間 の 衝撃 が 忘れ られ ませ ん!'},
 {'score': 0.05512003228068352,
  'token': 16947,
  'token_str': '感覚',
  'sequence': 'ある 日 、 友人 が 砂糖 と 塩 を 間違え て コーヒー に 入れ まし た 。 飲ん だ 瞬間 の 感覚 が 忘れ られ ませ ん!'},
 {'score': 0.04658579081296921,
  'token': 21166,
  'token_str': '感動',
  'sequence': 'ある 日 、 友人 が 砂糖 と 塩 を 間違え て コーヒー に 入れ まし た 。 飲ん だ 瞬間 の 感動 が 忘れ られ ませ ん!'}]

この結果から、モデルは「記憶」を最も自然な予測とし、次に「反応」、「衝撃」、「感覚」、「感動」という順で予測しています。

モデルを直接読み込む方法

プログラムの流れは次のようになっています。

  • トークン化したテキストをモデルに入力します。
  • モデルからの出力を取得します。
  • 出力から予測されたトークンのインデックスを取得します。
  • トークナイザーを使って予測されたトークンをデコードします。
  • マスクされたトークンのインデックスを特定し、その予測トークンを取得して表示します。
from transformers import AutoTokenizer, AutoModelForMaskedLM
import torch

model_id = "tohoku-nlp/bert-base-japanese-v2"
tokenizer = AutoTokenizer.from_pretrained(model_id)
model = AutoModelForMaskedLM.from_pretrained(model_id)

text = "ある日、友人が砂糖と塩を間違えてコーヒーに入れました。飲んだ瞬間の[MASK]が忘れられません!"
inputs = tokenizer(text, return_tensors="pt")

# モデルに入力を与えて出力を得る
outputs = model(**inputs)

# 予測されたトークンのインデックスを取得
predicted_token_ids = outputs.logits.argmax(dim=-1)

# 予測されたトークンをデコード
predicted_tokens = tokenizer.decode(predicted_token_ids[0], skip_special_tokens=True)

# マスクされたトークンだけを取得
masked_index = (inputs['input_ids'] == tokenizer.mask_token_id).nonzero(as_tuple=True)[1]
predicted_masked_token_id = predicted_token_ids[0, masked_index].item()
predicted_masked_token = tokenizer.decode(predicted_masked_token_id)

print(f"入力文: {text}")
print(f"予測されたマスクトークン: {predicted_masked_token}")
print(f"予測された文全体: {predicted_tokens}")
入力文: ある日、友人が砂糖と塩を間違えてコーヒーに入れました。飲んだ瞬間の[MASK]が忘れられません!
予測されたマスクトークン: 記 憶
予測された文全体: ! ある 日 、 友人 が 砂糖 と 塩 を 間違え て コーヒー に 入れ まし た 。 飲ん だ 瞬間 の 記憶 が 忘れ られ ませ ん! 。

ふゅか
自分でモデルを読み込んで使う方法もあるんだね。便利!

はるか
そう、直接使うことで細かい制御ができる。

使用された計算資源

 

Transformersに関連する書籍

最後に、Transformersに関連する書籍についてまとめました!

機械学習エンジニアのためのTransformers ―最先端の自然言語処理ライブラリによるモデル開発
大規模言語モデル入門

-python3, 機械学習・ディープラーニング
-, , ,