環境構築編 - 自然言語処理環境
AI 物見遊山をするための自然言語処理用の環境を構築する。 前の記事 環境構築編 - 基礎環境 で作成した環境上で作業をする前提とする。
利用するパッケージ等
- Transformers
- Google が発表した深層学習モデル
- https://huggingface.co/docs/transformers/ja/index
- SpeechBrain
- 音声処理ツールキット
- https://speechbrain.github.io/
- GiNZA NLP Library
- 日本語の自然言語処理に特化したライブラリ
- 形態素解析器
- https://megagonlabs.github.io/ginza/
- janome
- 形態素解析器
- https://mocobeta.github.io/janome/
- MeCab
- 形態素解析器
- https://taku910.github.io/mecab/
- mecab-python3
- gensim
- トピックモデリングや文書類似度分析に特化したライブラリ
- https://radimrehurek.com/gensim/
- pyannote.audio
- 音声データから「いつ、誰が話したか」を自動的に推定する(話者ダイアライゼーション)ライブラリ
- https://github.com/pyannote/pyannote-audio
構築手順
Transformers をインストールする。
pip install transformers[torch]
動作確認する。
python3 -c "from transformers import pipeline; print(pipeline('sentiment-analysis')('we love you'))"
自動的にモデルがダウンロードされ、以下のような表示がされる。
[{'label': 'POSITIVE', 'score': 0.9998704195022583}]
SpeechBrain をインストールする。
依存パッケージの ffmpeg をインストールする。 SpeechBrain は、処理内部で ffmpeg を利用している。
sudo apt install ffmpeg
SpeechBrain のインストール方法には、パッケージでインストールする方法と、ソースからインストールする方法がある。 パッケージでインストールすると、コア機能の一部のみ利用できる。 ソースからインストールすると、モデルの学習などからすべての機能が利用できる。
ここでは、ソースからインストールする。
git clone https://github.com/speechbrain/speechbrain.git
cd speechbrain
# torch-directml 0.2.5 の場合は、torch==2.5.0 以上だとエラーとなるため、バージョン制限をしている。
pip install -r requirements.txt 'torch>=1.9.0,<2.5.0'
pip install --editable .
pip install soundfile
pip install k2
sudo apt install build-essential
pip install ctc-segmentation
cd
動作確認する。
cat <<'EOL' | python
from speechbrain.inference import EncoderDecoderASR
asr_model = EncoderDecoderASR.from_hparams(source="speechbrain/asr-conformer-transformerlm-librispeech", savedir="pretrained_models/asr-transformer-transformerlm-librispeech")
print(asr_model.transcribe_file("speechbrain/tests/samples/ASR/spk1_snt1.wav"))
EOL
モデルのダウンロードされ、音声をテキストに変換する。 最後に以下のように変換されたテキストが表示される。
THE CHILD ALMOST HURT THE SMALL DOG
GiNZA NLP Library をインストールする。
GiNZA NLP Library は、オープンソース日本語 NLP ライブラリとなる。 spaCy を基盤とし、SudachiPy、Transformers などを利用してる。 形態素解析器としても利用できる。 自然言語処理モデルを利用するため、メモリ、CPU や、GPU などのリソースがかなり必要となる。
pip install -U ginza
GiNZA 用のモデルをインストールする。 モデルは、β版の ja_ginza_bert_large を利用する。
そのままインストールすると、依存パッケージ tokenizers
v0.13.3 のインストールでエラーとなるため、依存パッケージ設定を修正する。
エラーは、tokenizers
で、
casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
のように発生する。
tokenizers
は、spacy-transformers
v1.2.5 の依存パッケージなので、spacy-transformers
を v1.3.5 にすることでエラーを回避する。
以下のファイルをダウンロード
https://github.com/megagonlabs/ginza/releases/download/v5.2.0/ja_ginza_bert_large-5.2.0b1-py3-none-any.whl
whl ファイル(zipファイル)を解凍する。
sudo apt install zip unzip
mkdir work
cd work
unzip ../ja_ginza_bert_large-5.2.0b1-py3-none-any.whl
ja_ginza_bert_large-5.2.0b1.dist-info/METADATA
ファイルを以下のように変更する。
vim ja_ginza_bert_large-5.2.0b1.dist-info/METADATA
12 行目
Requires-Dist: spacy-transformers <1.3.0,>=1.2.5
↓
Requires-Dist: spacy-transformers <1.4.0,>=1.2.5
再び zip 圧縮して、ファイル拡張子を .whl に変更する。
zip -r ja_ginza_bert_large-5.2.0b1-py3-none-any.whl ja_ginza_bert_large*
インストールする。
pip install ja_ginza_bert_large-5.2.0b1-py3-none-any.whl
動作確認
ginza コマンドで実行する。
echo "すももも、ももも、もものうち。" | ginza
途中、色々とログが出力され、最後に結果が出力される。
# text = すももも、ももも、もものうち。
1 すもも すもも NOUN 名詞-普通名詞-一_ 4 nsubj _ SpaceAfter=No|BunsetuBILabel=B|BunsetuPositionType=SEM_HEAD|NP_B|Reading=スモモ|NE=B-OTHERS|ENE=B-Flora|ClauseHead=4
2 も も ADP 助詞-係 _詞 1 case _ SpaceAfter=No|BunsetuBILabel=I|BunsetuPositionType=SYN_HEAD|Reading=モ|ClauseHead=4
3 、 、 PUNCT 補助記号_読点 1 punct _ SpaceAfter=No|BunsetuBILabel=I|BunsetuPositionType=CONT|Reading=、|ClauseHead=4
4 もも もも NOUN 名詞-普通名詞-一_ 9 nsubj _ SpaceAfter=No|BunsetuBILabel=B|BunsetuPositionType=SEM_HEAD|NP_B|Reading=モモ|NE=B-OTHERS|ENE=B-Flora|ClauseHead=4
5 も も ADP 助詞-係 _詞 4 case _ SpaceAfter=No|BunsetuBILabel=I|BunsetuPositionType=SYN_HEAD|Reading=モ|ClauseHead=4
6 、 、 PUNCT 補助記号_読点 4 punct _ SpaceAfter=No|BunsetuBILabel=I|BunsetuPositionType=CONT|Reading=、|ClauseHead=4
7 もも もも NOUN 名詞-普通名詞-一_ 9 nmod _ SpaceAfter=No|BunsetuBILabel=B|BunsetuPositionType=SEM_HEAD|NP_B|Reading=モモ|NE=B-PRODUCT|ENE=B-Food_Other|ClauseHead=9
8 の の ADP 助詞-格 _詞 7 case _ SpaceAfter=No|BunsetuBILabel=I|BunsetuPositionType=SYN_HEAD|Reading=ノ|ClauseHead=9
9 うち うち NOUN 名詞-普通名詞-副_ 可能 0 root _ SpaceAfter=No|BunsetuBILabel=B|BunsetuPositionType=ROOT|NP_B|Reading=ウチ|ClauseHead=9
10 。 。 PUNCT 補助記号_句点 9 punct _ SpaceAfter=No|BunsetuBILabel=I|BunsetuPositionType=CONT|Reading=。|ClauseHead=9
Python で実行する。
cat <<'EOL' | python
import spacy
nlp = spacy.load('ja_ginza_bert_large')
doc = nlp('すももも、ももも、もものうち。')
for sent in doc.sents:
for token in sent:
print(
token.i,
token.orth_,
token.lemma_,
token.norm_,
token.morph.get("Reading"),
token.pos_,
token.morph.get("Inflection"),
token.tag_,
token.dep_,
token.head.i,
)
print('EOS')
EOL
ログの最後に以下のように表示される。 インデックスが 0 から始まっている点を除いて、コマンド実行時と結果は同じとなる。
0 すもも すもも 李 ['スモモ'] NOUN [] 名詞-普通名詞-一般 nsubj 3
1 も も も ['モ'] ADP [] 助詞-係助詞 case 0
2 、 、 、 ['、'] PUNCT [] 補助記号-読点 punct 0
3 もも もも もも ['モモ'] NOUN [] 名詞-普通名詞-一般 nsubj 8
4 も も も ['モ'] ADP [] 助詞-係助詞 case 3
5 、 、 、 ['、'] PUNCT [] 補助記号-読点 punct 3
6 もも もも もも ['モモ'] NOUN [] 名詞-普通名詞-一般 nmod 8
7 の の の ['ノ'] ADP [] 助詞-格助詞 case 6
8 うち うち うち ['ウチ'] NOUN [] 名詞-普通名詞-副詞可能 ROOT 8
9 。 。 。 ['。'] PUNCT [] 補助記号-句点 punct 8
EOS
janome をインストールする。
Janome は,Pure Python で書かれた、辞書内包の形態素解析器となる。 処理速度は、早くはない。
pip install janome
動作確認
cat <<'EOL' | python
from janome.tokenizer import Tokenizer
t = Tokenizer()
for token in t.tokenize('すももも、ももも、もものうち。'):
print(token)
EOL
結果
すもも 名詞,一般,*,*,*,*,すもも,スモモ,スモモ
も 助詞,係助詞,*,*,*,*,も,モ,モ
、 記号,読点,*,*,*,*,、,、,、
もも 名詞,一般,*,*,*,*,もも,モモ,モモ
も 助詞,係助詞,*,*,*,*,も,モ,モ
、 記号,読点,*,*,*,*,、,、,、
もも 名詞,一般,*,*,*,*,もも,モモ,モモ
の 助詞,連体化,*,*,*,*,の,ノ,ノ
うち 名詞,非自立,副詞可能,*,*,*,うち,ウチ,ウチ
。 記号,句点,*,*,*,*,。,。,。
MeCab をインストールする。
MeCab は、C 言語で実装された高速な形態素解析器となる。 Python から利用するため、mecab-python3 パッケージを利用する。 辞書は、UniDic を利用する。
pip install mecab-python3 unidic
python -m unidic download
動作確認
cat <<'EOL' | python
import MeCab
stat = ['正常', '未知語', '文頭', '文末']
tagger = MeCab.Tagger()
node = tagger.parseToNode('すももも、ももも、もものうち。')
while node:
print(f'表層形:"{node.surface}"')
print(f'品詞:{node.feature}')
print(f'状態:{stat[node.stat]}')
print('-----')
node = node.next
EOL
結果
表層形:""
品詞:BOS/EOS,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*
状態:文頭
-----
表層形:"すもも"
品詞:名詞,普通名詞,一般,*,*,*,スモモ,李,すもも,スモモ,すもも,スモモ,和,*,*,*,*,*,*,体,スモモ,スモモ,スモモ,スモモ,0,C2,*,15660352771596800,56972
状態:正常
-----
表層形:"も"
品詞:助詞,係助詞,*,*,*,*,モ,も,も,モ,も,モ,和,*,*,*,*,*,*,係助,モ,モ,モ,モ,*,"動詞%F2@-1,形容詞%F4@-2,名詞%F1",*,10324972564259328,37562
状態:正常
-----
表層形:"、"
品詞:補助記号,読点,*,*,*,*,*,、,、,*,、,*,記号,*,*,*,*,*,*,補助,*,*,*,*,*,*,*,6605693395456,24
状態:正常
-----
表層形:"もも"
品詞:名詞,普通名詞,一般,*,*,*,モモ,桃,もも,モモ,もも,モモ,和,*,*,*,*,*,*,体,モモ,モモ,モモ,モモ,0,C3,*,10425303000293888,37927
状態:正常
-----
表層形:"も"
品詞:助詞,係助詞,*,*,*,*,モ,も,も,モ,も,モ,和,*,*,*,*,*,*,係助,モ,モ,モ,モ,*,"動詞%F2@-1,形容詞%F4@-2,名詞%F1",*,10324972564259328,37562
状態:正常
-----
表層形:"、"
品詞:補助記号,読点,*,*,*,*,*,、,、,*,、,*,記号,*,*,*,*,*,*,補助,*,*,*,*,*,*,*,6605693395456,24
状態:正常
-----
表層形:"もも"
品詞:名詞,普通名詞,一般,*,*,*,モモ,桃,もも,モモ,もも,モモ,和,*,*,*,*,*,*,体,モモ,モモ,モモ,モモ,0,C3,*,10425303000293888,37927
状態:正常
-----
表層形:"の"
品詞:助詞,格助詞,*,*,*,*,ノ,の,の,ノ,の,ノ,和,*,*,*,*,*,*,格助,ノ,ノ,ノ,ノ,*,名詞%F1,*,7968444268028416,28989
状態:正常
-----
表層形:"うち"
品詞:名詞,普通名詞,副詞可能,*,*,*,ウチ,内,うち,ウチ,うち,ウチ,和,*,*,*,*,*,*,体,ウチ,ウチ,ウチ,ウチ,0,C3,*,881267193291264,3206
状態:正常
-----
表層形:"。"
品詞:補助記号,句点,*,*,*,*,*,。,。,*,。,*,記号,*,*,*,*,*,*,補助,*,*,*,*,*,*,*,6880571302400,25
状態:正常
-----
表層形:""
品詞:BOS/EOS,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*
状態:文末
-----
gensim をインストールする。
pip install POT gensim
Word2Vec で利用する学習済みモデルをインストール
chiVe: Sudachi による日本語単語ベクトル のデータを分散表現データとして利用する。 このサイトには、複数のデータがあり、先人が言うには「A 単位語のみ」の資源のデータで事足りそうだが、 大は小を兼ねるということで、全部入りのデータを利用することにする。
「データ」表「v1.3 mc5」の「gensim」欄の「2.9GB (tar.gz)」をダウンロードして、
~/models/chive-1.3-mc5_gensim
ディレクトリ以下にモデルファイルを格納する。
cd
mkdir models
cd models
wget https://sudachi.s3-ap-northeast-1.amazonaws.com/chive/chive-1.3-mc5_gensim.tar.gz
tar -zxvf chive-1.3-mc5_gensim.tar.gz
もう一つ分散表現データをインストールする。
GitHub - Wikipedia Entity Vectors サイトの
リリースページから、
jawiki.all_vectors.300d.txt.bz2
ファイル(1.74 GB)をダウンロードする。
解凍した、jawiki.all_vectors.300d.txt
ファイル(4.92 GB)を ~/models/
ディレクトリに格納する。
FastText で利用する学習済みモデルをインストール
以下のサイトにブラウザでアクセスする。
https://github.com/facebookresearch/fastText/blob/master/docs/crawl-vectors.md
モデルの Japanese: bin
のリンクから日本語モデル圧縮ファイル(cc.ja.300.bin.gz)(4.18 GB)をダウンロードする。
https://dl.fbaipublicfiles.com/fasttext/vectors-crawl/cc.ja.300.bin.gz
cc.ja.300.bin.gz ファイルを解凍して、cc.ja.300.bin ファイル(6.75 GB)を、
~/models/
ディレクトリに格納する。
Doc2Vec で利用する学習済みモデルをインストール
学習済みモデル(dmpv300d)は、 日本語Wikipediaで学習したdoc2vecモデル - Out-of-the-box をありがたく利用させていただくつもりだったが、 このモデルは、gensim 3.x で作成されたようで (3.8.3 でロードできることは確認した)、 4.x では、ロード時に以下のようなエラーとなった。
AttributeError: 'Doc2Vec' object has no attribute 'dv'. Did you mean: 'dm'?
4.x 用に変換する方法などは見当たらなかったので、 諦めることにする。 モデルは、用途に合ったデータで学習させることが普通で、 汎用的なものは無いのかもしれない。 最初は、Word2Vec のモデルを、Doc2Vec に利用できるのかと思ったが、 そうではないようだ。
動作確認
Word2Vec のモデルを確認する。
cd
cat <<'EOL' | python
import gensim
model = gensim.models.KeyedVectors.load("./models/chive-1.3-mc5_gensim/chive-1.3-mc5.kv")
print(model.similarity('犬', '人'))
print(model.most_similar('徳島', topn=5))
EOL
犬
と人
の単語間の類似度と、徳島
の単語の類似単語が表示される。
0.29249397
[('徳島県', 0.7955368757247925), ('愛媛', 0.7929633855819702), ('高知', 0.7896395325660706), ('徳島市', 0.769208
7888717651), ('香川', 0.7571912407875061)]
pyannote.audio をインストールする。
pyannote.audio 用のモデルを利用するために準備が必要となる。 事前に Hugging Face のアカウント(無料)を作成してログインする。
このパッケージ用のモデルを利用するには、アクセストークン生成などが必要となる。 モデルを利用する手順は、 github.com/pyannote/pyannote-audio を参照。
以下に、上記手順の補足を記載する。
- パッケージをインストールする。
pip install pyannote.audio
- pyannote/segmentation-3.0 利用条件に同意する
- pyannote/segmentation-3.0 にブラウザでアクセスする。
You need to agree to share your contact information to access this model
のCompany/university
とWebsite
を入力して、Agree and access repository
を押下する。
- pyannote/speaker-diarization-3.1 利用条件に同意する
- pyannote/speaker-diarization-3.1 にブラウザでアクセスする。
You need to agree to share your contact information to access this model
のCompany/university
とWebsite
を入力して、Agree and access repository
を押下する。
- アクセストークンを作成
- hf.co/settings/tokens にブラウザでアクセスする。
+ Create new token
ボタンをクリックする。Token name
欄に任意の名前を入力する。Read access to contents of all public gated repos you can access
をチェックする。Create token
ボタンを押下する。- 表示されたトークンを控えておく。再表示はできないので注意。
動作確認
単一の話者音声の場合
cat <<'EOL' | python
from pyannote.audio import Pipeline
pipeline = Pipeline.from_pretrained(
"pyannote/speaker-diarization-3.1",
use_auth_token="ここにトークンを指定する")
diarization = pipeline("speechbrain/tests/samples/ASR/spk1_snt1.wav")
for turn, _, speaker in diarization.itertracks(yield_label=True):
print(f"start={turn.start:.1f}s stop={turn.end:.1f}s speaker_{speaker}")
EOL
ログの末尾に以下のように表示される。
start=0.0s stop=2.9s speaker_SPEAKER_00
複数の話者音声の場合
音声データを準備する
ffmpeg -i speechbrain/tests/samples/ASR/spk1_snt1.wav -i speechbrain/tests/samples/ASR/spk2_snt1.wav -filter_complex amix=inputs=2:duration=longest annote-sample.wav
# ファイルのフォーマットを確認する。
ffprobe -hide_banner annote-sample.wav
Input #0, wav, from 'annote-sample.wav':
Metadata:
encoder : Lavf60.16.100
Duration: 00:00:02.87, bitrate: 256 kb/s
Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 16000 Hz, 1 channels, s16, 256 kb/s
# 再生する。
paplay annote-sample.wav
実行する。
cat <<'EOL' | python
from pyannote.audio import Pipeline
pipeline = Pipeline.from_pretrained(
"pyannote/speaker-diarization-3.1",
use_auth_token="ここにトークンを指定する")
diarization = pipeline("annote-sample.wav")
for turn, _, speaker in diarization.itertracks(yield_label=True):
print(f"start={turn.start:.1f}s stop={turn.end:.1f}s speaker_{speaker}")
EOL
ログの末尾に以下のように表示される。
start=0.0s stop=1.9s speaker_SPEAKER_01
start=0.0s stop=2.9s speaker_SPEAKER_00
- 前の記事:環境構築編 - 基礎環境
- 次の記事:自然言語処理編 - 単語のベクトル化