🔬 不器用パパの休日

完全自動化はあきらめた。それでいいと思った話

「この本、代わりに読んでくれたらいいのに」——そう思ったのが始まりだった。

子どもの読み聞かせで毎晩のように寝落ちする自分。手持ちの小説を音声化できたら、通勤中にも聴ける。目が疲れていても物語を楽しめる。

そこからOCR、LLM、TTSと技術を積み上げて、ここまで来た。振り返ってみれば、かなり長い道のりだった。

この最終回では、現在のパイプラインの全体像と、「完全自動化をあきらめてハイブリッド運用に落ち着いた」理由をまとめる。

やってみた理由

シリーズを通して向き合ってきたのは「自分の好きな本を音声で聴きたい」というシンプルな欲求だった。

OCRの精度を追い、LLMで誤字を直し、TTSの声を選び、Whisperで品質を測る——そのたびに「もう少しで完全自動になりそう」という手応えと、「やっぱり人が見ないと無理だ」という現実が交互に来た。

最終回として、その答え合わせを残しておきたかった。

やったこと

パイプラインの全体像:16ステップ

現在のパイプラインは、PDFから音声ファイルまで16のステップで構成されている。

PDF(紙の本をスキャン or Kindleスクショ)

 ├─ ocr_yomitoku     :YomiToku GPU OCR → マークダウン形式テキスト

 ├─ area_segment     :目次・章・奥付の自動検出

 ├─ deep_clean       :ルビ・メタデータ・ノイズの一括除去

 ├─ ocr_confusion_fix:形状類似文字の修正(力→カ、夕→タなど30+パターン)

 ├─ sentence_struct  :段落バッファ方式で一文一行化

 ├─ punct_normalize  :句読点正規化・行末ケア

 ├─ llm_fix          :Qwen3 32BによるOCR誤字修正

 ├─ ruby_strip       :段落先頭ルビ行の除去

 ├─ llm_prep         :TTS向け最終整形

 ├─ ruby_strip_post  :llm_prep後の残留ルビ除去

 ├─ tts_preprocess   :行マージ・辞書置換・記号正規化

 ├─ tts              :マルチエンジン音声合成

 ├─ whisper_stt      :faster-whisperで文字起こし(品質検証用)

 ├─ tts_quality_eval :CER品質評価

 ├─ book-collect     :チャンク結合 + 無音挿入 + ラウドネス正規化

 └─ book-export      :MP3/M4B変換 + チャプターマーカー

全自動で動く部分と、人間の判断が必要な部分がある。

自動化できた部分

完全自動(PDFを入れたら手放しで進む):

# 書籍登録(PDFを26チャンクに分割、ジョブ作成)
bash ops/scripts/book-new.sh --pdf input.pdf --title "書籍名"

# 全チャンク一括実行
bash ops/scripts/book-run.sh data/books/<book_id>

# チャンク結合 → 最終音声ファイル
bash ops/scripts/book-collect.sh data/books/<book_id>

# MP3エクスポート
bash ops/scripts/book-export.sh data/books/<book_id>

OCRからTTS、品質チェックまでがこのコマンド群で走る。504ページの小説なら、LLM処理を含めて約3〜4時間で完走する。

自動化の仕組み:

  • ジョブロックflock ベースの排他制御。同じジョブの二重実行を防ぐ
  • resume対応 — 各ステップの .ok マーカーで完了済みステップをスキップ。途中で止まっても再実行すれば続きから
  • runtime preflight — ジョブ開始前にOCR/LLM/TTSの全設定を検証。未設定ならblocked状態で停止
  • 品質ゲート — 各ステップ完了後に品質チェック。failed_chunks=0、奥付残留ゼロ、ルビ残留ゼロを確認

自動化できなかった部分(人間がやること)

1. 読み仮名辞書の更新

TTS品質で最も影響が大きいのが漢字の読み間違い。「吾輩は猫である」のような古い文体だと、現代ではあまり使わない言い回しや旧字体に近い表現で読みが揺れる。OCRにルビが付いている部分は自動抽出できるが、ルビなしで誤読される漢字は手動で辞書に登録するしかない。

現在の運用:

  1. 初回TTS実行 → Whisper品質チェック → failチャンク特定
  2. tts-review.sh(marimo notebook)で音声を聴きながらテキストを確認
  3. 読み間違いを見つけたら tts_yomi_dict.json に追加
  4. 該当チャンクだけ再生成(tts.sh --chunk-indices "3,7,15"

2. 品質の最終判断

Whisper CERはあくまで参考値。CER 0.678でも「聴いてみたら問題ない」ケースもあれば、CER 0.02でも不自然な間が気になるケースもある。最終的な品質判断は、自分の耳で聴いて決める。

3. 声質・エンジンの選択

どのTTSエンジンを使うか、どのボイスプリセットを選ぶかは、作品のジャンルと好みで決める。古典文学には落ち着いたナレーション調、軽いエッセイにはVOICEVOXのずんだもん——こういう判断はAIにはできない。

結局こうなった:ハイブリッド運用

【自動】PDF → OCR → テキスト前処理 → LLM校正 → TTS前処理

【人間】辞書レビュー → 声質選択

【自動】TTS → Whisper品質チェック → チャンク結合

【人間】聴感チェック → 必要なら辞書更新 + 部分再生成

【自動】最終エクスポート(MP3/M4B)

自動と手動が交互に入る。完全自動化にはならなかった。でも、これでいいと思っている。

なぜ「これでいい」のか

理由1:100%の自動化は100%の品質を保証しない

読み仮名の判断には文脈が必要だ。「日」は「ひ」なのか「にち」なのか。「生」は「なま」「せい」「しょう」「いきる」のどれか。プログラムで正確に判定するには形態素解析以上の知識が必要で、それは結局LLMの領域になる——が、LLMも100%は間違えない保証はない。

理由2:「聴く」こと自体が目的に近い

このプロジェクトの出発点は「自分の好きな本を音声で聴きたい」だった。品質チェックで聴く時間は、無駄じゃなくて「先行試聴」だ。辞書を更新して再生成する作業は面倒だが、本を読む行為の一部でもある。

理由3:自動化の限界を知ったことが最大の学び

OCR 81.4%、LLM校正で更に改善、TTS→Whisperのフィードバックループ——技術的には相当なところまで来た。でも残りの数%は「人間が判断すべき領域」だった。AIが万能じゃないことを、身をもって理解できた。

結果

シリーズ全体の成果

項目成果
処理書籍504ページの小説(26チャンク)
最終出力book_all.mp3(475MB、8.6時間、128kbps)
パイプライン精度81.4%(M0マスター比)
テスト数473テスト全PASS
ジョブ数283ジョブ処理済み
TTSエンジン4種(VOICEVOX・SBV2・Qwen3-TTS・ComfyUI)
ボイスプリセット22種類登録済み
Python実装52ツール + 46シェルスクリプト

パイプライン品質の到達点

OCR生出力   → 40.2%
deep_clean  → 52.9%
confusion   → 56.9%
sentence    → 79.4%
punct_norm  → 81.4%
LLM fix     → さらに改善(定量値は継続測定中)

使ったもの

技術用途
YomiToku日本語特化GPU OCR
Ollama + Qwen3:32bローカルLLM(OCR校正)
VOICEVOX辞書ベースTTS(高速・正確)
Style-Bert-VITS2日本語特化TTS
Qwen3-TTS 1.7BAI推論TTS(自然な声)
ComfyUIVoiceDesign・VoiceClone
faster-whisper品質検証用STT
Docker全サービスのコンテナ化
RTX 5090GPU推論の基盤(32GB VRAM)

うまくいった点

  • 非エンジニアでもここまで来れた — 工場勤務のサラリーマンが、PDFからオーディオブックを生成するパイプラインを構築できた。Claude Codeの力が大きいが、「やってみたいをやってみる」をここまで形にできたのは自信になった
  • モジュール設計 — 16ステップそれぞれが独立したスクリプト。1つ壊れても他に影響しない。エンジンの入れ替え(TesseractからYomiTokuへ、LlamaからQwenへ)も、該当ステップだけ修正すればいい
  • テストの充実 — 473テスト。回帰テスト(regression-test.sh)で全ステップの品質を一発確認できる。「何か変えたら全部壊れた」を防ぐ安全網がある
  • ハイブリッド運用の割り切り — 「自動化できるところは自動化し、人間が判断すべきところは人間がやる」。この割り切りに至れたのが一番の成果かもしれない

失敗・課題

  • 開発期間が長い — 2026年1月に始めて、4月現在も改善を続けている。非エンジニアのサイドプロジェクトとしては、投入時間が大きい。「本を読む時間」の何倍もの時間を「本を読むシステムを作る時間」に使っている
  • 汎用性の限界 — 現在のパイプラインは「縦書き日本語小説のPDF」に最適化している。横書きの技術書や、図表が多い本、英語の書籍にはそのまま使えない
  • 品質の天井 — OCR 81.4%は良い数値だが、残り18.6%の改善は指数関数的に難しくなる。deep_cleanのルビ残留や#記号処理が最大のボトルネック
  • RTX 5090への依存 — パイプライン全体がRTX 5090の32GB VRAMを前提にしている。Qwen3 32B(20GB)+ YomiToku + Qwen3-TTS + Whisperの全てにGPUが必要。誰でも再現できるセットアップではない

次にやること

このシリーズは今回で一区切りだ。自分自身が使う分には、ある程度問題なく聴ける状態まで来た。だからシリーズとしては、ここで一旦区切る。

ただ、プロジェクトそのものを終わらせるつもりはない。

短期:

  • deep_cleanの精度改善(65.4% → 80%目標)
  • 複数チャンクでM0マスター作成・検証
  • TTS Review UIの実機テスト

中期:

  • 違うジャンルの本が手元に来たときに、そのたびにパイプラインをブラッシュアップしていく
  • 読み仮名辞書を、扱う作品に合わせて少しずつ広げる

長期:

  • シーンに合った声を追求したい。静かな場面と動きのある場面で同じトーンで読まれると違和感が出る。声色や間を場面ごとに変えられたら、もっと「物語を聴く」に近づけるはず

「この本、代わりに読んでくれたらいいのに」から始まった挑戦。完全自動にはならなかったけど、手持ちの小説を音声で聴ける状態にはなった。

不器用でも、やってみたいをやってみたら、ここまで来れた。


この実験で使った機材 【PR】

ZOTAC GAMING GeForce RTX 5090 SOLID — このシリーズ全体の基盤。OCR・LLM・TTS・STTすべてのGPU推論に使用。VRAM 32GBがローカルAIの選択肢を広げてくれた