実行プログラムと拡張機能

SGLangでローカルモデルを動かす:キャッシュと高速化を分けて考える

同じ文書について質問を続けると、最初は長く待ったのに、次はすぐ回答が始まることがあります。モデルが突然速くなったのではなく、すでに処理した入力を再利用しているのかもしれません。この違いを理解することが、SGLangが自分の仕事に合うか、どの設定を残すかの判断につながります。

1. 繰り返す質問と新しい文書は別の仕事

長いプロジェクト説明を付けて、何度もコード修正を頼む場面を考えてください。入力の先頭が毎回同じなら、計算済みの部分を再利用できる余地があります。SGLangのRadixキャッシュは、こうした共通の接頭部を活用します。一方、新しい文書を次々に入れる仕事では、同じ効果を期待しにくくなります。両方を一つのプリフィル速度にまとめると、待ち時間を見誤ります。

キャッシュは回答の正しさを保証するものではありません。アプリが過去の会話や新しい文書をどう送っているかも確認します。比較では新規入力と再入力を分け、回答生成中のtok/sも別に見てください。同時に複数のリクエストを受けたときの総処理量は、一人が読む出力速度とは違います。文書の一括処理と対話用の設定を、同じ順位で評価できない理由です。

2. SparkのコマンドをPCやMacへそのまま貼らない

一般的なNVIDIA向け経路では、Linux、CUDA、PyTorch、SGLangのGPUカーネルパッケージの組み合わせが合う必要があります。別環境にインストールし、正常に動いたバージョンを残してください。DGX SparkにはARM64とBlackwellの両方に対応するビルドが必要です。特定モデル向けのコンテナやパッチによる性能を、通常のインストールでも出ると考えると再現が難しくなります。

Macにも、公式文書で説明されているMLXベースのMetal実行経路があります。SGLANG_USE_MLX=1で有効にするこの経路は、CUDAと同じインストールではありません。MLX変換モデルと対応機能を別に確認します。画像・動画向けのSGLang Diffusionが使うPyTorch MPSの経路とも区別してください。以下の起動コマンドはNVIDIA CUDA環境用であり、Mac向けの実行手順ではありません。

3. 高速化の前にサーバーと質問をつなぐ

インストール後は、小さなQwen2.5-0.5B-Instructでサーバーが質問を受け付けるか確認します。コンテキスト上限4,096と同時リクエスト1は接続確認用であり、機器ごとの最高速設定ではありません。ファイルがなければ初回にダウンロードします。モデルの読み込みとサーバーの準備を待ち、別のターミナルで二つ目のコマンドを実行してください。

正常に回答が返ったら、アプリをhttp://127.0.0.1:30000/v1へ接続します。つながらないときは、待ち受けアドレスを0.0.0.0へ変える前に、サーバーの準備状態、ポート、モデル名を合わせてください。小さなモデルの回答品質で、普段使うモデルを選ぶわけではありません。ここで確かめるのはエンジンとクライアントの接続です。

SGLangのCUDAサーバーを起動

python3 -m sglang.launch_server \
  --model-path Qwen/Qwen2.5-0.5B-Instruct \
  --host 127.0.0.1 --port 30000 \
  --context-length 4096 --max-running-requests 1

使用するNVIDIA機器に合うSGLangをインストールした後で実行する、接続確認用の例です。

ローカルサーバーへ短い質問を送る

curl --fail-with-body http://127.0.0.1:30000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{"model":"Qwen/Qwen2.5-0.5B-Instruct","messages":[{"role":"user","content":"Explain what a local AI server does in two sentences."}],"max_tokens":64,"temperature":0}'

サーバーとリクエストで同じモデル名を使います。公開の例文なので、個人の文書を入れる必要はありません。

4. 読み込み中に止まるのか、生成中に止まるのか

普段使うモデルに替えたら、見慣れた量子化名でもローダーとGPU演算の対応を確認します。重みとKVキャッシュに使う割合は--mem-fraction-staticで調整しますが、計算用の空間も必要です。高い値を写して空きメモリを埋めると、かえって実行中に失敗することがあります。小さな確認用モデルで動いた設定が、大きなモデルでも動くとは限りません。

長い文書のプリフィル中にメモリが不足するなら、--chunked-prefill-sizeを減らして一度に処理する入力を分けてみます。待ち時間も変わる可能性があります。回答生成中だけ不足するなら、まず--max-running-requestsを下げます。モデル自体が載らない問題と、作業中の領域不足を分けることで、より小さな量子化ファイルが必要か、設定変更で足りるかが分かります。

5. MTPとNGRAMを名前だけでまとめない

SGLangのMTPは、モデルに合った投機的デコーディングの経路を使います。--speculative-algorithmや候補の深さ・幅の設定が登場しますが、別のドラフトモデルを必要とする方式と内蔵MTPは異なります。現在の文書ではNEXTNはEAGLEの別名と説明されています。この名前があるからといって、すべてのQwen・Gemma・GLMファイルに同じコマンドを付けられるわけではありません。

NGRAMの投機的デコーディングは、過去のトークンから候補を探す機能です。大きなn-gram埋め込みテーブルをRAMやSSDへ置くPLEオフロードとは別の話です。高速化を追加するときは、候補の検証用メモリと現在のバックエンドの制約も確認します。まず高速化なしで同条件の記録を残し、有効にした後で新しい文書と繰り返す文書をそれぞれ比較してください。

6. 動いた設定を残してから次を試す

カーネルやライブラリのエラーなら、既存の仮想環境へパッケージを重ね続けるより、最後に動いた環境へ戻します。MTP追加後にメモリエラーが出たなら、先に高速化を外してください。未対応オプションという表示は、モデル性能ではなく、インストールしたバージョンとコマンドのずれかもしれません。他のエンジンの--gpu-memory-utilizationを、SGLangのメモリ設定の代わりに入れないでください。

最後に、モデルrevision、ランタイムとカーネルのバージョン、高速化の有無、実際の入力長をまとめて残します。同条件でウォームアップ後に3回以上確認し、最初のトークンまでとデコードの時間を分けて見てください。Sparkを2台使う場合も、容量を増やすためのモデル分割と、リクエストを分担する処理では目的が違います。普段の仕事が改善するという記録を得てから機器を増やしても遅くありません。

変更履歴

サイトの説明を変更した記録です。インストール済みのエンジンやモデルのバージョンを自動で確認した結果ではありません。

  1. SGLangのキャッシュ・モデル別オプションの案内を追加

    ローカルサーバーへの接続例と、プリフィル・デコードの各段階でメモリを調整する手順を追加しました。繰り返し入力のキャッシュ効果を分け、NGRAMの候補検索とPLEテーブルのRAM・SSDへの配置を別の機能として説明しました。