yasuokaの日記: なぜnlp-waseda/roberta-base-japaneseのトークナイザはJuman++とSentencePieceの両方を必要とするのか 1
早稲田大学の河原研究室から、日本語RoBERTaモデルroberta-base-japaneseがリリースされたので、早速、使ってみたのだが、Juman++とSentencePieceの両方がトークナイザに必要で、かなり難儀した。何とかGoogle Colaboratoryで動かすことができたので、以下にやり方を示しておく。
!test -d jumanpp-2.0.0-rc3 || curl -L https://github.com/ku-nlp/jumanpp/releases/download/v2.0.0-rc3/jumanpp-2.0.0-rc3.tar.xz | tar xJf -
!test -x /usr/local/bin/jumanpp || ( mkdir jumanpp-2.0.0-rc3/build && cd jumanpp-2.0.0-rc3/build && cmake .. -DCMAKE_BUILD_TYPE=Release && make install )
!pip install transformers sentencepiece
import subprocess
from transformers import AutoTokenizer,AutoModelForMaskedLM,FillMaskPipeline
tkz=AutoTokenizer.from_pretrained("nlp-waseda/roberta-base-japanese")
mdl=AutoModelForMaskedLM.from_pretrained("nlp-waseda/roberta-base-japanese")
fmp=FillMaskPipeline(model=mdl,tokenizer=tkz)
pipeline=lambda text: fmp(subprocess.check_output(["jumanpp","--segment"],input=text,encoding="utf-8").replace("[MASK ]","[MASK]"))
print(pipeline("国境の[MASK]トンネルを抜けると雪国であった。"))
「国境の[MASK]トンネルを抜けると雪国であった。」の[MASK]を穴埋めさせてみたところ、私(安岡孝一)の手元では以下の結果になった。
[{'score': 0.04856615141034126, 'token': 2941, 'token_str': 'トンネル', 'sequence': '国境 の トンネル トンネル を 抜ける と 雪国 であった 。 '}, {'score': 0.03849461302161217, 'token': 1990, 'token_str': '裏', 'sequence': '国境 の 裏 トンネル を 抜ける と 雪国 であった 。 '}, {'score': 0.03716845065355301, 'token': 2754, 'token_str': '奥', 'sequence': '国境 の 奥 トンネル を 抜ける と 雪国 であった 。 '}, {'score': 0.036876387894153595, 'token': 575, 'token_str': 'ような', 'sequence': '国境 の ような トンネル を 抜ける と 雪国 であった 。 '}, {'score': 0.024394523352384567, 'token': 2244, 'token_str': '地下', 'sequence': '国境 の 地下 トンネル を 抜ける と 雪国 であった 。 '}]
残念ながら、結果に形容詞が一つも出てこない。もしかしたら、Juman++とSentencePieceの繋ぎ方が悪いのか、と思って、他にも色々と試してみたのだが、そもそもトークナイザの作りが日本語向けになっておらず、いい結果が得られなかった。うーむ、こういう日本語モデル、さて、どうやって使えばいいのかしら。
末尾にrstrip()が必要 (スコア:2)
のようにすべきだ、との御連絡をいただきました。jumanppの出力から、改行を引っぺがさなければいけないようです。これだと結果は以下のようになりました。
2番目に「長い」が出てきてます。素晴らしい。