HuggingFace で日本語モデルを使ってみる

事前学習済みの日本語モデルが数行書くだけで試せる時代になったようです

目次

クロスワードパズルとか NLP でできるのかなーとちょっと思ったので、最近流行りの HuggingFace を試してみました。 どうやら事前学習済みの日本語モデルが数行書くだけで試せる時代になったようです。

環境構築

今回は pyenv を使って Python3.9 系に poetry を使って色々 Install していきます。

前提環境

  • MacBook Pro(M1), OS: Monterey(12.0.1)
  • brew は Install 済みとします
  • pyenv: 2.2.2
    • もしまだ Install されていなければ、 brew install pyenv で Install できます
  • Python: 3.9.9
    • もしまだ Install されていなければ pyenv install 3.9.9 で Install できます

プロジェクト環境構築

まず ディレクトリ を作って、Python3.9.9 を使うように指定して、poetry の初期化をします。

mkdir my_bert
cd my_bert
pyenv local 3.9.9
poetry init -n --python '>=3.9,<3.10'

上記のように --python '>=3.9,<3.10' としておくのは大事で、そうしないと poetry add numpy がバージョン互換性のために失敗してしまいます。


numpy, torch, transformers を Install します。 ちょっと前までは M1 Mac にこれらを Install するのが難航したものですが、今は簡単に入りますね。

poetry add numpy torch transformers

今回使う bert-base-japanese-char-v2mecab, fugashi, unidic_lite を必要とするので、これも Install します。 どの言語モデルがどういうライブラリを要求するかは色々あるので、 実際は「何かエラーが出たら追加で Install する」という感じになると思います。

※ わざわざ再現するのもあれなので最初から Install します。

brew install mecab
poetry add fugashi unidic_lite

最終的に Install されていたバージョンは以下の通りです。

numpy = "^1.21.5"
torch = "^1.10.1"
transformers = "^4.15.0"
fugashi = "^1.1.1"
unidic-lite = "^1.0.8"

動かしてみる

bert-base-japanese-char-v2 は、 東北大学が公開してくれている学習済みモデルです。 ちょっと変わっているのは「辞書に載っているような単語単位で学習したモデル」ではなく「文字単位で学習したモデル」というところです。

なので例えば、文章の一部分を隠して推測させるタスク( fill-mask) では、1文字分の予測結果を返すことになります。 クロスワードパズルとかできそうですね。

サンプルコード

以下のようなコードで 「私は ◯ です。」 の 「◯」の部分を予測させることができます。

# play.py
from pprint import pprint

from transformers import AutoTokenizer, AutoModelForMaskedLM, pipeline
from transformers import BertForMaskedLM, BertJapaneseTokenizer  # for type complemention

tokenizer = AutoTokenizer.from_pretrained("cl-tohoku/bert-base-japanese-char-v2")  # type: BertJapaneseTokenizer
model = AutoModelForMaskedLM.from_pretrained("cl-tohoku/bert-base-japanese-char-v2")  # type: BertForMaskedLM
pipe = pipeline("fill-mask", model=model, tokenizer=tokenizer)

MASK = tokenizer.mask_token
text = f"今日は休みなので、私は{MASK}です。"
pprint(pipe(text, top_k=3))

コマンドラインから

poetry run python play.py

などで実行してみると、以下のようになりました。

[{'score': 0.2861271798610687,
  'sequence': '今 日 は 休 み な の で 、 私 は 嫌 で す 。',
  'token': 1941,
  'token_str': '嫌'},
 {'score': 0.13725848495960236,
  'sequence': '今 日 は 休 み な の で 、 私 は 朝 で す 。',
  'token': 2821,
  'token_str': '朝'},
 {'score': 0.07323182374238968,
  'sequence': '今 日 は 休 み な の で 、 私 は 暇 で す 。',
  'token': 2773,
  'token_str': '暇'}]

まあ、3つ目くらいが妥当ですかね…

いろいろ遊べる部分

  • 言語モデルは Hugging Face Models の中から選んで指定できます。ただし、モデルによって必要なライブラリが違うので、エラ ーが出たらその名前から適当に Install してみると良いでしょう。キーワードはたいていモデル説明ページのドキュメントにも書いてあることが多いです。
  • top_k=3 の部分で上位いくつの結果を返すかを指定できます。
  • pipe(text, targets=["嘘", "馬", "前", "橘", "上"]) というように targets で指定した単語の score を返してくれます。
    [{'score': 0.007146810181438923,
    'sequence': '今 日 は 休 み な の で 、 私 は 嘘 で す 。',
    'token': 1681,
    'token_str': '嘘'},
    {'score': 0.004257831256836653,
    'sequence': '今 日 は 休 み な の で 、 私 は 前 で す 。',
    'token': 1402,
    'token_str': '前'},
    {'score': 0.0002205580531153828,
    'sequence': '今 日 は 休 み な の で 、 私 は 上 で す 。',
    'token': 1037,
    'token_str': '上'},
    {'score': 0.00012557016452774405,
    'sequence': '今 日 は 休 み な の で 、 私 は 馬 で す 。',
    'token': 5741,
    'token_str': '馬'},
    {'score': 2.5849765279417625e-06,
    'sequence': '今 日 は 休 み な の で 、 私 は 橘 で す 。',
    'token': 3049,
    'token_str': '橘'}]
    
  • 色々な言語タスクに対応した pipeline があって、それらはこんな感じで簡単に使えます。各 pipeline の説明は、この方の Note がとてもわかりやすかったです。

さいごに

使うだけならここまでお手軽に使えるようです。 あとは超高精度な言語モデルが一般公開されれば…

Reference