LoginSignup
1
2

SwallowのLlamaTokenizerFastに常用漢字「𠮟」「塡」「剝」「頰」を追加するには

Posted at

12月21日の記事の続きだが、Swallowのトークナイザは常用漢字2136字のうち51字をサポートしておらず、これら51字はバイトフォールバックしてしまう。ただ、第3水準漢字の「𠮟」「塡」「剝」「頰」については、代わりに「叱」「填」「剥」「頬」で事前学習されているようだ。Swallow-7b-hfで確かめてみよう。

>>> from transformers import LlamaTokenizerFast
>>> tkz=LlamaTokenizerFast.from_pretrained("tokyotech-llm/Swallow-7b-hf")
>>> print(tkz.convert_ids_to_tokens(sum(tkz(["𠮟責","頰","剝離","装塡"])["input_ids"],[])))
['<s>', '▁', '<0xF0>', '<0xA0>', '<0xAE>', '<0x9F>', '責', '<s>', '▁', '<0xE9>', '<0xA0>', '<0xB0>', '<s>', '▁', '<0xE5>', '<0x89>', '<0x9D>', '離', '<s>', '▁', '装', '<0xE5>', '<0xA1>', '<0xA1>']
>>> print(tkz.convert_ids_to_tokens(sum(tkz(["叱責","頬","剥離","装填"])["input_ids"],[])))
['<s>', '▁', '叱', '責', '<s>', '▁', '頬', '<s>', '▁', '剥', '離', '<s>', '▁', '装', '填']

それならば、入力中の「𠮟」「塡」「剝」「頰」を、それぞれ「叱」「填」「剥」「頬」にReplaceするよう、トークナイザを書き換えてしまった方がうれしい気がする。とりあえず、現状のnormalizerがどうなっているか見てみよう。

>>> import json
>>> d=json.loads(tkz.backend_tokenizer.to_str())
>>> print(d["normalizer"])
{'type': 'Sequence', 'normalizers': [{'type': 'Prepend', 'prepend': '▁'}, {'type': 'Replace', 'pattern': {'String': ' '}, 'content': '▁'}]}

Sequenceの中身は、メタスペースのPrependと、空白からメタスペースへのReplaceなので、「𠮟」「塡」「剝」「頰」のReplaceSequenceに追加すればよさそうだ。

>>> from tokenizers.normalizers import Sequence,Prepend,Replace
>>> tkz.backend_tokenizer.normalizer=Sequence([Prepend("\u2581"),Replace(" ","\u2581"),Replace("𠮟","叱"),Replace("頰","頬"),Replace("剝","剥"),Replace("塡","填")])
>>> print(tkz.convert_ids_to_tokens(sum(tkz(["𠮟責","頰","剝離","装塡"])["input_ids"],[])))
['<s>', '▁', '叱', '責', '<s>', '▁', '頬', '<s>', '▁', '剥', '離', '<s>', '▁', '装', '填']

よし、うまくいった。mySwallow-7b-hfに保存しよう。

>>> tkz.save_pretrained("mySwallow-7b-hf")
('mySwallow-7b-hf/tokenizer_config.json', 'mySwallow-7b-hf/special_tokens_map.json', 'mySwallow-7b-hf/tokenizer.model', 'mySwallow-7b-hf/added_tokens.json', 'mySwallow-7b-hf/tokenizer.json')

ちなみに、モデル自体も同じディレクトリに保存しておくと、pipelineとかの読み込みで便利だったりするが、27GBもあるのでハードディスクと相談してほしい。

>>> from transformers import LlamaForCausalLM
>>> mdl=LlamaForCausalLM.from_pretrained("tokyotech-llm/Swallow-7b-hf")
>>> mdl.save_pretrained("mySwallow-7b-hf")

ただし、このReplaceをやってしまうと、たとえば「頬と頰はどちらが子供の名づけに使えますか?」という質問には、絶対に答えられなくなってしまう。その点に注意してReplaceしてほしい。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2