by Takuya Nishimoto (nishimoto atmark m.ieice.org)

このチュートリアルの概要

このチュートリアルでは Galatea Toolkit for Linux を用いて簡単な音声対話システムを構築します.次のツールや言語処理系を使用します.

  • Ubuntu Linux 9.04 / 10.04
    • Ubuntu Desktop 32bit (日本語 Remix) CD-ROM
    • 日本語 EUC-JP ロケール環境で開発をしています。
      • 下記の手順で EUC-JP ロケールを作成してください。
    • wubi による Windows とのデュアルブート環境でも動作します。VMWare ゲスト環境では未確認です。
    • 64bit 環境には対応していません。
  • Galatea Toolkit for Linux (2009-09)
  • Ruby on Rails 2.0.2 以降

ライセンス

License をお読みの上お使いください。

なお galatea-ja-unidic パッケージは UniDic プロジェクトの成果を使用しており、他のパッケージとライセンスが異なります。下記にて利用者登録をしてからお使いください。

インストール

Ubuntu 9.04 (JA-remix)

Ubuntu Linux の場合,インストールは簡単です. ただし,以下の機能が有効でない場合は,ハードウェアの設定を行ってください.

  • オーディオ入力およびオーディオ出力(16KHz, 16bit, mono)
  • OpenGL による3Dグラフィックス(3D デスクトップ効果に対応していれば大丈夫です)

EUC-JP ロケールの作成

$ sudo chmod 666 /var/lib/locales/supported.d/local
$ sudo echo "ja_JP.EUC-JP EUC-JP" >> /var/lib/locales/supported.d/local
$ sudo locale-gen

必要な外部パッケージのインストール

$ sudo apt-get install libstdc++5
$ sudo apt-get install ruby
$ sudo apt-get install freeglut3
$ sudo apt-get install openjdk-6-jre
$ sudo apt-get install chasen

ただし,顔画像表示モジュール(FSM)は3Dデスクトップ効果において画面が乱れる ことがあります(ビデオドライバに依存するという情報がありますが、詳細は確認中です). あらかじめ以下を設定してください.

 システム → 外観の設定 → 視覚効果 → 効果なし(N) を選択

続いて,Galatea Toolkit をインストールします. (ファイル名の途中のバージョン番号は異なる場合があります)

$ sudo dpkg -i galatea-ja-chaone_yyyymmdd-1_i386.deb
$ sudo dpkg -i galatea-ja-unidic_yyyymmdd-1_i386.deb
$ sudo dpkg -i galatea-engine_yyyymmdd-1_i386.deb
$ sudo dpkg -i galatea-dialog_yyyymmdd-1_i386.deb

実行してみる(galatea-runner)

無事にインストールできていれば,/usr/local/bin に galatea-runner と galatea-generate の2つのコマンドが作成されます.

galatea-runner をオプションなして実行すると, デフォルトの対話ファイルを開始します.

$ galatea-runner

以下のように2つの画面が表示されます.

この状態でマイクから「こんにちは」「さようなら」のいずれかを発話すると, 「あなたは,こんにちは,と言いました」 「あなたは,さようなら,と言いました」 のいずれかをエージェントが喋ると思います.

Galatea Dialog Studio ウィンドウの Run/Pause ボタンは,対話制御を一時停止するものです. (音声認識および音声合成を直接止めるものではありません) また「マイクテスト」と喋ると,音声認識はされますが,応答はしません.

終了する場合は,galatea-runner を実行したターミナルで, Ctrl-C を押してください.

対話ファイルの詳細

対話ファイルは VoiceXML によって記述されています. デフォルト対話ファイルは Source タブを選択すると確認できます.

<?xml version="1.0" encoding="UTF-8"?>
<vxml version="2.0" xml:lang="ja">

<form id="init">
 <var expr="'to @AM-MCL set Mask = woman01 HAPPY 10 0 0 0'" name="mask_woman"/>
 <block>
  <native expr="mask_woman"/>
  <native>to @FS-MCL set HeadMoveRatio = 1.0 0.9</native>
  <native>to @FS-MCL set AutoMove = 1</native>
  <native>to @DIM set AutoGaze = 1</native>
  <goto next="#form1"/>
 </block>
</form>

<form id="form1">

 <grammar root="#greeting" version="1.0">
 <rule id="greeting">
 <one-of>
  <item> <token sym="まいくてすと">マイクテスト</token> </item>
  <item> <token slot="field1" sym="こんにちは">こんにちは</token> </item>
  <item> <token slot="field1" sym="さようなら">さようなら</token> </item>
 </one-of>
 </rule>
 </grammar>

 <field name="field1">
  <prompt>
    <native>to @FS-MCL set Emotion = HAPPY 10</native>
    <break time="600s"/>
  </prompt>

  <filled>
    あなたは<value expr="field1"/>と言いました。
    <clear namelist="field1"/>
  </filled>
 </field>

</form>

</vxml>

Logger タブで音声認識の動作を確認できます. 例えば前述の例で「マイクテスト」と発話すると,発話受理のイベントが表示されます. (初期設定では音声認識の動作ログのみが表示されます. ログを表示したい要素は対話システムの内部モジュールの単位で 有効・無効の切り替えができます)

また,Grammar タブを用いて,上記の VoiceXML の grammar 要素が どのように音声認識エンジン(Julius)の文法に変換されたかを 確認できます.

/home/nishi/.galatea/vxml_rule2.dfa

[voca]
% NS_B
silB: silB 
% NS_E
silE: silE 
% grm1_greeting
マイクテスト m a i k u t e s u t o 
% grm2_greeting
こんにちは@field1=こんにちは k o N n i ch i h a 
% grm3_greeting
さようなら@field1=さようなら s a y o: n a r a 


[grammar]
S : NS_B root NS_E 
root : greeting 
greeting : grm1_greeting 
greeting : grm2_greeting 
greeting : grm3_greeting 

プロジェクトを作成する(galatea-generate)

新たなバージョンでは対話システムに必要な設定をまとめて「プロジェクト」として ひとつのディレクトリにまとめて管理することができます。

プロジェクトディレクトリを作成するコマンドは galatea-generate です。

$ galatea-generate myproject
mkdir -p myprojct
mkdir -p myprojct/config
mkdir -p myprojct/script
myprojct/script/runner generated.
myprojct/config/project.yml generated.

プロジェクトの中で対話システムを実行するコマンドは script/runner です。

$ cd myproject
$ script/runner 
config script/../config/project.yml /usr/local/istc-galatea-dialog/files/galatea.yml
tmppath /home/nishi/.galatea
set broadcast = AM-MCL
set broadcast = DM
set broadcast = FS-MCL
set broadcast = PAR
LOG: START FS-MCL
LOG: START AM-MCL
LOG: START DIM
LOG: START PAR
LOG: START SSM
LOG: START DM
LOG: START FSM
Galatea Dialog Studio 2.2.4b2 (090214)
(c)2003-2009 Takuya NISHIMOTO (nishimoto [atmark] m.ieice.org)
Uses Mozilla Rhino from mozilla.org.
See http://www.mozilla.org/rhino/.
Rhino 1.7 release 1 2008 10 20

runner の --dry-run (-n) オプションは、各エンジンの設定ファイルの生成のみを行い、 実行さえるコマンドの表示のみを行います。

$ script/runner --dry-run
config script/../config/project.yml /usr/local/istc-galatea-dialog/files/galatea.yml
tmppath /home/nishi/.galatea
[runner] export LANG=ja_JP.eucJP;export LC_ALL=ja_JP.eucJP;export PERL_BADLANG=0;export AUDIODEV=/dev/dsp; 
cd /usr/local/istc-galatea-dialog/files/Modules; 
/usr/bin/perl ./AgentManager-gdm.pl -C /home/nishi/.galatea/am.conf

各エンジンの設定ファイルは runner において動的に生成されます。 初期状態ではユーザの ~/.galatea に設定ファイルが置かれます。 また、音声認識の文法に関する一時ファイルもここに作成されます。

$ ls ~/.galatea
am.conf          fsm.conf     ssm.conf         vxml_rule2.grammar  vxml_rule3.dfa      vxml_rule3.term
am_mcl.conf      gdm.conf     vxml_rule2.dfa   vxml_rule2.term     vxml_rule3.dict     vxml_rule3.voca
chasenrc-euc-jp  julius.conf  vxml_rule2.dict  vxml_rule2.voca     vxml_rule3.grammar

プロジェクト固有の設定ファイルは config/project.yml です。 これは galatea-generate が生成します。 今後のリリースではこのファイルをユーザが改変することで、 様々な要素をカスタマイズできる予定です。

$ cat config/project.yml 
enginepath: /usr/local/istc-galatea-engine
dmpath: /usr/local/istc-galatea-dialog/files
tmppath: /home/nishi/.galatea

ウェブアプリケーションとの連携

ウェブアプリケーションのフレームワークと連携することで、 Galatea を制御するアプリケーションを実現できます。

Ruby on Rails のプロジェクト作成

ここでは gem でインストールされた Ruby on Rails 2.0.2 を使用して例を示します。

$ which rails
/usr/bin/rails
$ rails dialog
      create  
      create  app/controllers
      create  app/helpers
      create  app/models
      ...

$ ./dialog/script/server
=> Booting WEBrick...
=> Rails application started on http://0.0.0.0:3000
=> Ctrl-C to shutdown server; call with --help for options
[2009-02-18 15:50:56] INFO  WEBrick 1.3.1
[2009-02-18 15:50:56] INFO  ruby 1.8.7 (2008-08-11) [i486-linux]
[2009-02-18 15:50:56] INFO  WEBrick::HTTPServer#start: pid=25026 port=3000

http://localhost:3000/ を Mozilla Firefox で開くと、Rails の画面が表示されます。 確認できたら script/server は Ctrl-C でいったん止めてください。

これから、非常に簡単な Model-View-Controller 連携の VoiceXML アプリケーションを実装します。

まず、http://server:port/model/index.vxml 形式の URL で vxml フォーマットの View が参照されるように routes.rb を編集します。

  • emacs はお好きなスクリーンエディタに置き換えてください。
  • 文字コードは UTF-8 で保存してください。
$ emacs dialog/config/routes.rb
ActionController::Routing::Routes.draw do |map|
  # ....
  map.connect ':controller/:action/:id'
  map.connect ':controller/:action/:id.:format'
  map.connect ':controller/:action.:format' # この行を追加
end

Model の作成

product という名前で Model(データベース)の作成を行います。

$ cd dialog
$ ./script/generate model product name:string yomi:string price:integer
      exists  app/models/
      exists  test/unit/
      exists  test/fixtures/
      create  app/models/product.rb
      create  test/unit/product_test.rb
      create  test/fixtures/products.yml
      create  db/migrate
      create  db/migrate/001_create_products.rb
$ emacs test/fixtures/products.yml
p01:
  name: 玉子丼
  yomi: たまごどん
  price: 550
p02:
  name: のり弁
  yomi: のりべん
  price: 580
p03:
  name: おにぎりセット
  yomi: おにぎりせっと
  price: 600
p04:
  name: のりメンタイ
  yomi: のりめんたい
  price: 600
$ rake db:migrate
(in /home/nishi/myprojct/dialog)
== 1 CreateProducts: migrating ================================================
-- create_table(:products)
   -> 0.0052s
== 1 CreateProducts: migrated (0.0053s) =======================================
$ rake db:fixtures:load

View と Controller の作成

$ ./script/generate controller product 
      exists  app/controllers/
      exists  app/helpers/
      create  app/views/product
      exists  test/functional/
      create  app/controllers/product_controller.rb
      create  test/functional/product_controller_test.rb
      create  app/helpers/product_helper.rb
$ emacs app/controllers/product_controller.rb
  • 先頭の class と末尾の end の間に def ... end を2つ追加します。
class ProductController < ApplicationController
  def index
    @products = Product.find(:all)
  end
  def show
    @product = Product.find(params[:id])
  end
end
$ emacs app/views/product/index.vxml.erb
<?xml version="1.0"?>
<vxml version="2.0" xml:lang="ja">
 <form id='main'>
  <block><log>商品リスト</log></block>
  <field name='id'>
   <prompt timeout='20s'>
    <% @products.each do |p| -%>
    <%=h p.name -%>、
    <% end -%>
   </prompt>
   <grammar version='1.0' root='#product'>
    <rule id='product'>
    <one-of>
    <% @products.each do |p| -%>
    <item> <token sym="<%=h p.yomi %>" slot="id" value="<%=h p.id %>"> <%=h p.name %> </token> </item>
    <% end -%>
    <item> <token sym="まいくてすと">マイクテスト</token> </item>
    </one-of>
    </rule>
   </grammar>
  </field>
  <block>
   <submit next="<%= url_for(:action=>'show', :format=>'vxml') %>"/>
  </block>
 </form>
</vxml>
$ emacs app/views/product/show.vxml.erb
<?xml version="1.0"?>
<vxml version="2.0" xml:lang="ja">
 <form id='main'>
  <block>
  <prompt>
    <%=h @product.name %>は<%=h @product.price %>円です。<break time="1s"/>    
  </prompt>
  <goto next="<%= url_for(:action=>'index', :format=>'vxml') %>" />
  </block>
 </form>
</vxml>

以上で準備が整いました。

アプリケーションを起動する

端末を2つ用意してください。

端末1:

$ ./script/server 

端末2:

$ galatea-runner http://localhost:3000/product/index.vxml

rails アプリケーション(サーバ)と galatea を同時に起動する

galatea の runner には rails アプリケーションを起動するオプションがあります。

$ cd ..
$ ./script/runner --rails-server ./dialog http://localhost:3000/product/index.vxml

JapaneseIndex に戻る