yasuokaの日記: 古典中国語(漢文)AI向け言語モデルroberta-classical-chinese-base-charの作成
3月27日の日記のアイデアをethanyt/guwenbert-baseに適用して、簡化字と繁體字の両方を使えるようにしてみた。端的にはSuPar-Kanbun内蔵のsimplify.pyを使って、guwenbert-base(簡化字)の単語ベクトルを、繁體字(および日本の常用漢字)へと拡張した。Google Colaboratoryの助けを借りるなら、以下の通り。
from google.colab import drive
drive.mount("/content/drive")
output_dir="/content/drive/My Drive/roberta-classical-chinese-base-char"
!pip install suparkanbun
import torch,os
from suparkanbun.simplify import simplify
from transformers import AutoTokenizer,AutoModelForMaskedLM
tokenizer=AutoTokenizer.from_pretrained("ethanyt/guwenbert-base")
model=AutoModelForMaskedLM.from_pretrained("ethanyt/guwenbert-base")
c=[]
for k,v in simplify.items():
if tokenizer.add_tokens([k,v])==1:
t=tokenizer.convert_tokens_to_ids([k,v])
c.append((max(t[0],t[1]),min(t[0],t[1])))
e=model.resize_token_embeddings(len(tokenizer))
with torch.no_grad():
for k,v in c:
e.weight[k,:]=e.weight[v,:]
model.set_input_embeddings(e)
tokenizer.save_pretrained(output_dir)
model.save_pretrained(output_dir)
t=tokenizer.convert_ids_to_tokens([i for i in range(tokenizer.vocab_size,len(tokenizer))])
with open(os.path.join(output_dir,"vocab.txt"),"a",encoding="utf-8") as f:
print("\n".join(t),file=f)
os.remove(os.path.join(output_dir,"added_tokens.json"))
これで、Google Driveにroberta-classical-chinese-base-charが作成される。「孟子[MASK]梁恵王」で試してみよう。
from google.colab import drive
drive.mount("/content/drive")
!pip install transformers
import torch
from transformers import AutoTokenizer,AutoModelForMaskedLM
tokenizer=AutoTokenizer.from_pretrained("/content/drive/My Drive/roberta-classical-chinese-base-char")
model=AutoModelForMaskedLM.from_pretrained("/content/drive/My Drive/roberta-classical-chinese-base-char")
tokens=tokenizer.tokenize("孟子[MASK]梁恵王")
print(tokens)
mask=tokens.index("[MASK]")
ids=torch.tensor([tokenizer.convert_tokens_to_ids(tokens)])
with torch.no_grad():
outputs=model(ids)
pred=outputs[0][0,mask].topk(5)
for i,t in enumerate(tokenizer.convert_ids_to_tokens(pred.indices)):
tokens[mask]=t
print(i+1,tokens)
私(安岡孝一)の手元では、以下の結果が得られた。
['孟', '子', '[MASK]', '梁', '恵', '王']
1 ['孟', '子', '见', '梁', '恵', '王']
2 ['孟', '子', '見', '梁', '恵', '王']
3 ['孟', '子', '曰', '梁', '恵', '王']
4 ['孟', '子', '謂', '梁', '恵', '王']
5 ['孟', '子', '谓', '梁', '恵', '王']
「孟子见梁恵王」がトップだが、2番目に「孟子見梁恵王」が得られている。1文字=1単語のRoBERTaモデルではあるものの、これでかなり使いやすくなったはずだ。古典中国語(漢文)解析に、ぜひぜひ使ってみてほしい。
古典中国語(漢文)AI向け言語モデルroberta-classical-chinese-base-charの作成 More ログイン