sglang について
SGLangは、LLMや視覚言語モデルを提供するフレームワークを扱うスキルガイドです。構造化生成と、プロンプトやコンテキストを再利用する処理向けのRadixAttentionキャッシュを中心に解説します。
主な機能
- 01共有プレフィックスの自動キャッシュ
- 02JSON・正規表現・文法による制約
- 03関数呼び出しワークフロー
- 04複数ターンの会話対応
- 05連続バッチ処理
- 06OpenAI互換API
活用シーン
- 01スキーマ制約付きJSONの生成
- 02プロンプトを繰り返し使うエージェントの提供
- 03複数ターンの会話処理
- 04並列推論リクエストのバッチ処理
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ kalarislabs/ research-agent-skills --skill sglangインストール後、Claude Code で/sglangを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/deployment.mdradix-attention.mdstructured-generation.md詳細
SGLang
RadixAttention によるプレフィックスの自動キャッシュ機能を備えた、LLM および VLM 向けの高性能サービングフレームワークです。
SGLang を使用する場面
次の場合は SGLang を使用してください。
- 構造化出力(JSON、正規表現、文法)が必要な場合
- プレフィックスを繰り返し使用するエージェント(システムプロンプト、ツール)を構築する場合
- 関数呼び出しを使うエージェント型ワークフロー
- コンテキストを共有する複数ターンの会話
- より高速な JSON デコードが必要な場合(標準方式と比べて 3 倍)
次の場合は vLLM を使用してください。
- 構造化せずにシンプルなテキスト生成を行う場合
- プレフィックスキャッシュが不要な場合
- 成熟し、広くテストされた本番環境向けシステムを求める場合
次の場合は TensorRT-LLM を使用してください。
- 1 リクエストあたりのレイテンシを最小化する場合(バッチ処理が不要)
- NVIDIA のみの環境にデプロイする場合
- H100 で FP8/INT4 量子化が必要な場合
クイックスタート
インストール
# pip install (recommended)
pip install "sglang[all]"
# With FlashInfer (faster, CUDA 11.8/12.1)
pip install sglang[all] flashinfer -i https://flashinfer.ai/whl/cu121/torch2.4/
# From source
git clone https://github.com/sgl-project/sglang.git
cd sglang
pip install -e "python[all]"
サーバーを起動する
# Basic server (Llama 3-8B)
python -m sglang.launch_server \
--model-path meta-llama/Meta-Llama-3-8B-Instruct \
--port 30000
# With RadixAttention (automatic prefix caching)
python -m sglang.launch_server \
--model-path meta-llama/Meta-Llama-3-8B-Instruct \
--port 30000 \
--enable-radix-cache # Default: enabled
# Multi-GPU (tensor parallelism)
python -m sglang.launch_server \
--model-path meta-llama/Meta-Llama-3-70B-Instruct \
--tp 4 \
--port 30000
基本的な推論
import sglang as sgl
# Set backend
sgl.set_default_backend(sgl.OpenAI("http://localhost:30000/v1"))
# Simple generation
@sgl.function
def simple_gen(s, question):
s += "Q: " + question + "\n"
s += "A:" + sgl.gen("answer", max_tokens=100)
# Run
state = simple_gen.run(question="What is the capital of France?")
print(state["answer"])
# Output: "The capital of France is Paris."
構造化 JSON 出力
import sglang as sgl
@sgl.function
def extract_person(s, text):
s += f"Extract person information from: {text}\n"
s += "Output JSON:\n"
# Constrained JSON generation
s += sgl.gen(
"json_output",
max_tokens=200,
regex=r'\{"name": "[^"]+", "age": \d+, "occupation": "[^"]+"\}'
)
# Run
state = extract_person.run(
text="John Smith is a 35-year-old software engineer."
)
print(state["json_output"])
# Output: {"name": "John Smith", "age": 35, "occupation": "software engineer"}
RadixAttention(主要な革新)
機能:リクエスト間で共通するプレフィックスを自動的にキャッシュし、再利用します。
パフォーマンス:
- 共有システムプロンプトを使うエージェント型ワークロードで 5 倍高速
- 例を繰り返し使う few-shot プロンプトで 10 倍高速
- 設定不要 — 自動的に機能します
仕組み:
- 処理済みのすべてのトークンから基数木を構築します
- 共有プレフィックスを自動的に検出します
- 一致するプレフィックスの KV キャッシュを再利用します
- 新しいトークンのみを計算します
例(システムプロンプトを使うエージェント):
Request 1: [SYSTEM_PROMPT] + "What's the weather?"
→ Computes full prompt (1000 tokens)
Request 2: [SAME_SYSTEM_PROMPT] + "Book a flight"
→ Reuses system prompt KV cache (998 tokens)
→ Only computes 2 new tokens
→ 5× faster!
構造化生成のパターン
スキーマを使った JSON
@sgl.function
def structured_extraction(s, article):
s += f"Article: {article}\n\n"
s += "Extract key information as JSON:\n"
# JSON schema constraint
schema = {
"type": "object",
"properties": {
"title": {"type": "string"},
"author": {"type": "string"},
"summary": {"type": "string"},
"sentiment": {"type": "string", "enum": ["positive", "negative", "neutral"]}
},
"required": ["title", "author", "summary", "sentiment"]
}
s += sgl.gen("info", max_tokens=300, json_schema=schema)
state = structured_extraction.run(article="...")
print(state["info"])
# Output: Valid JSON matching schema
正規表現で制約した生成
@sgl.function
def extract_email(s, text):
s += f"Extract email from: {text}\n"
s += "Email: "
# Email regex pattern
s += sgl.gen(
"email",
max_tokens=50,
regex=r'[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}'
)
state = extract_email.run(text="Contact [email protected] for details")
print(state["email"])
# Output: "[email protected]"
文法ベースの生成
@sgl.function
def generate_code(s, description):
s += f"Generate Python code for: {description}\n"
s += "```python\n"
# EBNF grammar for Python
python_grammar = """
?start: function_def
function_def: "def" NAME "(" [parameters] "):" suite
parameters: parameter ("," parameter)*
parameter: NAME
suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT
"""
s += sgl.gen("code", max_tokens=200, grammar=python_grammar)
s += "\n```"
関数呼び出しを使うエージェントのワークフロー
import sglang as sgl
# Define tools
tools = [
{
"name": "get_weather",
"description": "Get weather for a location",
"parameters": {
"type": "object",
"properties": {
"location": {"type": "string"}
}
}
},
{
"name": "book_flight",
"description": "Book a flight",
"parameters": {
"type": "object",
"properties": {
"from": {"type": "string"},
"to": {"type": "string"},
"date": {"type": "string"}
}
}
}
]
@sgl.function
def agent_workflow(s, user_query, tools):
# System prompt (cached with RadixAttention)
s += "You are a helpful assistant with access to tools.\n"
s += f"Available tools: {tools}\n\n"
# User query
s += f"User: {user_query}\n"
s += "Assistant: "
# Generate with function calling
s += sgl.gen(
"response",
max_tokens=200,
tools=tools, # SGLang handles tool call format
stop=["User:", "\n\n"]
)
# Multiple queries reuse system prompt
state1 = agent_workflow.run(
user_query="What's the weather in NYC?",
tools=tools
)
# First call: Computes full system prompt
state2 = agent_workflow.run(
user_query="Book a flight to LA",
tools=tools
)
# Second call: Reuses system prompt (5× faster)
パフォーマンスベンチマーク
RadixAttention の高速化
few-shot プロンプト(プロンプト内に 10 個の例):
- vLLM:2.5 秒/リクエスト
- SGLang:0.25 秒/リクエスト(10 倍高速)
- スループット:4 倍向上
エージェントのワークフロー(システムプロンプト 1000 トークン):
- vLLM:1.8 秒/リクエスト
- SGLang:0.35 秒/リクエスト(5 倍高速)
JSON デコード:
- 標準方式:45 tok/s
- SGLang:135 tok/s(3 倍高速)
スループット(Llama 3-8B、A100)
| ワークロード | vLLM | SGLang | 高速化 |
|---|---|---|---|
| シンプルな生成 | 2500 tok/s | 2800 tok/s | 1.12× |
| few-shot(例 10 個) | 500 tok/s | 5000 tok/s | 10× |
| エージェント(ツール呼び出し) | 800 tok/s | 4000 tok/s | 5× |
| JSON 出力 | 600 tok/s | 2400 tok/s | 4× |
複数ターンの会話
@sgl.function
def multi_turn_chat(s, history, new_message):
# System prompt (always cached)
s += "You are a helpful AI assistant.\n\n"
# Conversation history (cached as it grows)
for msg in history:
s += f"{msg['role']}: {msg['content']}\n"
# New user message (only new part)
s += f"User: {new_message}\n"
s += "Assistant: "
s += sgl.gen("response", max_tokens=200)
# Turn 1
history = []
state = multi_turn_chat.run(history=history, new_message="Hi there!")
history.append({"role": "User", "content": "Hi there!"})
history.append({"role": "Assistant", "content": state["response"]})
# Turn 2 (reuses Turn 1 KV cache)
state = multi_turn_chat.run(history=history, new_message="What's 2+2?")
# Only computes new message (much faster!)
# Turn 3 (reuses Turn 1 + Turn 2 KV cache)
state = multi_turn_chat.run(history=history, new_message="Tell me a joke")
# Progressively faster as history grows
高度な機能
投機的デコード
# Launch with draft model (2-3× faster)
python -m sglang.launch_server \
--model-path meta-llama/Meta-Llama-3-70B-Instruct \
--speculative-model meta-llama/Meta-Llama-3-8B-Instruct \
--speculative-num-steps 5
マルチモーダル(ビジョンモデル)
@sgl.function
def describe_image(s, image_path):
s += sgl.image(image_path)
s += "Describe this image in detail: "
s += sgl.gen("description", max_tokens=200)
state = describe_image.run(image_path="photo.jpg")
print(state["description"])
バッチ処理と並列リクエスト
# Automatic batching (continuous batching)
states = sgl.run_batch(
[
simple_gen.bind(question="What is AI?"),
simple_gen.bind(question="What is ML?"),
simple_gen.bind(question="What is DL?"),
]
)
# All 3 processed in single batch (efficient)
OpenAI 互換 API
# Start server with OpenAI API
python -m sglang.launch_server \
--model-path meta-llama/Meta-Llama-3-8B-Instruct \
--port 30000
# Use with OpenAI client
curl http://localhost:30000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "default",
"messages": [
{"role": "system", "content": "You are helpful"},
{"role": "user", "content": "Hello"}
],
"temperature": 0.7,
"max_tokens": 100
}'
# Works with OpenAI Python SDK
from openai import OpenAI
client = OpenAI(base_url="http://localhost:30000/v1", api_key="EMPTY")
response = client.chat.completions.create(
model="default",
messages=[{"role": "user", "content": "Hello"}]
)
対応モデル
テキストモデル:
- Llama 2、Llama 3、Llama 3.1、Llama 3.2
- Mistral、Mixtral
- Qwen、Qwen2、QwQ
- DeepSeek-V2、DeepSeek-V3
- Gemma、Phi-3
ビジョンモデル:
- LLaVA、LLaVA-OneVision
- Phi-3-Vision
- Qwen2-VL
HuggingFace の 100 以上のモデル
ハードウェアサポート
NVIDIA:A100、H100、L4、T4(CUDA 11.8 以降) AMD:MI300、MI250(ROCm 6.0 以降) Intel:GPU 搭載 Xeon(近日対応予定) Apple:MPS 経由の M1/M2/M3(実験的)
参考資料
- 構造化生成ガイド - JSON スキーマ、正規表現、文法、検証
- RadixAttention の詳細 - 仕組み、最適化、ベンチマーク
- 本番環境へのデプロイ - マルチ GPU、モニタリング、自動スケーリング
リソース
- GitHub: https://github.com/sgl-project/sglang
- ドキュメント: https://sgl-project.github.io/
- 論文: RadixAttention(arXiv:2312.07104)
- Discord: https://discord.gg/sglang
エージェントの作業手順
- 環境を確認します。 ハードウェア、フレームワークとサーバーのバージョン、モデル形式、想定される負荷を確認します。
- 入力を明確にします。 データまたはユーザーに、形式、識別子、パラメーターを確認します。結果を左右する値は推測せず、質問してください。
- まず小規模に実行します。 規模を拡大する前に、単一のリクエストを処理または記録するか、エンドツーエンドで実行します。
- 上記の指示と参考情報を使って、タスク全体を実行します。
- 結果を検証します。 レイテンシ、スループット、出力の正確性を参照値と比較して測定し、リソース使用量とコストを確認します。
- 報告します。 実行した内容(バージョン、コマンド、パラメーター)、確認した内容、未確定の点を明記します。
| 次の状況が発生した場合 | 対応 |
|---|---|
| サーバーが起動しない、または OOM が発生する | モデルサイズとメモリ、量子化、並列処理の設定を確認します。 |
| これらの指示にある関数、フラグ、エンドポイントがインストール済みバージョンに存在しない | インストール済みバージョンのドキュメント(help()、--help、公式ドキュメント)を確認し、対応を調整してユーザーに伝えます。API を捏造してはいけません。 |
| 必須の入力、識別子、パラメーターが曖昧 | ユーザーに質問するか、実行前に仮定を明示します。 |
誠実性に関するルール
- 結果、パラメーター、識別子、引用、統計を決して捏造しないでください。実行または検証できない場合は、その旨を明確に伝えます。
- サービスや認証情報を公開しないでください。プロビジョニングの前にクラウドのコストを確認します。
- ここに記載されたバージョン固有の詳細は古くなっている可能性があります。インストール済みバージョンの公式ドキュメントで確認してください。
- 費用が発生する操作、共有 GPU やクラウドクォータを消費する操作、個人データや患者データに触れる操作、取り消せない操作を行う前に、必ず確認してください。
関連スキル
tensorrt-llm:NVIDIA TensorRT を使用して LLM 推論を最適化し、スループットを最大化してレイテンシを最小化します。outlines:Outlines(dottxt.ai)を使用して、LLM から常に有効な構造化出力を生成します。有限状態機械を使ってトークンのサンプリングを制約します。…llama-cpp:NVIDIA ハードウェアなしで、CPU、Apple Silicon、一般向け GPU 上で LLM 推論を実行します。
コメント
Markdown 対応