Published on

transformers多言語モデル中の日本語語彙調査

Author
株式会社イエローバックの機械学習エンジニアです

はじめに

前回に引き続き、HuggingFace transformers のネタです。

日本語も扱える多言語モデルの語彙数は 10 万以上になっていることが多いですが、そのうち日本語(っぽい)語彙がどのくらい含まれているのかふと気になったので調べてみました。

調査対象モデル

調査対象モデルは以下の通りです。

  • xlm-roberta-base
  • bert-base-multilingual-cased
  • distilbert-base-multilingual-cased
  • facebook/mbart-large-cc25
  • google/mt5-base
  • facebook/m2m100_418M

比較として日本語特化モデルについても調べてみました。

調査方法

UTF-8 中の日本語の判別方法ですが、ひらがなやカタカナはいいとして漢字については中国語と日本語を区別するのがむずかしそうです。 そこで、今回は簡易的に cp932 コードに含まれているものを日本語と識別することにしました。 試行錯誤の結果、以下のようにしました。

  • 0x8f 以下は対象外(英語圏の文字)
  • ギリシャ文字は日本語テキストでも数学の記号として使われていることが多いので対象
  • キリル文字は対象外
  • 特殊文字('▁','#')は除外して、すべての文字が上記のなかに入っていれば日本語の語彙とする

正確な方法ではありませんが、おおよその傾向をつかむにはこの程度でいいかなと思います。

日本語文字判別用コード

cp932_chars.py
def get_cp932_chars(include_cyrillic=False):
    # cp932 code
    # see https://uic.jp/charset/show/cp932/

    all_list = []

    # one byte characters
    for i in range(0xa1, 0xf0):
        all_list.append([i])

    # two bytes characters
    ranges_2bytes = [
        (0x8100, 0x8400),
        (0x849f, 0xa000),
        (0xe000, 0xeb00),
        (0xfa00, 0xfd00)
    ]
    if include_cyrillic:
        ranges.append((0x8440, 0x8492))

    for r in ranges_2bytes:
        for i in range(r[0], r[1]):
            upper,lower = divmod(i, 0x100)
            all_list.append([upper,lower])

    cp932_chars = set()

    for x in all_list:
        try:
            chr = bytes(x).decode('cp932')
            cp932_chars.add(chr)
        except:
            pass

    #print(len(char_list))
    return cp932_chars
japanese_char_checker.py
from cp932_chars import get_cp932_chars

class JapaneseCharChecker:
    def __init__(self, remove_chars = []):
        self.chars = get_cp932_chars()
        self.remove_chars = set(remove_chars)

    def _line2boollist(self, line):
        return [c in self.chars for c in line if c not in self.remove_chars]

    def fullmatch(self, line):
        return all(self._line2boollist(line))

    def anymatch(self, line):
        return any(self._line2boollist(line))
from transformers import AutoTokenizer
from japanese_char_checker import JapaneseCharChecker

checker = JapaneseCharChecker(remove_chars=['▁', '#'])

model = 'xlm-roberta-base'

tokenizer = AutoTokenizer.from_pretrained(model)
vocab = tokenizer.get_vocab().keys()
vocab_ja = [k for k in vocab if checker.fullmatch(k)]
print(len(vocab_ja))

日本語語彙数調査結果

多言語モデル

日本語語彙数が多い順にソート

モデル全語彙数日本語語彙数
google/mt5-base25010023739
xlm-roberta-base25000217178
facebook/mbart-large-cc2525002717178
bert-base-multilingual-cased11954711706
distilbert-base-multilingual-cased11954711706
facebook/m2m100_418M1280047814

xlm-roberta-base, mbart-large-cc25, mt5-base あたりは日本語特化モデルの 6 割〜8 割程度の語彙を含んでいるようです。

日本語特化モデル

モデル全語彙数日本語語彙数
cl-tohoku/bert-base-japanese-v23276827842
cl-tohoku/bert-base-japanese-char-v261444981
rinna/japanese-gpt2-medium3200029150
sonoisa/t5-base-japanese3210029082
bandainamco-mirai/distilbert-base-japanese3200028486
laboro-ai/distilbert-base-japanese3200031050
hajime9652/xlnet-japanese3200026763

モデル毎の詳細

モデル毎に、以下の情報を調べてみました。

  • 全語彙数
  • 日本語語彙数(全マッチ): 語彙中のすべてのキャラクタが cp932 に含まれている場合
  • 日本語語彙数(部分マッチ): 語彙中のキャラクタがひとつでも cp932 に含まれている場合
  • 語彙サンプル
    • 日本語語彙として識別されたもの(ランダムな 10 エントリ)
    • 日本語語彙として識別されなかったもの(ランダムな 10 エントリ)
  • サンプルテキストをトークナイズした例
    • テキスト: 「自分は東北の田舎に生れましたので、汽車をはじめて見たのは、よほど大きくなってからでした。」(出典: 太宰治 人間失格より)

モデルによっては日本語語彙として識別された語彙のなかにギリシャ文字の語彙っぽいものも含まれているようです。ギリシャ文字を外すかどうかは少し悩みどころです。 また、中国語っぽい語彙も含まれているケースもあるようです。

xlm-roberta-base

  • 全語彙数: 250002
  • 日本語語彙数(全マッチ): 17178
  • 日本語語彙数(部分マッチ): 22830
語彙サンプル
日本語:  迎 ことになります 可能性がある 真是 引擎 全新 鄰 εξυπηρετ 珍惜 ミニ
非日本語:  ▁festeggia ▁biar ▁파트너 ▁hominem памят ై ▁Ofic ▁दूसरी ▁POLI ▁televisyen
サンプルテキストのトークナイズ
▁ 自分は 東北 の 田 舎 に 生 れ ました ので 、 汽車 を はじめて
見た のは 、 よ ほど 大きく なって から でした 。

bert-base-multilingual-cased

  • 全語彙数: 119547
  • 日本語語彙数(全マッチ): 11706
  • 日本語語彙数(部分マッチ): 12786
語彙サンプル
日本語:  してきた ##賞 碇 ##μη ##琦 誣 ##邪 敦 ビル ##胥
非日本語:  Anti ##ఎ những ubos Chiang funkcje нея ##gaande branch оценки
サンプルテキストのトークナイズ
自 分 は 東 北 の 田 舎 に 生 れ ##ま ##した ##ので 、
汽 車 を ##は ##じめ ##て 見 た ##のは 、 よ ##ほど 大 きく ##な
##って ##から ##で ##した 。

distilbert-base-multilingual-cased

  • 全語彙数: 119547
  • 日本語語彙数(全マッチ): 11706
  • 日本語語彙数(部分マッチ): 12786
語彙サンプル
日本語:  亳 揆 ##νια ##響 旦 偕 ##換 もあり 椽 鉗
非日本語:  pomocí ##틈 kompleks ##лас תוכנית choose Göy يسمى unterstützen attivo
サンプルテキストのトークナイズ
自 分 は 東 北 の 田 舎 に 生 れ ##ま ##した ##ので 、
汽 車 を ##は ##じめ ##て 見 た ##のは 、 よ ##ほど 大 きく ##な
##って ##から ##で ##した 。

facebook/mbart-large-cc25

  • 全語彙数: 250027
  • 日本語語彙数(全マッチ): 17178
  • 日本語語彙数(部分マッチ): 22830
語彙サンプル
日本語:  家庭 ┫ 未必 ▁ΠΑΟΚ 除此之外 潺 ▁εισ 下方 住院 ▁Τε
非日本語:  ▁* ▁benyttes осо ▁나아가 ▁spomína ▁ჯორჯ ▁pogleda ▁suelo ▁nettopp ▁तालुक्यातील
サンプルテキストのトークナイズ
▁ 自分は 東北 の 田 舎 に 生 れ ました ので 、 汽車 を はじめて
見た のは 、 よ ほど 大きく なって から でした 。

google/mt5-base

  • 全語彙数: 250100
  • 日本語語彙数(全マッチ): 23739
  • 日本語語彙数(部分マッチ): 27903
語彙サンプル
日本語:  οφυλ の範囲 ΟΤ 革新 中華 椦 過去 当代 がま 家は
非日本語:  tenia ▁хос ▁class الفيديو contributor การออกแบบ สงสัย Шо mhain ▁vyr
サンプルテキストのトークナイズ
▁ 自分は 東北 の 田舎 に 生 れました ので 、 汽車 を はじめて 見た のは
、 よ ほど 大きく なって から でした 。

facebook/m2m100_418M

  • 全語彙数: 128004
  • 日本語語彙数(全マッチ): 7814
  • 日本語語彙数(部分マッチ): 9495
語彙サンプル
日本語:  ’ ▁ 。 ▁“ 、 的 ” の ▁‘ ▁και
非日本語:  <s> <pad> </s> <unk> , . ▁de - ▁a :
サンプルテキストのトークナイズ
▁ 自分 は 東 北 の 田 舎 に 生 れ ました ので 、 汽
車 を は じ めて 見 た のは 、 よ ほど 大き くな って から
でした 。

cl-tohoku/bert-base-japanese-v2

  • 全語彙数: 32768
  • 日本語語彙数(全マッチ): 27842
  • 日本語語彙数(部分マッチ): 27846
語彙サンプル
日本語:  # § ° ± × ÷ Α Β Γ Δ
非日本語:  [PAD] [UNK] [CLS] [SEP] [MASK] <unused0> <unused1> <unused2> <unused3> <unused4>
サンプルテキストのトークナイズ
自分 は 東北 の 田舎 に 生 ##れ まし た の で 、 汽車 を
はじめて 見 た の は 、 よ ##ほど 大きく なっ て から でし た 。

cl-tohoku/bert-base-japanese-char-v2

  • 全語彙数: 6144
  • 日本語語彙数(全マッチ): 4981
  • 日本語語彙数(部分マッチ): 4980
語彙サンプル
日本語:  # § ° ± × ÷ Α Β Γ Δ
非日本語:  [PAD] [UNK] [CLS] [SEP] [MASK] <unused0> <unused1> <unused2> <unused3> <unused4>
サンプルテキストのトークナイズ
自 分 は 東 北 の 田 舎 に 生 れ ま し た の
で 、 汽 車 を は じ め て 見 た の は 、 よ
ほ ど 大 き く な っ て か ら で し た 。

rinna/japanese-gpt2-medium

  • 全語彙数: 32000
  • 日本語語彙数(全マッチ): 29150
  • 日本語語彙数(部分マッチ): 29277
語彙サンプル
日本語:  、 。 ▁ の は が ・ 年 に を
非日本語:  <unk> <s> </s> [PAD] [CLS] [SEP] [MASK] ) ( 1
サンプルテキストのトークナイズ
▁ 自分は 東北 の 田舎 に 生 れ ました の で 、 汽車 を はじめて
見た の は 、 よ ほど 大きく なって から で した 。

sonoisa/t5-base-japanese

  • 全語彙数: 32100
  • 日本語語彙数(全マッチ): 29082
  • 日本語語彙数(部分マッチ): 29197
語彙サンプル
日本語:  伝導 展開する 恩師 披 ざわ 煕 種小名 切手 積分 工業団地
非日本語:  ▁bar ▁1954 、1943 ration rr cas ning ch bri 6
サンプルテキストのトークナイズ
▁ 自分は 東北 の 田舎 に 生 れ ました の で 、 汽車 を はじめて
見た の は 、 よ ほど 大きく なって から で した 。

bandainamco-mirai/distilbert-base-japanese

  • 全語彙数: 32000
  • 日本語語彙数(全マッチ): 28486
  • 日本語語彙数(部分マッチ): 28555
語彙サンプル
日本語:  の 、 に 。 は た を で と が
非日本語:  [PAD] [UNK] [CLS] [SEP] [MASK] 1 ( ) 2 19
サンプルテキストのトークナイズ
自分 ##は ##東 ##北 ##の ##田 ##舎 ##に ##生 ##れ ##まし ##た ##の ##で 、
汽車 ##を ##は ##じめ ##て ##見 ##た ##の ##は 、 よ ##ほど ##大 ##き ##く
##なっ ##て ##から ##で ##した 。

laboro-ai/distilbert-base-japanese

  • 全語彙数: 32000
  • 日本語語彙数(全マッチ): 31050
  • 日本語語彙数(部分マッチ): 31105
語彙サンプル
日本語:  。 ▁ 、 の は が を で に 」
非日本語:  [UNK] [PAD] [CLS] [SEP] [MASK] ! ? ) ( ...
サンプルテキストのトークナイズ
▁自分は 東北 の 田舎 に 生 れました ので 、 汽車 を はじめて 見た の は
、 よ ほど 大きくなって から でした 。

hajime9652/xlnet-japanese

  • 全語彙数: 32000
  • 日本語語彙数(全マッチ): 26763
  • 日本語語彙数(部分マッチ): 26819
語彙サンプル
日本語:  ヤル 各国 ▁待機児童 ▁リン ▁卓上 ▁政務 ▁悪 埜 ▁石原さとみ ▁立地
非日本語:  诸 ▁BFB rop ▁Japan ▁KING mus ▁LinkedIn ▁SALE ▁MacRumors et
サンプルテキストのトークナイズ

xlnet-japanese は別途 MeCab によるトークナイズが必要となるため省略