.
ずんだもんな voicevox core で、
python + TTS ができるということで
お安め CUI (CLI) 環境で音声合成が可能か試してみました
今さらのネタですが、検証記録をかねて記載します
具体的な環境構築方法につきましては
いっぱい記事が出てきますのでここでは割愛します
※補足:CUI は和製英語で、CLI と同義ではありませんが、
GUI ではない OS で、CLI を用いた環境ということで、
CUI (CLI) と記載してます
[ 01. キッチン ]
xserver vps
・Xserver VPS / 2GB プラン
-> Ubuntu 22.04 (64bit)
voicevox_core
・ver. 0.14.4
(voicevox_core-0.14.4+cpu-cp38-abi3-linux_x86_64.whl)
-> CPU mode (accelemodes): CPU
ONNX RUNTIME
・libonnxruntime.so.1.13.1 (スクリプト直下に必要)
Open JTalk の辞書
・open_jtalk_dic_utf_8-1.11
pip
・voicevox_core: 0.14.4+cpu
・pydub: 0.25.1
[ 02. 結論 ]
メモリ 2GB、キツイです、厳しいです
例えば、
7月14日 08時45分 各地で強い雨 交通機関に影響
7月15日 09時10分 家電メーカーが新型掃除機を発表 省エネ性能を強調
7月16日 11時25分 国際会議が開催 温室効果ガス削減を主要議題に
7月17日 11時40分 都市部で停電 一時的に数万戸が影響受ける
7月18日 13時05分 プロサッカーの試合で新戦術が注目集める
7月19日 13時20分 新しい交通アプリが公開 利便性向上に期待
7月20日 15時30分 国内の観光地で入場者数が過去最高を更新
7月21日 15時55分 医療研究機関が新しい治療法の成果を発表
7月22日 18時10分 株式市場が大きく変動 投資家に警戒感広がる
7月23日 18時35分 新しい教育カリキュラム導入へ 来年度から実施予定
という 10 行のテキストがあったとして、
10行をまとめての一括処理では、killed レスポンスになる (メモリ枯渇による強制終了)
5行でも、killed レスポンスになる (メモリ枯渇による強制終了)
2行で、ギリ音声ファイルとしての生成は可能
という状況です
ですので、苦肉で、
textb1 =
'7月14日 08時45分 各地で強い雨 交通機関に影響。' +
'7月15日 09時10分 家電メーカーが新型掃除機を発表 省エネ性能を強調。'
textb2 =
'7月16日 11時25分 国際会議が開催 温室効果ガス削減を主要議題に。' +
'7月17日 11時40分 都市部で停電 一時的に数万戸が影響受ける。'
のように、2行ずつで、wav ファイル生成
-> 全 wav ファイルを生成後、結合
-> mp3 に 1ファイルとして保存
ということで回避してます
[ 03. 実際の実行 ]
・実行スクリプトは、voicevox core
サンプルスクリプト (run.py) のカスタマイズです
# -*- coding: utf-8 -*-
import sys, os, re, shutil
import time, datetime
from pathlib import Path, PurePosixPath
import gc
import voicevox_core
from voicevox_core import AccelerationMode, AudioQuery, VoicevoxCore
from pydub import AudioSegment
# ===================================
now1 = datetime.datetime.now()
now2 = '{0:%Y%m%d-%H%M%S}'.format(now1)
dir1 = os.path.dirname(os.path.abspath(__file__))
# ===================================
def mains() -> None:
global dir1
accelemodes = 'CPU'
# (VOICEVOX:2 -> 四国めたん)
speakids = 2
# jtalk 辞書 設定
dir2 = os.path.join(dir1, 'open_jtalk_dic_utf_8-1.11')
# wav / mp3 保存先
dir3 = os.path.join(dir1, 'outQ/')
textb1 = \
'7月14日 08時45分 各地で強い雨 交通機関に影響。' + \
'7月15日 09時10分 家電メーカーが新型掃除機を発表 省エネ性能を強調。'
textb2 = \
'7月16日 11時25分 国際会議が開催 温室効果ガス削減を主要議題に。' + \
'7月17日 11時40分 都市部で停電 一時的に数万戸が影響受ける。'
textb3 = \
'7月18日 13時05分 プロサッカーの試合で新戦術が注目集める。' + \
'7月19日 13時20分 新しい交通アプリが公開 利便性向上に期待。'
textb4 = \
'7月20日 15時30分 国内の観光地で入場者数が過去最高を更新。' + \
'7月21日 15時55分 医療研究機関が新しい治療法の成果を発表。'
textb5 = \
'7月22日 18時10分 株式市場が大きく変動 投資家に警戒感広がる。' + \
'7月23日 18時35分 新しい教育カリキュラム導入へ 来年度から実施予定。'
# 明示的に辞書にまとめる
textsG = {
1: textb1,
2: textb2,
3: textb3,
4: textb4,
5: textb5
}
print('')
print('wav 生成開始:')
# 2行ずつ wav に生成
for nn1 in range(1, 6):
# textbX ごとに処理
textb = textsG[nn1]
# audioXX.wav を設定
fname = f"audio{nn1:02d}.wav"
# 生成処理 =============================
outb = Path(dir3 + fname)
core = VoicevoxCore(acceleration_mode=accelemodes, open_jtalk_dict_dir=dir2)
core.load_model(speakids)
audio_query = core.audio_query(textb, speakids)
# 音量を2倍にする
audio_query.volume_scale = 2.0
wavb = core.synthesis(audio_query, speakids)
outb.write_bytes(wavb)
print('wav 生成: ' + fname)
# 生成処理 =============================
time.sleep(1)
# --- メモリ解放処理 (念のため) ---
del wavb
del audio_query
del core
gc.collect()
time.sleep(1)
# 出力 wav ファイルの結合準備
file_names = [f"audio{nn1:02d}.wav" for nn1 in range(1, 6)]
# 増幅dB
amplify_db = 2
silence_duration = 500 # 無音: 0.5秒(ミリ秒)
silence = AudioSegment.silent(duration=silence_duration)
audio_segments = []
print('wav 編集開始:')
# 各ファイルを読み込み -> 増幅/無音 処理
for idx, fnzq in enumerate(file_names):
pathpo = os.path.join(dir3, fnzq)
audio34 = AudioSegment.from_wav(pathpo)
audio34 = audio34 + amplify_db
audio_segments.append(audio34)
# 最終ファイル以外は0.5秒無音を追加
if idx < len(file_names) - 1:
audio_segments.append(silence)
# ファイル結合
combined = sum(audio_segments)
# MP3で保存(変換)
out_mp3 = os.path.join(dir3, now2 + ".mp3")
combined.export(out_mp3, format="mp3")
print('wav 結合 -> mp3 生成: ' + now2 +'.mp3')
print('')
# ===================================
if __name__ == "__main__":
mains()
time.sleep(1)
sys.exit(0)
# ===================================
$ python3 core-test.py
すると、
・wav x5 が生成され
・各 wav の編集を行い、
・wav x5 を 1 ファイルにして、mp3 で保存
という流れです
wav 生成開始:
wav 生成: audio01.wav
wav 生成: audio02.wav
wav 生成: audio03.wav
wav 生成: audio04.wav
wav 生成: audio05.wav
wav 編集開始:
wav 結合 -> mp3 生成: 20251018-181719.mp3
[ 04. クレジット表記について ]
・今回のテスト生成とは関係ないのですが、
どこかに展開する場合は、以下注意してください
「クレジット表記について」
VOICEVOX の音声を公開・配布する際は、
以下のクレジットを必ず記載してください
例: VOICEVOX:四国めたん
[ 05. デザート]
結論に書いておりますが、結構むりくり感です
20行(2行ずつ処理 x 10 wav ファイル -> 1 mp3 ファイルに結合)
を 1処理として、cron で、数時間おきに実行してみてますが、
今のところ、処理落ち (killed) は、ないようですが、
メモリ専有できるわけではないので、他の処理が走ると落ちる可能性はあります
運用にのせるには、この環境はあまり現実的ではないですね
用途の規模感にもよりますが、音声合成をするなら、
例えば xserver vps でいうなら
最低でも、上位の 6GB プラン は欲しいところです
.