🐳

早稲田大学河原研究室公開の日本語版RoBERTaを使う(Juman++のインストール方法)

commits4 min read

先日bertの後継であるrobertaの日本語版事前学習済みモデルが早稲田大学河原研究室より公開されました。

https://huggingface.co/nlp-waseda/roberta-base-japanese

京都大学黒橋・褚・村脇研究室や早稲田大学河原研究室の公開する事前学習済みモデルはよく使われるipadic系のmecabではなく、juman辞書を用いたjuman++にて前処理が行われておりhuggingface社の提供するtokenizer APIでは前処理が行えません。
本記事ではjuman++のインストールを含めて、先述の事前学習済みモデルが利用できるようになるまでの手順を説明します。

juman++について

https://github.com/ku-nlp/jumanpp
ソースコードはこちらに公開されていますので詳しくは、こちらのリポジトリを参照してください。

juman++のインストール

macOS(intel版の場合)

まず、ビルドツールのダウンロードを行います。

brew install zlib
brew install cmake
brew install wget

次にソースをダウンロードして手元環境でビルド&installします。
cmakeの実行時に-DCMAKE_INSTALL_PREFIX="インストール先"とフラグを設定することでインストール先を自由に設定できます。

wget "https://github.com/ku-nlp/jumanpp/releases/download/v2.0.0-rc3/jumanpp-2.0.0-rc3.tar.xz"
tar xvJf jumanpp-2.0.0-rc3.tar.xz

cd jumanpp-2.0.0-rc3
mkdir bld && cd bld
cmake .. -DCMAKE_BUILD_TYPE=Release
sudo make install -j $(getconf _NPROCESSORS_ONLN)

以上でjuman++のインストールは完了します。

jumanpp -v
# Juman++ Version: 2.0.0-rc3

Linux(debian系)の場合

必要なパッケージを一通りインストールします。

sudo apt update -q
sudo apt install -qy cmake g++ make wget xz-utils

ソースをダウンロードします。

wget "https://github.com/ku-nlp/jumanpp/releases/download/v2.0.0-rc3/jumanpp-2.0.0-rc3.tar.xz"
tar xvf jumanpp-2.0.0-rc3.tar.xz

ソースをビルドしてインストールします。

cd jumanpp-2.0.0-rc3
mkdir bld && cd bld
cmake .. -DCMAKE_BUILD_TYPE=Release
sudo make install -j "$(nproc)"
sudo make install

簡単な使い方

標準入力に解析したい文字列を流し込むことで形態素解析が行えます。

echo "形態素解析器を使ってみる。" | jumanpp
# 形態 けいたい 形態 名詞 6 普通名詞 1 * 0 * 0 "代表表記:形態/けいたい カテゴリ:形・模様"
# 素 そ 素 名詞 6 普通名詞 1 * 0 * 0 "代表表記:素/そ カテゴリ:抽象物 漢字読み:音"
# 解析 かいせき 解析 名詞 6 サ変名詞 2 * 0 * 0 "代表表記:解析/かいせき ドメイン:教育・学習;科学・技術 カテゴリ:抽象物"
# 器 き 器 名詞 6 普通名詞 1 * 0 * 0 "代表表記:器/き カテゴリ:人工物-その他 漢字読み:音"
# を を を 助詞 9 格助詞 1 * 0 * 0 NIL
# 使って つかって 使う 動詞 2 * 0 子音動詞ワ行 12 タ系連用テ形 14 "代表表記:使う/つかう"
# みる みる みる 接尾辞 14 動詞性接尾辞 7 母音動詞 1 基本形 2 "代表表記:みる/みる"
# 。 。 。 特殊 1 句点 1 * 0 * 0 NIL
# EOS

深層学習用途では単語分割ができれば良いので、その際は--segmentオプションをつけてください。

echo "形態素解析器を使ってみる。" | jumanpp --segment
# 形態 素 解析 器 を 使って みる 。

ファイルごと処理をする場合は

jumanpp --segment -o "出力ファイル" "入力ファイル"

と実行することで処理ができます。さらに詳しくは先述のリポジトリや、-hオプションを使って確認してください。

依存ライブラリのインストール

transformersはもちろんいくつかのライブラリをインストールしていないとエラーが出ます。

pip install torch
pip install git+https://github.com/huggingface/transformers
pip install sentencepiece
pip install protobuff

これで準備が整いました。

試してみる

"日本語の自然言語処理は難しい 。"という文字列を解析してみましょう。

echo "日本語の自然言語処理は難しい。" | jumanpp --segment
# 日本 語 の 自然 言語 処理 は 難しい 。

"難しい"というトークンを[MASK]に置き変えて、先ほど紹介した早大robertaでトークンの予測をしてみます。まずは利用するライブラリや事前学習済みモデルの読み込みを行います。

import torch
from transformers import AutoTokenizer, AutoModelForMaskedLM
tokenizer = AutoTokenizer.from_pretrained("nlp-waseda/roberta-base-japanese")
model = AutoModelForMaskedLM.from_pretrained("nlp-waseda/roberta-base-japanese")

次にmaskトークンの予測です。Huggingface社の提供するPipelines APIを使えばもっと簡単に実現できますが、今回はスクラッチで処理を記述します。

# maskされたトークン位置を取得する
def get_masked_index(encoding):
    for idx, id in enumerate(encoding.input_ids.squeeze(0)):
        if id == tokenizer.mask_token_id:
            return idx

# 上位k件の予測結果を取得
def get_top_k_token(target_probs, k=5):
    return torch.argsort(target_probs, descending=True)[:k]

# 入力系列の処理
sentence = '日本 語 の 自然 言語 処理 は [MASK] 。'
encoding = tokenizer(sentence, return_tensors='pt')

# 予測
pred = model(**encoding)

# 後処理(取得した予測分布から、maskトークンの上位k件の予測結果を取得)
masked_idx = get_masked_index(encoding)
target_probs = pred.logits.squeeze(0)[masked_idx]
top_k = get_top_k_token(target_probs)
for id in top_k:
    print(sentence.replace("[MASK]", f"'{tokenizer.decode(id)}'"))
# 日本 語 の 自然 言語 処理 は '得意' 。
# 日本 語 の 自然 言語 処理 は 'できる' 。
# 日本 語 の 自然 言語 処理 は '専門' 。
# 日本 語 の 自然 言語 処理 は 'ない' 。
# 日本 語 の 自然 言語 処理 は '苦手' 。

早大robertaによると日本語の自然言語処理は"得意"だそうです。
juman++で前処理がされていることで些か癖があると言える早大robertaですが、日本語wikipediaと、CC-100の日本語部分で学習されており既存の事前学習済みモデルより巨大なコーパスを用いて学習されている点が強みかと思います。
なお、このモデルは試験的な公開ということで学習時の最大系列長が128になっています(大抵は512)ので各タスクにfine-tuningをする際などは注意が必要です。

終わりに

また早大河原研究室では日本語版のGLUEベンチマーク(JGLUE)が作成されており近いうちにそのベンチマーク結果も公開されるとのことです。
日本語の自然言語処理のさらなる発展を期待しましょう。

GitHubで編集を提案

Discussion

ログインするとコメントできます