カールパティのトークナイザー動画から書籍章を作成した方法
本文の状態
日本語全文を表示中
詳細モードで約23分の本文を読めます。
同じ出来事の情報源
この情報源を基点に整理
Answer.AI
著者はSolveItプラットフォームを用い、アンドレイ・カールパティのトークナイザー動画チュートリアルを基に書籍章を作成した。SolveItは小さな検証可能なステップで問題を解決するアプローチであり、最終成果物には実行コードや追加解説が含まれる。
Source Article
元記事を日本語で読む
本文に関係しない購読案内、埋め込み通知、サイト内プロモーションは除いています。
本記事では、SolveIt を用いて Andrej Karpathy のトークナイザー動画チュートリアルから書籍の章を作成した過程について解説します。完成した成果物は、動画にはない実行可能なコード例、ハイパーリンク、画像、追加の説明を備えたテキスト版です。
続ける前に、SolveIt について一言。これはプラットフォームであると同時に、AI に一度にすべてを任せるのではなく、小さく検証可能なステップで作業を進めることを重視する問題解決のアプローチでもあります。このプラットフォームは、AI があなたが見ているものを正確に見るべきだという考えに基づいて構築されています。つまり、すべてのノート、コード、出力、文脈を AI が見られるようにし、真の共同パートナーとして機能できるようにしています。人々はこれをコーディング専用のツールだと考えることもありますが、私は学習や執筆、そしてこのケースでは動画から書籍の章を作成するという Andrej の挑戦に取り組む際にも同様に有用であると実感しました。このプラットフォームは、永続的なストレージを備えた完全な Linux 環境を提供し、ウェブ検索やメッセージ編集のための組み込みツールも用意されており、独自の Python 関数をツールとして定義することも可能です。最も重要なのは、すべての要素が編集可能である点です。作業中に整理整頓を行い、セクションを折りたたんだり、AI の回答を編集したりしてワークスペースを清潔に保つことができます。この「対話エンジニアリング」こそが、動画からドキュメントへのワークフローを実用的なものにした要因です。私は段階的に内容を充実させ、各追加箇所を検証しながら、必要な文脈を維持し続けることができました。同じアプローチは執筆フェーズにも持ち込まれ、まずアウトラインを作成し、その後セクションごとに書き進めながら、私の好みのスタイルに合わせて AI の回答を直接編集しました。
このアプローチを自分でも学びたい、あるいは私がこの記事で使っているプラットフォームを利用したいとお考えの場合は、11 月 3 日から solve.it.com でコースが開始されます。
私はまず、タイムスタンプ付きの動画文字起こしと重要な瞬間のスクリーンショットから始めました。AI に「この文字起こしを書籍の章に変換してほしい」と頼むこともできたのですが、以前試したところうまくいきませんでした。結果として、一見読みやすいものの、味気なく、文字起こしと比較して短すぎ、重要な概念を見落とし、深い解説が不足しており、ありえない内容(ハルシネーション)が含まれてしまうのです。これは、AI にプログラム全体を書かせるのと同じような問題で、プロセスを通じて深い理解を築いたり、制御を持ったり、何かを学んだりすることはできません。この問題は特に長い動画において顕著です——今回のケースでは 2 時間を超える動画でした。
そこで私は SolveIt のアプローチに従い、2 つのフェーズに分けて作業を行いました:まず、必要なすべての資料(アーティファクト)を加えながら文字起こしを一つずつ充実させ、次にその充実させたバージョンを使って実際の文章を書きました。一度にすべて終わらせるよりも時間はかかりましたが、最終的には自分が完全に理解できる内容が得られ、ゼロから書くよりはまだ速かったです。

完成した書籍の章の一部。テキスト、実行可能なコード、スクリーンショットが表示されています。
二重対話アプローチ
対話 1:文字起こしの充実化——この最初の対話は、必要な資料を加えながら文字起こしを一つずつ充実させることに焦点を当てました。
対話 2:書籍の章の執筆——2 つ目の対話では、充実させた文字起こしを用いて最終的な書籍の章を作成しました。
文字起こしの充実化
通訳は長く、2 時間以上のコンテンツが含まれていました。AI が焦点を維持できるようにするために、これをより小さなノートメッセージに分割し、一つずつ処理しました。
def split_tscript_as_msgs(dst, yt_video_id=None):
tscript_md = tscript_with_imgs(scribe_dst, False)
if yt_video_id: tscript_md = tscript_add_yt_links(tscript_md, yt_video_id)
sidx, chunks = 0, []
lines = tscript_md.splitlines()
for idx, l in enumerate(lines):
if l.startswith('!['):
chunks.append('\n\n'.join(lines[sidx:idx+2])) # include alt text
sidx = idx+2
for c in chunks[::-1]: add_msg(c)
単一の通訳ノートメッセージを複数のメッセージに分割する関数です。独自の分割ロジックを実装することもできます。
私は、以前説明したように、大きなテキストブロックを扱うのは管理が難しいため、この方法を選びました。より小さなセクションであれば、ハイパーリンクを追加したりコード例を作成したりと指示を出しても、AI は焦点を維持してくれます。さらに、次に進む前にすぐにコードを実行して動作を確認することもできました。
ハイパーリンクの追加
アンドレイ氏が以前の動画「ゼロから GPT を構築しよう」に言及した際、単なるプレーンテキストとして残すのは惜しいと思い、SolveIt に YouTube のリンクを検索させ、通訳内にハイパーリンクとして追加するよう依頼しました。
SolveIt はウェブ検索を使用してリンクを見つけ、メッセージ編集ツールを使って、適切なマークダウンリンクでノートを更新しました。私はこの手順を、動画内で言及された論文、ブログ投稿、GitHub リポジトリ、ウィキペディアページ、およびその他の外部リソースすべてに対して行いました。

SolveIt がウェブ検索とメッセージ編集ツールを使用して YouTube のハイパーリンクを検出し、追加する様子。
このスクリーンショットでは、上部にトランスクリプトの一部を含むノートメッセージが表示されています。その下には、YouTube リンクを見つけてハイパーリンクとして追加するよう SolveIt に指示するプロンプトメッセージがあります。AI の応答を見ると、ホバーした引用符から確認できるようにウェブ検索を使用して動画を検出し、適切なマークダウン形式のハイパーリンクを含む新しいコンテンツとメッセージ ID を引数として update_msg 関数(dialoghelper ツールの一種)を呼び出したことが示されています。メッセージはダイアログ内でリアルタイムに更新されます。ツール呼び出しの詳細は、画像に示されているように展開可能です。これは SolveIt が AI の推論プロセスとその行動の両方を可視化する方法を示しています—使用されたツールを正確に確認し、結果を検証できます。SolveIt のメッセージ編集ツールやダイアログエンジニアリング、プラットフォーム全体の機能についてさらに詳しく知りたい場合は、この機能概要ビデオをご覧ください。
画像からの情報抽出
いくつかのスクリーンショットには、テキストに取り込みたい情報が含まれていました—コードスニペット、図表、その他のコンテンツです。自分で行うと非常に時間がかかるため、AI を活用しました。SolveIt では、デフォルトではマークダウンに埋め込まれた画像は AI によって認識されません—これはコンテキストを管理可能に保つための措置です。ただし、画像のマークダウンに特別な #ai アンカータグを追加することで、特定の画像を AI に可視化させることができます。
画像を可視化できたので、SolveIt にそれを使って作業させることができました。この例では、スクリーンショットからコードを抽出するよう依頼しました。SolveIt は画像を読み取り、抽出されたコードを含むメッセージを作成したので、実際に実行して正しく動作するか確認したり、必要に応じて調整を加えたりすることができました。

スクリーンショットからのコード抽出 - SolveIt は画像を読み取り、実行可能なコードメッセージを作成します。
外部コンテキストの導入
エンリッチメント(情報強化)の前段階で、トランスクリプト全体を提示して、トークナイザーチュートリアルに関連するまたは言及されている GitHub リポジトリがどれかを特定するよう SolveIt に依頼しました。その結果、OpenAI の GPT-2 リポジトリ、tiktoken、Karpathy 氏の minBPE、Google の SentencePiece など、いくつかのリポジトリが見つかりました。
SolveIt は完全な Linux 環境を提供してくれるため、これらのリポジトリを直接ワークスペースにクローンすることができました。
!git clone https://github.com/karpathy/minbpe
このアイデアは、トランスクリプトを読み進める過程で、アンドレイ氏が議論している実際のソースコードにアクセスできるようにすることでした。
これは非常に有用であることがわかりました。BPE の実装方法について記されたセクションに取り組んでいる際、SolveIt にこれらのリポジトリ内の実際のコードを確認し、関連する関数を抽出するよう依頼できました。SolveIt はシェルコマンドを使用してコードベース内を検索し、ファイルを読み取り、必要な部分を抽出しました。
これらのリソースはウェブ上や API を通じて利用可能ですが、SolveIt は run_cmd などのカスタムツールを使用してローカルに保存されている場合に、より効率的にそれらと連携します。
import subprocess, shlex
def run_cmd(cmd: str, timeout=30):
"Run a bash command and return stdout, stderr, and return code"
try:
add_msg(f"!{cmd}", msg_type='code')
result = subprocess.run(shlex.split(cmd), capture_output=True, text=True, timeout=timeout)
return dict(stdout=result.stdout, stderr=result.stderr, returncode=result.returncode)
except subprocess.TimeoutExpired: return dict(error=f'Command timed out after {timeout}s')
except Exception as e: return dict(error=str(e))

SolveIt は bash コマンドを使用してクローンされたリポジトリを探索し、ローカルファイルから特定のコードを抽出します。
コード例の作成
アンドレイの説明にコード例を追加することで概念を明確化できる状況があることに気づきました。これは AI が得意とする分野です——私が明確な例を提供するよう依頼したところ、非常に堅牢なものが得られました。
例えば、あるセクションでアンドレイは UTF-8、UTF-16、UTF-32 の各エンコーディングの違いについて説明していました。口頭での説明は十分明確でしたが、具体的なコード例があるとより理解が深まると考えました。そこで私は次のように依頼しました:「UTF-8、UTF-16、UTF-32 の違いを示す最小限のコード例を作成してください。」
SolveIt がコードを生成し、すぐに実行して動作を確認し、私が意図したことが実際にデモンストレーションされることを検証しました。もし完璧でなければ、修正を加えたり変更を求めたりできました。これらの実行可能な例は、強化された転写稿の一部となり、後に最終的な書籍の章に組み込まれました。

UTF 符号化の違いを明確にするために SolveIt が生成したコード例 - すぐに実行して検証できました。
説明の追加
転写稿を読み進める中で、完全に理解できていない箇所や、より詳しい説明が必要と思われる部分がありました。理解の隙間をそのまま受け入れるのではなく、質問を行いました。
例えば、ある時点でアンドレイは BPE アルゴリズム(Byte Pair Encoding)においてトークンが最初は 0 から 255 の範囲になると言及していました。なぜその特定の範囲なのか、私は完全に明確ではなかったため、「現在、トークンが 0 から 255 になるのはなぜですか?なぜそのような状況なのでしょうか?」と質問しました。
SolveIt は、UTF-8 で符号化されたバイトから始め、各バイトは 0 から 255 の値を保持できる(2^8 = 256 の可能な値がある)ためだと説明しました。これは納得がいき、私はその転写稿の該当箇所に注釈としてその説明を追加しました。
これらの明確化のための質問と回答は、最終的なコンテンツへの貴重な追加となりました。これらは、読者(あるいは私自身)を混乱させる可能性のある隙間を埋め、私が自ら質問したからこそ理解できた説明でした。

エンリッチメント(情報追加)中に明確化のための質問を投げかけることで、説明が最終的なコンテンツへの貴重な追加要素となりました。
エンリッチメントのワークフロー
実際のワークフローのリズムは以下のようでした。トランスクリプトの一部を開き、読み進めて必要なものを判断します。例えば、リンクすべき論文に言及している場合や、コード例を必要とする概念がある場合、あるいは何かについて疑問を持つ場合があります。
私は小さく具体的なリクエストを出しました。「GPT-2 論文へのハイパーリンクを追加する」「このスクリーンショットからコードを抽出する」「SentencePiece における byte fallback は何をするのか?」といった具合です。SolveIt がそれを実行し、私が結果を確認します。もしそれがコードであれば、実行して検証してから次のセクションへ進みます。
これがスムーズに機能した理由は二つあります。第一に、私はいくつかの単純な Python 関数をツールとして定義しました。SolveIt 内の任意の Python 関数はツールとして利用可能になります。私の場合は、SolveIt がコードベースを検索するためにシェルコマンドを実行できるように run_cmd 関数を作成しました。また、SolveIt にはメッセージ編集のための dialoghelper を通じた組み込みツールも用意されており、私はこれを頻繁に使用してトランスクリプトのセクションを更新していました。
対話が進むにつれて、折りたたみ見出しを使ってセクションを整理し、重要なコンテキストメッセージをピン留めして切り捨てられないようにすることで、内容を管理しやすい状態に保ちました。AI の回答が完全に正確でない場合でも、再試行を依頼するのではなく、直接編集しました。これは実務上はるかに効果的です。なぜなら、AI は人間の指示よりも過去の回答に従う傾向があるからです。また、行き詰まった探索(結果が出なかった部分)も削除し、対話の焦点がぼやけないようにしました。
この作業は速くはありませんでしたが、徹底的でした。最終的には、トークン化について深い理解を得ており、すべてのコードスニペットを検証し、すべてのリンクを確認し、すべての画像が適切な位置に配置されていました。本の一節を書く前であっても、この強化された転記稿自体が非常に有用なものでした。
本の一節の執筆
強化された転記稿を入手した後、実際の書籍の一節を作成するために新しい対話を開始しました。その際、これらの強化されたノートメッセージとコードメッセージをすべて、新しい対話のコンテキストに読み込みました。
アウトラインから始める
いきなり書き始めず、まず SolveIt にアウトライン作成を依頼しました。全体の構造、つまりどのセクションが適切か、各セクションにどのようなサブセクションが必要か、カバーすべき主要なポイントは何かなど、そして各セクションにどの画像を配置すべきかを把握したかったのです。
プロンプトは以下のようなものでした:「この書籍の一節のための詳細なアウトラインを作成してください。セクションとサブセクションを含め、それぞれが何をカバーするかについての簡潔な箇条書き、および各セクションに関連する画像を明記してください。」
SolveIt が構造化された骨格を提供してくれ、それをレビューすることができました。このアウトラインが私の執筆のためのロードマップとなりました。全体像を事前に把握できることで、特定のセクションに着手する前に章全体の形を確認でき、何か不合理な点があれば構造自体も調整できました。

SolveIt が作成したアウトライン - セクション、サブセクション、主要ポイント、そして各画像をどこに配置すべきかを示しています。
セクションごとに執筆する
アウトラインが整ったので、執筆を開始しました。まず SolveIt に導入部を書いてもらい、その後、一つずつセクションを進めていきました。
SolveIt は導入部を作成する際、強化されたトランスクリプトから関連する詳細情報を引き出し、必要に応じてコードスニペットを含め、私がすでに強化作業で見つけたハイパーリンクを追加し、適切な画像を参照しました。私はそれを読み込み、必要な箇所で編集を加えた後、次のセクションへと進みました。
重要だったのは、これを段階的に行うことです。一度に全体を書かせるのではなく、各セクションごとに個別の依頼を行い、それぞれレビューと反復作業を行いました。これにより作業範囲を管理しやすく保ちつつ、品質やトーンに対するコントロールを維持できました。

一つずつセクションを書いていく - SolveIt は強化されたトランスクリプトからの成果物を組み込み、私はレビューと調整を行います。
AI の回答の編集
SolveIt がセクションに対して行った最初の試みが必ずしも完璧ではなかったことがあります。トーンがずれていたり、冗長すぎたり、強調すべき点が違ったりしたのです。そのような場合、私が欲しいものを言葉で説明しようとするよりも、回答を直接編集する方がはるかに効果的だと分かりました。
私は AI の回答に入り込み、自分の好みのスタイルに合わせて一部を書き直し、その後 SolveIt に「以前の回答を望むトーンに合わせるよう更新しました。残りのセクションもこのスタイルで続けてください」と伝えます。
これは言語モデルが自己回帰的(autoregressive)であるため機能します。つまり、モデルは過去の出力に基づいて次に来るものを予測します。AI の出力を自分が望む通りに編集することで、例を通じて教えることになり、言葉による指示よりもはるかに効果的です。AI は「あなたが何を求めているか」の説明よりも、自身の以前の回答に従う方がより確実に従います。

AI の出力が完璧でない場合、私はそれを直接編集して好みのスタイルに合わせ、その調子で続けるよう指示しました。
各セクションのレビュー
各セクションを書き終えた後、まず自分でレビューを行います。意味が通じるか?正確か?補完されたトランスクリプトと一致しているか?また、書かれたテキストセクションの末尾にトランスクリプトからの引用を含めることで、追加の確認層を設けるのも役立ちます。
時折、SolveIt にも「この小節には、トランスクリプトに基づいて重要な抜け漏れはありませんか?」と尋ねていました。これにより、私が見過ごしていた点を発見できました。アンドレイの説明からの重要なポイントが文章に反映されていなかったり、含めるべき重要なコードスニペットを見落としていたりするケースがありました。私は自分の判断と AI が指摘した点の両方を踏まえて調整を行い、次のセクションへと進みました。
この行き来を繰り返すレビュー作業は時間の無駄ではありませんでした。すべてのセクションを終える頃には、内容が確固たるものであるという自信を持てていたのです。全体を通して反復して改善していたため、最後に大規模な修正を行う必要はありませんでした。

各セクションの後は、自分でレビューを行い、トランスクリプトから重要な抜け漏れがないかを AI にも確認してもらいました。
最終的な統合
すべてのセクションが記述され、レビューされた後、それらを単一のまとまりのあるドキュメントに結合する必要がありました。AI からの回答はすべてダイアログ内の個別のメッセージとして存在しており、イントロダクション用、各セクション用など、それぞれ別々のメッセージでした。
dialoghelper から提供されるツールを使用して、記述されたすべてのセクションを単一のノートメッセージに統合しました。その結果、文章、コードブロック、画像、ハイパーリンクなどすべてが適切にフォーマットされた、完成したマークダウン形式の書籍章が完成しました。
その時点で、私は SolveIt の公開ボタンを押して share.solveit.com で共有可能な URL を取得するか、Markdown エクスポートを行って好みの出版プラットフォームで利用するかのどちらかを選ぶことができました。私の場合は両方の方法で公開しました - SolveIt 経由での共有と、Quarto を使用して fast.ai のブログへの公開のためのエクスポートです。
なぜこのように作業するのか
この二段階のプロセスは、AI に「このトランスクリプトを書籍の章に変換してください」と単に依頼するよりも時間がかかりました。しかし、いくつかの実用的な理由から、その価値があったと考えています:
最終的に得られた成果物は、動画に含まれる重要な内容をすべて網羅しています。これは AI を盲目的に信頼するのではなく検証されたものであり、すべてのコードスニペットは実行可能で、すべてのハイパーリンクが正しい場所に接続し、すべての画像がそれぞれのセクションに関連しています。
私は全体を通じてコントロールを維持しました。Andrej が簡単に言及した何かを強調したい場合、そのセクションについてさらに深く掘り下げることもできました。動画内の内容で書籍の章においてそれほど多くのスペースを必要としないものは、要約することもできました。最終的な成果物は、機械的な変換ではなく、私が重要だと判断した内容を反映しています。
実際にその教材を学ぶことができました。トークン化セクションを一つずつ進め、理解できない点については質問し、コード例を実行しました - 終わる頃には、BPE がどのように動作するか、異なるアプローチ間のトレードオフは何かといったことを実際に理解できるようになっていました。
これは AI を使うべきではないと言っているわけではありません。私はこのプロセス全体を通じて常に AI を利用していました。しかし、結果を即座に検証できるような小さく具体的な方法でのみ使用しました。それがすべてを分ける要因となりました。
始め方
このアプローチは、入手可能な動画の文字起こしであればどれでも適用できます。いくつかの実用的な情報源をご紹介します:
YouTube 動画:yt-dlp --write-auto-sub を使用して自動生成されたキャプションをダウンロードします
Zoom の録画:文字起こしを VTT または TXT 形式でエクスポートします
音声ファイル:Whisper、AssemblyAI、または同様の文字起こしサービスを使用します
文字起こしが揃えば、ワークフローは同じです。それを SolveIt に読み込み、管理可能なセクションに分割するか(短 enough であれば一つのメッセージとして保持)、エンリッチメントを開始します。利用可能なツールには、リンク検索のための Web 検索、スクリーンショットからの情報抽出のための画像分析、例の検証のためのコード実行、リポジトリのクローン作成やリソースダウンロードのためのファイルシステムアクセス、メッセージ操作のための dialoghelper ツールがあります。
最も重要な部分は特定のツールや技術ではなく、アプローチそのものです。小さな単位で作業し、進行中に検証を行い、理解できないことがあれば質問してください。コードを実行して動作を確認し、単にコンテンツを再フォーマットするのではなく、真の理解を構築してください。
完全な例をご覧になりたい場合は、出版された書籍の章でこのワークフローがどのような成果を生むかを確認できます。また、以前リンクした 2 つのダイアログを見れば、各フェーズをどのように進めたかを具体的に知ることができます。
関連記事
今日のまとめ
AIデイリーブリーフで今日の重要ニュースをまとめ読み