# VOICEVOX ENGINE [![build](https://github.com/VOICEVOX/voicevox_engine/actions/workflows/build.yml/badge.svg)](https://github.com/VOICEVOX/voicevox_engine/actions/workflows/build.yml) [![releases](https://img.shields.io/github/v/release/VOICEVOX/voicevox_engine)](https://github.com/VOICEVOX/voicevox_engine/releases) [![discord](https://img.shields.io/discord/879570910208733277?color=5865f2&label=&logo=discord&logoColor=ffffff)](https://discord.gg/WMwWetrzuh) [![test](https://github.com/VOICEVOX/voicevox_engine/actions/workflows/test.yml/badge.svg)](https://github.com/VOICEVOX/voicevox_engine/actions/workflows/test.yml) [![Coverage Status](https://coveralls.io/repos/github/VOICEVOX/voicevox_engine/badge.svg)](https://coveralls.io/github/VOICEVOX/voicevox_engine) [![build-docker](https://github.com/VOICEVOX/voicevox_engine/actions/workflows/build-docker.yml/badge.svg)](https://github.com/VOICEVOX/voicevox_engine/actions/workflows/build-docker.yml) [![docker](https://img.shields.io/docker/pulls/voicevox/voicevox_engine)](https://hub.docker.com/r/voicevox/voicevox_engine) [VOICEVOX](https://voicevox.hiroshiba.jp/) のエンジンです。 実態は HTTP サーバーなので、リクエストを送信すればテキスト音声合成できます。 (エディターは [VOICEVOX](https://github.com/VOICEVOX/voicevox/) 、 コアは [VOICEVOX CORE](https://github.com/VOICEVOX/voicevox_core/) 、 全体構成は [こちら](https://github.com/VOICEVOX/voicevox/blob/main/docs/%E5%85%A8%E4%BD%93%E6%A7%8B%E6%88%90.md) に詳細があります。) ## ダウンロード [こちら](https://github.com/VOICEVOX/voicevox_engine/releases/latest)から対応するエンジンをダウンロードしてください。 ## API ドキュメント [API ドキュメント](https://voicevox.github.io/voicevox_engine/api/)をご参照ください。 VOICEVOX エンジンもしくはエディタを起動した状態で http://127.0.0.1:50021/docs にアクセスすると、起動中のエンジンのドキュメントも確認できます。 今後の方針などについては [VOICEVOX 音声合成エンジンとの連携](./docs/VOICEVOX音声合成エンジンとの連携.md) も参考になるかもしれません。 リクエスト・レスポンスの文字コードはすべて UTF-8 です。 ### HTTP リクエストで音声合成するサンプルコード ```bash echo -n "こんにちは、音声合成の世界へようこそ" >text.txt curl -s \ -X POST \ "127.0.0.1:50021/audio_query?speaker=1"\ --get --data-urlencode text@text.txt \ > query.json curl -s \ -H "Content-Type: application/json" \ -X POST \ -d @query.json \ "127.0.0.1:50021/synthesis?speaker=1" \ > audio.wav ``` 生成される音声はサンプリングレートが 24000Hz と少し特殊なため、音声プレーヤーによっては再生できない場合があります。 `speaker` に指定する値は `/speakers` エンドポイントで得られる `style_id` です。互換性のために `speaker` という名前になっています。 ### 読み方を AquesTalk 記法で取得・修正するサンプルコード `/audio_query`のレスポンスにはエンジンが判断した読み方が AquesTalk ライクな記法([本家の記法](https://www.a-quest.com/archive/manual/siyo_onseikigou.pdf)とは一部異なります)で記録されています。 記法は次のルールに従います。 - 全てのカナはカタカナで記述される - アクセント句は`/`または`、`で区切る。`、`で区切った場合に限り無音区間が挿入される。 - カナの手前に`_`を入れるとそのカナは無声化される - アクセント位置を`'`で指定する。全てのアクセント句にはアクセント位置を 1 つ指定する必要がある。 - アクセント句末に`?`(全角)を入れることにより疑問文の発音ができる ```bash # 読ませたい文章をutf-8でtext.txtに書き出す echo -n "ディープラーニングは万能薬ではありません" >text.txt curl -s \ -X POST \ "127.0.0.1:50021/audio_query?speaker=1" \ --get --data-urlencode text@text.txt \ > query.json cat query.json | grep -o -E "\"kana\":\".*\"" # 結果... "kana":"ディ'イプ/ラ'アニングワ/バンノオヤクデワアリマセ'ン" # "ディイプラ'アニングワ/バンノ'オヤクデワ/アリマセ'ン"と読ませたいので、 # is_kana=trueをつけてイントネーションを取得しnewphrases.jsonに保存 echo -n "ディイプラ'アニングワ/バンノ'オヤクデワ/アリマセ'ン" > kana.txt curl -s \ -X POST \ "127.0.0.1:50021/accent_phrases?speaker=1&is_kana=true" \ --get --data-urlencode text@kana.txt \ > newphrases.json # query.jsonの"accent_phrases"の内容をnewphrases.jsonの内容に置き換える cat query.json | sed -e "s/\[{.*}\]/$(cat newphrases.json)/g" > newquery.json curl -s \ -H "Content-Type: application/json" \ -X POST \ -d @newquery.json \ "127.0.0.1:50021/synthesis?speaker=1" \ > audio.wav ``` ### ユーザー辞書機能について APIからユーザー辞書の参照、単語の追加、編集、削除を行うことができます。 #### 参照 `/user_dict`にGETリクエストを投げることでユーザー辞書の一覧を取得することができます。 ```bash curl -s -X GET "127.0.0.1:50021/user_dict" ``` #### 単語追加 `/user_dict_word`にPOSTリクエストを投げる事でユーザー辞書に単語を追加することができます。 URLパラメータとして、以下が必要です。 - surface (辞書に登録する単語) - pronunciation (カタカナでの読み方) - accent_type (アクセント核位置、整数) アクセント核位置については、こちらの文章が参考になるかと思います。 〇型となっている数字の部分がアクセント核位置になります。 https://tdmelodic.readthedocs.io/ja/latest/pages/introduction.html 成功した場合の返り値は単語に割り当てられるUUIDの文字列になります。 ```bash surface="test" pronunciation="テスト" accent_type="1" curl -s -X POST "127.0.0.1:50021/user_dict_word" \ --get \ --data-urlencode "surface=$surface" \ --data-urlencode "pronunciation=$pronunciation" \ --data-urlencode "accent_type=$accent_type" ``` #### 単語修正 `/user_dict_word/{word_uuid}`にPUTリクエストを投げる事でユーザー辞書の単語を修正することができます。 URLパラメータとして、以下が必要です。 - surface (辞書に登録するワード) - pronunciation (カタカナでの読み方) - accent_type (アクセント核位置、整数) word_uuidは単語追加時に確認できるほか、ユーザー辞書を参照することでも確認できます。 成功した場合の返り値は`204 No Content`になります。 ```bash surface="test2" pronunciation="テストツー" accent_type="2" # 環境によってword_uuidは適宜書き換えてください word_uuid="cce59b5f-86ab-42b9-bb75-9fd3407f1e2d" curl -s -X PUT "127.0.0.1:50021/user_dict_word/$word_uuid" \ --get \ --data-urlencode "surface=$surface" \ --data-urlencode "pronunciation=$pronunciation" \ --data-urlencode "accent_type=$accent_type" ``` #### 単語削除 `/user_dict_word/{word_uuid}`にDELETEリクエストを投げる事でユーザー辞書の単語を削除することができます。 word_uuidは単語追加時に確認できるほか、ユーザー辞書を参照することでも確認できます。 成功した場合の返り値は`204 No Content`になります。 ```bash # 環境によってword_uuidは適宜書き換えてください word_uuid="cce59b5f-86ab-42b9-bb75-9fd3407f1e2d" curl -s -X DELETE "127.0.0.1:50021/user_dict_word/$word_uuid" ``` ### プリセット機能について `presets.yaml`を編集することで話者や話速などのプリセットを使うことができます。 ```bash echo -n "プリセットをうまく活用すれば、サードパーティ間で同じ設定を使うことができます" >text.txt # プリセット情報を取得 curl -s -X GET "127.0.0.1:50021/presets" > presets.json preset_id=$(cat presets.json | sed -r 's/^.+"id"\:\s?([0-9]+?).+$/\1/g') style_id=$(cat presets.json | sed -r 's/^.+"style_id"\:\s?([0-9]+?).+$/\1/g') # AudioQueryの取得 curl -s \ -X POST \ "127.0.0.1:50021/audio_query_from_preset?preset_id=$preset_id"\ --get --data-urlencode text@text.txt \ > query.json # 音声合成 curl -s \ -H "Content-Type: application/json" \ -X POST \ -d @query.json \ "127.0.0.1:50021/synthesis?speaker=$style_id" \ > audio.wav ``` - `speaker_uuid`は、`/speakers`で確認できます - `id`は重複してはいけません - エンジン起動後にファイルを書き換えるとエンジンに反映されます ### 2 人の話者でモーフィングするサンプルコード `/synthesis_morphing`では、2 人の話者でそれぞれ合成された音声を元に、モーフィングした音声を生成します。 ```bash echo -n "モーフィングを利用することで、2つの声を混ぜることができます。" > text.txt curl -s \ -X POST \ "127.0.0.1:50021/audio_query?speaker=0"\ --get --data-urlencode text@text.txt \ > query.json # 元の話者での合成結果 curl -s \ -H "Content-Type: application/json" \ -X POST \ -d @query.json \ "127.0.0.1:50021/synthesis?speaker=0" \ > audio.wav export MORPH_RATE=0.5 # 話者2人分の音声合成+WORLDによる音声分析が入るため時間が掛かるので注意 curl -s \ -H "Content-Type: application/json" \ -X POST \ -d @query.json \ "127.0.0.1:50021/synthesis_morphing?base_speaker=0&target_speaker=1&morph_rate=$MORPH_RATE" \ > audio.wav export MORPH_RATE=0.9 # query、base_speaker、target_speakerが同じ場合はキャッシュが使用されるため比較的高速に生成される curl -s \ -H "Content-Type: application/json" \ -X POST \ -d @query.json \ "127.0.0.1:50021/synthesis_morphing?base_speaker=0&target_speaker=1&morph_rate=$MORPH_RATE" \ > audio.wav ``` ### 話者の追加情報を取得するサンプルコード 追加情報の中の portrait.png を取得するコードです。 ([jq](https://stedolan.github.io/jq/)を使用して json をパースしています。) ```bash curl -s -X GET "127.0.0.1:50021/speaker_info?speaker_uuid=7ffcb7ce-00ec-4bdc-82cd-45a8889e43ff" \ | jq -r ".portrait" \ | base64 -d \ > portrait.png ``` ### キャンセル可能な音声合成 `/cancellable_synthesis`では通信を切断した場合に即座に計算リソースが開放されます。 (`/synthesis`では通信を切断しても最後まで音声合成の計算が行われます) この API は実験的機能であり、エンジン起動時に引数で`--enable_cancellable_synthesis`を指定しないと有効化されません。 音声合成に必要なパラメータは`/synthesis`と同様です。 ### CORS設定 VOICEVOXではセキュリティ保護のため`localhost`・`127.0.0.1`・`app://`・Originなし以外のOriginからリクエストを受け入れないようになっています。 そのため、一部のサードパーティアプリからのレスポンスを受け取れない可能性があります。 これを回避する方法として、エンジンから設定できるUIを用意しています。 #### 設定方法 1. にアクセスします。 2. 利用するアプリに合わせて設定を変更、追加してください。 3. 保存ボタンを押して、変更を確定してください。 4. 設定の適用にはエンジンの再起動が必要です。必要に応じて再起動をしてください。 ## アップデート エンジンディレクトリ内にあるファイルを全て消去し、新しいものに置き換えてください。 ## Docker イメージ ### CPU ```bash docker pull voicevox/voicevox_engine:cpu-ubuntu20.04-latest docker run --rm -p '127.0.0.1:50021:50021' voicevox/voicevox_engine:cpu-ubuntu20.04-latest ``` ### GPU ```bash docker pull voicevox/voicevox_engine:nvidia-ubuntu20.04-latest docker run --rm --gpus all -p '127.0.0.1:50021:50021' voicevox/voicevox_engine:nvidia-ubuntu20.04-latest ``` #### トラブルシューティング GPU版を利用する場合、環境によってエラーが発生することがあります。その場合、`--runtime=nvidia`を`docker run`につけて実行すると解決できることがあります。 ## 貢献者の方へ Issue を解決するプルリクエストを作成される際は、別の方と同じ Issue に取り組むことを避けるため、 Issue 側で取り組み始めたことを伝えるか、最初に Draft プルリクエストを作成してください。 [VOICEVOX 非公式 Discord サーバー](https://discord.gg/WMwWetrzuh)にて、開発の議論や雑談を行っています。気軽にご参加ください。 ## 環境構築 `Python 3.11.3` を用いて開発されています。 インストールするには、各 OS ごとの C/C++ コンパイラ、CMake が必要になります。 ```bash # 開発に必要なライブラリのインストール python -m pip install -r requirements-dev.txt -r requirements-test.txt # とりあえず実行したいだけなら代わりにこちら python -m pip install -r requirements.txt ``` ## 実行 コマンドライン引数の詳細は以下のコマンドで確認してください。 ```bash python run.py --help ``` ```bash # 製品版 VOICEVOX でサーバーを起動 VOICEVOX_DIR="C:/path/to/voicevox" # 製品版 VOICEVOX ディレクトリのパス python run.py --voicevox_dir=$VOICEVOX_DIR ``` ```bash # モックでサーバー起動 python run.py --enable_mock ``` ```bash # ログをUTF8に変更 python run.py --output_log_utf8 # もしくは VV_OUTPUT_LOG_UTF8=1 python run.py ``` ### CPU スレッド数を指定する CPU スレッド数が未指定の場合は、論理コア数の半分か物理コア数が使われます。(殆どの CPU で、これは全体の処理能力の半分です) もし IaaS 上で実行していたり、専用サーバーで実行している場合など、 エンジンが使う処理能力を調節したい場合は、CPU スレッド数を指定することで実現できます。 - 実行時引数で指定する ```bash python run.py --voicevox_dir=$VOICEVOX_DIR --cpu_num_threads=4 ``` - 環境変数で指定する ```bash export VV_CPU_NUM_THREADS=4 python run.py --voicevox_dir=$VOICEVOX_DIR ``` ### 過去のバージョンのコアを使う VOICEVOX Core 0.5.4以降のコアを使用する事が可能です。 Macでのlibtorch版コアのサポートはしていません。 #### 過去のバイナリを指定する 製品版VOICEVOXもしくはコンパイル済みエンジンのディレクトリを`--voicevox_dir`引数で指定すると、そのバージョンのコアが使用されます。 ```bash python run.py --voicevox_dir="/path/to/voicevox" ``` Macでは、`DYLD_LIBRARY_PATH`の指定が必要です。 ```bash DYLD_LIBRARY_PATH="/path/to/voicevox" python run.py --voicevox_dir="/path/to/voicevox" ``` #### 音声ライブラリを直接指定する [VOICEVOX Coreのzipファイル](https://github.com/VOICEVOX/voicevox_core/releases)を解凍したディレクトリを`--voicelib_dir`引数で指定します。 また、コアのバージョンに合わせて、[libtorch](https://pytorch.org/)や[onnxruntime](https://github.com/microsoft/onnxruntime)のディレクトリを`--runtime_dir`引数で指定します。 ただし、システムの探索パス上にlibtorch、onnxruntimeがある場合、`--runtime_dir`引数の指定は不要です。 `--voicelib_dir`引数、`--runtime_dir`引数は複数回使用可能です。 APIエンドポイントでコアのバージョンを指定する場合は`core_version`引数を指定してください。(未指定の場合は最新のコアが使用されます) ```bash python run.py --voicelib_dir="/path/to/voicevox_core" --runtime_dir="/path/to/libtorch_or_onnx" ``` Macでは、`--runtime_dir`引数の代わりに`DYLD_LIBRARY_PATH`の指定が必要です。 ```bash DYLD_LIBRARY_PATH="/path/to/onnx" python run.py --voicelib_dir="/path/to/voicevox_core" ``` ## コードフォーマット このソフトウェアでは、リモートにプッシュする前にコードフォーマットを確認する仕組み(静的解析ツール)を利用できます。 利用するには、開発に必要なライブラリのインストールに加えて、以下のコマンドを実行してください。 プルリクエストを作成する際は、利用することを推奨します。 ```bash pre-commit install -t pre-push ``` エラーが出た際は、以下のコマンドで修正することが可能です。なお、完全に修正できるわけではないので注意してください。 ```bash pysen run format lint ``` ## タイポチェック [typos](https://github.com/crate-ci/typos) を使ってタイポのチェックを行っています。 [typos をインストール](https://github.com/crate-ci/typos#install) した後 ```bash typos ``` でタイポチェックを行えます。 もし誤判定やチェックから除外すべきファイルがあれば [設定ファイルの説明](https://github.com/crate-ci/typos#false-positives) に従って`_typos.toml`を編集してください。 ## API ドキュメントの確認 [API ドキュメント](https://voicevox.github.io/voicevox_engine/api/)(実体は`docs/api/index.html`)は自動で更新されます。 次のコマンドで API ドキュメントを手動で作成することができます。 ```bash python make_docs.py ``` ## ビルド この方法でビルドしたものは、リリースで公開されているものとは異なります。 また、GPUで利用するにはcuDNNやCUDA、DirectMLなどのライブラリが追加で必要となります。 ```bash python -m pip install -r requirements-dev.txt OUTPUT_LICENSE_JSON_PATH=licenses.json \ bash build_util/create_venv_and_generate_licenses.bash # ビルド自体はLIBCORE_PATH及びLIBONNXRUNTIME_PATHの指定がなくても可能です LIBCORE_PATH="/path/to/libcore" \ LIBONNXRUNTIME_PATH="/path/to/libonnxruntime" \ pyinstaller --noconfirm run.spec ``` ## 依存関係 ### 更新 [Poetry](https://python-poetry.org/) を用いて依存ライブラリのバージョンを固定しています。 以下のコマンドで操作できます: ```bash # パッケージを追加する場合 poetry add `パッケージ名` poetry add --group dev `パッケージ名` # 開発依存の追加 poetry add --group test `パッケージ名` # テスト依存の追加 # パッケージをアップデートする場合 poetry update `パッケージ名` poetry update # 全部更新 # requirements.txtの更新 poetry export --without-hashes -o requirements.txt # こちらを更新する場合は下3つも更新する必要があります。 poetry export --without-hashes --with dev -o requirements-dev.txt poetry export --without-hashes --with test -o requirements-test.txt poetry export --without-hashes --with license -o requirements-license.txt ``` ### ライセンス 依存ライブラリは「コアビルド時にリンクして一体化しても、コア部のコード非公開 OK」なライセンスを持つ必要があります。 主要ライセンスの可否は以下の通りです。 - MIT/Apache/BSD-3: OK - LGPL: OK (コアと動的分離されているため) - GPL: NG (全関連コードの公開が必要なため) ## ユーザー辞書の更新について 以下のコマンドで openjtalk のユーザー辞書をコンパイルできます。 ```bash python -c "import pyopenjtalk; pyopenjtalk.create_user_dict('default.csv','user.dic')" ``` ## マルチエンジン機能に関して VOICEVOX エディターでは、複数のエンジンを同時に起動することができます。 この機能を利用することで、自作の音声合成エンジンや既存の音声合成エンジンを VOICEVOX エディター上で動かすことが可能です。
### マルチエンジン機能の仕組み VOICEVOX API に準拠した複数のエンジンの Web API をポートを分けて起動し、統一的に扱うことでマルチエンジン機能を実現しています。 エディターがそれぞれのエンジンを実行バイナリ経由で起動し、EngineID と結びつけて設定や状態を個別管理します。 ### マルチエンジン機能への対応方法 VOICEVOX API 準拠エンジンを起動する実行バイナリを作ることで対応が可能です。 VOICEVOX ENGINE リポジトリを fork し、一部の機能を改造するのが簡単です。 改造すべき点はエンジン情報・キャラクター情報・音声合成の3点です。 エンジンの情報はエンジンマニフェスト(`engine_manifest.json`)で管理されています。 マニフェストファイル内の情報を見て適宜変更してください。 音声合成手法によっては、例えばモーフィング機能など、VOICEVOX と同じ機能を持つことができない場合があります。 その場合はマニフェストファイル内の`supported_features`内の情報を適宜変更してください。 キャラクター情報は`speaker_info`ディレクトリ内のファイルで管理されています。 ダミーのアイコンなどが用意されているので適宜変更してください。 音声合成は`voicevox_engine/synthesis_engine/synthesis_engine.py`で行われています。 VOICEVOX API での音声合成は、エンジン側で音声合成クエリ`AudioQuery`の初期値を作成してユーザーに返し、ユーザーが必要に応じてクエリを編集したあと、エンジンがクエリに従って音声合成することで実現しています。 クエリ作成は`/audio_query`エンドポイントで、音声合成は`/synthesis`エンドポイントで行っており、最低この2つに対応すれば VOICEVOX API に準拠したことになります。 ### マルチエンジン機能対応エンジンの配布方法 VVPP ファイルとして配布するのがおすすめです。 VVPP は「VOICEVOX プラグインパッケージ」の略で、中身はビルドしたエンジンなどを含んだディレクトリの Zip ファイルです。 拡張子を`.vvpp`にすると、ダブルクリックで VOICEVOX エディターにインストールできます。 エディター側は受け取った VVPP ファイルをローカルディスク上に Zip 展開したあと、ルートの直下にある`engine_manifest.json`に従ってファイルを探査します。 VOICEVOX エディターにうまく読み込ませられないときは、エディターのエラーログを参照してください。 また、`xxx.vvpp`は分割して連番を付けた`xxx.0.vvppp`ファイルとして配布することも可能です。 これはファイル容量が大きくて配布が困難な場合に有用です。
## GitHub Actions ### Variables | name | description | | :----------------- | :---------------------------------------------------------------------- | | DOCKERHUB_USERNAME | Docker Hub ユーザ名 | ### Secrets | name | description | | :----------------- | :---------------------------------------------------------------------- | | DOCKERHUB_TOKEN | [Docker Hub アクセストークン](https://hub.docker.com/settings/security) | ## 事例紹介 **[voicevox-client](https://github.com/tuna2134/voicevox-client) [@tuna2134](https://github.com/tuna2134)** ・・・ VOICEVOX ENGINE のためのPythonラッパー ## ライセンス LGPL v3 と、ソースコードの公開が不要な別ライセンスのデュアルライセンスです。 別ライセンスを取得したい場合は、ヒホ(twitter: @hiho_karuta)に求めてください。