チャプター 09 · コンテキスト · 8 min
モデルが覚えていること
コンテキストウィンドウ:完璧だが有界の記憶。ChatGPTが忘れる理由とそのコスト。
記憶のパラドックス
LLMは完璧な記憶を持っている——そして、それでも忘れる。
完璧なのは、コンテキストウィンドウ内のすべてが即座に、絶対的な精度でアクセス可能だからだ。モデルは10回前のやり取りで言ったことを「なんとなく覚えている」のではない:まさにそのままの形で、今もそれを見ている。
しかし限界がある。このウィンドウには最大サイズがあるからだ。それを超えると、トークンは永遠に消える——痕跡もなく。緩やかな劣化もなく、ぼやけもなく。ただ:存在するか、しないか。
これが、ChatGPTとプロジェクトについて1時間話した後、新しい会話を開くとそのコンテキストをすべて「忘れている」という不思議な体験を説明している。バグではない——アーキテクチャの根本的な制約だ。
コンテキストウィンドウとは何か
コンテキストウィンドウは、モデルが一回のパスで処理できるトークンの数だ。このウィンドウに入るもの——あなたの質問、会話の履歴、システムの指示、貼り付けたドキュメント——はすべて、一回のパスでまとめて処理される。
GPT-3の最初のバージョンは2,048トークンのウィンドウを持っていた。今日、一部のモデルは100万トークンに達する。これは大きな進化だが、問題の本質は変わらない:常に限界がある。
そしてその限界はコストに直結する。
アテンションは高価だ
アテンションのメカニズムを思い出してほしい。各トークンは重みを計算するためにすべての他のトークンを見る。ウィンドウにn個のトークンがある場合、アテンションはn²回の演算を行う。
ウィンドウを2倍にしても、コストは2倍にならない——4倍になる。
- 1,000トークン:100万回の演算
- 2,000トークン:400万回
- 8,000トークン:6,400万回
- 128,000トークン:160億回
だからプロバイダーはトークンごとに料金を請求する。そして長い会話が短い会話より指数関数的に高くなる理由だ。
ウィンドウで遊ぶ
一つずつメッセージを送ってみよう。古いターンがウィンドウの外に落ちる瞬間を見てみよう——たとえ明示的に参照しても、モデルはもうそれにアクセスできない。
ウィンドウサイズを変えて、忘却がどのくらい速くなるか遅くなるかを確認しよう。
コンテンツをスライドさせてみよう:ウィンドウから外れたものは完全に忘れられる。Attention の計算コストはコンテキスト長に対して O(n²) で増えるため、各社が 100 万トークンのウィンドウを争う理由になっている。
KVキャッシュ、ひとことで
新しいステップごとにすべてのトークンに対してアテンションを計算するのは壊滅的だ。状況を救う最適化がKVキャッシュだ:すでに行われた計算をメモリに保持し、各ステップで新しいトークンの行だけを追加する。
これがリアルタイム生成を可能にしている——そしてコンテキストの長さに比例してVRAMを消費するものでもある。詳細は第 18 章で再び取り上げる。
システムプロンプトとチャットテンプレート
ChatGPTやClaudeにメッセージを送るとき、モデルが受け取るのはあなたのメッセージそのものではない。次のような、注意深くフォーマットされた列だ:
<|im_start|>system
あなたは有用で簡潔なアシスタントです。
<|im_end|>
<|im_start|>user
フランスの首都は?
<|im_end|>
<|im_start|>assistant
このフォーマット——チャットテンプレート——は、対話を線形なトークン列に変換し、特殊なマーカーで役割(system、user、assistant)を区別する。モデルはファインチューニング中にこれらを認識するように学習されている。
システムプロンプトは、最初に置かれる特別なメッセージだ。振る舞い、トーン、制約(「JSONで応答する」、「あるトピックの質問には決して答えない」、「あなたは知財専門のアメリカ人弁護士だ」)を設定する。他のすべてと同様にコンテキストウィンドウの中に存在するが、最初に置かれるという位置と特権的な役割により、通常のメッセージより重みを持つ。
各モデルファミリーは独自のテンプレートを持つ:OpenAIのChatML、Llama 2の [INST]…[/INST]、Llama 3やClaudeの新しい変種など。正しいフォーマットを尊重せずに手で対話を書くと、モデルは誤動作する——これらのマーカーを見るように訓練されており、それを期待しているからだ。
ウィンドウ内での位置の重要性
最近の研究からの驚くべき発見:LLMはすべてのコンテキストを同等の効果で使用するわけではない。
ウィンドウの最初と最後にある情報は、中間にある情報よりもよく利用される。この現象は**「中間で迷子になる(lost in the middle)」**と呼ばれる——モデルは長いコンテキストの中央に埋もれた部分を無視する傾向がある。
実用的な結果:参照ドキュメントを使ったアシスタントを構築するなら、最も重要な情報をプロンプトの最初か最後に置こう。中間ではなく。
より長いウィンドウへ
研究者たちはコストを爆発させずにウィンドウを拡張するいくつかのアプローチを探っている:
- スパースアテンション:すべてのトークンを見る代わりに、各トークンはサブセット(近くのもの、または重要度で選択されたもの)だけを見る。
- スライディングウィンドウアテンション:スライドするウィンドウ——各トークンは最も近いk個の隣人だけを見る。
- Flash Attention:計算量の削減ではなく、正確なアテンションのはるかにGPU効率の良い実装。
しかし、これらの技術はすべて精度や実装の複雑さにコストを払っている。まだ完璧な解決策はない。推論側の詳細——特にこれらがKVキャッシュとどう相互作用するか——は第 18 章で扱う。
実践的な教訓
これらすべてから導き出されるいくつかの実用的なルール:
プロンプトを簡潔にする。 コンテキスト内のすべてのトークンはメモリと計算を消費する。10,000トークンのコンテキストは1,000トークンのコンテキストの10倍以上のコストがかかる。
ドキュメントを構造化する。 コンテンツ(ノート、記事、コード)を注入する場合、まずチャンクに分けてフィルタリングする——関連性がない部分が90%もある長いブロックをそのまま貼り付けない。
短いセッションを使う。 長い反復タスクでは、巨大な会話を成長させ続けるよりも、コンテキストの要約を持って新しい会話を始める方が多くの場合は効果的だ。
そして非常に大量の情報(何千ページも、データベースなど)にモデルがアクセスできるようにする必要がある場合——コンテキストウィンドウは正しい解決策ではない。そこで次の章(RAG)が登場する。
更新日