Context Window
コンテキストウィンドウとは、1回のリクエストでモデルが処理できるトークン数の上限です。プロンプト、履歴、ドキュメント、応答で共有されます。
コンテキストウィンドウとは、モデルが1回のリクエストで考慮できるtokensの最大数です。大規模言語モデル (LLM)では、読み込む内容と生成する内容のすべてがこの上限を共有します。システムプロンプト、ツール定義、会話履歴、取得した文書、ユーザーの質問、生成する回答が含まれます。ウィンドウの外にあるテキストはモデルに届かないため、非常に長い会話で以前のターンが切り捨てられると、チャットボットは会話の冒頭を追えなくなります。ウィンドウはGPT-3の2,048トークンから、2023年後半のGPT-4 Turboの128Kトークン、2024年のGoogle Gemini 1.5 Proの100万トークンへと拡大し、MetaのLlama 4 Scoutは1,000万トークンをうたっています。
コンテキストウィンドウを構成する要素#
トークン化では、テキストをサブワード単位に分割します。英語では平均して約4文字が1トークンに相当するため、128Kトークンのウィンドウには約300ページ分の文章が入ります。視覚言語モデル (VLM)では画像にもトークンを使い、通常は画像ごとに数百個のパッチトークンが必要です。そのため、長い動画は文字起こしよりもはるかに速くウィンドウを埋めます。生成されたトークンも同じ上限に含まれ、プロバイダーはその範囲内に別途出力長の上限を設けます。そのため、長い会話やAIエージェントを扱うアプリケーションは、各ターンでプロンプトを組み立て、何を残すかを決めます。
ウィンドウに上限がある理由#
長さに応じて増えるコストが2つあります。セルフアテンションはすべてのトークンを他のすべてのトークンと比較するため、アテンションの計算量はトークン数の2乗に比例して増加します。テキスト生成中は、KVキャッシュがそれ以前のすべてのトークンのキーと値を保持します。32層、128次元のキー・バリューヘッドを8つ備えるLlama 3.1 8Bは、16ビット精度でトークンごとに128 KiBを保存します。最大131,072トークンのウィンドウでは16 GiBとなり、重みが占める16 GBを超えます。
ウィンドウの長さは学習によっても決まります。8Kトークンのシーケンスで学習したモデルは、その位置より先を見たことがないため、ウィンドウを拡張するには、YaRNなどの手法で回転位置埋め込み (RoPE)を再スケーリングし、長いテキストで短期間ファインチューニングします。長いウィンドウのサービングには、メモリを節約する手法が使われます。フラッシュアテンションはスコア行列全体を保存せずに正確なアテンションを計算し、グループ化クエリアテンション (GQA)はKVキャッシュを小さくし、スライディングウィンドウアテンションは各トークンが直近の隣接トークンのみを参照するようにし、リングアテンションは1つのシーケンスを複数のGPUに分割します。
公称コンテキストと実効コンテキスト#
100万トークンを受け付けるモデルでも、すべてのトークンを同じ精度で扱えるわけではありません。2023年の研究Lost in the Middleでは、関連する文章がプロンプトの冒頭または末尾にある場合にモデルの回答精度が最も高く、中央にある場合に最も低くなることが示されました。干し草の山の中の針 (NIAH)テストでは、さまざまな深さと長さの位置に挿入した1つの事実をどの程度想起できるかを測定します。より難しいRULERベンチマークでは、32Kトークン以上をうたう17モデルのうち、32Kで十分な性能を示したのは半数にとどまりました。入力が長くなるにつれて性能が徐々に低下する現象はコンテキスト劣化と呼ばれます。検索拡張生成 (RAG)とコンテキストエンジニアリングは、関連する情報だけをウィンドウに入れることでこれを抑えます。
コンテキストウィンドウと関連用語の比較#
- 受容野:畳み込みニューラルネットワーク (CNN)の1つの出力に影響する入力画像の範囲です。カーネルサイズと深さによって決まり、トークン数の上限であるコンテキストウィンドウとは異なります。
- バッチサイズ:同時に処理する独立したシーケンスの数です。コンテキストウィンドウは各シーケンスの長さを制限します。
- メモリ:ベクトルデータベースに保存されたエピソード記憶などのエージェントメモリは、ウィンドウの外部に保持され、関連する場合にウィンドウへコピーされます。
オープンボキャブラリー検出におけるコンテキストウィンドウ#
視覚モデル内のテキストエンコーダーにもウィンドウがあります。Ultralytics YOLOEとYOLO-Worldは、CLIP系列のテキストエンコーダーを使って各クラスプロンプトをエンコードします。このエンコーダーのコンテキストウィンドウは77トークンで、Ultralyticsのテキストエンコーダーはデフォルトで長いプロンプトを切り詰めます。同じCLIPトークナイザーで、何が切り捨てられるかを確認できます。
import clip
from clip.simple_tokenizer import SimpleTokenizer
prompt = (
"a warehouse worker wearing a yellow high-visibility vest, a white hard hat, blue gloves and clear safety "
"glasses, standing beside a red forklift that carries wooden pallets stacked with brown cardboard boxes, "
"under bright ceiling lights in a narrow aisle between tall metal shelves, next to a fire extinguisher "
"mounted on the wall, a green emergency exit sign, an open loading dock door and a black dog"
)
# CLIP's BPE tokenizer wraps the text in start and end tokens
tokenizer = SimpleTokenizer()
print(f"Prompt length: {len(tokenizer.encode(prompt)) + 2} tokens")
# The text encoder reads a fixed 77-token window, so truncation drops the tail
tokens = clip.tokenize(prompt, truncate=True)[0]
kept = tokenizer.decode(tokens[1:-1].tolist())
print(f"Window: {len(tokens)} tokens ending in '{' '.join(kept.split()[-4:])}'")
print(f"'black dog' kept: {'black dog' in kept}")このプロンプトは80トークンなので、ウィンドウに保持されるのは最初の75個のテキストトークンと開始・終了マーカーです。プロンプトは「loading dock door and」で終わり、「a black dog」はエンコーダーに届く前に削除されます。










