パスワードを忘れた? アカウント作成
15525132 journal
人工知能

yasuokaの日記: なぜnlp-waseda/roberta-base-japaneseのトークナイザはJuman++とSentencePieceの両方を必要とするのか 1

日記 by yasuoka

早稲田大学の河原研究室から、日本語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の繋ぎ方が悪いのか、と思って、他にも色々と試してみたのだが、そもそもトークナイザの作りが日本語向けになっておらず、いい結果が得られなかった。うーむ、こういう日本語モデル、さて、どうやって使えばいいのかしら。

この議論は、yasuoka (21275)によって ログインユーザだけとして作成されたが、今となっては 新たにコメントを付けることはできません。
  • by yasuoka (21275) on 2021年12月26日 18時57分 (#4176662) 日記

    !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]").rstrip())
    print(pipeline("国境の[MASK]トンネルを抜けると雪国であった。"))

    のようにすべきだ、との御連絡をいただきました。jumanppの出力から、改行を引っぺがさなければいけないようです。これだと結果は以下のようになりました。

    [{'score': 0.16705641150474548, 'token': 2244, 'token_str': '地下', 'sequence': '国境 の 地下 トンネル を 抜ける と 雪国 であった 。'}, {'score': 0.1442069262266159, 'token': 2309, 'token_str': '長い', 'sequence': '国境 の 長い トンネル を 抜ける と 雪国 であった 。'}, {'score': 0.026420066133141518, 'token': 509, 'token_str': '北', 'sequence': '国境 の 北 トンネル を 抜ける と 雪国 であった 。'}, {'score': 0.02307763881981373, 'token': 526, 'token_str': '南', 'sequence': '国境 の 南 トンネル を 抜ける と 雪国 であった 。'}, {'score': 0.019045764580368996, 'token': 577, 'token_str': '山', 'sequence': '国境 の 山 トンネル を 抜ける と 雪国 であった 。'}]

    2番目に「長い」が出てきてます。素晴らしい。

typodupeerror

「毎々お世話になっております。仕様書を頂きたく。」「拝承」 -- ある会社の日常

読み込み中...