94057c3d3e
PR Test (NPU) / check-changes (push) Has been cancelled
PR Test (NPU) / pr-gate (push) Has been cancelled
PR Test (NPU) / set-image-config (push) Has been cancelled
PR Test (NPU) / stage-b-test-1-npu-a2 (0) (push) Has been cancelled
PR Test (NPU) / stage-b-test-1-npu-a2 (1) (push) Has been cancelled
PR Test (NPU) / stage-b-test-2-npu-a2 (0) (push) Has been cancelled
PR Test (NPU) / stage-b-test-2-npu-a2 (1) (push) Has been cancelled
PR Test (NPU) / stage-b-test-4-npu-a3 (push) Has been cancelled
PR Test (NPU) / stage-b-test-16-npu-a3 (push) Has been cancelled
PR Test (NPU) / multimodal-gen-test-1-npu-a3 (push) Has been cancelled
PR Test (NPU) / multimodal-gen-test-2-npu-a3 (push) Has been cancelled
PR Test (Arm64) / pr-gate (push) Has been cancelled
PR Test (Arm64) / check-changes (push) Has been cancelled
PR Test (Arm64) / build-test (push) Has been cancelled
PR Test (sgl-router) / gate (push) Has been cancelled
PR Test (sgl-router) / tier-1 — lint (push) Has been cancelled
PR Test (sgl-router) / tier-2 — build + test (push) Has been cancelled
PR Test (sgl-router) / tier-3 — docker (placeholder) (push) Has been cancelled
PR Test (sgl-router) / tier-3 — k8s integration (push) Has been cancelled
PR Test (sgl-router) / tier-3 — e2e (push) Has been cancelled
PR Test (sgl-router) / finish (push) Has been cancelled
PR Test (NPU) / single-node-poc (map[name:qwen3_6_27b_w8a8_1p_in64k_out1k_50ms runner:linux-aarch64-a3-2 test_case:test/registered/ascend/performance/qwen3_6_27b/test_npu_qwen3_6_27b_w8a8_1p_in64k_out1k_50ms.py test_type:perf]) (push) Has been cancelled
PR Test (NPU) / pr-test-npu-finish (push) Has been cancelled
PR Test (Xeon) / pr-gate (push) Has been cancelled
PR Test (Xeon) / check-changes (push) Has been cancelled
PR Test (Xeon) / build-test (, xeon-gnr, base-b-test-cpu) (push) Has been cancelled
PR Test (XPU) / check-changes (push) Has been cancelled
PR Test (XPU) / pr-gate (push) Has been cancelled
PR Test (XPU) / stage-a-test-1-gpu-xpu (push) Has been cancelled
PR Test (XPU) / wait-for-stage-a (push) Has been cancelled
PR Test (XPU) / stage-b-test-1-gpu-xpu (push) Has been cancelled
PR Test (XPU) / finish (push) Has been cancelled
CI Model Inventory / build-inventory (push) Has been cancelled
Lint / lint (push) Has been cancelled
PR Benchmark (SMG Components) / Benchmark Compilation Check (push) Has been cancelled
PR Benchmark (SMG Components) / Benchmark - Manual Policy (push) Has been cancelled
PR Benchmark (SMG Components) / Benchmark - Request Processing (push) Has been cancelled
PR Benchmark (SMG Components) / Benchmark Summary (push) Has been cancelled
PR Test (SMG) / build-wheel (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on windows (x86_64 - auto) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on macos (x86_64 - auto) (push) Has been cancelled
PR Test (SMG) / python-unit-tests (push) Has been cancelled
PR Test (SMG) / unit-tests (push) Has been cancelled
PR Test (SMG) / benchmarks (push) Has been cancelled
PR Test (SMG) / chat-completions (push) Has been cancelled
PR Test (SMG) / chat-completions-4gpu (push) Has been cancelled
PR Test (SMG) / e2e (push) Has been cancelled
PR Test (SMG) / docker-build-test (push) Has been cancelled
PR Test (SMG) / k8s-integration (push) Has been cancelled
PR Test (SMG) / finish (push) Has been cancelled
PR Test (SMG) / summarize-benchmarks (push) Has been cancelled
Release SGLang Model Gateway Docker Image / publish (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on macos (aarch64 - auto) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on linux (aarch64 - auto) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on linux (x86_64 - auto) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on linux (aarch64 - musllinux_1_1) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on linux (x86_64 - musllinux_1_1) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / Build SDist (push) Has been cancelled
Release SGLang Model Gateway to PyPI / Upload to PyPI (push) Has been cancelled
Release SGLang Kernels / build-cu129-matrix (aarch64, 12.9, 3.10, arm-kernel-build-node) (push) Has been cancelled
Release SGLang Kernels / build-cu129-matrix (x86_64, 12.9, 3.10, x64-kernel-build-node) (push) Has been cancelled
Release SGLang Kernels / release-cu129 (push) Has been cancelled
Release SGLang Kernels / build-cu130-matrix (aarch64, 13.0, 3.10, arm-kernel-build-node) (push) Has been cancelled
Release SGLang Kernels / build-cu130-matrix (x86_64, 13.0, 3.10, x64-kernel-build-node) (push) Has been cancelled
Release SGLang Kernels / release-cu130 (push) Has been cancelled
Release SGLang Kernels / build-rocm-matrix (3.10, 700) (push) Has been cancelled
Release SGLang Kernels / build-rocm-matrix (3.10, 720) (push) Has been cancelled
Release SGLang Kernels / release-rocm700 (push) Has been cancelled
Release SGLang Kernels / release-rocm720 (push) Has been cancelled
Release SGLang Kernels / build-musa43 (43, 3.10) (push) Has been cancelled
Release SGLang Kernels / release-musa43 (push) Has been cancelled
292 lines
9.1 KiB
Plaintext
292 lines
9.1 KiB
Plaintext
{
|
||
"cells": [
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"# Offline Engine API\n",
|
||
"\n",
|
||
"SGLang provides a direct inference engine without the need for an HTTP server, especially for use cases where additional HTTP server adds unnecessary complexity or overhead. Here are two general use cases:\n",
|
||
"\n",
|
||
"- Offline Batch Inference\n",
|
||
"- Custom Server on Top of the Engine\n",
|
||
"\n",
|
||
"This document focuses on the offline batch inference, demonstrating four different inference modes:\n",
|
||
"\n",
|
||
"- Non-streaming synchronous generation\n",
|
||
"- Streaming synchronous generation\n",
|
||
"- Non-streaming asynchronous generation\n",
|
||
"- Streaming asynchronous generation\n",
|
||
"\n",
|
||
"Additionally, you can easily build a custom server on top of the SGLang offline engine. A detailed example working in a python script can be found in [custom_server](https://github.com/sgl-project/sglang/blob/main/examples/runtime/engine/custom_server.py).\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Nest Asyncio\n",
|
||
"Note that if you want to use **Offline Engine** in ipython or some other nested loop code, you need to add the following code:\n",
|
||
"```python\n",
|
||
"import nest_asyncio\n",
|
||
"\n",
|
||
"nest_asyncio.apply()\n",
|
||
"\n",
|
||
"```"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Advanced Usage\n",
|
||
"\n",
|
||
"The engine supports [vlm inference](https://github.com/sgl-project/sglang/blob/main/examples/runtime/engine/offline_batch_inference_vlm.py) as well as [extracting hidden states](https://github.com/sgl-project/sglang/blob/main/examples/runtime/hidden_states). \n",
|
||
"\n",
|
||
"Please see [the examples](https://github.com/sgl-project/sglang/tree/main/examples/runtime/engine) for further use cases."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Ray Integration\n",
|
||
"\n",
|
||
"When running in a Ray cluster, you can use `RayEngine` with a custom placement group for fine-grained GPU placement control.\n",
|
||
"\n",
|
||
"### Custom Placement Groups\n",
|
||
"\n",
|
||
"Pass a `placement_group` with 1-GPU-per-bundle bundles to control exactly which GPUs are used. Each bundle should have exactly 1 GPU for deterministic mapping.\n",
|
||
"\n",
|
||
"```python\n",
|
||
"import ray\n",
|
||
"from ray.util.placement_group import placement_group\n",
|
||
"from sglang.srt.ray.engine import RayEngine\n",
|
||
"\n",
|
||
"ray.init()\n",
|
||
"\n",
|
||
"# Create placement group with specific GPU bundles\n",
|
||
"pg = placement_group(\n",
|
||
" [{\"GPU\": 1} for _ in range(4)], # 4 bundles, each with 1 GPU\n",
|
||
" strategy=\"STRICT_PACK\",\n",
|
||
")\n",
|
||
"ray.get(pg.ready())\n",
|
||
"\n",
|
||
"# Launch RayEngine on custom placement group\n",
|
||
"engine = RayEngine(\n",
|
||
" model_path=\"meta-llama/Meta-Llama-3-8B-Instruct\",\n",
|
||
" tp_size=4,\n",
|
||
" use_ray=True,\n",
|
||
" placement_group=pg,\n",
|
||
")\n",
|
||
"\n",
|
||
"# Optional: specify exact bundle indices via environment variable\n",
|
||
"# export SGLANG_RAY_BUNDLE_INDICES=\"0,1,2,3\"\n",
|
||
"```\n",
|
||
"\n",
|
||
"### Bundle Index Control\n",
|
||
"\n",
|
||
"Use `SGLANG_RAY_BUNDLE_INDICES` environment variable to specify which placement group bundles to use for each worker rank. This enables:\n",
|
||
"- Skipping unhealthy GPUs\n",
|
||
"- Topology-aware placement (e.g., NVLink-connected GPUs)\n",
|
||
"- Non-sequential bundle assignment\n",
|
||
"\n",
|
||
"```bash\n",
|
||
"# Use bundles 0,1,2,7 (skip bundles 3-6) for tp_size=4\n",
|
||
"export SGLANG_RAY_BUNDLE_INDICES=\"0,1,2,7\"\n",
|
||
"\n",
|
||
"# Place workers on NVLink-connected GPUs\n",
|
||
"export SGLANG_RAY_BUNDLE_INDICES=\"0,1,2,3\"\n",
|
||
"```\n",
|
||
"\n",
|
||
"The number of indices must match `world_size` (`tp_size * pp_size * dp_size`, or `tp_size * pp_size` when `enable_dp_attention=True`)."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Offline Batch Inference\n",
|
||
"\n",
|
||
"SGLang offline engine supports batch inference with efficient scheduling."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# launch the offline engine\n",
|
||
"import asyncio\n",
|
||
"\n",
|
||
"import sglang as sgl\n",
|
||
"import sglang.test.doc_patch # noqa: F401\n",
|
||
"from sglang.utils import async_stream_and_merge, stream_and_merge\n",
|
||
"\n",
|
||
"llm = sgl.Engine(model_path=\"qwen/qwen2.5-0.5b-instruct\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Non-streaming Synchronous Generation"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"prompts = [\n",
|
||
" \"Hello, my name is\",\n",
|
||
" \"The president of the United States is\",\n",
|
||
" \"The capital of France is\",\n",
|
||
" \"The future of AI is\",\n",
|
||
"]\n",
|
||
"\n",
|
||
"sampling_params = {\"temperature\": 0.8, \"top_p\": 0.95}\n",
|
||
"\n",
|
||
"outputs = llm.generate(prompts, sampling_params)\n",
|
||
"for prompt, output in zip(prompts, outputs):\n",
|
||
" print(\"===============================\")\n",
|
||
" print(f\"Prompt: {prompt}\\nGenerated text: {output['text']}\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Streaming Synchronous Generation"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"prompts = [\n",
|
||
" \"Write a short, neutral self-introduction for a fictional character. Hello, my name is\",\n",
|
||
" \"Provide a concise factual statement about France’s capital city. The capital of France is\",\n",
|
||
" \"Explain possible future trends in artificial intelligence. The future of AI is\",\n",
|
||
"]\n",
|
||
"\n",
|
||
"sampling_params = {\n",
|
||
" \"temperature\": 0.2,\n",
|
||
" \"top_p\": 0.9,\n",
|
||
"}\n",
|
||
"\n",
|
||
"print(\"\\n=== Testing synchronous streaming generation with overlap removal ===\\n\")\n",
|
||
"\n",
|
||
"for prompt in prompts:\n",
|
||
" print(f\"Prompt: {prompt}\")\n",
|
||
" merged_output = stream_and_merge(llm, prompt, sampling_params)\n",
|
||
" print(\"Generated text:\", merged_output)\n",
|
||
" print()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Non-streaming Asynchronous Generation"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"prompts = [\n",
|
||
" \"Write a short, neutral self-introduction for a fictional character. Hello, my name is\",\n",
|
||
" \"Provide a concise factual statement about France’s capital city. The capital of France is\",\n",
|
||
" \"Explain possible future trends in artificial intelligence. The future of AI is\",\n",
|
||
"]\n",
|
||
"\n",
|
||
"sampling_params = {\"temperature\": 0.8, \"top_p\": 0.95}\n",
|
||
"\n",
|
||
"print(\"\\n=== Testing asynchronous batch generation ===\")\n",
|
||
"\n",
|
||
"\n",
|
||
"async def main():\n",
|
||
" outputs = await llm.async_generate(prompts, sampling_params)\n",
|
||
"\n",
|
||
" for prompt, output in zip(prompts, outputs):\n",
|
||
" print(f\"\\nPrompt: {prompt}\")\n",
|
||
" print(f\"Generated text: {output['text']}\")\n",
|
||
"\n",
|
||
"\n",
|
||
"asyncio.run(main())"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Streaming Asynchronous Generation"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"prompts = [\n",
|
||
" \"Write a short, neutral self-introduction for a fictional character. Hello, my name is\",\n",
|
||
" \"Provide a concise factual statement about France’s capital city. The capital of France is\",\n",
|
||
" \"Explain possible future trends in artificial intelligence. The future of AI is\",\n",
|
||
"]\n",
|
||
"\n",
|
||
"sampling_params = {\"temperature\": 0.8, \"top_p\": 0.95}\n",
|
||
"\n",
|
||
"print(\"\\n=== Testing asynchronous streaming generation (no repeats) ===\")\n",
|
||
"\n",
|
||
"\n",
|
||
"async def main():\n",
|
||
" for prompt in prompts:\n",
|
||
" print(f\"\\nPrompt: {prompt}\")\n",
|
||
" print(\"Generated text: \", end=\"\", flush=True)\n",
|
||
"\n",
|
||
" # Replace direct calls to async_generate with our custom overlap-aware version\n",
|
||
" async for cleaned_chunk in async_stream_and_merge(llm, prompt, sampling_params):\n",
|
||
" print(cleaned_chunk, end=\"\", flush=True)\n",
|
||
"\n",
|
||
" print() # New line after each prompt\n",
|
||
"\n",
|
||
"\n",
|
||
"asyncio.run(main())"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"llm.shutdown()"
|
||
]
|
||
}
|
||
],
|
||
"metadata": {
|
||
"language_info": {
|
||
"codemirror_mode": {
|
||
"name": "ipython",
|
||
"version": 3
|
||
},
|
||
"file_extension": ".py",
|
||
"mimetype": "text/x-python",
|
||
"name": "python",
|
||
"nbconvert_exporter": "python",
|
||
"pygments_lexer": "ipython3"
|
||
}
|
||
},
|
||
"nbformat": 4,
|
||
"nbformat_minor": 2
|
||
}
|