yomitoku 0.13.0 アップグレードと自炊書籍の OCR 取り込み
朝、GitHub の release ページを開いたら yomitoku の v0.13.0 が出ていた。手元のローカルは 0.10.1 のまま放置していたので、まず環境を上げるところから始めて、その勢いで自炊した1冊(235 ページの問題集)をまるごと取り込んだ。途中、torch の入れ替わりと章タブの混入と Amazon メタデータの古いデータと、3つ転んだ。
yomitoku を 0.13.0 に上げる
pyproject.toml の依存を書き換えて pip でインストール直してもらったつもりが、画面の進捗バーを見ていて違和感を拾った。Downloading torch-2.12.0-cp311-cp311-win_amd64.whl と表示されている。手元には CUDA 11.8 でビルドされた torch==2.7.1+cu118 を入れていたはずなのに、CPU 版が降ってきていた。
GPU 推論が前提の処理を CPU で回すと、235 ページの本 1 冊で 1 時間コースになる。すぐ止めて、pyproject.toml を書き直してもらった。
[[tool.uv.index]]
name = "pytorch-cu118"
url = "https://download.pytorch.org/whl/cu118"
explicit = true
[tool.uv.sources]
torch = { index = "pytorch-cu118" }
torchvision = { index = "pytorch-cu118" }
CUDA 版のインデックスを明示してから入れ直したら torch==2.7.1+cu118 に戻った。今後同じ罠を踏まないように、作業の流れと地雷を memo/2026-05-15/yomitoku-upgrade-0.13.0.md にまとめて書き残してもらった。
自炊書籍を流し込む
自炊した1冊(235 ページ)を yomitoku にかけた。GPU で 362 秒、ほぼ 6 分で全ページ抽出が終わる。CPU 版に逆戻りしていたら昼までかかっていたはずなので、ここで CUDA を取り戻した効果が効いた。
抽出結果を眺めていて、すぐ次の問題に気づいた。各ページの紙面の端に、縦書きで「第 N 章 章名」というインデックスタブが印刷されている。OCR はこれを律儀に拾って、本文の途中に章名を 3 連、4 連と並べてくる。問題文の中に章タイトルが闖入してくるので、全文検索の精度が露骨に落ちる。
方針を「全部削除でいい」と決めて、yomitoku_import.py の前処理に章タブブロック除去のロジックを足してもらった。
# 「第N章 章名」が3個以上連続するブロックを章タブとみなして除去
CHAPTER_TAB = re.compile(
r"(?:第\s*\d+\s*章[^\n]{0,30}\n){3,}", re.MULTILINE
)
text = CHAPTER_TAB.sub("", text)
p30、p60、p100 あたりを目視で確認しながらしきい値を詰めていった。3 個以下に下げると、目次や章扉の正当な見出しまで削ってしまう。3 個連続を境にして、紙面のタブだけが落ちる位置に着地させた。
最終的に 235 ページが 211 チャンクに分かれて Turso(book-knowledge-base DB)に入った。ページあたり 1 チャンクではないのは、白紙ページと章扉ページが前処理で間引かれているため。
Amazon メタデータの古いデータが残っていた
DB に入れたあと、book_metadata テーブルの該当 file_no を覗いたら、まったく別の本のタイトル(テスト用ダミー)がそのまま居座っていた。前にテスト用に流し込んだダミーを消し忘れていたらしい。
WebFetch で Amazon を引きにいかせたら 403 が返ってきたので、最初から agent-browser に切り替えた。ログイン済みの Chrome で開けば書誌情報がそのまま読める。正しい ASIN と書影 URL、ページ数、出版社情報を引っ張ってきて、該当行を UPDATE で上書きしてもらった。
入口の DB を直さないと、あとで Claude Code に「○○について本棚から要約して」と頼んだとき、表紙だけ別の本になる事故が起きる。気づいた瞬間に書き換えてもらった。
restructure-book でセクション粒度を整える
ページ単位の 211 チャンクをそのままにしておくと、横断検索したときに 1 ページずつ断片で返ってきて文脈が読めない。/restructure-book を回して、ページ→セクションへ統合してもらった。
粒度の方針はこう決めた。
- 第 1 章〜第 9 章、第 11 章以降は 章単位 にまとめる
- 第 10 章は問題が独立しているので 問題単位(問 1、問 2…)で分ける
- 解答解説部分は 章別 で分ける
- 模試部分は 大問単位 で分ける
章境界は紙面の目次と章扉ページで自分の目で確認した。yomitoku は章扉のレイアウトをそれなりに保ってくれているので、ここの判別は手作業をほとんど挟まずに済んだ。結果として 211 チャンクが 45 セクションに落ち着いた。横断検索するにはちょうど扱いやすい粒度になった。
履歴ファイルを書き出してもらい、途中で使った一時スクリプトを片付けてもらって、午前の作業をここで閉じた。
章タブが残っているように見えた 45 件の検証
第N章 で grep をかけ直したら、45 件のマッチが残っていた。一瞬「前処理が抜けていたか」と背筋が伸びたが、上位 3 件を中身まで開いて確認したら、いずれも正当な構造だった。
- 目次ページの章名行
- 章扉ページの章タイトル見出し
- 解答解説の章別見出し
3 個連続の章名ブロックは消えていて、本文に紛れ込む形での残存はない。残った 45 件はむしろ消してはいけない構造なので、ここで前処理をいじり直す必要はないと判断した。
今日の落とし所
- yomitoku 0.13.0 でアップグレード時の torch CPU フォールバックを踏んだ。pyproject.toml に CUDA インデックスを明示しておけば再発しない
- 紙面の章タブは「3 連以上の繰り返し」というシグナルでだけ落とせば、正当な見出しを傷つけずに済む
- DB の
book_metadataは agent-browser で Amazon を引いて整える運用にする。WebFetch で 403 が出たら粘らず agent-browser に切り替える - 章単位だけで切るとセクションが大きくなりすぎる本がある(問題集型)。問題別・解答解説の章別・大問単位を混ぜると、検索体験が一段良くなる
「○○について本棚から横断検索して」と Claude Code に頼んだとき、過去問の該当箇所も一緒に出てくるようになった。教科書だけだった棚に、問題集の身が混ざった感触がある。