アイソモカ

知の遊牧民の開発記録

開発記録 210917 Fri BertJapaneseTokenizer でトークン化(気になったこと)

『Pytorch自然言語処理プログラミング』の5章を引き続きやっていきます。

isomocha.hatenablog.com

気になったこと。

BertJapaneseTokenizer.encode() に『分かち書きした形態素リスト』を入力すると、どうやら WordPiece によるサブワード分割が働かないっぽい

# bert8_fromlocal.py
# 5.8 ローカルに置いたモデルからの読み込み
from transformers import BertJapaneseTokenizer
from transformers.models.bert_japanese import tokenization_bert_japanese

tknz = BertJapaneseTokenizer(
    vocab_file="BERT-base_mecab-ipadic-bpe-32k/vocab.txt",
    do_lower_case=False, do_basic_tokenize=False
    )
tknz.word_tokenizer = tokenization_bert_japanese.MecabTokenizer()

toks = tknz.word_tokenizer.tokenize("毎朝父は味噌汁を飲みますが、私はコーヒーを飲みます。")
print(toks) 
# ['毎朝', '父', 'は', '味噌汁', 'を', '飲み', 'ます', 'が', '、', '私', 'は', 'コーヒー', 'を', '飲み', 'ます', '。']

ids = tknz.encode(toks)
print(ids)
# [2, 1, 800, 9, 1, 11, 9346, 2610, 14, 6, 1325, 9, 9171, 11, 9346, 2610, 8, 3]
print(tknz.convert_ids_to_tokens(ids)) 
# ['[CLS]', '[UNK]', '父', 'は', '[UNK]', 'を', '飲み', 'ます', 'が', '、', '私', 'は', 'コーヒー', 'を', '飲み', 'ます', '。', '[SEP]']

サブワード分割が働いていなくて、「毎朝」「味噌汁」がボキャブラリにないため [UNK] (未知語)トークンになってしまった。

ところが、BertJapaneseTokenizer.encode()への入力が、『空白で分かち書きされた文字列』または、『分かち書きしていない文字列』の場合は、サブワード分割が働く。

# bert8_fromlocal.py の続き
ids_joined = tknz.encode(" ".join(toks))
print(ids_joined) 
# [2, 979, 28956, 800, 9, 16022, 30628, 11, 9346, 2610, 14, 6, 1325, 9, 9171, 11, 9346, 2610, 8, 3]
print(tknz.convert_ids_to_tokens(ids_joined)) 
# ['[CLS]', '毎', '##朝', '父', 'は', '味噌', '##汁', 'を', '飲み', 'ます', 'が', '、', '私', 'は', 'コーヒー', 'を', '飲み', 'ます', '。', '[SEP]']

ids_nowakati = tknz.encode("毎朝父は味噌汁を飲みますが、私はコーヒーを飲みます。")
print(ids_nowakati) # [2, 979, 28956, 800, 9, 16022, 30628, 11, 9346, 2610, 14, 6, 1325, 9, 9171, 11, 9346, 2610, 8, 3]
print(tknz.convert_ids_to_tokens(ids_nowakati)) # ['[CLS]', '毎', '##朝', '父', 'は', '味噌', '##汁', 'を', '飲み', 'ます', 'が', '、', '私', 'は', 'コーヒー', 'を', '飲み', 'ます', '。', '[SEP]']

「毎朝」「味噌汁」が、'毎', '##朝''味噌', '##汁' にサブワード分割され、[UNK]が出ていない。

うーん、これはいつかどこかでハマりそうな予感。

この後、Laboro版BERT も使ってみようとして M1 Mac に四苦八苦しながら TensorFlow を入れたものの、結局 BertForMaskedLM を動かす方法がよくわからず(HuggingFace版じゃなくて original BERTだからか?)、放棄した。

M1 Mac に TensorFlow を入れるのはめんどくさい

元々 pyenv で Python 3.7.4 を使っていて、いつも通りに pip で tensorflow を入れようとしたら、import すると Python が落ちる。Illegal instruction: 4 とか言われるので、エッ!?そんな違法なことしたつもりはないぞ???と思ったら、どうやら M1 Mac では pip から tensorflow が入れれないらしい。

Apple Silicon(M1) Mac+tensorflow-macosでディープラーニングするMiniForgeを使ったインストール方法 に従ってインストールした。

途中「ややや?」となったところ:
numpy を import するところで、 Reason: image not found って言われる。何だよ image って。

ググった。

まさにこれだ!ということで、numpyを入れ直して解決。

$ conda uninstall numpy
$ conda install -c conda-forge conda-forge::numpy
$ pip install --upgrade -t "$env/lib/python3.8/site-packages/" --no-dependencies --force "$libs/tensorflow_macos-0.1a2-cp38-cp38-macosx_11_0_arm64.whl"
$ conda install opt_einsum -c conda-forge #よくわかんないけど、ないってtensorflowに怒られるので
$ python3
Python 3.8.11 (default, Aug 16 2021, 12:04:33) 
[Clang 12.0.0 ] :: Anaconda, Inc. on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import tensorflow as tf
>>> tf.__version__
'2.4.0-rc0'