オフラインで利用可能な、英語の自然な音声合成ソフトウェアです。2021年にMozilla TTS の開発が停止し、その後継として作られました。名前の由来は、プエルトリコに生息する小さなカエル「Coquí」とのことです。TTSは、Text-to-Speech の略です。
Git bash を使って説明しているので、Git for Windows をインストールしておく必要があります。また、Visual C++ も必要になるので Visual Studio の コミュニティ版などをインストールする必要があります。
Coqui TTS の特徴
- 高品質な音声合成:Deep Learning ベースで、非常に自然な音声が生成可能です。
- マルチスピーカー対応:複数の話者のモデルを使って、話者の切り替えが可能。
- 多言語対応:英語、日本語、スペイン語など、複数言語に対応(ただしモデルによる)。
- 学習も可能:自分でデータを用意すれば、独自の TTS モデルをトレーニング可能。
- Web UI あり:簡単に試せる Web インターフェースも提供されています。(この記事では取り扱っていません)
- CLI・Python API:コマンドラインまたは Python スクリプトで使える。
準備:前提条件
必須項目 | 内容 |
---|---|
OS | Windows 10 / 11 |
Python | 3.8〜3.11(推奨:3.11) |
環境管理 | 仮想環境(venv)推奨 |
コンパイラ | Visual Studio Build Tools(C++付き)インストール済み |
Git bash で実行する
言語系を設定する。
vi ~/.bashrc
以下のようになっていること
PS1='\$ '
export LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8
export PYTHONUTF8=1
Python 3.11を入れる
pyenv install 3.11.9
pyenv global 3.11.9
バージョンを確認
python --version
Python 3.11.9
ステップ 1:仮想環境の作成(任意)
python -m venv myenv
source myenv/Scripts/activate
ステップ 2:pip を更新し必要なツールを入れる
python -m pip install --upgrade pip
pip install setuptools wheel
ステップ 3:Coqui TTS をインストール
pip install TTS
これで TTS コマンドが使えるようになります。
後で設定するもので、一部バージョンが合わないものがあるので入れ替え。
pip uninstall -y torch torchaudio
pip install -y torch==2.3.0 torchaudio==2.3.0
ステップ 4:モデルを探す(一覧表示)
tts --list_models
おすすめの英語モデル:
モデル名 | 特徴 |
---|---|
tts_models/en/ljspeech/tacotron2-DDC | 自然なナレーション向き、安定性あり |
tts_models/en/vctk/vits | 複数話者対応、イントネーション自然 |
tts_models/en/ljspeech/glow-tts | 高速生成タイプ |
ステップ 5:音声を生成(例)
tts --text "Hello, this is a test." \
--model_name "tts_models/en/ljspeech/tacotron2-DDC" \
--out_path output.wav
output.wav
が生成されます。
ステップ 6(任意):モデルを事前ダウンロード(オフライン用)
tts --model_name "tts_models/en/ljspeech/tacotron2-DDC" --download_only
別音声対応
espeak-ng をインストール
別の音声で使うので espeak-ng をインストールします。
Release 1.52 · espeak-ng/espeak-ng ← このページから espeal-ng.msi をダウンロードしてインストールします。(ダウンロード時にWindows が警告を出すかもしれません)
インストール後、Git bash を再起動する必要があります。
自動化
途中いろいろ書いていますが、「自動化」のところまで読み飛ばしてもらって大丈夫です。
補足:エラー対策
cl
がない → Visual Studio Installer で「C++によるデスクトップ開発」をインストールUnicodeDecodeError
→ Git Bash ではexport PYTHONUTF8=1
を先に実行- pip install で SSL 関連のエラー
- –trusted-host pypi.org –trusted-host files.pythonhosted.org で回避
- SSL 周りのエラーで、音声ライブラリがダウンロードできない
- 直接ダウンロードして、ファイルを置く
- 置く場所:
C:\Users\<ユーザ名>\AppData\Local\tts
- ダウンロード場所
- Release v0.6.1 models · coqui-ai/TTS (ほかのモデルとボコーダー)
- ファイル (ここまでの例で使う分)
- ファイル(後で使う分)

日本語音声対応
日本語の音声もあったので試してみました。
男性の声で、品質はそれほど高くありませんでした。たぶん、別のソフトを使った方が良いです。
pip install TTS[ja]
実行
tts --text "こんにちは、これはテストです。" \
--model_name tts_models/ja/kokoro/tacotron2-DDC \
--vocoder_name vocoder_models/ja/kokoro/hifigan_v1 \
--out_path output-ja.wav
別の英語音声を使う
vctk/vits
を使うと espeak-ng が必要になる
espeak-ng.msi をインストールする
espeak-ng をインストールすると環境変数にパスが追加されます。Git bash を再起動します。
英語マルチスピーカーモデル tts_models/en/vctk/vits
用のおすすめ男女話者 各3名ずつ
VCTK話者の性別はエディンバラ大学の公式サイトに基づいています。
女性話者(おすすめ)
話者ID | 備考 |
---|---|
p225 | ナチュラルで柔らかめな英語発音 |
p227 | 標準的なナレーション風 |
p248 | 若干高め、テンポがよい |
男性話者(おすすめ)
話者ID | 備考 |
---|---|
p226 | 落ち着いた自然な低音 |
p228 | ややはきはきした声、ニュース風 |
p252 | やや若々しく明るい印象 |
テストスクリプト
# 女性話者テスト
tts --text "This is a test spoken by speaker p225." \
--model_name "tts_models/en/vctk/vits" \
--speaker_idx p225 \
--out_path "female_p225.wav"
tts --text "This is a test spoken by speaker p227." \
--model_name "tts_models/en/vctk/vits" \
--speaker_idx p227 \
--out_path "female_p227.wav"v"
tts --text "This is a test spoken by speaker p248." \
--model_name "tts_models/en/vctk/vits" \
--speaker_idx p248 \
--out_path "female_p248.wav"
# 男性話者テスト
tts --text "This is a test spoken by speaker p226." \
--model_name "tts_models/en/vctk/vits" \
--speaker_idx p226 \
--out_path "male_p226.wav"
tts --text "This is a test spoken by speaker p228." \
--model_name "tts_models/en/vctk/vits" \
--speaker_idx p228 \
--out_path "male_p228.wa
tts --text "This is a test spoken by speaker p252." \
--model_name "tts_models/en/vctk/vits" \
--speaker_idx p252 \
--out_path "male_p252.wav"
クレジット表記が不要のモデル
以下に、Coqui TTS に含まれる「商用利用可能・クレジット表記不要・無償・オフライン利用可能」な英語音声モデルのおすすめをまとめました。
選定条件
- 商用利用可能(無償)
- クレジット表記不要
- オフラインで動作可能
- 明瞭で中立的な成人の声
- 高品質なTTSモデル(Tacotron2, VITSなど)
推奨モデル一覧(日本語まとめ)
モデル名(--model_name ) | ライセンス | 声の特徴 | 備考 |
---|---|---|---|
tts_models/en/ljspeech/tacotron2-DDC | Apache 2.0 | 女性、落ち着いたアメリカ英語 | Audiobook音源を元にした定番モデル。ナチュラルで安定した音声。 |
tts_models/en/ljspeech/vits | Apache 2.0 | 女性、自然な発音 | 上記と同じ話者。VITSモデルでよりスムーズ。 |
tts_models/en/sam/tacotron-DDC | Apache 2.0 | 中性的な大人の声 | Accenture提供の「Sam」データセットを利用。性別の色が薄くニュートラル。 |
tts_models/en/ek1/tacotron2 | Apache 2.0 | 女性、落ち着いたイギリス英語 | RP(英国標準発音)で非常に明瞭。 |
tts_models/en/vctk/vits | Apache 2.0 | 複数(男性・女性) | 英国系の複数話者から選択可(109人)。--speaker_idx で選べる。 |
モデル選びのポイント
- 品質を重視するなら
ljspeech/vits
がおすすめ。 - 話者を選びたいなら
vctk/vits
(複数話者から選択可能)。 - 中性的な声が必要なら
sam/tacotron-DDC
。
使い方の例(コマンド)
# ljspeech/vits モデルで英語音声を生成
tts --text "Welcome to our company event." \
--model_name ljspeech/vits \
--out_path output.wav
※ vctk/vits
を使う場合は --speaker_idx
も指定してください。
商用利用とライセンスについて
すべてのモデルは Apache License 2.0 です:
- 商用利用可
- クレジット(著作権表示)は不要
- 改変・再配布も可
自動化
準備
requirements.txt
dotenv
soundfile
numpy
numba
librosa
torch==2.3.0
torchaudio==2.3.0
openpyxl
pandas
使うパッケージを入れておく
pip install -r requirements.txt
.env
INPUT_FILE=input.xlsx
OUTPUT_DIR=output_wav
input.xlsx
Excelのシート名はデフォルトの「Sheet1」を使用し、以下の形式で作成してください:
番号 | 話者 | 再生速度 | 音声の文章 |
---|---|---|---|
1 | lj_taco | 1.0 | Welcome to our event. |
2 | p225 | 1.0 | This is a test for speaker p225. |
3 | p226 | 1.0 | This is a test for speaker p226. |
4 | sam | 1.0 | This is a test for speaker sam. |
話者は、初期状態で、
lj_taco、lj_vits、sam、ek1、p225、p226、p227、p228、p248、p252
vctk/vits の話者は vctk_speakers 配列に名前を追加したら使えます。
main.py
import os
import numpy as np
import librosa
import pandas as pd
from dotenv import load_dotenv
from TTS.api import TTS
import soundfile as sf
# .env を読み込み
load_dotenv()
# 設定取得
input_excel = os.getenv("INPUT_FILE")
output_dir = os.getenv("OUTPUT_DIR")
# 出力フォルダがなければ作成
os.makedirs(output_dir, exist_ok=True)
# VCTK の話者名 をリストに
vctk_speakers = [
"p225", "p226", "p227", "p228", "p248", "p252"
]
# モデル名 を話者コードから筛選する関数
def resolve_model_and_speaker(speaker_str):
if speaker_str in vctk_speakers:
return "tts_models/en/vctk/vits", speaker_str
elif speaker_str == "lj_taco":
return "tts_models/en/ljspeech/tacotron2-DDC", None
elif speaker_str == "lj_vits":
return "tts_models/en/ljspeech/vits", None
elif speaker_str == "sam":
return "tts_models/en/sam/tacotron-DDC", None
elif speaker_str == "ek1":
return "tts_models/en/ek1/tacotron2", None
else:
raise ValueError(f"Unknown speaker: {speaker_str}")
# モデルに対応する最適なボコーダー一覧
def resolve_vocoder(model_name):
vocoder_map = {
"tts_models/en/ljspeech/tacotron2-DDC": "vocoder_models/en/ljspeech/hifigan_v2",
"tts_models/en/ljspeech/vits": None,
"tts_models/en/vctk/vits": None,
"tts_models/en/sam/tacotron-DDC": None,
"tts_models/en/ek1/tacotron2": None
}
return vocoder_map.get(model_name)
# librosa による速度変更関数
def change_speed(wav, sr, speed):
if isinstance(wav, list):
processed = []
for w in wav:
if hasattr(w, 'cpu'):
w = w.cpu().numpy()
w = np.atleast_1d(w)
processed.append(w)
wav = np.concatenate(processed)
elif hasattr(wav, 'cpu'):
wav = wav.cpu().numpy()
wav = np.atleast_1d(wav).astype(np.float32)
return librosa.effects.time_stretch(wav, rate=speed)
# Excelファイルを読み込み
try:
df = pd.read_excel(input_excel)
except Exception as e:
print(f"[ERROR] Failed to read input Excel file: {e}")
exit(1)
error_rows = []
for index, row in df.iterrows():
try:
num_str, speaker_str, speed, text = row.iloc[0], row.iloc[1], row.iloc[2], row.iloc[3]
num_padded = f"{int(num_str):03d}"
output_filename = f"{num_padded}_{speaker_str}.wav"
output_path = os.path.join(output_dir, output_filename)
model_name, speaker = resolve_model_and_speaker(speaker_str)
vocoder_name = resolve_vocoder(model_name)
speed = float(speed) if not pd.isna(speed) else 1.0
print(f"[INFO] Generating {output_path} with model={model_name} speaker={speaker} speed={speed} vocoder={vocoder_name}")
tts = TTS(model_name)
if speaker is not None:
wav = tts.tts(text, speaker=speaker)
else:
wav = tts.tts(text)
if speed != 1.0:
wav = change_speed(wav, tts.synthesizer.output_sample_rate, speed)
sf.write(output_path, wav, samplerate=tts.synthesizer.output_sample_rate)
except Exception as e:
print(f"[ERROR] Failed processing row {index + 2}: {e}")
error_rows.append(index + 2)
if error_rows:
print(f"[DONE] Completed with errors at rows: {', '.join(map(str, error_rows))}")
else:
print("[DONE] All files generated successfully.")
実行
python main.py
output_wav
フォルダにファイルが生成される。
ファイル名は、Excel ファイルの 番号を3桁にしたもの + 話者名 です。