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

yasuokaの日記: Transformersにおける日本語トークナイザBertMecabTokenizerFastの試作

日記 by yasuoka

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"とか、どうするべきかなあ。

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

ソースを見ろ -- ある4桁UID

読み込み中...