国語研長単位品詞付与・係り受け解析モデルllm-jp-3-{150m,440m,980m,1.8b}-ud-embedsリリース

[LLM-jp-3シリーズ](https://llmc.nii.ac.jp/topics/llm-jp-3-instruct2-3/)は、入出力幅4096トークンの日本語LLaMAで、[1.5億](https://huggingface.co/llm-jp/llm-jp-3-150m)・[4.4億](https://huggingface.co/llm-jp/llm-jp-3-440m)・[9.8億](https://huggingface.co/llm-jp/llm-jp-3-980m)・[18億](https://huggingface.co/llm-jp/llm-jp-3-1.8b)・[37億](https://huggingface.co/llm-jp/llm-jp-3-3.7b)・[72億](https://huggingface.co/llm-jp/llm-jp-3-7.2b)・[130億](https://huggingface.co/llm-jp/llm-jp-3-13b)パラメータのモデルが公開されている。ちなみに、[1720億](https://huggingface.co/llm-jp/llm-jp-3-172b)パラメータのモデルもあるらしいが、これは使用許諾が必要だ。1.5億パラメータだと、私(安岡孝一)が作った[青空文庫ModernBERT](https://qiita.com/KoichiYasuoka/items/6b6ecb5361a8fdae6481)のbaseモデルより小さい。次の4.4億パラメータだと、青空文庫ModernBERTのlargeモデルより少し小さい。となると、比較したくなるのが人情だったりする。

ただ、入出力幅が4096トークンだと、係り受け解析の隣接行列を上三角行列に変換しても89×89あたりが限界で、それ以上は空行を間引く必要が生じる。また、LLM-jp-3のトークナイザは、かなり癖が強い。ちょっと見てみよう。

```
>>> from transformers import AutoTokenizer
>>> tkz=AutoTokenizer.from_pretrained("llm-jp/llm-jp-3-150m")
>>> print(tkz.convert_ids_to_tokens(tkz("国境の長いトンネルを抜けると雪国であった。","夜の底が白くなった。")["input_ids"]))
['
', '▁国境', 'の', '長い', 'トンネル', 'を', '抜ける', 'と', '雪', '国', 'であった。', '
', '▁夜', 'の', '底', 'が', '白', 'くなった', '。']
```

文頭のmetaspaceが邪魔だ。しかも「であった。」が、句点を含んだまま1トークンになっていて、かなり使いづらい。仕方ないので、トークナイザを改良することにした。

```
>>> from transformers import AutoTokenizer
>>> from tokenizers import Regex
>>> from tokenizers.pre_tokenizers import Sequence,Split,Whitespace,Punctuation
>>> tkz=AutoTokenizer.from_pretrained("llm-jp/llm-jp-3-150m")
>>> tkz.backend_tokenizer.normalizer=None
>>> tkz.backend_tokenizer.pre_tokenizer=Sequence([Split(Regex("[ぁ-ん]"),"isolated"),Whitespace(),Punctuation()])
>>> print(tkz.convert_ids_to_tokens(tkz("国境の長いトンネルを抜けると雪国であった。","夜の底が白くなった。")["input_ids"]))
['
', '国境', 'の', '長', 'い', 'トンネル', 'を', '抜', 'け', 'る', 'と', '雪', '国', 'で', 'あ', 'っ', 'た', '。', '
', '夜', 'の', '底', 'が', '白', 'く', 'な', 'っ', 'た', '。']
```

ひらがなが細かすぎる気がしないでもないが、とりあえず、このやり方でトークナイザを改良して、国語研長単位品詞付与・係り受け解析モデルllm-jp-3-{[150m](https://huggingface.co/KoichiYasuoka/llm-jp-3-150m-ud-embeds),[440m](https://huggingface.co/KoichiYasuoka/llm-jp-3-440m-ud-embeds),[980m](https://huggingface.co/KoichiYasuoka/llm-jp-3-980m-ud-embeds),[1.8b](https://huggingface.co/KoichiYasuoka/llm-jp-3-1.8b-ud-embeds)}-ud-embedsを試作してみた。[一昨日の記事](https://qiita.com/KoichiYasuoka/items/c08eab1ff21a3de02502)にしたがって、係り受け解析の精度を比較してみよう。Google Colaboratoryだと、こんな感じ。

```
!pip install transformers
mdl="KoichiYasuoka/llm-jp-3-{}-ud-embeds"
org="llm-jp/llm-jp-3-{}"
import os,sys,subprocess
from transformers import pipeline
url="https://github.com/UniversalDependencies/UD_Japanese-GSDLUW"
f=os.path.join(os.path.basename(url),"ja_gsdluw-ud-test.conllu")
os.system(f"test -f {f} || git clone --depth=1 {url}")
url="https://universaldependencies.org/conll18/conll18_ud_eval.py"
c=os.path.basename(url)
os.system(f"test -f {c} || curl -LO {url}")
with open(f,"r",encoding="utf-8") as r:
  s=[t[8:].strip() for t in r if t.startswith("# text =")]
rst=[]
for z in ["150m","440m","980m","1.8b"]:
  for tkz in ["original","refined"]:
    nlp=pipeline("universal-dependencies",mdl.format(z),trust_remote_code=True)
    if tkz=="original":
      from transformers import AutoTokenizer
      from tokenizers.normalizers import Replace
      nlp.tokenizer=AutoTokenizer.from_pretrained(org.format(z))
      nlp.tokenizer.backend_tokenizer.normalizer=Replace(" ","▁")
      nlp.tokenizer.model_input_names=["input_ids","attention_mask"]
    with open("result.conllu","w",encoding="utf-8") as w:
      for t in s:
        w.write(nlp(t))
    p=subprocess.run([sys.executable,c,"-v",f,"result.conllu"],
      encoding="utf-8",stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
    os.system("mkdir -p "+os.path.join("result",mdl.format(z)))
    rst.append(os.path.join("result",mdl.format(z),tkz+".txt"))
    with open(rst[-1],"w",encoding="utf-8") as w:
      print(f"\n*** {mdl.format(z)} ({tkz} tokenizer)",p.stdout,sep="\n",file=w)
!cat {" ".join(rst)}
```

私の手元では、以下の結果が出力された。

```
*** KoichiYasuoka/llm-jp-3-150m-ud-embeds (original tokenizer)
Metric     | Precision |    Recall |  F1 Score | AligndAcc
-----------+-----------+-----------+-----------+-----------
Tokens     |     71.64 |     54.32 |     61.79 |
Sentences  |    100.00 |    100.00 |    100.00 |
Words      |     71.64 |     54.32 |     61.79 |
UPOS       |     69.66 |     52.81 |     60.07 |     97.23
XPOS       |      0.00 |      0.00 |      0.00 |      0.00
UFeats     |     71.64 |     54.32 |     61.79 |    100.00
AllTags    |      0.00 |      0.00 |      0.00 |      0.00
Lemmas     |      0.00 |      0.00 |      0.00 |      0.00
UAS        |     47.63 |     36.11 |     41.08 |     66.49
LAS        |     46.85 |     35.52 |     40.41 |     65.40
CLAS       |     36.98 |     32.70 |     34.71 |     49.87
MLAS       |     30.73 |     27.17 |     28.84 |     41.43
BLEX       |      0.00 |      0.00 |      0.00 |      0.00

*** KoichiYasuoka/llm-jp-3-150m-ud-embeds (refined tokenizer)
Metric     | Precision |    Recall |  F1 Score | AligndAcc
-----------+-----------+-----------+-----------+-----------
Tokens     |     95.08 |     95.82 |     95.45 |
Sentences  |    100.00 |    100.00 |    100.00 |
Words      |     95.08 |     95.82 |     95.45 |
UPOS       |     93.44 |     94.17 |     93.81 |     98.28
XPOS       |      0.00 |      0.00 |      0.00 |      0.00
UFeats     |     95.05 |     95.79 |     95.42 |     99.97
AllTags    |      0.00 |      0.00 |      0.00 |      0.00
Lemmas     |      0.00 |      0.00 |      0.00 |      0.00
UAS        |     84.29 |     84.94 |     84.62 |     88.65
LAS        |     83.47 |     84.12 |     83.79 |     87.79
CLAS       |     75.88 |     77.03 |     76.45 |     81.62
MLAS       |     72.83 |     73.93 |     73.37 |     78.33
BLEX       |      0.00 |      0.00 |      0.00 |      0.00

*** KoichiYasuoka/llm-jp-3-440m-ud-embeds (original tokenizer)
Metric     | Precision |    Recall |  F1 Score | AligndAcc
-----------+-----------+-----------+-----------+-----------
Tokens     |     71.12 |     53.89 |     61.32 |
Sentences  |    100.00 |    100.00 |    100.00 |
Words      |     71.12 |     53.89 |     61.32 |
UPOS       |     69.22 |     52.45 |     59.68 |     97.33
XPOS       |      0.00 |      0.00 |      0.00 |      0.00
UFeats     |     71.11 |     53.88 |     61.31 |     99.98
AllTags    |      0.00 |      0.00 |      0.00 |      0.00
Lemmas     |      0.00 |      0.00 |      0.00 |      0.00
UAS        |     45.75 |     34.67 |     39.44 |     64.32
LAS        |     45.09 |     34.17 |     38.88 |     63.40
CLAS       |     35.03 |     31.83 |     33.35 |     49.02
MLAS       |     29.30 |     26.62 |     27.89 |     41.00
BLEX       |      0.00 |      0.00 |      0.00 |      0.00

*** KoichiYasuoka/llm-jp-3-440m-ud-embeds (refined tokenizer)
Metric     | Precision |    Recall |  F1 Score | AligndAcc
-----------+-----------+-----------+-----------+-----------
Tokens     |     95.57 |     96.07 |     95.82 |
Sentences  |    100.00 |    100.00 |    100.00 |
Words      |     95.57 |     96.07 |     95.82 |
UPOS       |     93.90 |     94.39 |     94.15 |     98.25
XPOS       |      0.00 |      0.00 |      0.00 |      0.00
UFeats     |     95.57 |     96.07 |     95.82 |    100.00
AllTags    |      0.00 |      0.00 |      0.00 |      0.00
Lemmas     |      0.00 |      0.00 |      0.00 |      0.00
UAS        |     83.76 |     84.20 |     83.98 |     87.64
LAS        |     82.97 |     83.40 |     83.19 |     86.81
CLAS       |     77.57 |     79.38 |     78.46 |     83.99
MLAS       |     74.59 |     76.32 |     75.45 |     80.76
BLEX       |      0.00 |      0.00 |      0.00 |      0.00

*** KoichiYasuoka/llm-jp-3-980m-ud-embeds (original tokenizer)
Metric     | Precision |    Recall |  F1 Score | AligndAcc
-----------+-----------+-----------+-----------+-----------
Tokens     |     72.53 |     54.93 |     62.52 |
Sentences  |    100.00 |    100.00 |    100.00 |
Words      |     72.53 |     54.93 |     62.52 |
UPOS       |     70.84 |     53.64 |     61.05 |     97.66
XPOS       |      0.00 |      0.00 |      0.00 |      0.00
UFeats     |     72.52 |     54.92 |     62.50 |     99.98
AllTags    |      0.00 |      0.00 |      0.00 |      0.00
Lemmas     |      0.00 |      0.00 |      0.00 |      0.00
UAS        |     48.47 |     36.71 |     41.78 |     66.83
LAS        |     47.71 |     36.13 |     41.12 |     65.78
CLAS       |     36.87 |     33.10 |     34.88 |     49.74
MLAS       |     31.12 |     27.94 |     29.44 |     41.98
BLEX       |      0.00 |      0.00 |      0.00 |      0.00

*** KoichiYasuoka/llm-jp-3-980m-ud-embeds (refined tokenizer)
Metric     | Precision |    Recall |  F1 Score | AligndAcc
-----------+-----------+-----------+-----------+-----------
Tokens     |     95.70 |     96.14 |     95.92 |
Sentences  |    100.00 |    100.00 |    100.00 |
Words      |     95.70 |     96.14 |     95.92 |
UPOS       |     94.34 |     94.78 |     94.56 |     98.58
XPOS       |      0.00 |      0.00 |      0.00 |      0.00
UFeats     |     95.67 |     96.12 |     95.89 |     99.97
AllTags    |      0.00 |      0.00 |      0.00 |      0.00
Lemmas     |      0.00 |      0.00 |      0.00 |      0.00
UAS        |     85.80 |     86.20 |     86.00 |     89.66
LAS        |     85.01 |     85.40 |     85.20 |     88.83
CLAS       |     78.39 |     79.53 |     78.96 |     83.70
MLAS       |     75.75 |     76.85 |     76.30 |     80.88
BLEX       |      0.00 |      0.00 |      0.00 |      0.00

*** KoichiYasuoka/llm-jp-3-1.8b-ud-embeds (original tokenizer)
Metric     | Precision |    Recall |  F1 Score | AligndAcc
-----------+-----------+-----------+-----------+-----------
Tokens     |     72.85 |     54.10 |     62.09 |
Sentences  |    100.00 |    100.00 |    100.00 |
Words      |     72.85 |     54.10 |     62.09 |
UPOS       |     71.00 |     52.73 |     60.52 |     97.47
XPOS       |      0.00 |      0.00 |      0.00 |      0.00
UFeats     |     72.83 |     54.09 |     62.08 |     99.98
AllTags    |      0.00 |      0.00 |      0.00 |      0.00
Lemmas     |      0.00 |      0.00 |      0.00 |      0.00
UAS        |     47.60 |     35.36 |     40.58 |     65.35
LAS        |     46.89 |     34.83 |     39.97 |     64.37
CLAS       |     35.28 |     31.06 |     33.03 |     47.83
MLAS       |     29.92 |     26.33 |     28.01 |     40.56
BLEX       |      0.00 |      0.00 |      0.00 |      0.00

*** KoichiYasuoka/llm-jp-3-1.8b-ud-embeds (refined tokenizer)
Metric     | Precision |    Recall |  F1 Score | AligndAcc
-----------+-----------+-----------+-----------+-----------
Tokens     |     95.74 |     96.14 |     95.94 |
Sentences  |    100.00 |    100.00 |    100.00 |
Words      |     95.74 |     96.14 |     95.94 |
UPOS       |     94.28 |     94.68 |     94.48 |     98.47
XPOS       |      0.00 |      0.00 |      0.00 |      0.00
UFeats     |     95.72 |     96.13 |     95.92 |     99.98
AllTags    |      0.00 |      0.00 |      0.00 |      0.00
Lemmas     |      0.00 |      0.00 |      0.00 |      0.00
UAS        |     86.74 |     87.10 |     86.92 |     90.59
LAS        |     85.96 |     86.33 |     86.14 |     89.79
CLAS       |     79.07 |     79.73 |     79.40 |     84.05
MLAS       |     76.39 |     77.03 |     76.71 |     81.20
BLEX       |      0.00 |      0.00 |      0.00 |      0.00
```

UPOS/LAS/MLASを表にしてみよう。

|  |トークナイザ改良前|トークナイザ改良後|
|:-|:-:|:-:|
|llm-jp-3-150m-ud-embeds|60.07/40.41/28.84|93.81/83.79/73.37|
|llm-jp-3-440m-ud-embeds|59.68/38.88/27.89|94.15/83.19/75.45|
|llm-jp-3-980m-ud-embeds|61.05/41.12/29.44|94.56/85.20/76.30|
|llm-jp-3-1.8b-ud-embeds|60.52/39.97/28.01|94.48/86.14/76.71|

この結果を見る限り、トークナイザの改良は、品詞付与・係り受け解析の精度に寄与する。一方、モデルの規模(パラメータ数)は、微妙には寄与するものの、思いのほか効かないようだ。あくまで品詞付与・係り受け解析に限った話ではあるものの、もう少しトークナイザに気をつけて設計してくれると、私個人としてはうれしいなあ。