VOICEVOX/AivisSpeech で音声合成を自動化 - NotebookLM 音声概要 吹き替え計画 その2
概要
- 前回の記事で作成した話者分離済みの文字起こしCSVデータをもとに、ローカル環境で音声合成を行う方法を解説します。
- オープンソースの音声合成ソフトウェアVOICEVOXおよびAivisSpeechのエンジンAPIを活用します。
- 話者ごとのテキストから音声ファイルを自動生成するPythonプログラムを開発しGitHubリポジトリで公開しています。
- 本記事では、
VOICEVOX
とAivisSpeech
の概要、開発したプログラムの仕組みと使い方、実際の実行結果と比較、そして両エンジンの特徴や使い分けについて詳しく説明します。 - ローカル環境での音声合成自動化に関心のある方を対象としています。
本記事を書くに至った経緯
本記事は、シリーズ「NotebookLM 音声概要 吹き替え計画」の第2弾です。
前回の記事「Whisper/pyannoteを用いたローカル環境での話者分離&文字起こし - NotebookLM 音声概要 吹き替え計画 その1」では、音声ファイルから話者ごとの発話区間を特定し、それぞれの発話を文字起こししてCSVファイルに出力するプログラムを作成しました。これにより、NotebookLMの音声概要機能で生成されるような、話者情報付きのテキストデータを得ることができました。
今回はその続きとして、前回作成した話者分離済みの文字起こしCSVデータをもとに、ローカル環境で合成音声を作成する方法について解説します。音声合成エンジンには、オープンソースで利用可能な「VOICEVOX」および「AivisSpeech」を用います。
今後のシリーズ記事の予定:
- 話者分離を含めた文字起こしをローカル環境で実行する方法
- 話者分離済みの文字起こしデータから音声合成を行う方法 (本記事)
- ローカルLLMを用いた文字起こし結果の修正と、音声合成に適したテキストへの加工 (今後・実装予定)
本記事で使用する音声合成エンジンの概要
本記事では、下記 2 つの オープンソース音声合成エンジン を扱います。どちらもローカル実行と HTTP API 提供が可能で、スクリプトから制御しやすいのが共通点です。
項目 | VOICEVOX | AivisSpeech |
---|---|---|
公式サイト | https://voicevox.hiroshiba.jp/ | https://aivis-project.com/ |
OSS リポジトリ | https://github.com/VOICEVOX/voicevox_engine | https://github.com/Aivis-Project/AivisSpeech-Engine |
主な特徴 (2025-05 時点) | • 複数話者・簡易エディタ付き • 軽量 GPU/CPU モード |
• Style-Bert-VITS 2 採用 • VOICEVOX 互換 API |
動作環境 | Win / macOS / Linux | Win / macOS |
ライセンス |
エンジン : LGPL v3 もしくは別途有償ライセンス (デュアルライセンス) 音声モデル : 各モデルの規約に従う |
同左 |
商用利用 | 2025-05 現在、デュアルライセンスのため商用可。 LGPL v3 に従うか、ソース公開不要の別ライセンスを取得する必要あり。最新情報を必ず確認。 |
同左 |
⚠️ 本記事に記載のライセンス・料金情報は 2025-05-15 時点の資料に基づきます。最新の利用条件は必ず公式サイトをご確認ください。
この後の章では、具体的に API を呼び出して音声を生成する Python スクリプト と、話者 ID の確認方法など実践的な手順を解説します。
作成したプログラム
本記事では、文字起こしの結果であるCSVファイルから、VOICEVOXまたはAivisSpeechのAPI(エンジン)を利用して合成音声を作成するPythonプログラムを作成しました。
リポジトリと使い方
プログラムのコードは以下のGitHubリポジトリで公開しています。詳細な環境構築手順やコマンドラインオプションについては、リポジトリ内のREADMEファイルをご確認ください。
プログラムの概要
このプログラムは、指定されたCSVファイルを読み込み、各行の話者名とテキストに基づいて音声合成を行います。合成された個々の音声は、適切な無音を挟みながら結合され、最終的に一つのWAVファイルとして出力されます。
処理の流れ
- 入力: プログラムは、文字起こし結果のCSVファイルパス、話者マッピング情報(どの話者名にどのエンジンIDを割り当てるか)、および(必要であれば)音声合成エンジンのURLや無音時間などのオプションを引数として受け取ります。
-
CSV読み込み: 指定されたCSVファイルを読み込み、
speaker
列とtext
列のデータを抽出します。 -
音声合成ループ: CSVの各行について、以下の処理を行います。
-
speaker
列の値から、指定された話者マッピングに基づいて対応するエンジン話者IDを取得します。 -
text
列のテキストと取得した話者IDを、指定された音声合成エンジンAPIに送信します。 - エンジンAPI(
audio_query
とsynthesis
エンドポイント)から、その行に対応する音声データ(WAV形式のバイト列)を受け取ります。
-
-
結合と出力:
- すべての行について音声合成が完了したら、得られた音声セグメントを順番に結合します。
- 結合する際には、話者の変化に応じて設定された長さの無音データを各セグメント間に挿入します。
- 最終的に結合された音声データを、一つのWAVファイルとして指定されたパスに出力します。
実行結果
今回の音声合成プログラムを以下の環境とデータで実行しました。
-
実行環境:
- マシン: MacBook Air (M3, 2024年モデル)
- メモリ: 24GB
- OS: macOS Sequoia (15.4.1)
-
対象音声ファイル:
- 提供元: GENIEE マーケティングクラウド
- 長さ: 526秒 (約8分46秒)
-
文字起こしデータ:
- 前回の記事で作成したプログラムを使用し、openai/whisper-large-v3モデルで文字起こししたCSVファイル。
文字起こしのデータ
"start","end","speaker","text"
"00:00:04","00:00:30","SPEAKER_01","こんにちはジェニービジネスサテライトラジオを聞いていただきありがとうございますこのチャンネルは最近のビジネス市場とAIやデジタルソリューションの活用マーケティングと経営のあり方について考えていくカジュアルトーク番組ですぜひコメント欄に番組の感想リスナーの皆さんが聞きたいテーマなどお気軽に書き込みいただけましたら嬉しいですまたチャンネル登録いいねもよろしくお願いします"
"00:00:31","00:00:48","SPEAKER_01","さて今回も様々な資料を読み込んできましたけど日本の労働市場の未来からB2B戦略のABMあとはセールステックの動向それから営業組織のパフォーマンス管理まで結構幅が広いですよね"
"00:00:48","00:00:52","SPEAKER_00","そうですねそれぞれがつながってるんですよね"
"00:00:52","00:01:00","SPEAKER_01","ですよねこれらをつなぎ合わせて今のビジネス環境で特に大事なポイントっていうのを今日は深振りしていきたいなと"
"00:01:00","00:01:05","SPEAKER_00","まさに、特にやっぱり避けられないのが、その労働力不足っていう大きな課題。"
"00:01:05","00:01:15","SPEAKER_00","これに対して企業がどうやって戦略的にリソースを配分してテクノロジーを使って成長していくかそのあたりのヒントを探っていきましょう"
"00:01:15","00:01:16","SPEAKER_01","はい。"
"00:01:16","00:01:20","SPEAKER_00","きっとあなたの日々の業務とか将来の計画に役立つ何か発見があると思いますよ"
"00:01:20","00:01:34","SPEAKER_01","マズラのパーソルさんの労働市場の未来推計2035これ結構インパクトありましたね2035年に労働時間が1日あたり1775万時間不足する"
"00:01:35","00:01:35","SPEAKER_00","へぇ"
"00:01:35","00:01:42","SPEAKER_01","これ2023年の1.85倍働き手で言うと384万人分"
"00:01:42","00:01:44","SPEAKER_01","深刻だなぁと"
"00:01:44","00:01:49","SPEAKER_00","そうなんですよねただちょっと面白いというかポイントなのが"
"00:01:50","00:01:56","SPEAKER_00","働き手の数自体は実は増える見込みなんですよ2035年に向けて400万人ぐらい"
"00:01:56","00:01:59","SPEAKER_01","あ、そうなんですか?数は増えるのに時間が足りなくなる?"
"00:01:59","00:02:04","SPEAKER_00","それはつまりシニアの方とか女性それから外国人の方々"
"00:02:04","00:02:09","SPEAKER_00","こういう就業者が増えることで、一人当たりの労働時間が短くなる傾向にあると。"
"00:02:09","00:02:10","SPEAKER_01","なるほど"
"00:02:10","00:02:13","SPEAKER_00","それに加えて働き方改革の影響もありますしね"
"00:02:13","00:02:14","SPEAKER_01","労働時間の短縮"
"00:02:14","00:02:21","SPEAKER_00","資料にもありましたけど2070年には外国人労働者が人口の1割を占めるかもしれないなんて話も"
"00:02:21","00:02:28","SPEAKER_01","へーじゃあ単純に人が足りないっていうのとはちょっと違うんですね働き方の中身が変わってくると"
"00:02:28","00:02:33","SPEAKER_00","そういうことです。だから、長時間労働で頑張るマラソン型じゃなくて、"
"00:02:33","00:02:34","SPEAKER_01","ふふ"
"00:02:34","00:02:40","SPEAKER_00","短い時間でみんなで効率よくつないでいくバケツリレー型みたいな働き方に変えていく必要があるんじゃないかと"
"00:02:40","00:02:42","SPEAKER_01","バケツリレー型わかりやすいですね"
"00:02:42","00:02:47","SPEAKER_01","これ日本だけの話じゃないっていうのも資料にありましたねオランダとかスペインとか"
"00:02:47","00:02:55","SPEAKER_00","そうなんですよやっぱり労働供給の制約っていうのは多くの先進国が直面している課題なんですね"
"00:02:55","00:03:05","SPEAKER_00","こういう環境だからこそ企業としては限られたリソースをじゃあどこに集中させるのっていうその戦略的な判断がもうめちゃくちゃ重要になってくるわけです"
"00:03:05","00:03:07","SPEAKER_01","リソース配分ですね"
"00:03:07","00:03:18","SPEAKER_00","特にSaaSみたいに顧客の裾野が広がりやすいビジネスだと本当にこれが生命線になるザモデルでも言われている本質って突き詰めると案外こういうところにあるのかもしれないですね"
"00:03:18","00:03:27","SPEAKER_01","なるほど。そこで具体的な戦略として出てくるのが、あの、蔡流さんのガイドブックにあったABM、アカウントベーストマーケティング。"
"00:03:27","00:03:28","SPEAKER_00","はいはいABMですね"
"00:03:28","00:03:30","SPEAKER_01","これってどういう考え方なん でしょう"
"00:03:30","00:03:46","SPEAKER_00","えーとですねABMっていうのはすごく簡単に言うとこの企業は将来的にすごく価値が高まりそうだぞって見込んだターゲット企業をまず絞り込むんですふもふもでそこにマーケティングとか営業のリソースをもう意図的に集中させるっていうアプローチですねなるほど"
"00:03:46","00:03:47","SPEAKER_01","選んで集中すると"
"00:03:47","00:04:06","SPEAKER_00","成功の鍵になるのがそのターゲット企業に共通するキーポテンシャルってやつを見抜くことキーポテンシャルはい例えば資料にあった経理サスの例だと特定の会計ソフトを使っている企業みたいなそういう隠れた共通項ですねこれを見つける"
"00:04:06","00:04:16","SPEAKER_00","それからリレーションマップっていうのを作ってその会社の中の誰がキーパーソンで誰と誰がどういう関係なのかそれをこう見える化するんです"
"00:04:16","00:04:18","SPEAKER_01","人間関係まで"
"00:04:19","00:04:24","SPEAKER_00","そうすることでより手角にピンポイントでアプローチできるようになるというわけです"
"00:04:24","00:04:30","SPEAKER_01","なるほどなぁなんか闇雲に当たるんじゃなくて狙いを定める感じですね"
"00:04:30","00:04:36","SPEAKER_00","でもそういう戦略を実行するとなるとやっぱり道具というかテクノロジーが必要になってきそうですね"
"00:04:36","00:04:37","SPEAKER_01","まさにおっしゃる通りです"
"00:04:38","00:04:47","SPEAKER_01","マークワイドリサーチのレポートにもありましたけど世界的にSFA営業支援システムの市場が伸びてるっていうのはまさにそういう背景があるからですよね"
"00:04:47","00:04:50","SPEAKER_00","効率化とかデータに基づいた意思決定とか"
"00:04:50","00:04:51","SPEAKER_01","そうですそうです"
"00:04:51","00:04:56","SPEAKER_01","セールスフォースみたいな大手はもちろん本当に色んなツールが出てきてますし"
"00:04:56","00:05:03","SPEAKER_00","国内を見ても、BMSマーケット動向でしたっけ?ITサービス、特にSaaSの分野がすごく伸びてる。"
"00:05:03","00:05:05","SPEAKER_01","伸びてますね"
"00:05:05","00:05:13","SPEAKER_00","M&Aも活発で、NTTデータさんとTerra Skyさんの提携とかああいうのを見るとやっぱりDXの需要が高いんだなと"
"00:05:13","00:05:23","SPEAKER_01","ええ、専門性を高めてその需要に応えようという動きですよね。ABMみたいな戦略をやる上での基盤が整いつつあるとも言えるかもしれませんね。"
"00:05:23","00:05:24","SPEAKER_00","確かに"
"00:05:24","00:05:31","SPEAKER_00","ただ、戦略があってツールがあっても、それを動かすその組織のパフォーマンス管理、"
"00:05:31","00:05:34","SPEAKER_00","これがちゃんとできてないと、手にかいた餅になっちゃう。"
"00:05:34","00:05:41","SPEAKER_01","いやー本当にそうなんですよそこで重要になってくるのがエクザクトリーの資料にもあったフォーキャスト"
"00:05:41","00:05:43","SPEAKER_01","つまり売上予測の精度"
"00:05:43","00:05:49","SPEAKER_00","フォーキャストの精度、これ営業担当者の報告をただ足し合わせるだけじゃダメなんですよね。"
"00:05:49","00:05:50","SPEAKER_01","全然ダメですね"
"00:05:51","00:05:54","SPEAKER_01","それだとどうしても希望的観測が入り込んじゃいますから"
"00:05:54","00:05:55","SPEAKER_00","ああ確かに"
"00:05:55","00:06:09","SPEAKER_01","そうじゃなくてもっと客観的に例えば商談がどのフェーズにあるのかちゃんと管理した上でこれはコミットほぼ確実こっちはアップサイドまあ可能性ありみたいに角度をちゃんと分類する"
"00:06:09","00:06:09","SPEAKER_00","ふむふむ"
"00:06:10","00:06:21","SPEAKER_01","で、過去のデータとか傾向値なんかも見ながら多角的に予測を組み立てていく必要があるんです目指すのはプラスマイナス5%から10%って言われてますね"
"00:06:21","00:06:25","SPEAKER_00","プラスマイナス5%から10%かなりシビアですね"
"00:06:25","00:06:31","SPEAKER_01","シビアですでもこれができないと結局さっき話したリソース配分の制度にも関わってきますから"
"00:06:31","00:06:40","SPEAKER_00","なるほどつながってるんですね予測だけじゃなくて実際に社員の人たちがどう動くかそれを導く報酬設計も大事だと"
"00:06:40","00:06:45","SPEAKER_01","まさにそこが肝です人は何で評価されるかで行動が決まりますからね"
"00:06:45","00:06:46","SPEAKER_00","ですよね"
"00:06:46","00:06:59","SPEAKER_01","会社の戦略として今はとにかく新規顧客を獲得してほしいとかこの新しいプロダクトを売ってほしいとかそういう意図があるんだったらそれをインセンティブプラン報酬の仕組みにちゃんと反映させないと"
"00:06:59","00:07:02","SPEAKER_00","具体的にはどういう工夫が考えられますか?"
"00:07:02","00:07:05","SPEAKER_01","例えば達成率によってコミッションのレートを変えるとか"
"00:07:06","00:07:11","SPEAKER_01","あとは担当する顧客の規模によって評価する期間を変えるとかですね"
"00:07:12","00:07:19","SPEAKER_01","SMB担当なら月字で細かく見てエンタープライズ担当なら市販期とか年次とか少し長いスパンで評価するとか"
"00:07:19","00:07:20","SPEAKER_00","なるほど"
"00:07:20","00:07:22","SPEAKER_00","評価サイクルも大事なんですね"
"00:07:22","00:07:28","SPEAKER_01","そうやってモチベーションを維持しつつ会社の戦略目標達成につなげていくわけです"
"00:07:28","00:08:07","SPEAKER_00","いやー今回の資料いろいろありましたけど労働力不足っていう大きなマクロな変化から始まってABMみたいな具体的な戦略それを支えるSFAとかのテクノロジーで最後はフォーキャストとか報酬設計っていう組織運営の細かいところまでなんか全部が一本の線でつながっている感じがしますねええ本当にそう思います制約のある中でどうやって成果を最大化するか"
"00:08:07","00:08:08","SPEAKER_01","3位一体ですね"
"00:08:08","00:08:20","SPEAKER_00","そうですねさてここまでいろいろ見てきましたけどこれを踏まえてリスナーのあなたが明日から自分の仕事とかチームで何か一つでも試せそうなことありますかね"
"00:08:20","00:08:21","SPEAKER_01","うーん"
"00:08:21","00:08:24","SPEAKER_00","ちょっとそんなことを考えてみる時間になれば嬉しいです"
"00:08:24","00:08:39","SPEAKER_01","本日のセッションはここまでとさせていただきます。ぜひコメント欄に番組の感想、リスナーの皆さんが聞きたいテーマなどお気軽に書き込みいただけましたら嬉しいです。またチャンネル登録、いいねもよろしくお願いします。ではまた次回お会いしましょう。"
VOICEVOXでの合成結果
-
実行コマンド:
uv run ./main.py ./demo.csv "SPEAKER_00:2 SPEAKER_01:3" --output_wav_path metan-zunda.wav
-
話者割り当て:
-
SPEAKER_00
: 四国めたん (ノーマル, ID:2
) -
SPEAKER_01
: ずんだもん (ノーマル, ID:3
) -
補足: 使用する話者のIDは、VOICEVOX Engineが起動している状態で以下の
curl http://localhost:50021/speakers
を実行することで確認できます。
-
curlの結果
[
{
"name": "四国めたん",
"speaker_uuid": "7ffcb7ce-00ec-4bdc-82cd-45a8889e43ff",
"styles": [
{
"name": "ノーマル",
"id": 2,
"type": "talk"
},
... 省略
],
"version": "0.15.7",
"supported_features": {
"permitted_synthesis_morphing": "SELF_ONLY"
}
},
{
"name": "ずんだもん",
"speaker_uuid": "388f246b-8c41-4ac1-8e2d-5d79f3ff56d9",
"styles": [
{
"name": "ノーマル",
"id": 3,
"type": "talk"
},
... 省略
],
"version": "0.15.7",
"supported_features": {
"permitted_synthesis_morphing": "SELF_ONLY"
}
},
... 省略
]
- 合成時間: 127秒 (約2分7秒)
-
合成された音声:
- 8分47秒(24.2MB)
AivisSpeechでの合成結果
-
実行コマンド:
uv run ./main.py ./demo.csv "SPEAKER_00:888753760 SPEAKER_01:1388823424" --output_wav_path anneli-eru.wav --engine_url http://localhost:10101
- 話者割り当て:
curlの結果
[
{
"name": "Anneli",
"speaker_uuid": "e756b8e4-b606-4e15-99b1-3f9c6a1b2317",
"styles": [
{
"name": "ノーマル",
"id": 888753760,
"type": "talk"
},
... 省略
],
"version": "1.0.1",
"supported_features": {
"permitted_synthesis_morphing": "NOTHING"
}
},
{
"name": "凛音エル",
"speaker_uuid": "d2c99ca6-73e5-486c-994e-ee0ce2d74928",
"styles": [
{
"name": "ノーマル",
"id": 1388823424,
"type": "talk"
},
... 省略
],
"version": "1.0.0",
"supported_features": {
"permitted_synthesis_morphing": "NOTHING"
}
}
]
- 合成時間: 170秒 (約2分50秒)
-
合成された音声:
- 8分35秒(24.2MB)
考察
-
読み方の自然さ:
- AivisSpeechは、特に専門用語(例: SaaS→サーズ、労働力不足→ろうどうりょくぶそく、Terra Sky→テラスカイ)をデフォルトで自然に読む
- VOICEVOXは、同様の語句でアルファベット読みや異なる読み方(例: エスエーエーエス、ろうどうちからぶそく)になる場合があったが、辞書登録機能で修正可能
-
合成時間:
- 同じテキストデータ(元音声約8分46秒分)の合成において、VOICEVOX(約2分7秒)の方がAivisSpeech(約2分50秒)より高速だった。
-
API互換性:
- AivisSpeech EngineはVOICEVOX Engineと互換性のあるAPIを提供しており、VOICEVOX用に作成したプログラムを流用できる点は利便性が高い。
-
選択のポイント:
- AivisSpeech: 手間なく自然な読み方を優先する場合に適しているが、合成時間は少し長め。
- VOICEVOX: 合成速度や辞書によるカスタマイズ性を重視する場合に適しているが、読み方の調整が必要な場合がある。
まとめ
- 話者分離済みの文字起こしCSVデータから、ローカル環境で音声合成を自動化する手法を解説しました。
- VOICEVOXおよびAivisSpeechのエンジンAPIを利用し、話者情報を維持したまま音声ファイルを自動生成するPythonプログラムを開発・公開しました (GitHub)。
- 実データを用いた比較検証により、VOICEVOXは合成速度、AivisSpeechはデフォルトでの読み方の自然さに利点があることを確認しました。両エンジンはAPI互換性があります。
- 次回予告はローカルLLM(Qwen3 量子化モデル)を活用し、文字起こし結果の修正や合成音声に適したテキスト加工を行う手法を紹介予定です。
Discussion