2024年12月19日の記事の手法をQwen3-0.6Bに適用して、UD_English-EWTのUPOS品詞付与を試してみた。Google Colaboratory (GPU版)だと、こんな感じ。
!pip install transformers datasets evaluate seqeval accelerate
s='$1=="transformers"{printf("-b v%s",$2)}'
!test -d transformers || git clone `pip3 list | awk '{s}'` https://github.com/huggingface/transformers
!test -d UD_English-EWT || git clone --depth=1 https://github.com/UniversalDependencies/UD_English-EWT
import json
def makejson(conllu_file,json_file):
with open(conllu_file,"r",encoding="utf-8") as r, open(json_file,"w",encoding="utf-8") as w:
d={"tokens":[],"tags":[]}
for s in r:
if s.strip()=="":
if d["tokens"]>[]:
print(json.dumps(d),file=w)
d={"tokens":[],"tags":[]}
else:
t=s.split("\t")
if len(t)==10 and t[0].isdecimal():
d["tokens"].append(t[1])
d["tags"].append(t[3])
makejson("UD_English-EWT/en_ewt-ud-train.conllu","train.json")
makejson("UD_English-EWT/en_ewt-ud-dev.conllu","dev.json")
makejson("UD_English-EWT/en_ewt-ud-test.conllu","test.json")
!env WANDB_DISABLED=true python3 transformers/examples/pytorch/token-classification/run_ner.py --task_name pos --model_name_or_path Qwen/Qwen3-0.6B --train_file train.json --validation_file dev.json --test_file test.json --output_dir ./Qwen3-0.6B-english-upos --overwrite_output_dir --do_train --do_eval --do_predict
私(安岡孝一)の手元では、1時間40分ほどで以下のmetricsが出力されて、Qwen3-0.6B-english-uposが出来上がった。
***** train metrics *****
epoch = 3.0
total_flos = 4296208GF
train_loss = 0.1966
train_runtime = 1:28:11.70
train_samples = 12544
train_samples_per_second = 7.112
train_steps_per_second = 0.889
***** eval metrics *****
epoch = 3.0
eval_accuracy = 0.9154
eval_f1 = 0.8995
eval_loss = 0.3669
eval_precision = 0.9006
eval_recall = 0.8983
eval_runtime = 0:00:28.48
eval_samples = 2001
eval_samples_per_second = 70.243
eval_steps_per_second = 8.811
***** predict metrics *****
predict_accuracy = 0.9169
predict_f1 = 0.9003
predict_loss = 0.3495
predict_precision = 0.9007
predict_recall = 0.8999
predict_runtime = 0:00:29.87
predict_samples_per_second = 69.53
predict_steps_per_second = 8.704
eval・predictともにF1値が0.90程度で、正直あまり良くない。ちょっと動かしてみよう。
from transformers import pipeline
nlp=pipeline("token-classification","Qwen3-0.6B-english-upos")
print(nlp("It don't mean a thing if it ain't got that swing"))
出来立てのQwen3-0.6B-english-uposで「It don't mean a thing if it ain't got that swing」に品詞付与してみたところ、私の手元では以下の結果が得られた。
[{'entity': 'PRON', 'score': np.float32(0.9998696), 'index': 0, 'word': 'It', 'start': 0, 'end': 2}, {'entity': 'AUX', 'score': np.float32(0.8005378), 'index': 1, 'word': 'Ġdon', 'start': 2, 'end': 6}, {'entity': 'PART', 'score': np.float32(0.99996376), 'index': 2, 'word': "'t", 'start': 6, 'end': 8}, {'entity': 'VERB', 'score': np.float32(0.99999404), 'index': 3, 'word': 'Ġmean', 'start': 8, 'end': 13}, {'entity': 'DET', 'score': np.float32(0.99962735), 'index': 4, 'word': 'Ġa', 'start': 13, 'end': 15}, {'entity': 'NOUN', 'score': np.float32(0.9999932), 'index': 5, 'word': 'Ġthing', 'start': 15, 'end': 21}, {'entity': 'SCONJ', 'score': np.float32(1.0), 'index': 6, 'word': 'Ġif', 'start': 21, 'end': 24}, {'entity': 'PRON', 'score': np.float32(0.9999958), 'index': 7, 'word': 'Ġit', 'start': 24, 'end': 27}, {'entity': 'AUX', 'score': np.float32(0.9502168), 'index': 8, 'word': 'Ġain', 'start': 27, 'end': 31}, {'entity': 'PART', 'score': np.float32(0.9999628), 'index': 9, 'word': "'t", 'start': 31, 'end': 33}, {'entity': 'VERB', 'score': np.float32(0.9777384), 'index': 10, 'word': 'Ġgot', 'start': 33, 'end': 37}, {'entity': 'ADV', 'score': np.float32(0.49614692), 'index': 11, 'word': 'Ġthat', 'start': 37, 'end': 42}, {'entity': 'NOUN', 'score': np.float32(0.9643484), 'index': 12, 'word': 'Ġswing', 'start': 42, 'end': 48}]
空白が「Ġ」に化けてしまっているのは、まあ何とかするとしても、「that」が読めていない。やはりQwen3ForTokenClassificationも、品詞付与の精度がイマイチ上がらないようだ。うーん、残念。