#音声合成#TTS#再現性#MLOps

声をガチャで引く — キャプション1行と乱数種だけで、同じ声が何度でも出てくる


キャプションから声を作れるTTSを使っている。声の説明文と乱数種を渡すと、その説明どおりの声で喋る。

{
  "input": "こんにちは。本日はお集まりいただき、ありがとうございます。",
  "irodori": {
    "caption": "落ち着いた知的な大人の女性の声。滑らかで聞き取りやすく、上品で信頼感のある話し方。",
    "seed": 1042
  }
}

キャプションを固定してseedを振ると、同系統だが微妙に違う声が次々に出る。ガチャだ。

そして同じキャプションと同じseedからは、何度でも同じ声が出る。この決定論性が、運用上いちばん効いた性質だった。

声の「設計値」という考え方

決定論的なら、(caption, seed) の組が声の識別子になる。音声ファイルではなく、その2つを保存しておけばいい。

キャラクター7体を作ったとき、こういう台帳を残した。

| key    | 名前   | seed | caption |
|--------|--------|------|---------|
| luna   | ルナ   | 1042 | キラキラした明るいアイドル風の若い女性の声。高めで華やかで、ファンに語りかけるように楽しそうに話している。 |
| haruto | ハルト | 1042 | 爽やかで明るい若い男性の声。人懐っこく、ハキハキとした聞き取りやすい話し方。 |
| mio    | ミオ   |  777 | 元気いっぱいのアイドル風の少女の声。少し高めでハツラツとして、笑顔が伝わる話し方。 |
| shiori | シオリ | 1042 | 落ち着いた知的な大人の女性の声。滑らかで聞き取りやすく、上品で信頼感のある話し方。 |
| sora   | ソラ   | 1042 | 少年のような元気な声。中性的でボーイッシュ、はきはきとした明るい話し方。 |
| gen    | ゲン   | 1042 | 深く渋い大人の男性の声。低音で落ち着いたトーン、ナレーターのように力強く語る話し方。 |

seed が 1042 に偏っているのは、最初に良い結果が出たseedを他のキャプションにも使い回したから。キャプションが違えば同じseedでも別の声になるので問題ない。

台帳が効いた日

このシステムは、生成した音声を学習素材にして軽量なモデルを焼く二段構えになっている。あるとき、生成を回していたドライバースクリプトが消えた

学習済みモデルは残っていたが、作り直そうとすると設計値が分からない。キャプションが1文字でも違えば別の声になる。

このとき台帳が無ければ、7体ぶんの声を最初から設計し直すことになった。実際には、作業ログから設計値を復元して台帳に書き起こし、同じ声を焼き直せた

2026-08-06承認・2026-08-27にセッション履歴から復元(生成スクリプト消失のため)。
同caption+seedで完全決定的。

学習済みモデルのファイルは数百MBあり、バックアップの対象になりにくい。設計値は数百バイトで、テキストファイルに書いてgitに入れられる。 復元コストが桁違いに違う。

台帳に何を書くか

最終的にこういう形に落ち着いた。

| key  | 名前             | seed   | 話体         | caption |
|------|------------------|--------|--------------|---------|
| narF | 女性ナレーター   |  55555 | narration    | 落ち着いた大人の女性ナレーターの声。ゆったりとした語り口で、温かみと信頼感があり、長い文章を丁寧に読み上げる。 |
| narM | 男性ナレーター   |   3407 | narration    | 深く渋い男性ナレーターの声。低音で落ち着いた語り口、ゆったりと重厚に、長い文章を丁寧に読み上げる。 |
| cnsF | 女性カウンセラー |   1042 | counseling   | とても優しく穏やかな女性の声。ゆっくりと柔らかく、相手を安心させるように語りかける。息づかいのやわらかい話し方。 |
| salM | 男性営業         |      7 | sales        | 明るく信頼感のある男性の声。前向きでハキハキとして、押し付けがましくない爽やかな提案の話し方。 |

話体(conv_style)を足したのが後からの追加だった(学習後に話速は変えられない)。同じキャプションとseedでも、学習コーパスの台本を変えると語尾や話速の癖が変わる。つまり (caption, seed) だけでは声を一意に決められず、(caption, seed, 話体) の三つ組が必要だった。

この列を足していなかった時期のモデルは、後から「これはどの話体で焼いたのか」が分からなくなっている。識別子に必要な項目は、増えたときに遡って埋められない。

台帳を機械可読にしなかった判断

台帳は Markdown の表で、パースする仕組みは作らなかった。理由は3つある。

人が読んで判断する頻度のほうが高い。 「ナレーターっぽい声はどれだったか」を探すのは人間で、その用途にはテーブルが読めれば十分だった。

キャプションが長い。 50〜60文字の日本語が入るので、CSVやJSONにすると読みにくい。エスケープの問題も出る。

正本はDBにもある。 実際に投入したジョブは voice_design_jobs テーブルに name / caption / seed / progress.params.conv_style として残る。機械的に引きたいときはこちらを見る。

SELECT name, seed, progress->'params'->>'conv_style' AS conv_style, caption
FROM voice_design_jobs WHERE status = 'ready' ORDER BY created_at;

つまり台帳は人間用の索引で、DBが機械用の正本という分担にした。二重管理になるが、台帳のほうは「承認された設計値」だけを載せるので、実験で失敗したものが混ざらない。用途が違う。

決定論性を運用で確かめる

「決定論的」を信じて台帳を作るなら、それが本当かを確認しておく必要がある。同じ入力で2回生成して、バイト列が一致するかを見た。

a = gen("テスト文です。", caption, seed=1042)
b = gen("テスト文です。", caption, seed=1042)
assert a == b      # 完全一致した

さらに、実際に幻覚が出るケースでも一致した。

1回目: 「なぜだと思いますか?そうだ!これに似てる円形と思いました」
2回目: 「なぜだと思いますか?そうだ!これに似てる円形と思いました」

幻覚まで再現する。これは検証の役に立った。バグの調査で「必ず失敗する入力」を固定資産として持てるからだ。

⚠️ ただしモデルのバージョンが変われば結果は変わる。TTSサーバのイメージを更新したら、同じ設計値から違う声が出る可能性がある。台帳には日付を書いておき、大きく更新するときは主要な声を再生成して聴き比べるようにしている。

副次的な効果: 声を「増やせる」

設計値が残っていると、同じ声で用途違いを焼き足せる

キャラクターの「シオリ」はナレーター用途で焼いてあるが、コールセンター用途が欲しくなったら、キャプションとseedはそのままで話体だけ support に変えてもう1本焼けばいい。1本1〜2時間で作れる。

実際、あるキャラクターは「配信用(カジュアル)」と「業務用(丁寧)」の2バリアントを持っている。声は同じで、語尾の癖と保有する感情スタイルが違う。

この運用ができるのは、声のアイデンティティ(caption+seed)と、喋り方(話体)が分離しているからだ。分離していなければ、用途ごとに声から作り直すことになっていた。

まとめ

  • 生成が決定論的なら、設計値が声の識別子になる。モデルのファイルより桁違いに小さく、gitに入る
  • 識別子に必要な項目は後から遡れない。話体を足す前のモデルは、どの話体か分からなくなった
  • 人間用の索引と機械用の正本を分ける。用途が違うので二重管理でも構わない
  • 決定論性は運用前に実測する。同じ入力で2回生成してバイト一致を確認するだけ
  • 設計値が残っていれば声を増やせる。同じ声で用途違いを焼き足す運用が成立する

シリーズ: 拡散TTSから実用ボイスを量産する

キャプション1行から声を設計し、学習コーパスを製造して、役割別の実用ボイスを量産するまでの記録です。この記事は第1部 設計にあたります。

← 前: 音質で選んだTTSが、会話には遅すぎた → 次: 「ナレーターっぽい声」を24候補から機械に選ばせる

シリーズ全18本
  1. 音質で選んだTTSが、会話には遅すぎた 2. 声をガチャで引く ← いまここ
  2. 「ナレーターっぽい声」を24候補から機械に選ばせる
  3. 品質ゲートを厳しくするほど、棒読みが生き残る
  4. 学習後に話速は変えられない
  5. 生成するたび「録音場所」が変わるTTS
  6. クリップ1本の粗さが、スタイル全体を嗄れさせる
  7. AIが「こんにちわー」と伸ばす癖は、どこで身についたのか
  8. 「少々」が「しょも」になる — 許可文字リストが日本語を削っていた
  9. ハルシネーション対策のコードが、ハルシネーションの時だけ動かなかった
  10. 品質ゲートが許した「3文字」が、モデルの口癖になった
  11. 治せる欠陥で候補を落としていた
  12. 文字起こしでは見つからない欠陥がある
  13. 70分かけた学習素材が、ネットワークの一瞬の瞬きで消えた
  14. “ja” を “JP” と書いて喃語モデルができるまで
  15. 登録経路が4つ、管理画面が0
  16. デプロイのたびに互いの成果を消していた
  17. 測れていないものを閾値で追い込むと、必ず失敗する

知見の元になったノートは 拡散TTSから実用ボイスを量産する製造パイプライン にまとめてあります。

← 記事一覧へ