yasuokaの日記: Transformersにおける日本語トークナイザBertMecabTokenizerFastの試作
2022年1月4日の日記でデッチ上げたBertJapaneseTokenizerFastだが、連続する[UNK]に対する動作がマズイので、BertMecabTokenizerFastとして書き直してみた。Google Colaboratoryで動かしてみよう。
!pip install transformers fugashi unidic_lite
from transformers import BertTokenizerFast
from transformers.models.bert_japanese.tokenization_bert_japanese import MecabTokenizer
class MecabPreTokenizer(MecabTokenizer):
def mecab_split(self,i,normalized_string):
t=str(normalized_string)
e=0
z=[]
for c in self.tokenize(t):
s=t.find(c,e)
e=e if s<0 else s+len(c)
z.append((0,0) if s<0 else (s,e))
return [normalized_string[s:e] for s,e in z if e>0]
def pre_tokenize(self,pretok):
pretok.split(self.mecab_split)
class BertMecabTokenizerFast(BertTokenizerFast):
def __init__(self,vocab_file,do_lower_case=False,tokenize_chinese_chars=False,**kwargs):
from tokenizers.pre_tokenizers import PreTokenizer,BertPreTokenizer,Sequence
super().__init__(vocab_file=vocab_file,do_lower_case=do_lower_case,tokenize_chinese_chars=tokenize_chinese_chars,**kwargs)
d=kwargs["mecab_kwargs"] if "mecab_kwargs" in kwargs else {"mecab_dic":"ipadic"}
self._tokenizer.pre_tokenizer=Sequence([PreTokenizer.custom(MecabPreTokenizer(**d)),BertPreTokenizer()])
tokenizer=BertMecabTokenizerFast.from_pretrained("cl-tohoku/bert-base-japanese-v2")
d=tokenizer("𠮟られても平気なの☺ ☺☺",return_offsets_mapping=True)
print([tokenizer.convert_ids_to_tokens(t) for t in d["input_ids"]],d,sep="\n")
cl-tohoku/bert-base-japanese-v2のトークナイザを拡張して、「𠮟られても平気なの☺ ☺☺」をトークナイズしてみたところ、私(安岡孝一)の手元では以下の結果になった。
['[CLS]', '[UNK]', 'られ', 'て', 'も', '平', '##気', 'な', 'の', '[UNK]', '[UNK]', '[SEP]']
{'input_ids': [2, 1, 11158, 888, 916, 2180, 7193, 892, 896, 1, 1, 3], 'token_type_ids': [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], 'offset_mapping': [(0, 0), (0, 1), (1, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 8), (8, 9), (9, 10), (11, 13), (0, 0)]}
連続する[UNK]に対しても、offset_mappingがちゃんと出ていてうれしい。ただ、このBertMecabTokenizerFastは、word_tokenizer_type="mecab"かつsubword_tokenizer_type="wordpiece"決め打ちでサポートしているので、それ以外の組み合わせに対しては動作がマズかったりする。さて、"jumanpp"とか"char"とか、どうするべきかなあ。
Transformersにおける日本語トークナイザBertMecabTokenizerFastの試作 More ログイン