SGLang是一个针对大语言模型和视觉语言模型的快速高效的服务框架,它的功能与vllm类似,用于部署开源模型,并提高模型的推理速度。
SGLang的安装 SGLang 的安装方式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 方式一: 1. 直接使用pip或者uv安装 pip install "sglang[all]>=0.5.2rc2" -i https://pypi.tuna.tsinghua.edu.cn/simple 方式二: 1. 使用docker compose安装 如果需要将模型调用部署成单机或者单节点的服务,可以使用这种方式 1)拉取镜像到本地:docker pull lmsysorg/sglang:latest 2)使用docker-compose执行官方提供的compose.yml文件 compose.yml文件: https://github.com/sgl-project/sglang/blob/main/docker/compose.yaml 官方还有其他方式,这里就不多介绍了,可以查阅文档: https://docs.sglang.ai/get_started/install.html
以下代码中使用的是 Llama-3-8B-Instruct 这个模型,运行环境是 ubuntu22.04、RTX 4090D(24GB) * 1、16 vCPU Intel(R) Xeon(R) Platinum 8474C,不同模型对显存的要求不一样,如果模型参数小,可以使用更小的GPU。
由于模型文件和python包所占空间都很大,所以磁盘空间要足够大,不然在下载模型或者安装包的时候会进行不下去。
SGLang的用法 基础用法 离线推理 SGLang支持离线推理,非流式的代码如下:
1 2 3 4 5 6 7 8 9 10 import sglang as sglif __name__ == '__main__' : llm = sgl.Engine(model_path="/root/autodl-tmp/cache/models/LLM-Research/Meta-Llama-3-8B-Instruct" ) prompt = "The capital of France is" sampling_params = {"temperature" : 0.8 , "top_p" : 0.95 } output = llm.generate(prompt, sampling_params, stream=True ) print(f"=====output: {output} " )
需要流式输出时,在 generate 中加一个 stream=True 参数即可。
可以把离线推理的代码封装在 FastAPI 等web服务器中,通过接口调用离线推理。下面是一个简单的例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 import sglang as sglfrom fastapi import FastAPIfrom pydantic import BaseModelfrom contextlib import asynccontextmanagerengine = None @asynccontextmanager async def lifespan (app: FastAPI) : global engine print("Loading SGLang engine..." ) engine = sgl.Engine( model_path="/root/autodl-tmp/cache/models/LLM-Research/Meta-Llama-3-8B-Instruct" ) print("SGLang engine loaded." ) yield app = FastAPI(lifespan=lifespan) class Chat (BaseModel) : prompt: str @app.post("/api/v1/chat/completion") async def chat_completion (chat: Chat) : global engine prompt = chat.prompt sampling_params = {"temperature" : 0.8 , "top_p" : 0.95 } output = await engine.async_generate(prompt, sampling_params) return output if __name__ == "__main__" : import uvicorn uvicorn.run(app, host="0.0.0.0" , port=8011 )
可以通过 python 脚本请求上面的接口:
1 2 3 4 5 6 7 8 9 import requestsresponse = requests.post( "http://localhost:8011/api/v1/chat/completion" , json={ "prompt" : "Please tell me the capital of France is" , }, ) print(response.json())
通过命令行启动服务 也可以直接通过命令行启动服务:
1 python -m sglang.launch_server --model-path /root/autodl-tmp/cache/models/LLM-Research/Meta-Llama-3-8B-Instruct --port 6006
上面是基于 Llama3-8B-Instruct 模型启动的一个服务,下面是请求这个大模型服务的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 import requestsresponse = requests.post( "http://localhost:6006/generate" , json={ "text" : "The capital of France is" , "sampling_params" : { "temperature" : 0 , "max_new_tokens" : 32 , }, }, ) print(response.json())
如果需要流式输出,可以加上 stream 参数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 import requestsresponse = requests.post( "http://localhost:6006/generate" , json={ "text" : "Please tell me the capital of France is" , "sampling_params" : { "temperature" : 0 , "max_new_tokens" : 32 , }, "stream" : True , }, stream=True ) for chunk in response.iter_lines(decode_unicode=False ): chunk = chunk.decode("utf-8" ) print(f"=====chunk: {chunk} " )
使用 openai 库调用大模型服务:
1 2 3 4 5 6 7 8 9 10 11 12 13 import openaiclient = openai.Client(base_url=f"http://127.0.0.1:6006/v1" , api_key="None" ) response = client.chat.completions.create( model="Meta-Llama-3-8B-Instruct" , messages=[ {"role" : "user" , "content" : "List 3 countries and their capitals." }, ], temperature=0 , max_tokens=64 , ) print(response)
通过Python脚本启动服务 SGLang也可以通过python脚本启动服务,就是把命令行的命令在python代码中执行,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 from sglang.test.doc_patch import launch_server_cmdfrom sglang.utils import wait_for_server, print_highlight, terminate_processif __name__ == '__main__' : server_process, port = launch_server_cmd( """ python -m sglang.launch_server --model-path /root/autodl-tmp/cache/models/LLM-Research/Meta-Llama-3-8B-Instruct --host 0.0.0.0 --log-level warning """ ) print(f"=====port: {port} " ) wait_for_server(f"http://localhost:{port} " )
调用上面的服务:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 import requestsresponse = requests.post( "http://localhost:39955/generate" , json={ "text" : "Please tell me the capital of France is" , "sampling_params" : { "temperature" : 0 , "max_new_tokens" : 32 , }, }, ) print(response.json())
SGLang原生API SGLang提供了原生API供我们调用大模型服务,上面使用的 /generate 就是其中一个原生API。部分原生API列表:
1 2 3 4 5 6 /generate /get_model_info 获取模型信息 /get_server_info 获取模型服务的信息 /update_weights 在不重启服务的情况下,从磁盘上更新文件权重 /encode 将文本转换为向量,只适用于向量模型 /v1/rerank 对若干个文档查询对进行重排序,只适用于Cross-encoder的模型
/update_weights api的请求例子如下:
1 2 3 4 5 6 7 8 import requestsresponse = requests.post( "http://localhost:39955/update_weights" , json={"model_path" : "/root/autodl-tmp/cache/models/LLM-Research/Meta-Llama-3-8B-Instruct" } ) print(response.json())
高级特性 SGLang Router SGLang Router是一个高性能的请求分发系统,它可以把推理请求路由到多个 SGLang 运行实例上,它具有缓存感知负载平衡、容错功能,并支持高级部署模式,包括数据并行和预填充解码分解。
安装方式:
1 pip install sglang-router
SGLang Router 支持三种部署模型:
1 2 3 联合启动模式: Router和workers一起启动,适用于单节点部署 分开启动模式: Router和workers分别独立启动,如果是多节点部署,可以选择这种方式 预填充解码分解:分解服务的专用模式
联合启动模式是在一个命令行中同时启动router和worker进程,命令如下:
1 python -m sglang_router.launch_server --model-path /root/autodl-tmp/cache/models/Qwen/Qwen3-4B --dp-size 2 --host 0.0.0.0 --port 12073
通过router的服务调用推理服务:
1 2 3 4 5 6 7 8 9 10 11 12 13 import requestsresponse = requests.post( "http://localhost:12073/generate" , json={ "text" : "你是谁" , "sampling_params" : { "temperature" : 0 , "max_new_tokens" : 32 , }, }, ) print(response.json())
分开启动模式是分别启动worker和router,先启动两个推理服务worker:
1 2 python -m sglang.launch_server --model-path /root/autodl-tmp/cache/models/Qwen/Qwen3-4B --mem-fraction-static 0.4 --port 12071 python -m sglang.launch_server --model-path /root/autodl-tmp/cache/models/Qwen/Qwen3-4B --mem-fraction-static 0.5 --port 12072
再启动router服务:
1 2 3 4 5 python -m sglang_router.launch_router \ --worker-urls http://localhost:12071 http://localhost:12072 \ --host 0.0.0.0 \ --port 12070 \ --policy random
可以通过 router 的 12070 端口调用服务,router 会根据策略将请求分发到不同的 worker 上。也可以通过 worker 的端口单独访问某个 worker。
其中,policy参数的可选值有:random、round_robin、cache_aware、power_of_two,默认值是 cache_aware。
policy参数值的含义:
1 2 3 4 random: 在 worker 之间随机分配请求 round_robin: 按顺序循环分发请求 power_of_two: 抽样两个 worker,将请求分配到负载较少的那个 worker 中 cache_aware: 结合了缓存优化与负载均衡的分发的策略
FastAPI中使用SGLang 最后看一个在 FastAPI 中调用 SGLang 的例子,主要功能是通过 SGLang 部署多个模型,然后通过 FastAPI 接口访问不同模型的推理服务。(或者部署多个 SGLang Router 服务,通过 Fast API 接口访问 SGLang Router 服务)
首先使用 SGLang 部署两个模型:
1 2 python -m sglang.launch_server --model-path /root/autodl-tmp/cache/models/Qwen/Qwen3-4B --mem-fraction-static 0.4 --port 12071 python -m sglang.launch_server --model-path /root/autodl-tmp/cache/models/Qwen/Qwen2.5-3B-Instruct --mem-fraction-static 0.5 --port 12072
然后在 FastAPI 接口中请求这两个服务:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 import requestsimport uvicornfrom fastapi import FastAPIfrom pydantic import BaseModelapp = FastAPI() MODEL_SGLANG_SERVER_MAPPING = { "Qwen3-4B" : "http://localhost:12071/generate" , "Qwen2.5-3B-Instruct" : "http://localhost:12072/generate" } class Chat (BaseModel) : model: str prompt: str @app.post("/api/v1/chat/completion") async def chat_completion (chat: Chat) : model = chat.model server = MODEL_SGLANG_SERVER_MAPPING.get(model) if not server: return None sampling_params = {"temperature" : 0.8 , "top_p" : 0.95 } resp = requests.post( server, json={ "text" : chat.prompt, "sampling_params" : sampling_params } ) return resp.json() if __name__ == "__main__" : uvicorn.run(app, host="0.0.0.0" , port=12070 )
调用 FastAPI 接口执行推理:
1 2 3 4 5 6 7 8 9 10 11 12 import requestsresponse = requests.post( "http://localhost:12070/api/v1/chat/completion" , json={ "model" : "Qwen2.5-3B-Instruct" , "prompt" : "你是谁" , "stream" : False } ) print(response.json())