インストールはdockerhubの通り。
voicevox/voicevox_engine - Docker Image
このページは、Raspberry Pi 5(以下 Pi5)の Docker で VOICEVOX ENGINE を動かし、テキストを音声(WAV)に変換するまでの記録だ。VOICEVOX ENGINE は VOICEVOX の中核となる音声合成エンジンで、ずんだもん・四国めたんなどの話者を HTTP API 経由で呼び出せる。GUI を入れず、サーバとして常駐させて使う形を想定している。
このページで分かること
前提は Raspberry Pi 5(4コアの Cortex-A76・arm64)+ Raspberry Pi OS 64bit + Docker だ。イメージは arm64 を含む multi-arch なので、Pi5 側で --platform を指定する必要はない。
CPU版:
上のタグは「cpu=CPU推論」「ubuntu20.04=ベース OS」の組み合わせを表す。ただし 20.04 のタグはすでに配布が止まっており、現行は cpu-ubuntu22.04-latest / cpu-ubuntu24.04-latest / cpu-latest の3系統だ。CPU版は GPU が無くても動くので、Pi5 ではこれ一択になる。初回の pull はイメージが大きいため時間と空き容量を見込んでおく。
docker pull voicevox/voicevox_engine:cpu-ubuntu20.04-latest
docker run --rm -it -p '127.0.0.1:50021:50021' voicevox/voicevox_engine:cpu-ubuntu20.04-latest
GPU版:(macは使えないらしい)
GPU版は nvidia 系のタグ(nvidia-ubuntu22.04-latest など)と NVIDIA Container Toolkit が必要で、そもそも Pi5 の GPU(VideoCore VII)は CUDA 非対応なので選ぶ余地は無い。nvidia 系タグは amd64 しか用意されていないため、Apple Silicon の Mac でも動かない。なお下のブロックはコマンドが cpu タグのままコピーされている(GPU版として使うならタグを nvidia 系に読み替える必要がある)。
docker pull voicevox/voicevox_engine:cpu-ubuntu20.04-latest
docker run --rm -it -p '127.0.0.1:50021:50021' voicevox/voicevox_engine:cpu-ubuntu20.04-latest
voicevoxの起動オプションはlocalhostからのアクセスしか許可されていないため、外部のPCからAPIをたたく場合は以下のオプションで起動。
':50021:50021' は「ホスト側の全インターフェース(0.0.0.0)の 50021 番に公開する」という意味で、これを書くと LAN 内の他端末からも叩ける。逆に 127.0.0.1:50021:50021 なら、そのホスト自身からしか届かない。VOICEVOX ENGINE には認証が無いので、LAN に開ける場合もルータのポート開放まではせず、外から使いたいときは Tailscale などの VPN 経由に限るのが無難だ。
docker run --rm -it -p ':50021:50021' voicevox/voicevox_engine:cpu-ubuntu20.04-latest
さらにデーモン起動させたい場合は以下のオプションで起動。
-d はバックグラウンド起動(デタッチ)の指定だ。--name voicevox を付けておくと docker logs voicevox / docker stop voicevox で扱いやすくなる。--rm 付きだと停止のたびにコンテナが消えるため、再起動後も自動で立ち上げたい場合は --restart unless-stopped を併用する。
docker run --rm -it -d -p ':50021:50021' voicevox/voicevox_engine:cpu-ubuntu20.04-latest
コア数指定
VV_CPU_NUM_THREADS は音声合成に使うスレッド数を指定する環境変数だ。Pi5 は4コアなので 4 が上限の目安になる。未指定でも実用上は大きく変わらないが、下の実測では 4 指定のほうがわずかに速い。他のプロセスと同居させるなら 2〜3 に落としておくと、応答時間が安定しやすい。
docker run --rm -it -d -e VV_CPU_NUM_THREADS=4 -p ':50021:50021' voicevox/voicevox_engine:cpu-ubuntu20.04-latest
from pathlib import Path
from voicevox_core import VoicevoxCore, METAS
import sys, os
core = VoicevoxCore(open_jtalk_dict_dir=Path("./open_jtalk_dic_utf_8-1.11"))
speaker_id = 1 # 1:ずんだもん,2:四国めたん
text = sys.argv[1]
if not core.is_model_loaded(speaker_id):
core.load_model(speaker_id)
wave_bytes = core.tts(text, speaker_id)
with open("./" + text + ".wav", "wb") as f:
f.write(wave_bytes)
$ sudo apt install python3-pyaudio
この警告は VOICEVOX ENGINE 本体ではなく、クライアント側の PyAudio が ALSA の仮想デバイス(surround40 や iec958 など)を片っ端から列挙して失敗しているだけのものだ。音は出るので放置しても実害は無い。うるさい場合は下の error_hider.py のように snd_lib_error_set_handler で握りつぶせる。なお VOICEVOX ENGINE は合成した WAV を HTTP で返すだけで、コンテナの中で音を鳴らすわけではない。docker run に --device /dev/snd を渡す必要は無く、鳴らすのは Pi5 側の aplay などの再生コマンドの役目だ。
ALSA lib pcm_asym.c:105:(_snd_pcm_asym_open) capture slave is not defined
ALSA lib pcm.c:2666:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.front
ALSA lib pcm.c:2666:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.rear
ALSA lib pcm.c:2666:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.center_lfe
ALSA lib pcm.c:2666:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.side
ALSA lib pcm.c:2666:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround21
ALSA lib pcm.c:2666:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround21
ALSA lib pcm.c:2666:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround40
ALSA lib pcm.c:2666:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround41
ALSA lib pcm.c:2666:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround50
ALSA lib pcm.c:2666:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround51
ALSA lib pcm.c:2666:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround71
ALSA lib pcm.c:2666:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.iec958
ALSA lib pcm.c:2666:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.iec958
ALSA lib pcm.c:2666:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.iec958
ALSA lib pcm.c:2666:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.modem
ALSA lib pcm.c:2666:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.modem
ALSA lib pcm.c:2666:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.phoneline
ALSA lib pcm.c:2666:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.phoneline
ALSA lib pcm_oss.c:397:(_snd_pcm_oss_open) Cannot open device /dev/dsp
ALSA lib pcm_oss.c:397:(_snd_pcm_oss_open) Cannot open device /dev/dsp
ALSA lib pcm_a52.c:1001:(_snd_pcm_a52_open) a52 is only for playback
ALSA lib conf.c:5670:(snd_config_expand) Unknown parameters {AES0 0x6 AES1 0x82 AES2 0x0 AES3 0x2 CARD 0}
ALSA lib pcm.c:2666:(snd_pcm_open_noupdate) Unknown PCM iec958:{AES0 0x6 AES1 0x82 AES2 0x0 AES3 0x2 CARD 0}
ALSA lib confmisc.c:160:(snd_config_get_card) Invalid field card
ALSA lib pcm_usb_stream.c:482:(_snd_pcm_usb_stream_open) Invalid card 'card'
ALSA lib confmisc.c:160:(snd_config_get_card) Invalid field card
ALSA lib pcm_usb_stream.c:482:(_snd_pcm_usb_stream_open) Invalid card 'card'
ALSA lib pcm_dmix.c:999:(snd_pcm_dmix_open) unable to open slave
from ctypes import *
from contextlib import contextmanager
import pyaudio
ERROR_HANDLER_FUNC = CFUNCTYPE(None, c_char_p, c_int, c_char_p, c_int, c_char_p)
def py_error_handler(filename, line, function, err, fmt):
pass
c_error_handler = ERROR_HANDLER_FUNC(py_error_handler)
@contextmanager
def noalsaerr():
asound = cdll.LoadLibrary('libasound.so')
asound.snd_lib_error_set_handler(c_error_handler)
yield
asound.snd_lib_error_set_handler(None)
実行ファイル
from error_hider import noalsaerr
with noalsaerr():
pya = pyaudio.PyAudio()
jackd は PyAudio が JACK の有無を探しに行ったときに出す警告で、VOICEVOX ENGINE の動作そのものには関係しない。ダミードライバで起動しておけば警告が消えるだけで、音質や速度が変わるわけではない。常駐させたくないなら、ALSA のときと同じようにクライアント側で無視して構わない。
Cannot connect to server socket err = No such file or directory
Cannot connect to server socket
jack server is not running or cannot be started
$ sudo apt-get install jackd
$ jackd -d dummy &
上のログは、下のベンチマークで使った挨拶文(ずんだもんの自己紹介)を1回合成したときの出力だ。初回はモデルのロードが入るため大きい値になり、2回目以降は小さな値(クエリ生成)と約5秒の値(音声合成)が出ている。Pi5 の CPU 合成では1文あたり5秒前後かかる計算になるので、読み上げを連続で流す用途では文単位で事前に WAV へ書き出してキャッシュしておくほうが扱いやすい。長文を1リクエストにまとめるより、文で分割したほうが体感も改善しやすい。
Pi5 @ "こんにちは。私の名前はずんだもんです。"
default
pi@raspberrypi:~/voicevox $ docker run --rm -it -d -p ':50021:50021' voicevox/voicevox_engine:cpu-ubuntu20.04-latest
092ab3026bb93af683993cad71b47f5940cc26cc9b43a2043a387b36d129abf6
pi@raspberrypi:~/voicevox $ python voicevox.py
2.998706579208374
5.025799989700317
pi@raspberrypi:~/voicevox $ python voicevox.py
0.01204371452331543
5.007786989212036
pi@raspberrypi:~/voicevox $ python voicevox.py
0.011434555053710938
5.120377779006958
pi@raspberrypi:~/voicevox $ python voicevox.py
0.012158870697021484
5.118967294692993
pi@raspberrypi:~/voicevox $ python voicevox.py
0.015264272689819336
5.120145559310913
pi@raspberrypi:~/voicevox $ python voicevox.py
0.011675834655761719
5.1370744705200195
pi@raspberrypi:~/voicevox $ python voicevox.py
0.012323379516601562
5.090348482131958
pi@raspberrypi:~/voicevox $
VV_CPU_NUM_THREADS=4
pi@raspberrypi:~/voicevox $ docker run --rm -it -d -e VV_CPU_NUM_THREADS=4 -p ':50021:50021' voicevox/voicevox_engine:cpu-ubuntu20.04-latest
fa68f6c2a2a3bc73651abd69fb5c7fd51607574d4aec785f27dfaf2926ed81a2
pi@raspberrypi:~/voicevox $ python voicevox.py
3.3186028003692627
5.07768177986145
pi@raspberrypi:~/voicevox $ python voicevox.py
0.012700080871582031
4.997256278991699
pi@raspberrypi:~/voicevox $ python voicevox.py
0.012072563171386719
4.874383449554443
pi@raspberrypi:~/voicevox $ python voicevox.py
0.011792421340942383
4.764307260513306
pi@raspberrypi:~/voicevox $ python voicevox.py
0.011406183242797852
4.962157964706421
pi@raspberrypi:~/voicevox $ python voicevox.py
0.012336492538452148
4.7112250328063965
Raspberry Pi OS Bookworm 以降の Python は PEP 668 の管理下にあり、素の pip install が弾かれる。下の pip.conf はその制限を無効化する設定で、システム全体の Python に手を入れる点は留意しておく。影響を避けたいなら venv を作ってその中に入れるのが無難だ。
ラズパイでpipで入れると環境壊すぞ的なエラーが出た場合は
mkdir ~/.pip
nano ~/.pip/pip.conf
[global]
break-system-packages = true
pip install simpleaudio
VOICEVOX ENGINE は起動すると 50021 番で待ち受ける HTTP サーバになる。よく使うのは次の3つだ。
curl -s http://127.0.0.1:50021/speakers | jq .
curl -s -X POST 'http://127.0.0.1:50021/audio_query?text=こんにちは&speaker=1' > q.json
curl -s -X POST -H 'Content-Type: application/json' -d @q.json \
'http://127.0.0.1:50021/synthesis?speaker=1' -o hello.wav
aplay hello.wav # 再生は Pi5 側で行う
speaker は styleId で、1 がずんだもん(ノーマル)、2 が四国めたん(ノーマル)にあたる。バージョンによって話者は増減するので、正確な番号は /speakers の応答で確認する。長い文章は /audio_query にクエリ文字列で渡すとURLが長くなりすぎるため、文単位に分割して投げるほうが安全だ。
Q. Pi5 のメモリは何GBあれば足りる?
A. VOICEVOX ENGINE は使う話者のモデルを読み込む分だけメモリを食う。4GB でも起動はできるが、Docker と Raspberry Pi OS の常駐分を考えると 8GB モデルのほうが余裕がある。話者を増やすほど消費が増える点は覚えておく。
Q. コンテナに /dev/snd を渡す必要はある?
A. 不要だ。VOICEVOX ENGINE は WAV を HTTP で返すだけで、再生はクライアント側の仕事になる。ALSA や jack の警告は Pi5 上で動かしている PyAudio 側の話で、コンテナの中身とは別の話だ。
Q. CPU版とGPU版、Pi5 ではどちらを選ぶ?
A. CPU版一択になる。GPU版は NVIDIA の CUDA が前提で、イメージも nvidia 系タグの amd64 しか用意されていない。Pi5 の GPU では動かない。
Q. 50021 番を LAN に開けても大丈夫?
A. 認証が無いので、同じネットワークの誰からでも音声合成を叩ける状態になる。外部公開は避け、必要なときだけ VPN(Tailscale など)経由にするのが無難だ。
※ 本ページのAmazonリンクにはアフィリエイトタグ(toobf6-22)が付いている。
🤖 このページにはAIエージェント(ノア)による編集・加筆が含まれます。内容の正確性は保証できないため、重要な判断は一次情報でご確認ください。