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

yasuokaの日記: rinna/japanese-roberta-baseのトークナイザをRemBertTokenizerFastで置き換えるには

日記 by yasuoka

思うところあって、rinna/japanese-roberta-baseのトークナイザを、TransformersのRemBertTokenizerFastで置き換えてみた。T5Tokenizerはdo_lower_case=Trueを嫌っているし、まして[CLS]を付与したりしてくれないからだ。とりあえずGoogle Colaboratoryで、やってみよう。

!pip install 'transformers>=4.10.0' sentencepiece
from transformers import RemBertTokenizerFast,RobertaForMaskedLM
from transformers.file_utils import cached_path,hf_bucket_url
rinna="rinna/japanese-roberta-base"
tokenizer=RemBertTokenizerFast.from_pretrained(rinna,vocab_file=cached_path(hf_bucket_url(rinna,"spiece.model")))
model=RobertaForMaskedLM.from_pretrained(rinna)
tokenizer.do_lower_case=True
tokenizer.backend_tokenizer.pre_tokenizer.add_prefix_space=False
model.config.tokenizer_class="RemBertTokenizerFast"
tokenizer.save_pretrained("my.rinna.model")
model.save_pretrained("my.rinna.model")

うまくいけばmy.rinna.modelに新たなモデルが作られる。add_prefix_space=Falseすべきか迷ったのだが、これがTrueだと、[MASK]の直後に"_"を入れてくるのでウザイのだ。ちょっと使ってみよう。

import torch
from transformers import AutoTokenizer,AutoModelForMaskedLM
tokenizer=AutoTokenizer.from_pretrained("my.rinna.model")
model=AutoModelForMaskedLM.from_pretrained("my.rinna.model")
s=tokenizer("4年に1度[MASK]は開かれる。",return_offsets_mapping=True)
print(s)
ids=s["input_ids"]
mask=ids.index(tokenizer.mask_token_id)
tokens=tokenizer.convert_ids_to_tokens(ids)
print(tokens,mask)
inputs=torch.tensor([ids])
with torch.no_grad():
  outputs=model(inputs)
  pred=outputs[0][0,mask].topk(5)
for i,t in enumerate(tokenizer.convert_ids_to_tokens(pred.indices)):
  tokens[mask]=t
  print(i+1,tokens)

「4年に1度[MASK]は開かれる。」を穴埋めさせてみたところ、私(安岡孝一)の手元では以下の結果になった。

{'input_ids': [4, 37, 44, 24, 368, 6, 11, 21583, 8, 5], 'token_type_ids': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1], 'offset_mapping': [(0, 0), (0, 1), (1, 3), (3, 4), (4, 5), (5, 11), (11, 12), (12, 16), (16, 17), (0, 0)]}
['[CLS]', '4', '年に', '1', '度', '[MASK]', 'は', '開かれる', '。', '[SEP]'] 5
1 ['[CLS]', '4', '年に', '1', '度', '大会', 'は', '開かれる', '。', '[SEP]']
2 ['[CLS]', '4', '年に', '1', '度', '株主総会', 'は', '開かれる', '。', '[SEP]']
3 ['[CLS]', '4', '年に', '1', '度', 'オールスターゲーム', 'は', '開かれる', '。', '[SEP]']
4 ['[CLS]', '4', '年に', '1', '度', 'オリンピック', 'は', '開かれる', '。', '[SEP]']
5 ['[CLS]', '4', '年に', '1', '度', 'アジア競技大会', 'は', '開かれる', '。', '[SEP]']

まあまあの結果だが、文末の[SEP]は無い方がいいのかもしれない。ただ、単語長がUniDicより長い部分があるので、トークナイザを置き換えてもSuPar-UniDicには適さないようだ。うーん、残念。

この議論は、yasuoka (21275)によって「 ログインユーザだけ」として作成されている。 ログインしてから来てね。
typodupeerror

ハッカーとクラッカーの違い。大してないと思います -- あるアレゲ

読み込み中...