何をしようとしたのか?
NUC(DN2820FYKH)にLinuxをぶち込んで音声認識によって情報を音声で返すアシスタントを作りたかった。
Raspberry PiとかじゃなくてNUCなのは元々家庭用ファイルサーバーとか自分用ウェブサービス的なもののホスティングに使おうとしていたため。
当初はCentOS7が動いていたのでその上にJuliusとOpenJtalkを乗っけてやろうと思ったが、
そもそも先行事例がなさすぎて素人文系マンには無理だと見切ってUbuntuのLTSだったら情報もあるんじゃないの?
とUbuntuにした。
というのが始まりの部分
まだアシスタントは完成していないけどjulius,open_jtalkがそれぞれ無事動いたのでその辺りを公開。
あと相変わらずハマってる部分もあるのでそちらも書いておきます。
環境は?
- Ubuntuは上述の通り14.04
- Juliusは4.3.1
- OpenJTalkは1.06
- HMM-Based Speech Synthesis Engine(hts_engine API)は1.09
- Mecabは0.994
- hts_engineとMecabはおそらくOpenJTalkについてきたやつ。別枠でmakeしてぶっこんだとかどっかから持ってきたという記憶はないので。
OpenJTalk周りは非常に不親切な状態だったので自分のような素人の為にも後で詳しく書いておきます。
ハマった点リスト
julius周り
- OSS?ALSA?音声周りのドライバとかがよく分からない
- Bluetoothのヘッドセットが繋がらない、音を拾わない。
- 認識の成功率が低い、または関係ない言葉を正答として認識する
- module modeで起動したはいいけどこのXMLどう整形すんねん。
まだありそうだけどとりあえずざっくりこんな感じ
OpenJTalk周り
- 不親切なエラー
- OpenJTalkとhts_engineの依存関係がある...のか?
- sourceforgeを見ても見つからないあるいは探しづらい情報たち
- わかりづらい仕様変更と微妙に古い情報たち
- 過去のバージョンに直接アクセスできない素敵なウェブサイト
後で細かく追記していくけどざっくりとそれぞれどう解決したか、対処法とオススメの代替案
Juliusと愉快な仲間たち
- に関して:基本的にALSAをOSSエミュレーターで使う方法で解決した。
- に関して:ハード的にBTアンテナの線が抜けてるだけでした。さしなおして解決。かと思ったら未だにBTで繋がってても音を拾わない事例が多発。USBマイク刺しっぱなしの方がソリューションとしては楽
- に関して:認識した音声を辞書の単語リストとマッチングして近似の単語を投げ返してくるので、不要なゴミデータを意図的に作成すると相対的に正答データと誤答データの間の重み付けが分かれてそこそこの精度になる。まだ不満が残るのでSVMによる機械学習を用いて正誤判定するシステムを構築中。
- に関して:XML要素が扱いにくい形になっているのでので、任意のスクリプトで成型をかければよろしい。具体的にはタグ要素を捨てて任意のkeyのValueのみを変数に入れるスクリプトを書いた。というかいっそJuliusのソースをいじって出力データをJSON配列の形式に書き換えてしまえばだいぶ扱いやすくなる気がするのでそっちも検討したい
OpenJTalkと不快な仲間たち
- に関して:エラーの判別とエラー内容が非常に不親切で何のエラーなのやらさっぱりわからん。ソースコードを見ても複数条件で起きうるエラーをひとまとめにしてエラーとして吐いてたのでハマった。ググってにたような事例の人を見つけ対処方を見つけで解決した。地獄かよ。
- に関して:hts_engineとOpenJTalkにバージョンごとの依存関係があるのかは謎だが、OpenJTalkの設定ファイルの読み込み方が変わっているのでそのあたりの設定を書き換えないと動かなかった。ググっても詳しいことはでてこないしさらっとした解説がリリースノートにあっただけなので、簡単なミスなのに解決に長時間かかった。OpenJTalkのバージョンが1.06から、.htcdictで一括設定みたいな形になってたと思うので、それ以降のバージョンを使う場合は注意。
- に関して:もうsourceforgeつかうのやめちくりーってなる。アカデミック系出身のOSSにありがちな不親切なウェブサイトやドキュメント担ってるので説明書的なpdfドキュメントを隅から隅まで読んで初めてちゃんと使える。斜め読みで使いたい機能だけをサクッと使うには向かないわー。
- に関して:前述二つと関わるのだが、いまいち変更点がアナウンスされてない感じや、最新バージョンはリリースされててもブログやQiitaの記事は数年前とかのものだったりするのでOSやソフトのバージョンが違うと何が何やら...ってなる。RospeexやWebSpeechAPIの台頭によってこの辺のソフトをローカルに使う手間暇コストが馬鹿らしくなってるのもあって、2014年以降あまり使ってみた人のブログとかでの情報が出てないがソフトだけはちまちま更新されているので、公式ドキュメントをいちいち読んで変更点を把握しないとエラー吐いてしまうので使えない模様。
- に関して:これは作った人が悪い。ユーザーには何もできない。古いバージョンを使いたい場合はソースフォージからソースを持ってきてmakeしないといけないみたい。最新版は細部の仕様が変わっているのもあってハマりまくる原因になった。最新版がエラーを吐く場合は基本的に設定ファイルとかオプションの仕様が変わった所為なのでそのあたりを把握して修正してあげればソフトそのものは動きます。
オススメしたい代替案
特にこだわりがなければWebSpeechAPIを使ったウェブアプリを実装することをオススメします。
ロボットですらWi-Fi接続でリモート操作できる時代なので、音声認識システムはWebSpeechAPIに任せてChromeでWebAppを実行する形式にすると捗る。
- Chrome専用ウェブサイト(jsで音声認識周りを実装)→任意のサーバーサイドプログラムに投げてハードウェア側にコマンドを送ってハードを制御
とかにした方がシンプルで楽そう。
ハードウェア内にサーバーを持つのもRaspiとかで容易になっているので。
またはRospeexというソリューションも生まれてるのでそちらでもいいのかも。
いずれにせよネット接続必須になるのはメリットデメリットありますが。
進捗としては一応SVMをつかったりしてJuliusの認識精度を上げようとか、OpenJTalkで一時ファイルとして音声生成して再生するシステムを作ってやろうとかも一応並行して作業しているのですが、この辺りの努力をまるっとしなくて済むWebSpeechAPI版の実装を用いて完成を急ぐ方に力を入れることにしました。