2014年4月15日

RaSCとJuliusを用いた音声認識サーバーの構築


約1ヶ月前に開催された言語処理学会にて、RaSC (Rapid Service Connector)というツールがNICTから発表されました。

RaSCは,既存の形態素解析器や係り受け解析器などのプログラムを大量のWebページに高速に適用することを念頭に開発されたものであり,多種のユーザプログラムを複数起動し,それらを相互に接続して分散並列実行させるためのミドルウェアです.

RaSC上で稼働するユーザプログラムのプロセスは,一度起動されると計算機に常駐します.そのため,辞書ファイルをロードする言語処理プログラムのように,巨大ファイルのロードなどにより起動時間が長くなっているプログラムであっても,効率的に実行できます.また,ユーザプログラムはネットワークを介して容易に利用でき,複数件の入力があった際には,複数の計算機上で並列化・分散実行することによって高速化されます.ユーザプログラム同士は,UNIXのパイプのように,簡便にストリーム通信により接続できる他,ユーザプログラムの実行はユーザが意識することなく並列に行われます

このツールのすごい点、それは非常に簡単な手順で、プロセスを常駐化させ、ネットワーク経由でアクセスできることではないでしょうか。
今回はRaSCを用いてJuliusを常駐化させてみましょう。

補足

Juliusに関しては、とあるプロジェクトでWebUIと連携を行う際に少々触れた程度の知識しか持っておりませんので(勉強不足です)、以下のJuliusに関する内容は誤りがあるかもしれません。
間違い等ありましたら、遠慮なくコメント欄でご指摘いただければ幸いです。

RaSCを使うメリット

そもそもなぜRaSCを用いて常駐化を行う必要があるのでしょうか。
それは、RaSCページの引用文にも示されている通り、辞書ファイル等の読み込みが発生するプログラムを毎回起動させるコストを減らすことができるからです。

また今回サービス化を行うJuliusには、ネットワーク・ソケット経由で解析が可能になるモードが用意されておりますが、Julius独自のプロトコルの実装コスト並列分散化(Juliusは1対1の通信のみを想定しているため、複数のリクエストがあった時の処理が困難)を考えると、RaSCのメリットは非常に大きいのではないでしょうか。

他にもMeCabやCaboChaなど、起動時にモデルを読み込み、起動後は標準入力を受け取り結果を返すようなインタラクティブな動作(?)をすることができるツールには非常に応用が利きそうですね。
以下にRaSCサービス化可能なプログラムの要件を引用しておきます。

  • 標準入出力を介して入出力を行う
  • 1件の入力が与えられると,対応する結果を出力し,終了することなく次の入力を待つ.
  • 入力と出力に明示的な終端文字列を出力する

RaSCを試してみる

RaSCドキュメントには、非常に丁寧なチュートリアルが掲載されています。
以下のページのチュートリアルに従うことで、たった数分でMeCabをサービス化することができます。
MessagePack RPCでユーザプログラムを呼び出す — RaSC 1.0.1 documentation

Juliusのサービス化を行う

Juliusの準備

では、本題に入ります。
まずJuliusは上で述べた”RaSCサービス化可能なプログラムの要件”を満たしておりません。
Juliusの実行結果を見ればわかる通り、解析結果の最後にEOF等の区切り文字が出力されないのです。
今回は、まずJuliusにパッチを当てていきます。

以上でJuliusへパッチを当てることができました。
あとはこのソースコードのビルドを行いましょう。

以上で実行可能なバイナリが生成されます。
では試しに音声ファイルを渡して解析を行ってみましょう。

21行目に注目してください。
このように、EOSが出力されていれば成功です。

RaSCの導入

ではいよいよRaSCの導入を行います。
RaSCの実行には JDK7以上 が必要ですので、まずは導入されているかどうかを確認し、導入されていない場合には先にそちらを導入してください。

また、JuliusService.xmlを開いて、 ___PATH_TO_PROGRAM___となっている箇所に、実行したユーザープログラムのコマンドラインを設定します。

例えば、バイナリが /home/user/binary にある場合、以下のように設定できます。

今回の場合は、設定ファイル等のパラメータを渡す必要があるため、cmdArrayパラメータを使います。
先ほどの行を削除し、例として以下のように設定することができます。

ファイル全体の設定例は以下のようになります。

他にも様々なパラメータが用意されております。
詳しくは以下を参照してください。
サービス定義XML — RaSC 1.0.1 documentation

では、RaSCサービスを起動させてみましょう。
server.shの使い方は以下の通りです。

今回の場合は、例として以下のように起動させることができます。

Pythonから呼び出してみる

RaSCサービスを呼び出すのは非常に簡単です。ここでは例としてPythonを利用していきます。
なお、プログラムの実行には msgpack-rpc-python パッケージが必要ですので、easy_install 等で導入をしておきましょう。

これで、temp/sound.wav を解析した結果が表示されます。
あとは、PythonでWebサーバーを構築して、リクエストで受け取った音声データを必要に応じてsoxコマンド等で加工、RaSCサービス化したJuliusを呼び出せばよいでしょう。

(Juliusには -input stdin オプションを指定することで、標準入力から音声データを受け取ることが可能ですが、この場合1回の解析でJuliusが終了してしまったため、今回ファイル指定という形をとりました。
標準入力でもインタラクティブモードが可能であれば、そちらのほうが良いでしょう。その場合、cli.call(“analyze”,[音声データ])とすることで、音声データが送信されます。

最後に

いかがでしたか?
今回RaSCを使用することで、非常に簡単な手順でプロセスのサービス化に対応することができました。
今回は並列化に関しては触れませんでしたが、RaSCのページにはその点に関しても非常に親切なチュートリアルが掲載されておりますので、一度目を通してみることをおすすめします。
RaSCは非常に汎用性の高いツールですので、自然言語処理だけでなく、様々な場面で活用していけそうです。

参考ページ


Comment

  1. matumoto yuki より:

    突然失礼します。このページ通りに順番にしていったのですが、「pythonから呼び出してみる」のところのコードの部分を実行したところ、エラーが表示されます。自分でも調べてみましたが、このエラーの意味するところが分かりません。

    $ python rasc.py
    Traceback (most recent call last):
    File “rasc.py”, line 6, in
    result = cli.call(“analyze”, “sound.wav”)
    File “/usr/local/lib/python2.7/dist-packages/msgpackrpc/session.py”, line 41, in call
    return self.send_request(method, args).get()
    File “/usr/local/lib/python2.7/dist-packages/msgpackrpc/future.py”, line 45, in get
    raise error.RPCError(self._error)
    msgpackrpc.error.RPCError

    よろしければ教えてください。お願いします

    • admin より:

      ご連絡遅くなりまして申し訳ございません。
      このエラーはMessagePackRPCの呼び出しエラーです。考えられる原因は
      ・サーバー側が正常に動作していない
      ・クライアント側がサーバーに接続できていない
      のどちらかだと思います。
      RaSCはlogフォルダにログを出力するので、クライアントプログラムを実行した後、処理が行われたか実行ログを確認すると良いと思います。
      実行が行われていない場合は、クライアント・サーバー間の通信の問題、実行が行われていてサーバー側でエラーが出ている場合は、Julius側のエラーかMessagePackRPCのサーバーが正常に立っていない可能性があります。

      どうぞよろしくお願い致します。

  2. sympoe より:

    有益な記事ありがとうございます。
    大変参考になりました。
    私も「matumoto yuki」同様エラーになりました。
    プログラムのコマンドラインへの不足分「-input」と「rawfile」を追加すると動きました。

    全体はこんな感じです。

    /var/julius/julius
    -C
    /var/julius/settings/am-gmm.jconf
    -C
    /var/julius/settings/main.jconf
    -input
    rawfile

Leave a Reply

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

*