「Julius」は、日本の大学やIPAによって開発されているオープンソースの音声認識システムです。Raspberry Pi での音声認識の記事というと、大抵はこのJuliusを利用したもののようです。Google音声認識を利用した例もありますが、ライセンス的にかなり濃いグレーになりますので、ここではJuliusを使った音声認識を取り上げてみたいと思います。

※この記事は執筆・公開から3年以上経過しています。記事の情報が古くなっている場合がありますのでご注意ください。

公開日時:2016/12/14 21:12
最終更新:2019/12/10 04:57

Juliusの使い方(version 4.4.2 対応版)

イントロダクション

※Julius 4.3.1 までの記事は Juliusによる音声認識~国産オープンソースライブラリの活用 ラズベリーパイ研究室にあります。

Julius」は、日本の大学やIPAによって開発されているオープンソースの音声認識システムです。Raspberry Pi での音声認識の記事というと、大抵はこのJuliusを利用したもののようです。Google音声認識を利用した例もありますが、ライセンス的にかなり濃いグレーになりますので、ここではJuliusを使った音声認識を取り上げてみたいと思います。

バージョンについて

Juliusの最新バージョンは 4.4.2 となっています。(2016/9/12リリース)

Julius 4.3系からの大きな変更点はあまり無いようで、地道な機能追加とバグフィックスが行われているようです。体感的には、4.3系よりも音声認識が敏感になっているようで、小さな音でも拾ってくれるようになった感じがありますが、拾いすぎて認識文法を使った用途でゃ誤認識が多くなったように感じます。この辺はトレードオフですね。

なお、Julius のソースコードは時代の流れに即して GitHub で公開されるようになりましたので、git clone コマンドで入手できるようになりました。

ダウンロード

Julius 本体をダウンロードするには、まず、git をインストールします。

git --version

で、git version 2.1.4 といった情報が表示されない場合は未インストールですので、

sudo apt-get install libi2c-dev
sudo apt-get install git-core

で、git をインストールしてください。

合わせて、ビルドしたソフトウェアの管理アプリケーション paco をインストールします。

sudo apt-get install paco

※paco は 2014 年でメンテナンスが終了しており、現在は次期プロダクトの porg に移行しているようです。paco で管理していたデータを porg に移行するのも簡単なようなので、状況次第で、当サイトも porg に切り替えていきます。

git と paco の準備が整ったら、Julius のソースコードを GitHub から入手します。

cd ~

git clone https://github.com/julius-speech/julius.git

これで Julius のソースコードが入右手できたので、以下のコマンドを順次実行してインストールします。

cd julius
./configure --enable-words-int
make
sudo paco -lD "make install"

これで、Julius のコンパイルとインストールは完了です。

julius -version

で、正しくインストールされているか確認してください。また、以下のコマンドで paco で管理できていることを確認できます。

paco -a

Julius をアンインストールする場合は、

sudo paco -r パッケージ名(この場合はjulius)

とするだです。簡単ですね。

加えて、Julius の実行時に必要なカーネルモジュールを有効化します。

sudo modprobe snd-pcm-oss
sudo sh -c "echo snd-pcm-oss >> /etc/modules"

追加モジュール

併せて、ディクテーションキットと文法認識キットをダウンロードします。ディクテーションキットはディクテーション(自動口述筆記)に必要な最小限モデルが含まれたキット、文法認識キットは実用的な音声認識を行うために定型の文法を用いるためのキットです。

Julius のディレクトリから抜けて、2つのキットをwgetします。こちらはコンパイルする必要はありません。解凍して julius-kits ディレクトリに纏めておきます。

cd ../
wget -O dictation-kit-v4.4.zip "https://osdn.net/frs/redir.php?m=jaist&f=%2Fjulius%2F66544%2Fdictation-kit-v4.4.zip"

wget -O grammar-kit-4.3.1.zip "https://github.com/julius-speech/grammar-kit/archive/v4.3.1.zip"
unzip dictation-kit-v4.4.zip
unzip grammar-kit-4.3.1.zip

mkdir julius-kits

mv dictation-kit-v4.4 julius-kits/
mv grammar-kit-4.3.1 julius-kits/

マイクのテスト

音声認識をさせるためにはマイクが必要です。Raspberry Pi にはアナログマイク端子が無いのでUSBマイクを利用するのが一番効率が良いかと思います。

弊社でテストしたマイクはこちらです。

MM-MCUSB16 の方はシンプルなマイクで単一指向性ですが、MM-MCUB22 の方は全指向性でミュートボタンもついています。

特に MM-MCUB22 の方はかなり感度がよく良く音を拾いますが、物を置いた時の雑音など小さな音も拾うので、記述文法を使った限定的な音声認識では逆に誤認識が多くなるケースもあります。この場合はミュートボタンを使って適切に切り替えを行う事で対処して下さい。

なお、アナログマイクを利用されたい場合はUSB変換アダプターを利用する方法もあります。変換アダプターはノイズが多い物がありますので、弊社がテストした中ではこちらがお勧めです。

PlugableR USB オーディオ変換アダプタ 3.5mm ヘッドホン・マイク端子付(黒アルミニウム仕上げ、C-Media社CM108 チップ採用、Windows、Mac、 Linux 対応)

音声認識設定

マイクをRaspberry Pi に刺し、オーディオカードの優先順位を確認します。Julius では、マイクのサウンドカードが 0 番に設定されていないとエラーが出るようですので、マイクを優先させます。(Julius の設定で変更できるかどうかは不明です)

sudo cat /proc/asound/modules
 0 snd_usb_audio
 1 snd_bcm2835

上記の様に snd_usb_audio が上にあればUSBデバイスがオンボードのサウンドカードよりも優先されています。下にあった場合はUSBデバイスの優先度を上げるため、以下のように設定ファイルを作成します。

sudo vi /etc/modprobe.d/alsa-base.conf

で開いた設定ファイルを新規作成します。

options snd slots=snd_usb_audio,snd_bcm2835
options snd_usb_audio index=0
options snd_bcm2835 index=1

設定ファイルを保存して Raspberry Pi を再起動すると、USBオーディカードが優先されているはずです。再び sudo cat /proc/asound/modules で優先順位を確認してください。

いよいよ録音テストです。まずマイクのカード設定を確認します。

arecord -l

以下のような表示が出れば、マイクは認識されています。この場合、カード 0、デバイス 0 です。

i@raspberrypi:~ $ arecord -l
**** ハードウェアデバイス CAPTURE のリスト ****
カード 0: Device [USB Audio Device], デバイス 0: USB Audio [USB Audio]
  サブデバイス: 0/1
  サブデバイス #0: subdevice #0

次はマイクの音量を調節します。 -c オプションでカード番号を指定し、sset コンテンツ名 設定値 の順で値を設定します。

sudo amixer -c 0 sset 'Mic' 90%

マイクの調整が終わったら、次はスピーカーです。

aplay -l

次のようなリストが返るかと思います。この場合、カード 1、デバイス 0 がアナログスピーカー、カード 1、デバイス 1 が HDMI 出力です。

**** ハードウェアデバイス PLAYBACK のリスト ****
カード 1: ALSA [bcm2835 ALSA], デバイス 0: bcm2835 ALSA [bcm2835 ALSA]
  サブデバイス: 8/8
  サブデバイス #0: subdevice #0
  サブデバイス #1: subdevice #1
  サブデバイス #2: subdevice #2
  サブデバイス #3: subdevice #3
  サブデバイス #4: subdevice #4
  サブデバイス #5: subdevice #5
  サブデバイス #6: subdevice #6
  サブデバイス #7: subdevice #7
カード 1: ALSA [bcm2835 ALSA], デバイス 1: bcm2835 ALSA [bcm2835 IEC958/HDMI]
  サブデバイス: 1/1
  サブデバイス #0: subdevice #0

以下で、音声のコントロールセッティングが確認できます。

amixer controls

次のようなリストが確認できます。

pi@raspberrypi:~ $ amixer controls
numid=2,iface=MIXER,name='Mic Capture Switch'
numid=3,iface=MIXER,name='Mic Capture Volume'
numid=1,iface=PCM,name='Capture Channel Map'

参考)Sound configuration on Raspberry Pi with ALSA

この numid を使って、優先するカードを設定します。1 がアナログ出力、2 が HDMI、0 が自動認識です。

amixer -c 1 cset numid=3 1

HDMI端子は音の立ち上がりが遅いため、再生の最初が途切れてしまいます。このため、今回はアナログ端子でテストを行います。サンプルファイルを再生してみましょう。

スピーカーの音量を設定します。 -c と sset の意味は、マイクの時と同じです。

sudo amixer -c 1 sset 'PCM' 95%

では、サンプル音源を再生してみましょう。

aplay -D plughw:1,0 /usr/share/sounds/alsa/Front_Center.wav

無事、音声が再生されたでしょうか?

あとは録音・再生テストです。以下で、録音データが test.wav というファイルで書き出されます。録音を中止するにはCtrl + C を押してください。

arecord -D plughw:0,0 -f cd test.wav

-f cd というのは、16 bit little endian, 44100Hz, stereo のフォーマットで録音する事のようです。

参考)arecord(1) - Linux man page

再生してみましょう。

aplay -D plughw:1,0 test.wav

音声が再生されれば音声認識の準備は完了です。

Juliusでの音声認識

さて、では実際に Julius で音声認識です。最初はディクテーションキットを使って音声認識してみましょう。

cd julius-kits/dictation-kit-v4.3.1-linux
julius -C main.jconf -C am-gmm.jconf -demo

このキットは特定の文法や単語の定義セットを用いずに音声を認識するのでかなり時間がかかります。

まず、Raspberry Pi 3 の Julius 4.4 で認識を行ってみます。

補足ですが、Raspberry Pi 2 の Julius 4.3.1 の時の認識。処理速度は上がっていますが、認識精度は落ちているような…

このように自由文章ではかなり時間がかかるため、あらかじめ予想される文法を登録する「記述文法」を使って認識速度を向上させます。

このように自由文章ではかなり時間がかかるため、あらかじめ予想される文法を登録する「記述文法」を使って認識速度を向上させます。

文法ファイル作成

まず、voca ファイルに発音音素列を記述します。記述はローマ字(ヘボン式のようです)で行います。区切り文字は半角スペースです。

%で始まる行は、カテゴリ登録です。この後、構文制約ファイルを作成するときに使います。

"NS_B" と "NS_E" はそれぞれ文頭および文末の「無音区間」に対応する単語カテゴリで、文の最初と最後に必ず挿入する必要があります。

vi kaden.voca
% KADEN
テレビ   t e r e b i
電気    d e n k i
% WO        
を      w o 
% PLEASE    
つけて   t u k e t e
消して   k e sh i t e
% NS_B
[s]     silB
% NS_E
[s]     silE

次に、 構文制約を行うための grammar ファイルを作成します。

vi kaden.grammar
S      : NS_B KADEN_ PLEASE NS_E
KADEN_ : KADEN
KADEN_ : KADEN WO

KADEN と KADEN WO の両方のエイリアスとして KADEN_ を定義しています。これにより「電気つけて」と「電気をつけて」の両方の音声に対し、1つの構文制約で対応できます。

voca ファイルと grammar ファイルは基本的には一対になります。ですので同じ名前にしてください。

両ファイルを作成したらコンパイルを行って .dfa ファイル、.term ファイル、 .dict ファイルを生成するのですが、コンパイルに用いるプログラム mkdfa.pl について、少し注意が必要です。grammar-kit-v4.1 及び julius-4.3.1/gramtools/mkdfa/ に付属している mkdfa.pl(から参照されるmkfa) は正常に動作しないので、julius ディレクトリ内にある対応版の mkfa を利用する必要があります。

このため、以下のコマンドで mkfa と dfa_minimize を julius-4.3.1/gramtools/mkdfa/ 内のファイルと差し替えます。(コピー時に -b オプションを付けているので、旧ファイルは末尾に \~ 付きでバックアップされます)

sudo cp -b ./julius/gramtools/mkdfa/mkfa-1.44-flex/mkfa ./julius/gramtools/mkdfa/mkfa

sudo cp -b ./julius/gramtools/dfa_minimize/dfa_minimize ./julius/gramtools/mkdfa/dfa_minimize

ではコンパイルしてみましょう。

sudo ./julius/gramtools/mkdfa/mkdfa.pl kaden

上手く変換が出来た場合は kaden.dfa kaden.term kaden.dict の3ファイルが作成されます。kaden.dfa ファイルは「有限状態オートマトンに変換したもの」だそうで、構文制約によって定義される発音音素の遷移パターンのようです。kaden.term と kaden.dict の数値がこれに対応するようですが、詳しい仕様はThe Juliusbookを参照してください。

では、作成した .dfa ファイルを用いて音声認識を行ってみます。Julius では、マイクの入力がないと大量の Warning を出力しますが、-nostrip オプションをつけるとこれを抑制できます。

sudo julius -C /home/pi/julius-kits/grammar-kit-4.3.1/hmm_mono.jconf -input mic -gram kaden -nostrip

ディクテーションキットをそのまま使う場合と比べてほぼ実用的な速度になっていると思います。なお、音声認識に用いる文法ファイルですが、以下の様にカンマ区切りで複数列挙すれば同時に利用することも可能です。

julius -C /home/pi/julius-kits/grammar-kit-4.3.1/hmm_mono.jconf -input mic -gram kaden,fruit -nostrip

記事リンク