PythonからVOICEVOX Coreを使ってみる

[2025/03/29]
v0.14の情報からv0.16の情報に更新しました。
v0.14の情報を確認したい場合は、この記事の編集履歴をご確認ください。

---

VOICEVOX Core v0.16がリリースされました🎉
このリリースから、コアが色々変わったので、この記事で紹介したいと思います。


:::note warn
この記事はバージョン0.16.0時点の情報です。
バージョンアップに伴い、セットアップ方法や関数等に変更が入る可能性があります。
最新の情報はGithubをご確認ください。
:::

## 事前準備

### ダウンローダのセットアップ

VOICEVOX Coreの実行に必要なファイルをダウンロードしてくれるダウンローダが用意されています。
リリースのページから、OS/アーキテクチャに合った`download-*`ファイルをダウンロードします。

https://github.com/VOICEVOX/voicevox_core/releases

今回は、`download-windows-x64.exe`をダウンロードし、作業用フォルダに配置しました。
分かりやすいように、`download.exe`にリネームしておきます。

### ダウンローダの実行

コマンドプロンプト/シェルを開き、ダウンローダを実行します。
macOSやLinuxの場合は、事前に実行権限を付与（`chmod +x download`）してください。
（macOSやLinuxの方は、`download.exe`を`./download`に読み替えてください。）


```
# CPU版を利用する場合
download.exe -o . --exclude c-api

# DirectML版を利用する場合
download.exe -o . --exclude c-api --devices directml

# CUDA版を利用する場合
download.exe -o . --exclude c-api --devices cuda
```

今回はCPU版をダウンロードしました。
`dict`、`models`、`onnxruntime`フォルダが作成され、その下に必要なファイルがダウンロードされています。

### Pythonライブラリのインストール

（必要に応じて、`venv`で仮想環境をセットアップしてください）
pip等を使って、Pythonライブラリをインストールします。
whlファイルのURLはreleaseを確認してください。

https://github.com/VOICEVOX/voicevox_core/releases

```
pip install https://github.com/VOICEVOX/voicevox_core/releases/download/[バージョン]/voicevox_core-[バージョン]+[デバイス]-cp310-abi3-[OS・アーキテクチャ].whl
```

今回は、`voicevox_core-0.16.0-cp310-abi3-win_amd64.whl`をインストールしました。

---

:::note
`asyncio`等、非同期で実行する場合は、[実行（非同期版API）](#実行非同期版api)まで飛んでください。
:::

## 実行（ブロッキング版API）

https://voicevox.github.io/voicevox_core/apis/python_api/autoapi/voicevox_core/blocking/index.html

### 初期化

ダウンロードしたファイルを移動している場合は、それに合わせて`voicevox_onnxruntime_path`と`open_jtalk_dict_dir`を変更してください。

```python
from voicevox_core.blocking import Onnxruntime, OpenJtalk, Synthesizer, VoiceModelFile

voicevox_onnxruntime_path = "onnxruntime/lib/" + Onnxruntime.LIB_VERSIONED_FILENAME
open_jtalk_dict_dir = "dict/open_jtalk_dic_utf_8-1.11"
synthesizer = Synthesizer(Onnxruntime.load_once(filename=voicevox_onnxruntime_path), OpenJtalk(open_jtalk_dict_dir))
```

### VVMファイルの読み込み

[音声モデル(.vvm)ファイルと声（キャラクター・スタイル名）とスタイル ID の対応表](https://github.com/VOICEVOX/voicevox_vvm/blob/main/README.md#%E9%9F%B3%E5%A3%B0%E3%83%A2%E3%83%87%E3%83%ABvvm%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%A8%E5%A3%B0%E3%82%AD%E3%83%A3%E3%83%A9%E3%82%AF%E3%82%BF%E3%83%BC%E3%82%B9%E3%82%BF%E3%82%A4%E3%83%AB%E5%90%8D%E3%81%A8%E3%82%B9%E3%82%BF%E3%82%A4%E3%83%AB-id-%E3%81%AE%E5%AF%BE%E5%BF%9C%E8%A1%A8)を確認し、必要なVVMファイルを読み込みます。
今回は、ずんだもん（ノーマル）（スタイルID: 5）を使用するので、`0.vvm`を読み込みます。
ダウンロードしたファイルを移動している場合は、それに合わせて`VoiceModelFile.open`の引数を書き換えてください。

```python
with VoiceModelFile.open("models/vvms/0.vvm") as model:
    synthesizer.load_voice_model(model)
```

先ほど確認した、スタイルIDを変数として定義しておきます。
（昔のバージョンのspeaker_idと同じものです）

```python
style_id = 5
```

### 音声合成

```python
text = "こんにちは、これはテストです。"
wav = synthesizer.tts(text, style_id)

# wavをファイルに書き出す
with open("output.wav", "wb") as f:
    f.write(wav)
```

### AquesTalk風記法での音声合成

記法に関しては、Engineの方のREADMEに詳しく書いてあります。

https://github.com/VOICEVOX/voicevox_engine/blob/master/README.md#aquestalk-%E9%A2%A8%E8%A8%98%E6%B3%95

```python
text = "コ'ンニチワ、コレワ'/テ'_ストデ_ス"
wav = synthesizer.tts_from_kana(text, style_id)

# wavをファイルに書き出す
with open("output_2.wav", "wb") as f:
    f.write(wav)
```

デフォルトの音声合成結果と違い、こんにちは、の「こ」の位置にアクセントが来ていることが分かるかと思います。

## 実行（非同期版API）

`asyncio`等を用いて実行する場合は、こちらのAPIを使うといいです。

https://voicevox.github.io/voicevox_core/apis/python_api/autoapi/voicevox_core/asyncio/index.html

### 初期化

ダウンロードしたファイルを移動している場合は、それに合わせて`voicevox_onnxruntime_path`と`open_jtalk_dict_dir`を変更してください。

```python
import asyncio
from voicevox_core.asyncio import Onnxruntime, OpenJtalk, Synthesizer, VoiceModelFile

async def create_synthesizer():
    voicevox_onnxruntime_path = "onnxruntime/lib/" + Onnxruntime.LIB_VERSIONED_FILENAME
    open_jtalk_dict_dir = "dict/open_jtalk_dic_utf_8-1.11"

    ort = await Onnxruntime.load_once(filename=voicevox_onnxruntime_path)
    ojt = await OpenJtalk.new(open_jtalk_dict_dir)

    return Synthesizer(ort, ojt)

synthesizer = asyncio.run(create_synthesizer())
```

### VVMファイルの読み込み

[音声モデル(.vvm)ファイルと声（キャラクター・スタイル名）とスタイル ID の対応表](https://github.com/VOICEVOX/voicevox_vvm/blob/main/README.md#%E9%9F%B3%E5%A3%B0%E3%83%A2%E3%83%87%E3%83%ABvvm%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%A8%E5%A3%B0%E3%82%AD%E3%83%A3%E3%83%A9%E3%82%AF%E3%82%BF%E3%83%BC%E3%82%B9%E3%82%BF%E3%82%A4%E3%83%AB%E5%90%8D%E3%81%A8%E3%82%B9%E3%82%BF%E3%82%A4%E3%83%AB-id-%E3%81%AE%E5%AF%BE%E5%BF%9C%E8%A1%A8)を確認し、必要なVVMファイルを読み込みます。
今回は、ずんだもん（ノーマル）（スタイルID: 5）を使用するので、`0.vvm`を読み込みます。
ダウンロードしたファイルを移動している場合は、それに合わせて`load_model`の引数を書き換えてください。

```python
async def load_model(synthesizer, model_path):
    async with await VoiceModelFile.open(model_path) as model:
        await synthesizer.load_voice_model(model)

asyncio.run(load_model(synthesizer, "models/vvms/0.vvm"))
```

先ほど確認した、スタイルIDを変数として定義しておきます。
（昔のバージョンのspeaker_idと同じものです）

```python
style_id = 5
```

### 音声合成

```python
text = "こんにちは、これはテストです。"
wav = asyncio.run(synthesizer.tts(text, style_id))

# wavをファイルに書き出す
with open("output.wav", "wb") as f:
    f.write(wav)
```

### AquesTalk風記法での音声合成

記法に関しては、Engineの方のREADMEに詳しく書いてあります。

https://github.com/VOICEVOX/voicevox_engine/blob/master/README.md#aquestalk-%E9%A2%A8%E8%A8%98%E6%B3%95

```python
text = "コ'ンニチワ、コレワ'/テ'_ストデ_ス"
wav = asyncio.run(synthesizer.tts_from_kana(text, style_id))

# wavをファイルに書き出す
with open("output_2.wav", "wb") as f:
    f.write(wav)
```

## おまけ（大量の文章の読み上げサンプル）

非同期版APIでの実装例です。
ファイルの書き込み用に、`aiofiles`を使用しています。
（`pip install aiofiles`でインストールできます）

`texts`（strのリスト）で定義した文章を、音声合成して`output_{index}.wav`に保存します。
ファイルに保存しつつ音声合成できるので、直列で実行するより速くなるはず（多分）。

```python
import asyncio
import aiofiles
from voicevox_core.asyncio import Onnxruntime, OpenJtalk, Synthesizer, VoiceModelFile

texts = [
    ...  # 文章一覧をここに
]

async def tts(synthesizer, text, style_id, index):
    # 音声合成してファイルに保存するコルーチン
    wav = await synthesizer.tts(text, style_id)
    async with aiofiles.open(f"output_{index}.wav", mode="wb") as f:
        await f.write(wav)

async def main(texts):
    # synthesizerの作成
    voicevox_onnxruntime_path = "onnxruntime/lib/" + Onnxruntime.LIB_VERSIONED_FILENAME
    open_jtalk_dict_dir = "dict/open_jtalk_dic_utf_8-1.11"
    ort = await Onnxruntime.load_once(filename=voicevox_onnxruntime_path)
    ojt = await OpenJtalk.new(open_jtalk_dict_dir)
    synthesizer = Synthesizer(ort, ojt)
    # VVMファイルの読み込み
    async with await VoiceModelFile.open("models/vvms/0.vvm") as model:
        await synthesizer.load_voice_model(model)
    # 音声合成の一括実行
    # ttsのコルーチンのリストを作成し、asyncio.gatherで実行する
    style_id = 5  # ずんだもんノーマル（スタイルID: 5）
    await asyncio.gather(*[
        tts(synthesizer, t, style_id, i)
        for i, t in enumerate(texts)
    ])

asyncio.run(main(texts))
```