普通のPC+ノー環境構築でAI画像生成を遊ぶ
AIによる画像生成「Stable Diffusion」が話題なので、さっそく遊んでみましたのですが、これが結構面白いです。おもしろ画像を生成してくれるキーワードを大喜利のような感覚で探して楽しめます。例をいくつか挙げると
普通のPC+ノー環境構築でAI画像生成を遊ぶ Read More »
AIによる画像生成「Stable Diffusion」が話題なので、さっそく遊んでみましたのですが、これが結構面白いです。おもしろ画像を生成してくれるキーワードを大喜利のような感覚で探して楽しめます。例をいくつか挙げると
普通のPC+ノー環境構築でAI画像生成を遊ぶ Read More »
相変わらず愛しいVoice Kit V2です。
なおOpen JTalkではなく、前々回のGoogleあるいは前回のAmazonを試してみたい人は以下のリンクからどうぞ。
ラズベリーパイに日本語で喋らせる[その1]Google Cloud Text-To-Speech
ラズベリーパイに日本語で喋らせる[その2]Amazon Polly
Google、Amazonともに有料APIです(無料枠はありますが)。その点Open JTalkは完全無料かつオフラインで利用できるというメリットがありますので、用途によっては選択肢のひとつになると思います。というわけで試してみましょう。
私はRaspbianOSでやってますが、Linux系でスピーカー付いてりゃ何でもいいと思います。
とりあえずdebian系の方はいつもどおりaptでインストールします。
$ sudo apt install open-jtalk open-jtalk-mecab-naist-jdic hts-voice-nitech-jp-atr503-m001
3つのパッケージをインストールします。open-jtalk本体とmecab辞書、それに音声の3つです。open_jtalkコマンド実行時に辞書ディレクトリと音声モデルを指定する必要があります。基本的な書式は次のような感じ。
$ open_jtalk -x <辞書ディレクトリ> -m <音声ファイル> -ow <出力するwavファイル>
読み上げるテキストは標準入力かファイル名を指定します。先程インストールした辞書はRaspbianOSの場合は /var/lib/mecab/dic/open-jtalk/naist-jdic/ に、音声モデルは /usr/share/hts-voice/nitech-jp-atr503-m001/nitech_jp_atr503_m001.htsvoice にインストールされています。
実際に何か読み上げてみます。
$ echo "こんにちわ、私は金正恩です" | open_jtalk -x /var/lib/mecab/dic/open-jtalk/naist-jdic/ -m /usr/share/hts-voice/nitech-jp-atr503-m001/nitech_jp_atr503_m001.htsvoice -ow test.wav $ aplay test.wav
上手く読み上げできました? 標準の男性音声で再生されます。ちなみにaplayが入ってない環境なら、なんとかして作成したwavを再生してください。
ではPythonから合成・再生ができるようにしてみます。python用のライブラリがあるわけではないので、直接コマンドを叩く感じになります。
#!/usr/bin/env python3 import sys import subprocess DICT_PATH='/var/lib/mecab/dic/open-jtalk/naist-jdic/' VOICE_PATH='/usr/share/hts-voice/nitech-jp-atr503-m001/nitech_jp_atr503_m001.htsvoice' while True: print('何か入力してエンターキーを押してね(CTRL+Cで終了)') text = input() with open('speech.txt', 'w') as f: f.write(text) subprocess.run(['open_jtalk', '-x', DICT_PATH, '-m', VOICE_PATH, '-ow', 'speech.wav', 'speech.txt']) subprocess.run(['aplay', 'speech.wav'])
色々喋らせてみたんですが、音声合成の処理時間が結構かかってますね・・・。「こんにちわ」でも1秒ぐらいかかってます。非力なラズパイZeroだからかなあ・・・?これならGoogleやAmazonのオンラインAPIと大差無い気もします。
音響モデルを変更することで音声を変えることができます。このサイトが詳しいみたい。
MMDAgentのモデルが比較的高精度なモデルのような気がしますので、これだけ試しておきましょう。以下URLからファイルをダウンロードします。
MMDAgent_Example-1.8.zipというファイルをダウンロードします。解凍したらVoiceディレクトリの中にmeiとtakumiという音響モデルがありますが、これらが日本語音響モデルです。感情毎にモデルが別れているみたいですね。
モデルを先程のpythonで試してみる場合は、VOICE_PATHの値を適当に変更してください。
Open JTalkで使用できる音響モデルは正直言ってGoogleやAmazonのものと比べると見劣り(聞き劣りというべき?)しますね・・・。やはりGoogleやAmazonは偉大ということか・・・。外部APIを叩いてもサクッと返ってきますし、無料枠も太っ腹(特にGoogleは)なので、あえてOpen JTalkを使用する必要はないかな。地味にSSMLも役立ちそうな気もしますし。
そんな感じです。
ラズベリーパイに日本語で喋らせる[その3]Open JTalk Read More »
愛しいVoice Kit V2です。
AmazonではなくGoogle CloudのText-To-Speechを試してみたい人は前回の記事を見ていただければ。
ラズベリーパイに日本語で喋らせる[その1]Google Cloud Text-To-Speech
Amazonにも同様の読み上げAPIがあり、料金体系もGoogleと(見た感じ)ほぼ一緒です。合成音声の完成度やAPIのデキなどが気になるところなので、実際に日本語読み上げを試してみます。
公式はこちら
トップページで日本語音声も聴くことができます。Mizuki(女性)とTakumi(男性)の2パターンですね。これに関してはGoogleの方が選択肢が多いです。ここで試聴する感じではGoogleと大差はないかも。。
続いて料金について。
まずは無料枠を見てみます。(2020.03.05現在)
機能 | 最初の発話リクエストから 12 か月間 |
---|---|
スタンダード音声 | 0〜500 万文字 |
ニューラル音声 | 0〜100 万文字 |
ニューラル音声の方がハイテクな音声なのでしょう。どちらも充分な無料枠だと思います。
ただ最初の12ヶ月からは有料になるようですね。
機能 | 有料使用 |
---|---|
スタンダード音声 | 100 万文字あたり $4.00(USD) |
ニューラル音声 | 100 万文字あたり $16.00(USD) |
有料部分に関してはGoogleと同じってことでしょうか。しかしGoogleの無料枠は無期限なのでコスト的にはGoogleの方が安い(はず)です。後は機能面で比較ってことかな。
実際にAPIをPythonから利用していみたいと思います。流れ的にはGoogle Cloud Text-To-Speechと同じで、事前に認証系の設定が必要です。
まずはサービスキーが必要なので作りましょう。(シークレットアクセスキーが分かるなら)既存のものでもいいです。新しく作る場合はIAMのユーザーページから。
[アクセスキーの作成]ボタンをクリックすると、ダイアログが表示されアクセスキーIDとシークレットが表示されます。このシークレットアクセスキーはコピーしておきます。また今回は使いませんがcsvのダウンロードもしておきましょう。このダイアログを閉じると二度とダウンロードできないので。
なお、APIを使用するユーザーにPollyのAccess権限が必要です。ポリシーをアタッチするか、権限のあるグループ(Developersとか)にユーザーを追加するなどしておいてください。
AWSの設定といえばこれぐらいです。続いてPython用のAWSライブラリbotoをインストールしておきます。
$ pip install boto3 #環境によってはpip3です
以上で準備は完了。
何かテキストを入力するとMizukiさんが読み上げてくれるサンプルです。
#!/usr/bin/env python3 import sys import subprocess import boto3 polly_client = boto3.Session( aws_access_key_id='サービスアクセスキーID', aws_secret_access_key='シークレットアクセスキー', region_name='リージョン(ap-northeast-1とか)').client('polly') while True: print('何か入力してエンターを押してね(CTRL+Cで終了)') response = polly_client.synthesize_speech(VoiceId='Mizuki', OutputFormat='mp3', Text=input()) with open('speech.mp3', 'wb') as f: f.write(response['AudioStream'].read()) subprocess.run(['mpg321', '-q', 'speech.mp3'])
Sessionに渡す認証情報はご自分のものに書き換えてください。
音声はmp3でダウンロードしてます。wavの方が再生が簡単だったのですが、ぱっと見た感じwavで落とす方法がなさげだったので、あきらめてmpg321で再生しています。ここはmp3が再生できたら何でもいいです。mpg321をラズベリーパイにインストールする場合は、普通に sudo apt install mpg321 でOKです。
無事再生できたでしょうか?
色んなテキストを読み上げてもらいましたが、正直Googleと大差無い気もしますね・・。細かいところまで調べてませんが、どちらかが突出して優れているというわけでもなさそうな印象。であれば無料枠が無期限のGoogleに軍配があがるかなあ、と思っていたんですが、そういや完全無料スタンドアローンのOpenJTalkを試していないことを思い出しました。
というわけで、次回はOpenJTalkを試してみようと思います。
ラズベリーパイに日本語で喋らせる[その2]Amazon Polly Read More »
↓楽しいVoice Kit↓
Voice Kit同梱のaiyライブラリというものがあり、これを使用すれば一応ラズパイに喋らせることはできるのですが、無残にもこのText−To-Speech(以下TTS)ライブラリがまだ日本語に対応していないという。サポートされてるのヨーロッパ言語のみ・・・。ちきしょう。
しかし、GoogleのText−To-Speech API自体は日本語に対応しているので、そちらを直接叩くことで日本語で話させることができます。Text−To-Speech APIは無料ではないので気になる料金面から実装サンプルまで調べてみました。
その名の通り、テキストをスピーチ(音声)に変換する読み上げAPIです。文字列投げたら音声ファイルにして返してくれるイメージですね。大変便利なAPIなんですが無料では使えません。料金詳細については公式を見ていただくとして・・・
ポイントはここですね(2020.03.03現在)
機能 | 1 か月あたりの無料枠 | 有料使用 |
---|---|---|
標準(非 WaveNet)音声 | 0〜400 万文字 | 100 万文字あたり $4.00(USD) |
WaveNet 音声 | 0〜100 万文字 | 100 万文字あたり $16.00(USD) |
1ヶ月に変換させた文字数で決まるみたいです。非WaveNetとWaveNetで料金が違います。WaveNetとは一言で言うと『自然な音声』でして、Google HomeやAndroidのGoogleアシスタントで使用されている音声がそれです。こっちの方が料金が高いです。しかしGoogle様のご厚意により太っ腹な無料枠が用意されているので、ちょこちょこっと利用するぐらいなら無料枠で収まりそうですね。
ちなみにどんな音声なのか公式サイトで実際に聞くことができます。
日本語は男性・女性、それぞれ非WaveNetとWaveNetで2種類ごとあるようですね。
WaveNetの方が自然で音声もクリアな気がします。でも非WaveNet(Standard)もそんなに悪いもんじゃないですね・・。
やりましょう。しかし実装前に準備が必要です。全部公式に書いてます。
まずはGoogle Cloud Platformお約束の認証キーのダウンロードです。上記公式の通りに実施してください。手順の概要を書いておくと、
とこんな感じ。
その後も公式に書いてある通りですが、まずは環境変数を通して
$ export GOOGLE_APPLICATION_CREDENTIALS="JSONファイルのパス" fish shellなら↓ $ set -x GOOGLE_APPLICATION_CREDENTIALS "JSONファイルのパス"
pipでライブラリをインストールします。(環境によってはpip3で)
$ pip install --upgrade google-cloud-texttospeech
準備は以上で完了です。
ではサンプルです。これは公式のものと違って日本語対応してます。
#!/usr/bin/env python3 import sys import subprocess from google.cloud import texttospeech client = texttospeech.TextToSpeechClient() voice = texttospeech.types.VoiceSelectionParams( language_code='ja-JP', name='ja-JP-Wavenet-D') audio_config = texttospeech.types.AudioConfig( audio_encoding=texttospeech.enums.AudioEncoding.LINEAR16) while True: print('何か入力してエンターを押してね(CTRL+Cで終了)') synthesis_input = texttospeech.types.SynthesisInput(text=input()) response = client.synthesize_speech(synthesis_input, voice, audio_config) with open('output.wav', 'wb') as f: f.write(response.audio_content) subprocess.run(['aplay', 'output.wav'])
実行してしばらく待つと入力が促されるので何か入力してエンターキーを押します。すると入力された文字列をAPIに投げ、返ってきた音声ファイルをWAVで保存、再生するという流れです。
保存したWAVファイルは aplay というコマンドで再生しています。ALSAドライバを使用しているラズパイなら問題なく動くと思いますが、他のディストリビューションやMacなどでは動かないと思うので、適宜wavを再生できるコマンドに置き換えるなどしてください。
なおVoice Kitなら、いちいちWAVファイルに落とさなくても、バイトストリームから直接再生できます。
#!/usr/bin/env python3 import sys import subprocess from google.cloud import texttospeech from aiy.voice.audio import play_wav client = texttospeech.TextToSpeechClient() voice = texttospeech.types.VoiceSelectionParams( language_code='ja-JP', name='ja-JP-Wavenet-D') audio_config = texttospeech.types.AudioConfig( audio_encoding=texttospeech.enums.AudioEncoding.LINEAR16) while True: print('何か入力してエンターを押してね(CTRL+Cで終了)') synthesis_input = texttospeech.types.SynthesisInput(text=input()) response = client.synthesize_speech(synthesis_input, voice, audio_config) play_wav(response.audio_content)
ソースを見ればそんなに難しくないと思いますが、
SSMLとは音声のマークアップ言語です。
実物を見れば分かると思いますが、テキストを音声に変換する際、ここは強調してとか、ここで1秒休んで、とか、そういった細かな指示をするための言語みたいです。凝った音声を作りたければ便利そうですね。ただし料金は発話する文字数ではなくAPIに渡す文字数なので、SSMLを使った方が当然文字数は増えます。といっても短い文章を喋られせるぐらいならあまり神経質にならなくても大丈夫そうですがね・・・。一度作った音声ファイルを保存しておけば何度再生しても料金は発生しませんしね。
いやはや、なんとかこれでかなりナチュラルな音声発話ができるようになりました。
次回はこれのAmazon版であるAmazon Pollyを検証してみたいと思います。
ラズベリーパイに日本語で喋らせる[その1]Google Cloud Text-To-Speech Read More »
Raspberry Piで動くGoogle AIY Voice Kit V2というスマートスピーカーキットの基本操作のサンプルをまとめました。LEDやボタン、オーディオの基本操作とGoogleアシスタントAPI、Cloud Speechのサンプル等を載せています。
とは↓こんな感じ↓のダンボール型スマートスピーカーです。
LEDボタン・スピーカー・マイクが搭載されたラズベリーパイのキットです。自分で組み立てます。組立方法はとても簡単なので誰でも作れます。この値段でスマートスピーカーが作れるとは、なんていい時代なんでしょうか。
組み立ては誰でもできますが、いざ何かしようと思うとプログラミングが必要です。Googleが用意してくれているPython用のライブラリを使用してプログラミングしていきます。というわけでリファレンス的に使えるVoice Kit V2の基本操作のサンプルをまとめておくことにしました。
なお、各スクリプトの1行目で #!/usr/bin/env python3 してるのは、Voice Kit用のRaspbianOSにはPython2系と3系の両方がインストールされているのですが、aiyライブラリがPython3環境にインストールされているので、必ずそちらを使用するようにしているためです。(シェルで普通にpythonを実行すると2系が実行されちゃいますからね・・・)
LEDボタンを光らせたり点滅させたりします。Voice KitにはV1とV2があるのですが、まずは両バージョンに対応している基本操作から。
#!/usr/bin/env python3 import time from aiy.board import Board, Led print('LEDを点灯・消灯するサンプルです') with Board() as board: print('点灯します') board.led.state = Led.ON time.sleep(3) print('消灯します') board.led.state = Led.OFF time.sleep(3)
#!/usr/bin/env python3 import time from aiy.board import Board, Led print('LEDを点滅させるサンプルです') with Board() as board: board.led.state = Led.BLINK time.sleep(3)
#!/usr/bin/env python3 import time from aiy.board import Board, Led print('LEDの明るさを変更させるサンプルです') with Board() as board: print('まずは暗く') board.led.brightness = 0.1 board.led.state = Led.ON time.sleep(3) board.led.state = Led.OFF print('次は明るく') board.led.brightness = 1.0 board.led.state = Led.ON time.sleep(3)
#!/usr/bin/env python3 import time from aiy.board import Board, Led print('LEDを色んな感じで点滅させます') with Board() as board: print('BLINK_3') board.led.state = Led.BLINK_3 time.sleep(5) board.led.state = Led.OFF time.sleep(3) print('BEACON') board.led.state = Led.BEACON time.sleep(5) board.led.state = Led.OFF time.sleep(3) print('BEACON_DARK') board.led.state = Led.BEACON_DARK time.sleep(5) board.led.state = Led.OFF time.sleep(3) print('DECAY') board.led.state = Led.DECAY time.sleep(5) board.led.state = Led.OFF time.sleep(3) print('PULSE_SLOW') board.led.state = Led.PULSE_SLOW time.sleep(5) board.led.state = Led.OFF time.sleep(3) print('PULSE_QUICK') board.led.state = Led.PULSE_QUICK time.sleep(5)
↑BLINK_3〜DECAYは通常のBLINKと同じでした(?)。PULSE_SLOW/PULSE_QUICKはBLINKと違い、ボワーっと点滅します。
Voice Kit V2でのみ使用できるaiy.ledsライブラリです。
#!/usr/bin/env python3 import time from aiy.leds import Leds, Color print('LEDをカラフルに点灯させるサンプルです') COLORS = ( Color.BLACK, Color.BLUE, Color.CYAN, Color.GREEN, Color.PURPLE, Color.RED, Color.WHITE, Color.YELLOW, ) with Leds() as leds: for color in COLORS: for _ in range(2): leds.update(Leds.rgb_on(color)) time.sleep(1) leds.update(Leds.rgb_off()) time.sleep(1)
↑BLACKは黒とは言えない色でしたが・・・
#!/usr/bin/env python3 import time from aiy.leds import Leds, Color print('LEDを好きな色に点灯させるサンプルです') with Leds() as leds: # オレンジっぽい色 leds.update(Leds.rgb_on(Color.blend(Color.RED, Color.YELLOW, 0.9))) time.sleep(3)
#!/usr/bin/env python3 import time from aiy.leds import Leds, Color, Pattern print('LEDを好きなパターンで点滅させるサンプルです') with Leds() as leds: print('チカチカと点滅 blink500') leds.pattern = Pattern.blink(400) leds.update(Leds.rgb_pattern(Color.BLUE)) time.sleep(5) print('ブォーンブォーンと点滅 breathe500') leds.pattern = Pattern.breathe(800) leds.update(Leds.rgb_pattern(Color.RED)) time.sleep(5)
#!/usr/bin/env python3 from aiy.board import Board, Led print('ボタンの押しっ放しを検出するサンプルです(CTRL+Cで終了)') with Board() as board: while True: print('ボタンを押しっ放しにしてください...') board.button.wait_for_press() print('オン! 今度は離してみて!') board.led.state = Led.ON board.button.wait_for_release() print('オフ!') board.led.state = Led.OFF
#!/usr/bin/env python3 from aiy.board import Board, Led print('ボタンが押された時・離された時に処理を実行するサンプルです(CTRL+Cで終了)') def on_pressed(): print('押したよね!') def on_released(): print('離したよね!') with Board() as board: board.button.when_pressed = on_pressed board.button.when_released = on_released print('ボタンを押してみて...') while True: pass
aiy.voice.ttsというライブラリで、テキストを発話するAPIです(Text−To-Speech)。ただしこれ、まだ日本語には対応していません・・・。というわけでサンプルは英語です。
#!/usr/bin/env python3 import aiy.voice.tts print('Text−To-Speech(発話)のサンプルです(英語)') # 普通に aiy.voice.tts.say("Hello, I'm yoshiko.") # 気取って aiy.voice.tts.say("What have you got for me tonight?", lang='en-GB') # 大声で aiy.voice.tts.say("Put a sock in it!", volume=100) # 1オクターブ上 aiy.voice.tts.say("Lovely weather today.", pitch=200) # 早口で aiy.voice.tts.say("The quick brown fox jumped over the lazy dog.", speed=150)
基本的にはrecord_fileとplay_wavしているだけです。
#!/usr/bin/env python3 import time import threading from aiy.board import Board, Led from aiy.voice.audio import AudioFormat, play_wav, record_file with Board() as board: print('ボタンを押して録音開始') board.led.state = Led.ON board.button.wait_for_press() board.led.state = Led.OFF done = threading.Event() board.button.when_pressed = done.set def wait(): start = time.monotonic() while not done.is_set(): duration = time.monotonic() - start print('録音中: %.02f 秒 [ボタンを押してストップ]' % duration) time.sleep(0.5) record_file(AudioFormat.CD, filename='audio_record.wav', wait=wait, filetype='wav') print('ボタンを押して再生') board.led.state = Led.ON board.button.wait_for_press() board.led.state = Led.OFF print('再生中...') play_wav('audio_record.wav') print('終了')
↑ボタンを押して録音開始、もう一度押したら停止、さらにもう一回押して保存した音声を再生です。
GoogleのCloud Speechを利用します。SpeechToTextというAPIで、これは音声をテキストに変換するAPIです。使用するためには事前にGoogle Cloud PlatformでAPIを有効化し、認証キーファイル(JSON)をホームディレクトリに配置しておく必要があります。詳細な手順は以下の公式に従って下さい。
#!/usr/bin/env python3 import datetime from aiy.board import Board from aiy.cloudspeech import CloudSpeechClient print('Speech To Text(書き取り)のサンプルです("終了"と言うと終了します)') client = CloudSpeechClient() with Board() as board: while True: print('聴き取り中・・・') text = client.recognize(language_code='ja-JP', hint_phrases=('今何時', '今日の天気は', '終了')) if text is None: print('何かしゃべってよ') continue print('「{}」と言いましたね!'.format(text)) if '今何時' in text: now = datetime.datetime.now() print(now) if '今日の天気は' in text: print('たぶん晴れじゃないかなあ') elif '終了' in text: print('え?もう行っちゃうの・・・?') break
指定しておきたい定型文があれば、上記のようにhint_phrasesとして登録しておきます。こうしておくとCloudSpeechClient#recoginizeによる音声認識時に優先的にその語を検出してくれるようになります。要は発音が少しボケていてもちゃんと聴き取ってくれるようになるってイメージですね。あらかじめボイスコマンドを設定しておきたいときには便利なオプションだと思います。
いわゆるGoogle Homeのようなアシスタント機能を提供するAPIです。Assistant APIといいます。これも事前にAPIを有効化し、サービスアカウントキーを入手しておく必要があります。以下の公式の手順に従って下さい。
#!/usr/bin/env python3 from aiy.assistant.grpc import AssistantServiceClientWithLed from aiy.board import Board print('Google Homeもどきのサンプルです(CTRL+Cで終了)') with Board() as board: assistant = AssistantServiceClientWithLed(board=board, volume_percentage=50, language_code='ja-JP') while True: print('ボタンを押して会話を始めましょう') board.button.wait_for_press() print('スタート!') assistant.conversation()
まあこれだけあれば大体のことはできると思います。テキスト→発話の日本語ができないのは痛いですが、これに関しては別のライブラリで一応解決できますので、後日また書こうかな。
参考
Google AIY Voice Kit V2の基本操作サンプル集 Read More »