MITの講義資料956ページをiPhone向け日本語教材にした
MIT VNAVのPDF群を、ローカルLLM、学習用UI、Tailscale Serveで個人向けのモバイル教材に変換した記録です。
Xでシェア目次
AI利用の明示
本記事の構成と本文は、OpenAIのコーディングエージェント「Codex」が作成しました。内容を利用する際は、リンク先の原資料も確認してください。
MITの講義資料は充実していますが、PDFをiPhoneで読み、英語と数式を行き来しながら学ぶには少し根気が要ります。そこで、MIT 16.485 Visual Navigation for Autonomous Vehicles(VNAV)の講義資料を、スライドを見ながら日本語訳・補足・Notesを読める個人用のモバイル教材へ変換しました。
完成したのは、講義1〜33とMathematical Preliminariesをまとめた全27トピック、956ページのWebアプリです。ソースコードはlearning-labリポジトリに置きましたが、変換済み教材は個人学習とtailnet内での閲覧を前提にしています。

PDFビューアではなく「学習画面」にする
最初に作ったのは、第11講「Image Formation」の8ページを使ったサンプルです。この講義を選んだのは、原スライドとLecture Notesの両方があり、ピンホールカメラの図と投影式を使ってインタラクティブな説明を試せるからです。
iPhoneの縦画面は、上段をスライド、下段を説明に分けました。説明だけを縦にスクロールできるので、図を画面に残したまま日本語訳を読めます。横持ちやデスクトップでは左右2カラムに切り替わります。
学習用として、単にPDFを画像化する以外にも次を実装しました。
- 横スワイプ、前後ボタン、ページ一覧による移動
- スライドの全画面拡大とピンチズーム
- 日本語訳、基礎からの補足、英語原文の折りたたみ表示
- Notesの日本語要約、英語原文、参照ページの表示
- 文字サイズ変更とiPhoneのsafe areaへの対応
- お気に入り、学習済み、講義ごとの進捗、前回位置の保存
- お気に入り・未学習・学習済みによるページの絞り込み
- 数式の端末内レンダリング
操作領域は44px以上を基本にし、片手でもページ送りしやすい位置へ置いています。進捗と前回位置はlocalStorageへ保存するため、アカウントやデータベースは不要です。一方で、別端末との同期はできません。この割り切りは、tailnet内だけで使う個人教材には合っていました。
読むだけで終わらない小さな仕掛け
第11講には、焦点距離と奥行きをスライダーで変えられる投影シミュレーターを追加しました。カメラ座標の点を画像面へ写す式は次のとおりです。
u = fX / Z
v = fY / Z
奥行きZを大きくすると像が小さくなることや、XとZを同じ倍率にしても投影位置が変わらないことを、その場で動かして確認できます。さらに「XとZを同時に2倍にするとuはどうなるか」といった確認問題を2問入れました。
講義全体を一様にリッチ化するのではなく、まず理解の分岐点になる箇所だけを手作業で補強しています。956ページすべてへ演習を自動生成するよりも、重要な概念を選んでインタラクションを設計するほうが、学習体験として意味があると考えたためです。
956ページを生成する処理フロー
講義一覧には、Slidesだけがある回、Notesだけがある回、両方がある回が混在しています。そこで資料の違いを吸収し、1ページずつ共通形式へ変換するPythonスクリプトを作りました。
講義カタログ
↓ PDFを取得
SlidesがあればSlides、なければNotesを主教材に選択
↓
pypdfでページごとの英語テキストを抽出
+
pdftoppmで各ページをJPEG化
↓
関連するNotes候補を付与
↓
OllamaのローカルLLMで
タイトル/日本語訳/補足/Notes参照/Notes要約を生成
↓
ページごとにチェックポイントへ保存
↓
library.jsonとページ画像をWebアプリから読み込む
翻訳はローカルのOllamaへ1ページずつ渡す
実装時の既定モデルはgemma4:e4b-mlxで、Ollamaの/api/generateを呼び出しました。temperatureは0.1に抑え、数式と固有名詞を保持すること、資料にない事実を作らないこと、出力文字数を抑えることをpromptで指定しています。
出力はJSONではなく、次の5区画を必ず返す形式にしました。
[[TITLE_JA]]
[[TRANSLATION]]
[[EXTRA]]
[[NOTES_REF]]
[[NOTES_JA]]
JSON生成をLLMへ任せると、長い数式やバックスラッシュのescapeで壊れやすくなります。区切り文字で受け取り、Python側で構造化するほうが今回の入力には扱いやすい設計でした。
また、バッチサイズは1ページです。速度では不利ですが、失敗箇所が明確になり、再生成の単位を小さくできます。各ページの完了直後にtranslations.jsonへ保存するため、数時間かかる生成が止まっても、完了済みページを飛ばして続きから再開できます。
実際、講義31の186ページを処理中に接続が切れました。このとき生成されていた3件の代替文を検出して削除し、保存済みチェックポイントから該当ページだけを再生成しました。長時間のLLM処理では、モデルの選択以上に再開可能性と不完全な出力の検出が重要だと実感しました。
SlidesとNotesの対応は「候補提示」に留める
SlidesとNotesはページ数も構成も一致しません。全体の進行率から対応しそうなNotesページを求め、その前後1ページをLLMへ候補として渡しました。
center = round(slide_index * (notes_count - 1) / (slides_count - 1))
candidates = [center - 1, center, center + 1]
これは意味的な対応を保証する方法ではありません。そのためpromptでは、供給した候補以外を参照しないこと、確信がなければ直接対応すると断定しないことを要求しています。第11講のサンプル8ページだけは、人が節と式番号を確認し、たとえばピンホール投影をNotes §11.1・式(11.1)へ対応付けました。
全ページへ埋め込み検索を追加する方法もありますが、今回はローカルで完結する単純な生成器を優先しました。今後改善するなら、数式・見出しを含むchunk検索と、人が確認した対応関係の保存を組み合わせたいところです。
数式もオフライン資産として持つ
LLMの生成文にはLaTeX形式の数式が含まれます。最初の表示確認では、$$...$$や太字記号が文字列のまま見える箇所がありました。そこでMathJaxをアプリ内へ同梱し、表示時に数式だけをレンダリングするよう修正しました。

CDNを参照しないため、閲覧時にインターネット接続は不要です。PDF由来のページ画像、library.json、JavaScript、MathJaxをすべてMacから配信します。教材全体はページ画像が約101MB、JSONが約2.2MBです。初期表示では現在ページだけを使い、前後ページを先読みすることで、956枚を一度に読み込まないようにしています。
Tailscale Serveを「自分専用の配信」に使う
この教材は一般公開せず、外出先のiPhoneからだけ読めれば十分です。そこでホスティングサービスへアップロードせず、Mac上のNode.jsサーバーをTailscale Serveでtailnetへ公開しました。
npm start
/Applications/Tailscale.app/Contents/MacOS/Tailscale \
serve --bg --https=443 http://127.0.0.1:8765
ローカルサーバーは127.0.0.1:8765だけで待ち受け、配信対象をpublic/に限定しています。Serveがtailnet内のHTTPSを終端し、ローカルHTTPへreverse proxyします。
ここで面白かったのがmacOS版の制約です。Tailscale公式ドキュメントによると、Mac App Store版やsystem extensionを使うStandalone版は、sandboxの制約でローカルのファイルやディレクトリをServeから直接配信できません。一方、ポートの共有は可能です。そのため、ファイルを直接指定せず、小さなHTTPサーバーを間に置く構成にしました。
Funnelは使っていないので、URLは同じtailnetの端末からだけ開けます。Macへのログイン後はlaunchdでNode.jsサーバーを起動し、異常終了時も再起動するようにしました。ただし、Macがスリープ中、電源オフ、またはネットワーク未接続なら教材は読めません。クラウドへ置かない代わりに、配信元の稼働は自分で面倒を見る必要があります。
検証したことと、残る限界
生成後は全27トピック・956ページを走査し、ページIDの重複、画像欠落、日本語訳とNotes要約の空欄、代替文の残存がないことを確認しました。自動テストは次の7項目です。
- 手作業で作った第11講8ページの構成
- 全ページの日本語・英語・Notesデータ
u = fX/Zの投影計算- 2問の正解index
- 保存データが壊れた場合の復旧
- お気に入り・学習済みフィルター
- 全27トピックのID、本文、画像の整合性
さらに390×844pxのiPhone相当画面で、講義一覧、ページ移動、画像、数式、縦スクロール、投影シミュレーターを確認しました。
ただし、自動検査が確認するのは「空でない」「対応する画像がある」といった構造上の品質です。956ページすべての翻訳精度やNotesとの意味的対応を、人が精読したわけではありません。特に図だけのページ、PDFから文字を正しく抽出できないページ、複雑な数式では原資料との照合が必要です。
それでも、紙面をそのまま小さく表示するのではなく、原図・日本語・原文・進捗・操作できる例を一つの学習画面にまとめることで、難しい講義資料へ戻る心理的な負担はかなり下げられました。PDFをAIで翻訳するだけで終わらず、「次も開きたくなる閲覧体験」と「途中で壊れても再開できる生成処理」をセットで設計したことが、今回いちばん面白かった点です。