はじめに
かつてイルカやヒツジなどが PC や携帯電話の操作をサポートしてくれる時代があった.昨今では Google アシスタントや Siri,アレクサなど音声アシスタントが登場してきている.対応するスマート家電も多く,音声アシスタントは急速に知名度を上げている.
今回は前々から気になっていた Open Assistant を試してみる.
かっこいい.
環境
用意するもの.
- Raspberry Pi
- そんなに性能はいらないけどデフォルトで無線が利用できる 3 以上がおすすめ
- 適当なUSBマイク
- 適当なスピーカー
今回はたまたま余っていた RasPi2B を使ってインストールを進める.
pi@assistant:~ $ cat /etc/os-release
PRETTY_NAME="Raspbian GNU/Linux 10 (buster)"
NAME="Raspbian GNU/Linux"
VERSION_ID="10"
VERSION="10 (buster)"
VERSION_CODENAME=buster
ID=raspbian
ID_LIKE=debian
HOME_URL="http://www.raspbian.org/"
SUPPORT_URL="http://www.raspbian.org/RaspbianForums"
BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs"
インストール
RasPi の OS インストールは次の記事を参照.
Open Assistant 導入の前に音声の入出力設定をしておく.設定方法は次の記事を参照.
ソースをダウンロードして,必要なパッケージをインストールする.
$ sudo apt-get install git
$ git clone https://github.com/openassistant/oa-core.git
$ pip3 install -r oa-core/requirements.txt
$ sudo apt-get install libatlas-base-dev python3-gst-1.0
環境によってはこの状態でも動くかもしれない.私の環境ではいくつかの点でうまく動作しなかったので少し手直しする.
1) 音声入力状態が終わらず音声コマンドが実行されなかったので,適当なタイムアウトを設定.タイムアウト値はお好みで.
$ cat oa-core/oa/modules/ear/init.py
...
# The timeout parameter is the maximum number of seconds that a phrase continues before stopping and returning a result. If the timeout is None there will be no phrase time limit.
#"timeout": None,
"timeout": 6.5,
...
2) boot mind
コマンド実行後にミュート状態でコマンドを受け付けなくなったので,play
関数のバックエンドを変更する.
$ cat oa-core/oa/modules/sound/__init__.py
...
import subprocess # playsound から変更
...
try:
subprocess.call(f'aplay {path}', shell=True) # aplay で再生するよう変更
except Exception as ex:
_logger.error("Error playing sound: {}".format(ex))
...
実行
Open Assistant はいくつかのコンポーネントで構成されている.Open Assistant 上には複数のマインド(人格のようなもの)を用意することができ,EAR(マイク)やVOICE(スピーカー)などを通じてアシスタントを行ってくれる.デフォルトでは「ブートマインド」と「ルートマインド」の 2 つのマインドが用意されている.
ブートマインドは最初に呼び出されるマインド.この初期マインドから他のマインドを呼び出す.
ルートマインドは基本的なシステム機能を提供するコアマインド.
wiki ではユーザマインドという更にもう 1 つ上のレベルが定義されている.ユーザマインドは学習機能を持っていたり,ユーザマインド毎に個性があったりするらしい.ちなみに冒頭に貼ったデモ動画はチャーリーという名前のマインドが登場するが,これはルートマインドを拡張したもの.
プログラムを起動する.
$ cd oa-core
$ python3 -m oa -d
プログラムを起動したら音声入力待ち状態になるので,「boot mind」と音声入力してブートマインドを起動する.本来はブートマインドが起動すると R2D2 の音声が鳴るが,私の環境では wav ファイル再生に利用している playsound ライブラリの問題で音が鳴らなかった.代わりにインストール時の手直しで「start boot mind」と鳴るようになっている.
ブートマインドが起動したら「open assistant」と音声入力してルートマインドを起動する.「list commands」や「what can i say」と音声入力することで利用可能な音声コマンドを教えてくれる.私の発音が悪いのかもしれないが,音声認識精度にちょっと難あり.
カスタマイズ
声色を変える
アシスタントの音声生成には pyttsx3 を使っている.
プロパティを変更することで,発話速度 (rate),声量 (volume),声色 (voice)を変更することができる.Open Assistant では次の箇所を変更すると良い.
$ cat oa-core/oa/modules/voice/__init__.py
...
def _in(ctx):
if not flMac:
tts = pyttsx3.init()
tts.setProperty('rate',180) # 発話速度変更
tts.setProperty('voice', 'english_rp+f3') # 声色変更
...
ブートマインドとルートマインドは voice を共有しているので,残念ながら変更は両方のマインドに適用される.
声色はいくつか用意されていて,それぞれの voice に id,languages,gender,age が定義されている.お試し Python コードは次の通り.どれを選ぶかはお好みで.日本語が...発話できない...
import pyttsx3
tts = pyttsx3.init()
voices = tts.getProperty('voices')
for voice in voices:
print("Voice: %s" % voice.name)
print(" - ID: %s" % voice.id)
print(" - Languages: %s" % voice.languages)
print(" - Gender: %s" % voice.gender)
print(" - Age: %s" % voice.age)
tts.setProperty('voice',voice.id)
tts.say("hello world!")
tts.runAndWait()
音声コマンドを追加する
デモ動画ではそれなりにインタラクティブな会話ができているような印象を受けるが,実際には定義された音声コマンドに従って応答しているだけにすぎない (定義されてない音声には反応できない).例えば「change the light color to red」と言う音声コマンドは root.py で次のように定義されている.適当な応答の後に,スマートライトのライブラリを利用して色を変更する処理を行っている.
@command("change the light color to red")
def lights_lights_red():
say_affirmative()
bulb_color_red()
このように API がわかれば任意のスマート家電を操作可能なオリジナルの音声コマンドを実装できる.日本語には対応していないが,いわゆる「お前を消す方法」のようなものも実装できる.
おわりに
Open Assistant の導入とカスタマイズについて紹介した.注意点として RasPi 環境では wav ファイルの再生に利用する playsound ライブラリに問題があるようで,wav ファイルを再生できなかった.
ユーザマインドの実装は大変そう.アンドロイドが電気羊の夢を見る日は来るのか.
コメント