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

yasuokaの日記: bert-large-japanese-charのトークナイザをBertTokenizerFastで置き換えるには 2

日記 by yasuoka

とあるイキサツで、cl-tohoku/bert-large-japanese-charのトークナイザを、TransformersのBertTokenizerFastで置き換えてみた。bert-large-japanese-charのトークナイザは文字切りをおこなうのだが、なぜかfugashiを要求していて、正直ちょっと辛いのだ。とりあえずGoogle Colaboratoryで、やってみよう。

!pip install transformers
from transformers import BertTokenizerFast,AutoModelForMaskedLM
tokenizer=BertTokenizerFast.from_pretrained("cl-tohoku/bert-large-japanese-char")
model=AutoModelForMaskedLM.from_pretrained("cl-tohoku/bert-large-japanese-char")
tokenizer.backend_tokenizer.normalizer.handle_chinese_chars=True
tokenizer.backend_tokenizer.normalizer.strip_accents=False
tokenizer.backend_tokenizer.normalizer.lowercase=False
tokenizer.backend_tokenizer.decoder.prefix=""
tokenizer.backend_tokenizer.model.continuing_subword_prefix=""
tokenizer.backend_tokenizer.model.max_input_chars_per_word=200
tokenizer.save_pretrained("my.char.model")
model.config.tokenizer_class="BertTokenizerFast"
model.save_pretrained("my.char.model")

うまくいけばmy.char.modelに新たなモデルが作られる。中のjsonファイルがキモで、pytorch_model.binそのものは変わってないみたいだが、これでfugashiが不要になり、return_offsets_mappingが使えるようになる。ちょっと使ってみよう。

import torch
from transformers import AutoTokenizer,AutoModelForMaskedLM
tokenizer=AutoTokenizer.from_pretrained("my.char.model")
model=AutoModelForMaskedLM.from_pretrained("my.char.model")
s=tokenizer("酸素ボンベを充[MASK]する。",return_offsets_mapping=True)
print(s)
ids=s["input_ids"]
tokens=tokenizer.convert_ids_to_tokens(ids)
mask=ids.index(tokenizer.mask_token_id)
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)

「酸素ボンベを充[MASK]する。」を穴埋めさせてみたところ、私(安岡孝一)の手元では以下の結果になった。

{'input_ids': [2, 5343, 4159, 998, 1021, 995, 932, 1294, 4, 875, 925, 829, 3], 'token_type_ids': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], 'offset_mapping': [(0, 0), (0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 13), (13, 14), (14, 15), (15, 16), (0, 0)]}
['[CLS]', '酸', '素', 'ボ', 'ン', 'ベ', 'を', '充', '[MASK]', 'す', 'る', '。', '[SEP]'] 8
1 ['[CLS]', '酸', '素', 'ボ', 'ン', 'ベ', 'を', '充', '填', 'す', 'る', '。', '[SEP]']
2 ['[CLS]', '酸', '素', 'ボ', 'ン', 'ベ', 'を', '充', '電', 'す', 'る', '。', '[SEP]']
3 ['[CLS]', '酸', '素', 'ボ', 'ン', 'ベ', 'を', '充', '充', 'す', 'る', '。', '[SEP]']
4 ['[CLS]', '酸', '素', 'ボ', 'ン', 'ベ', 'を', '充', '給', 'す', 'る', '。', '[SEP]']
5 ['[CLS]', '酸', '素', 'ボ', 'ン', 'ベ', 'を', '充', '実', 'す', 'る', '。', '[SEP]']

どうやら大丈夫そうだ。なお、同じ方法でKoichiYasuoka/bert-large-japanese-char-extendedKoichiYasuoka/bert-base-japanese-char-extendedのトークナイザも、BertTokenizerFastに入れ替えておいたので、こちらも試してみてほしい。

この議論は、yasuoka (21275)によって ログインユーザだけとして作成されたが、今となっては 新たにコメントを付けることはできません。
typodupeerror

最初のバージョンは常に打ち捨てられる。

読み込み中...