知識がなくても始められる、AIと共にある豊かな毎日。
AIツールレビュー

手が塞がっている時間に読ませる — ローカルTTSで長文を音声にする設計

ゲンキ

サポート材を剥がしている。表面をヤスリで整えている。半田付けをしている。手は動いているが、目は画面を見られない。この時間が1日にどれだけあるか数えてみると、思ったより長い。ここに文章を流し込めれば、そのぶん読める量が増える。

やろうとすると、しかし単純にはいかない。7,000字の記事を音声にするという作業は、短い文をひとつ読み上げるのとは別の問題だからだ。本記事では、ローカルTTSで長文を音声化するときに実際に踏んだ設計と、うまくいかなかった点を記録する。成功談ではなく制約の話が中心になる。

忍者AdMax

要約ではなく全文にする理由

要約ではなく全文にする理由

まず方針を決める必要がある。要約を読ませるのか、全文を読ませるのか。

要約は短くて作りやすい。ただし、要約の音声は「聞いた気になる」だけで終わりやすい。数値や条件が落ちるので、後から確認したくなったときに結局テキストへ戻ることになる。それなら最初からテキストを読めばよい。

全文なら、情報は落ちない。代わりに長い。7,000字の記事なら、読み上げは相応の時間になる。だが手が塞がっている時間はもともと長いので、そこは問題になりにくい。むしろ短いほうが困る場面すらある。作業が30分続くのに音声が5分で終われば、残り25分は無音になる。

判断の分かれ目は、その音声を何の代わりに使うかにある。読む時間の代わりなら全文でよい。読むかどうかを決めるための下見なら要約が向く。前者は作業時間を埋める用途、後者は選別の用途で、必要な長さが正反対になる。当サイトが全文方式を採っているのは、記事本文を読む代わりに聞いてもらう想定だからだ。

当サイトのパイプラインは全文方式を採っている。そして本文の文字数が元記事の70%から130%に収まっているかを機械で検査する。この範囲を外れたら生成しない。要約に寄りすぎても、逆に膨らみすぎても止まる仕組みだ。ここを人の目視に任せると、いつのまにか要約になっていく。

書き言葉のまま読ませてはいけない

書き言葉のまま読ませてはいけない

方針が決まっても、記事本文をそのまま音声にすると聞けたものにならない。書き言葉と話し言葉は構造が違うからだ。

具体的に何が起きるか。まず、表が読めない。技術記事には比較表が入るが、これを機械が読み上げると「縦棒、項目、縦棒、値、縦棒」といった具合になる。次に、見出しの記号が読まれる。井桁や中黒がそのまま音になる。さらに、URLが災難で、意味のない英字の羅列が延々と続く。箇条書きの記号も同様だ。

したがって、音声化の前に話し言葉へ書き直す工程が要る。表は「Aは何々で、Bは何々です」という文に開く。見出しは「ここからは何々の話です」といった導入に変える。URLは落とす。この変換を経た原稿を音声にする。

書き直しの際に守るべき線が1つある。情報を落とさないことだ。読みやすくしようとすると、つい要約に寄る。前節で述べた文字数の範囲検査は、この傾向に対する歯止めとして働く。読みやすさのために削った結果、範囲を外れて止まるなら、削りすぎだったということになる。

長文をそのまま渡せない

長文をそのまま渡せない

方針が決まったら実装に入る。ここで最初の壁がある。長い文章を1回で渡すと、まともに返ってこない

理由は素直で、音声生成は入力が長いほど破綻しやすい。途中で読み飛ばす、繰り返す、末尾が切れる。安全に生成できる長さには上限がある。

したがって分割が必須になる。問題は、どこで切るかだ。

チャンク分割をどう設計するか

チャンク分割をどう設計するか

当サイトの実装では、段落を単位にして分割している。空行で区切られたかたまりをそのまま1チャンクにする。そして400文字を上限とし、これを超える段落は日本語の文境界でさらに分割する。

段落単位にした理由は、意味のまとまりを壊さないためだ。文の途中で切ると、前後で抑揚がつながらない。段落の切れ目なら、もともと間があって自然に聞こえる。

400文字という上限にも根拠がある。長いほど破綻しやすいので、余裕を持って下回る値を選んでいる。上限を高くすればチャンク数は減って所要は短くなるが、1チャンクの失敗確率が上がる。速度と安定性のつまみだと考えればよい。長時間ジョブでは、失敗のコストが大きいぶん安定性側に倒す判断になる。

ただし、この設計には後で効いてくる副作用がある。チャンク数が文字数ではなく段落数に依存することだ。同じ7,000字でも、短い段落を多用した記事はチャンク数が跳ね上がる。この点は後述する。

短い段落同士を結合しない実装になっているのも、意図的な単純さの結果だ。結合を入れれば所要は縮むが、どこまで結合してよいかの判断が要る。単純な規則で確実に動くほうを選んだという設計判断であり、最適化の余地として残っている部分でもある。

つなぎ目に0.5秒を入れる

つなぎ目に0.5秒を入れる

分割して生成したら、つなぎ直す必要がある。ここも単純ではない。

音声ファイルを単純に連結すると、チャンクの境目に間がまったくない状態になる。実装のコメントにはこう記録されている。「Back-to-back chunks via the plain concat demuxer have zero gap between them, which sounds unnaturally abrupt at chunk boundaries」。不自然に唐突に聞こえるわけだ。

対処として、チャンクとチャンクの間に0.5秒の無音を挟んでいる。このとき、無音のサンプルレートとチャンネル構成をチャンク自身に合わせる必要がある。合っていないと結合そのものが失敗するか、途中で音が変わる。

実装上は、単純に並べる方式ではなく、無音を生成して差し込む方式を使っている。前者は速いが間を作れない。後者は一手間かかるが、間の長さを制御できる。0.5秒という値は、段落の切れ目として不自然でなく、かつ間延びしない範囲として選んでいる。

地味な処理だが、ここを省くと聞き続けられない音声になる。長時間聞くものだからこそ、境目の処理が効く。数十分から数時間の音声を通しで聞くとき、境目の違和感は蓄積する。1か所なら気にならないものが、56か所あれば疲労になる。

余談だが、この「1回なら気にならないが、繰り返すと効いてくる」という性質は、3Dプリントの積層痕とよく似ている。1層の段差は見えなくても、それが百層積み重なれば表面の印象を決める。繰り返し要素の質は、回数で増幅される

56チャンクという実測

56チャンクという実測

設計どおりに動かした結果を書く。7,708字・11個の大見出しを持つ記事で、ナレーション本文は7,447字。これを分割したところ、56チャンクになった。内訳は本文54、それにタイトルと締めの挨拶が1つずつ加わる。

当初の見込みは18から20チャンクだった。実際は3倍近い。原因は前述のとおりで、見込みを文字数から立てていたのに対し、実装は段落数で切っていたためだ。技術記事は段落が短くなりやすく、この差が効いた。

ここから引き出せる教訓は、分割方式が所要時間を決めるということだ。1チャンクあたりの処理時間が同じでも、チャンク数が3倍なら所要も3倍になる。

所要時間は測ってある。機材は NVIDIA GeForce RTX 5070 Ti、モデルは1.7B、実際のチャンクでの計測だ。

チャンク長所要100字あたり
127字52.5秒41.4秒
241字102.0秒42.3秒
322字124.5秒38.6秒

約40秒で100字、つまり文字数にほぼ比例する。ナレーション本文が8,000字なら約55分かかる計算になる。記事7本なら6時間強だ。ここも、GPUの型番と使用モデルを併記して初めて意味を持つ数字であることは変わらない。

再開できないという制約

再開できないという制約

ここが最も重い制約だ。チャンク単位の再開機能がない

実装は一時ディレクトリに全チャンクを生成し、すべて揃ってから結合する。したがって途中で失敗したり中断したりすると、進捗はすべて失われ、次の実行は最初から始まる。56チャンクのうち50まで終わっていても、である。

長時間ジョブでこれは重い。数時間走らせて失敗したら、また数時間かかる。既知の制約として記録してあり、改善の余地がある部分だ。

運用でどう吸収したかを書いておく。1本ずつ、他の作業と切り離して実行する。記事の本文と画像がすべて確定してから、音声だけをまとめて後工程に回す。こうすると、失敗しても巻き戻る範囲が1本分に限定される。設計で解決できないものを、運用の順序で吸収した形だ。

なぜ設計で解決しないのかというと、優先順位の問題になる。チャンクごとに中間ファイルを残して再開できるようにするのは、実装として難しくない。ただし、それをやる前に原稿の品質を担保する仕組みのほうが先に要った。動くようになった順番と、あるべき完成度の順番は必ずしも一致しない。既知の制約として記録しておき、運用で回るならそのまま回す。この判断は、個人の道具立てでは珍しくないはずだ。

速くする余地についても書いておく。チャンクごとにモデルを解放せず常駐させる設定があり、当初はこれが効くと考えていた。ロードとアンロードの往復が支配的コストだと踏んでいたからだ。

測ってみると、効果はなかった。同じチャンクで、毎回解放する設定が32.0秒、常駐させる設定が33.7秒。誤差の範囲で、むしろわずかに遅い。つまり時間を食っているのはモデルの出し入れではなく、生成そのものだったということになる。

これは仮説が外れた例として残しておきたい。「ロードが重いはずだ」という筋書きはもっともらしく、実際そう書いてある資料もあった。しかし測らずに最適化の計画を立てていたら、効かない改修に時間を使っていた。短縮したいなら、文字数を減らすか、より小さいモデルを使うしかない。ただし小さいモデルには前述の副作用がある。

これは挿絵をローカル画像生成でまかなう(2026-08-27 公開)で扱った画像のバッチ生成と同じ考え方になる。長時間ジョブは、失敗したときにどこまで戻るかを先に決めておく。

モデルサイズで挙動が変わる

モデルサイズで挙動が変わる

使っているモデルについても書いておく。Qwen3-TTS は 2026年1月22日に 0.6B と 1.7B の2サイズで公開されており、ライセンスは Apache 2.0 だ。対応言語は中国語・英語・日本語・韓国語・ドイツ語・フランス語・ロシア語・ポルトガル語・スペイン語・イタリア語の10種類で、日本語はその1つとして公式に含まれている。

バリアントは Base、CustomVoice、VoiceDesign に分かれる。Base は「3秒の音声から素早く声を複製できる」と公式に説明されており、参照音声とその書き起こしを与える方式が用意されている。

そして特徴的なのが、自然言語の指示で話し方を制御できる点だ。公式は「timbre, emotion, and prosody といった多次元の音響属性を柔軟に制御できる」と説明している。落ち着いた口調で、といった指定を文章で書ける。

ここで自社環境での確認事項をひとつ。0.6B ではこの指示が黙って無視された。エラーにならず、指定なしと同じ結果が返る。1.7B に変えたところ、指示が反映されるようになった。公式ドキュメントで該当の記載を確認できていないため仕様だとは断定しないが、動かなかったときにエラーが出ないという挙動は、原因の特定を難しくする。同じ現象に当たった人のために書いておく。

この種の「静かに効かない」現象は、小さいモデルを使うときに広く起こりうる。指示を受け付ける形式は同じでも、その指示を扱う能力が備わっていなければ、素通りするだけになる。エラーを返すには「自分にはこれができない」と判断する必要があり、そこまで作り込まれていないことのほうが多い。

対処としては、指示の有無で出力が変わることを最初に1回だけ確認するのが確実だ。極端に違う指示を2つ与えて、結果が変わるかを聞き比べる。変わらなければ、そのモデルではその指示が効いていない。この確認を最初に済ませておけば、後から音声の雰囲気を調整しようとして無駄な時間を使わずに済む。

完全性をどう保証するか

完全性をどう保証するか

長文を機械で処理するときに怖いのは、一部が静かに欠けることだ。全部生成できたつもりで、実は3割落ちている。音声は目で見て確認できないので、聞き通すまで気づかない。

当サイトの対策は、生成前の文字数検査である。ナレーション原稿の本文が、元記事の70%から130%に収まっているかを機械で見る。範囲外なら生成に進まない。

なぜ100%ではなく幅を持たせるかというと、話し言葉への変換で分量が変わるからだ。表を文章に開けば増えるし、箇条書きをまとめれば減る。厳密な一致は求められないが、桁で外れていたら止めるという設計になる。

加えて、原稿からタイトル・URL・記号類が混入していないかも検査している。これらは読み上げると意味不明になるためだ。ローカルTTSを実務に組み込むなら、この種の前段の検査が効いてくる。

検査を生成の前に置いているのには理由がある。生成に数時間かかるものを、走らせてから間違いに気づくのは高くつく。前段の検査は数秒で終わる。数秒の検査で数時間の無駄を防げるなら、入れない理由がない。

この考え方は長時間ジョブ全般に当てはまる。走らせる前に検査できることを全部やってから走らせる。逆に、走らせてみないと分からないことは、小さく試してから本番に回す。所要時間の長い処理ほど、前段の検査に価値がある

3Dプリントの作業中に効く場面

3Dプリントの作業中に効く場面

具体的にどこで役立つかを挙げる。

印刷中の待ち時間が第一だ。造形は数時間かかることがある。その間ずっと見ている必要はないが、席は離れにくい。ここで技術文書を耳から入れられる。

後処理の作業中も向いている。サポートの除去、研磨、塗装。どれも手と目を使うが、耳は空いている。手順書そのものを読ませるより、関連する知識を入れておく使い方のほうが合う。

組み立て手順の読み上げという用途もあるが、こちらは注意が要る。手順書は数値が多く、聞き間違えると作業をやり直すことになる。寸法や締め付けトルクのような数値が結果を左右する場面では、耳だけに頼らないほうがいい。音声は理解の補助であって、確認の手段ではない。

数値が聞き取りにくい理由は、音声合成の精度というより日本語の構造にある。「零点二ミリ」と「二ミリ」は音として近く、前後の文脈が薄いと区別しにくい。単位も同様で、ミリとセンチは1音しか違わない。取り違えると10倍ずれる値を、音だけで受け取る設計にしない。手順書を音声にするなら、数値の部分は画面で確認する前提を残しておく。

逆に音声が向くのは、判断の理由が書かれた文章だ。なぜこの素材を選ぶのか、なぜこの向きで積層するのか。こうした内容は数値の正確さより筋道が主役なので、聞き流しても意味が残る。技術記事の本文は、たいていこちら側に属する。

こうした使い分けは、クラウドAIの請求書を見てローカルAIを考え直す(2026-08-24 公開)で整理した「失敗しても安い仕事か」という判断軸と同じ形になる。聞き逃しても実害がない用途から入るのが安全だ。

まとめ — 動くことと、使えること

まとめ — 動くことと、使えること

本記事の要点を整理する。

  • 全文方式を採るなら、元記事に対する文字数の範囲検査を機械で入れる
  • 長文は分割が必須。段落単位で切ると意味のまとまりが保たれる
  • チャンク数は文字数ではなく段落数に依存する。7,708字の記事で56チャンクになった
  • つなぎ目には無音を挟む。挟まないと不自然に唐突な音声になる
  • チャンク単位の再開機能がなく、中断すると進捗が全損する。運用で吸収する
  • Qwen3-TTS は 0.6B と 1.7B があり Apache 2.0。日本語を含む10言語に対応する
  • 自然言語による話し方の指示は、当サイトの環境では 0.6B で黙って無視された

ローカルTTSは動く。ただし動くことと、実務で使えることの間には距離がある。その距離を埋めるのは、モデルの性能ではなく、分割と結合と失敗時の設計だった。ここを飛ばして「生成できた」で止めると、2回目以降が続かない。

言い換えると、この領域で難しいのは音声合成そのものではない。長い処理を、失敗を前提に組むという一般的な設計の問題に落ちる。だからこそ、ここで得た教訓は音声以外にも転用が効く。画像の量産でも、大量のファイル変換でも、考えることは同じになる。

出典・参考

ブラウザだけでできる本格的なAI画像生成【ConoHa AI Canvas】
ABOUT ME
swiftwand
swiftwand
AIを使って、毎日の生活をもっと快適にするアイデアや将来像を発信しています。 初心者にもわかりやすく、すぐに取り入れられる実践的な情報をお届けします。 Sharing ideas and visions for a better daily life with AI. Practical tips that anyone can start using right away.
記事URLをコピーしました