ローカルLLMを使っていると、必ずぶつかるのが「コンテキストウィンドウの壁」です。GPT-4oやClaude 3.5のような大規模モデルは20万トークン以上のコンテキストを扱えますが、ローカルで動かす小さめのモデルだと4K〜8Kトークンが限界、ということも珍しくありません。

そこで注目されているのが「コンテキストパッキング」という手法です。Dockerが2026年2月に公式ブログで紹介したこのアプローチを、実際に試してみました。

コンテキストパッキングとは

コンテキストパッキングは、限られたコンテキストウィンドウに「より多くの有用な情報を詰め込む」ための最適化技術です。単純にテキストを切り詰めるのではなく、情報の密度を高めることでモデルの理解力を維持しつつ、トークン消費を抑えます。

具体的には、以下のような手法を組み合わせて実現します。

  • セマンティック圧縮:冗長な表現を意味を保ったまま短縮
  • 優先度ベースの選択:タスクに最も関連性の高い情報を優先的に含める
  • 構造化フォーマット:自然言語よりもトークン効率の良い形式でデータを渡す
  • 動的チャンキング:入力データを適切なサイズに分割して段階的に処理

なぜローカルLLMで重要なのか

クラウドAPIを使う場合、コンテキストウィンドウが足りなければ上位モデルに切り替えるという選択肢があります。しかしローカル環境では、GPUのメモリ量がコンテキストサイズの上限を決めてしまいます。

たとえば8GBのVRAMで動かせるモデルのコンテキストは、せいぜい4K〜8Kトークン程度。RAG(検索拡張生成)で外部知識を注入しようとしても、検索結果を全部コンテキストに入れるとすぐに溢れてしまいます。

コンテキストパッキングは、この物理的な制約の中で最大限のパフォーマンスを引き出すためのテクニックなんですね。

Docker Model Runnerでの実装

Docker Model RunnerとAgentic Composeを使うと、コンテキストパッキングを自動化できます。Docker Composeファイルにモデルとパッキング処理を定義するだけで、入力データが自動的に最適化されてモデルに渡されます。

services:
  llm:
    provider: model
    model: ai/llama3.2
    options:
      context_size: 8192

  packer:
    image: context-packer:latest
    environment:
      - TARGET_TOKENS=7000
      - STRATEGY=semantic
    depends_on:
      - llm

このように、パッキング処理をサービスとして定義し、LLMへの入力パイプラインに組み込む形です。

実践的なパッキング戦略

効果的なコンテキストパッキングには、いくつかの戦略があります。

1. メタデータの削除

ドキュメントのヘッダー、フッター、ナビゲーション要素など、タスクに無関係な情報を除去します。Webページをそのまま渡すと、実際のコンテンツは全体の30%程度しかないことも多いです。

2. 要約による前処理

長い参考資料は、まず軽量なモデルで要約してからメインモデルに渡す方法が有効です。2段階のパイプラインにはなりますが、情報密度は大幅に向上します。

3. 構造化入力の活用

自然言語の説明文よりも、JSONやYAMLの構造化データの方がトークン効率が良いケースがあります。「この商品は価格が1000円で、カテゴリは食品で…」と書くより、JSONで渡す方がコンパクトです。

GraphRAGとの組み合わせ

コンテキストパッキングはGraphRAGとの相性が特に良いです。知識グラフから取得した関連エンティティを、構造化された形でコンテキストに詰め込むことで、少ないトークン数でも豊富な背景知識をモデルに提供できます。

従来のRAGでは検索結果のテキストチャンクをそのまま並べていましたが、GraphRAGのトリプル(主語-述語-目的語)形式であれば、同じトークン数で3〜5倍の情報密度を実現できる場合があります。

ベンチマーク結果

Docker公式ブログの検証によると、コンテキストパッキングを適用したLlama 3.2(8Kコンテキスト)は、パッキングなしの同モデル(8K)と比較して、Q&Aタスクで約25%の精度向上が確認されたとのこと。

特に、複数のドキュメントを参照する必要がある質問で効果が顕著だったそうです。限られたコンテキストに「正しい情報」を選んで詰め込めるかどうかが、回答品質に直結するわけですね。

注意点

コンテキストパッキングにも限界はあります。過度な圧縮は情報の欠落を招きますし、パッキング処理自体にも計算コストがかかります。

また、モデルによっては構造化入力よりも自然言語の方が理解しやすい場合もあるため、対象モデルの特性に合わせたチューニングが必要です。プロンプトキャッシングと組み合わせれば、コスト面でもさらに最適化できるかもしれません。

まとめ

コンテキストパッキングは、ローカルLLMの実用性を大幅に引き上げるテクニックです。コンテキストウィンドウの物理的制限を「情報密度の最適化」で補うという発想は、GPUリソースが限られた環境では特に価値があると感じました。

Docker Model Runnerの設定ドキュメントでは、コンテキストサイズのカスタマイズ方法も詳しく解説されています。ローカルLLMの性能を限界まで引き出したい方は、ぜひ試してみてください。