パスワードを忘れた? アカウント作成
15246240 journal
中国

yasuokaの日記: 古典中国語(漢文)AI向け言語モデルroberta-classical-chinese-base-charの作成

日記 by yasuoka

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モデルではあるものの、これでかなり使いやすくなったはずだ。古典中国語(漢文)解析に、ぜひぜひ使ってみてほしい。

この議論は、yasuoka (21275)によって ログインユーザだけとして作成されたが、今となっては 新たにコメントを付けることはできません。
typodupeerror

日本発のオープンソースソフトウェアは42件 -- ある官僚

読み込み中...