slime 中基于 YAML 的 SGLang 高级引擎部署:--sglang-config 完整指南
2026/9/16 18:07:26 网站建设 项目流程

slime 中基于 YAML 的 SGLang 高级引擎部署:--sglang-config 完整指南

【免费下载链接】slimeslime is an LLM post-training framework for RL Scaling.项目地址: https://gitcode.com/GitHub_Trending/slime12/slime

--sglang-config是 slime(面向 RL Scaling 的 LLM 后训练框架)提供的基于 YAML 的 SGLang 引擎部署配置系统。通过一份 YAML 文件,你可以在一套训练流程中同时编排多模型服务(actor / reference / reward)、Prefill-Decode (PD) 分离异构服务器组(不同 TP 大小、不同 worker 类型、不同 ServerArgs 覆盖),甚至将其作为复杂推理拓扑的独立 SGLang 启动器。读完本文,你将掌握--sglang-config的完整配置语法、7 种实战部署模式、router 会话亲和路由原理,以及它与旧参数(--prefill-num-servers--rollout-external-engine-addrs)的边界与取舍。


架构概览:从单模型单 Router 到多模型多 Router

在默认配置(不使用--sglang-config)下,slime 部署单个模型,放在单个 router后面,使用统一的服务器组:

使用--sglang-config后,SGLang 部署扩展为多模型、多 router拓扑:

核心设计原则:

  • 每个模型拥有独立的 router。模型在路由层隔离,支持独立的负载均衡和容错;一个模型的路由故障不会影响其他模型的流量。
  • 同一模型内的服务器组可以异构。不同组可以有不同的 TP 大小、worker 类型(prefill / decode / regular / placeholder)以及独立的 SGLang ServerArgs 覆盖。
  • 权重同步按模型维度。只有update_weights: true的模型会接收来自训练的权重更新;冻结的模型(reference、reward 等)保持 checkpoint 原样服务,这避免了向只读模型推送训练权重带来的额外开销与风险。

从源码看,这一设计落实在slime/backends/sglang_utils/sglang_config.py的三层数据类上:SglangConfig(顶层,持有模型列表)→ModelConfig(单个模型的拓扑)→ServerGroupConfig(单个服务器组)。每个模型在启动后都会在args.sglang_model_routers{ model_name: (ip, port) }字典)中登记自己的 router 地址,供自定义 rollout 函数按名路由。


配置格式与字段参考

配置文件是一个 YAML 文档,顶层必须包含sglang键,其值为模型定义列表:

sglang: - name: <model_name> # 必填。模型的唯一标识符。 model_path: <path> # 可选。HF checkpoint 路径。默认使用 --hf-checkpoint。 update_weights: <bool> # 可选。是否从训练同步权重。未设置时自动推断。 num_gpus_per_engine: <int> # 可选。该模型所有组的默认 TP 大小。 server_groups: # 必填。服务器组配置列表。 - worker_type: <type> # 必填。可选:regular、prefill、decode、placeholder、encoder。 num_gpus: <int> # 必填。分配给该组的 GPU 总数(必须 > 0)。 num_gpus_per_engine: <int> # 可选。该组的 TP 大小覆盖。 overrides: <dict> # 可选。SGLang ServerArgs 字段覆盖。

模型级字段

字段类型默认值说明
namestr必填模型唯一名称(如"actor""ref""reward")。用作args.sglang_model_routers的 key,也是自定义 rollout 中get_model_url(args, name, ...)的查找键。
model_pathstrargs.hf_checkpointHuggingFace checkpoint 路径。同一模型内的所有服务器组必须共享同一个 model path(在ModelConfig.resolve()中校验)。
update_weightsbool自动推断该模型是否接收训练权重更新。未设置时自动推断:有效 model path 与--hf-checkpoint匹配则为true,否则为false(同时输出 warning)。
num_gpus_per_engineintargs.rollout_num_gpus_per_engine该模型服务器组的默认 TP 大小。各组可通过自身num_gpus_per_engine覆盖。
server_groupslist必填ServerGroupConfig条目列表,定义引擎拓扑。(engine_groups作为向后兼容别名仍可使用,见SglangConfig.from_yaml()的解析逻辑。)

服务器组级字段

字段类型默认值说明
worker_typestr必填引擎类型:regular(标准)、prefill(PD prefill worker)、decode(PD decode worker)或placeholder(占位,不启动引擎)。
num_gpusint必填该组的 GPU 总数。必须 > 0,否则ServerGroupConfig.__post_init__直接断言失败。
num_gpus_per_engineint模型的num_gpus_per_engineTP 大小覆盖。每个引擎实例占用的 GPU 数量。
overridesdict{}SGLangServerArgs字段覆盖。优先级最高,覆盖--sglang-*CLI 参数和模型级默认值。

Worker 类型

类型说明使用场景
regular标准 SGLang 引擎默认模式,同时处理 prefill 和 decode
prefillPD 分离的 prefill worker专门处理 prompt;与decodeworker 配对
decodePD 分离的 decode worker专门生成 token;与prefillworker 配对
placeholder占位,不创建引擎为训练共置预留 GPU 或留作未来使用

源码补充(encoder 类型):在ServerGroupConfig__post_init__校验中,合法类型集合为{"regular", "prefill", "decode", "placeholder", "encoder"}(见 sglang_config.py)。其中encoder用于 EPD(Encoder-Prefill-Decode)三级分离,encoder 引擎会最先启动,其 URL 被自动注入到 prefill 组的encoder_urls中;ModelConfig也据此暴露了has_pd_disaggregationhas_encoder_disaggregation两个属性供部署逻辑分支判断。这是比文档表格更进一步的最新能力。


使用模式:7 种实战部署

1. 基本单模型部署

最简单的配置即可复现默认行为:

# sglang_basic.yaml sglang: - name: default server_groups: - worker_type: regular num_gpus: 8
python train.py \ --sglang-config sglang_basic.yaml \ --rollout-num-gpus 8 \ --rollout-num-gpus-per-engine 2 \ ...

这将创建 4 个引擎(8 GPU ÷ 2 GPU/引擎),位于单个 router 之后。引擎数量 =num_gpus / num_gpus_per_engine_on_node,其中num_gpus_per_engine_on_node = min(num_gpus_per_engine, args.num_gpus_per_node)(见 engine_group.py),这意味着跨节点引擎会被正确切分。

2. PD 分离(Prefill-Decode Disaggregation)

将 prefill 和 decode 阶段分离到专用服务器组,以提升多轮和 agentic 场景的吞吐量:

# sglang_pd.yaml sglang: - name: actor server_groups: - worker_type: prefill num_gpus: 4 num_gpus_per_engine: 2 # 2 个 prefill 引擎,TP=2 - worker_type: decode num_gpus: 12 num_gpus_per_engine: 4 # 3 个 decode 引擎,TP=4
python train.py \ --sglang-config sglang_pd.yaml \ --rollout-num-gpus 16 \ ...

为什么需要 PD 分离?在多轮场景中,prefill 和 decode 具有完全不同的计算特性:prefill 是计算密集型(一次性处理整个 prompt 的 KV 计算),而 decode 是内存带宽密集型(逐 token 生成,受限于显存带宽)。将两者分离可以:

  • 为 prefill 使用更小的 TP(每 GPU 吞吐量更高,prompt 处理并行度更充分)
  • 为 decode 使用更大的 TP(单 token 延迟更低)
  • 独立扩展 prefill 与 decode 的容量(例如多轮对话场景 prefill 占比高,可单独扩容)

注意:PD 分离使用 SGLang Model Gateway(sgl-router)并设置pd_disaggregation=True。在ModelConfig中,只要任一组的worker_typeprefilldecodehas_pd_disaggregation即为true

3. 多模型服务(Multi-Model Serving)

同时部署多个模型,每个模型拥有独立的 router:

# sglang_multi_model.yaml sglang: - name: actor update_weights: true # 接收训练权重更新 server_groups: - worker_type: regular num_gpus: 8 num_gpus_per_engine: 4 - name: ref model_path: /path/to/ref_model # 不同的模型 checkpoint update_weights: false # 冻结,不更新权重 server_groups: - worker_type: regular num_gpus: 4 num_gpus_per_engine: 2 - name: reward model_path: /path/to/reward_model update_weights: false server_groups: - worker_type: regular num_gpus: 4 num_gpus_per_engine: 2
python train.py \ --sglang-config sglang_multi_model.yaml \ --rollout-num-gpus 16 \ --hf-checkpoint /path/to/actor_model \ --rollout-function-path my_rollout.generate_rollout \ ...

在自定义 rollout 函数中访问模型:

from slime.rollout.sglang_rollout import get_model_url from slime.utils.http_utils import post async def my_generate(args, sample, sampling_params): # 路由到 actor 模型(默认) actor_url = get_model_url(args, "actor", "/generate") output = await post(actor_url, {"text": sample.prompt, "sampling_params": sampling_params}) # 路由到 reference 模型 ref_url = get_model_url(args, "ref", "/generate") ref_output = await post(ref_url, {"text": sample.prompt, "sampling_params": sampling_params}) # 路由到 reward 模型(如 OpenAI 兼容 API) reward_url = get_model_url(args, "reward", "/v1/chat/completions") reward_output = await post(reward_url, {...}) ...

get_model_url()args.sglang_model_routers(一个将模型名称映射到(ip, port)元组的字典)中读取,该字典在引擎启动后自动填充。从实现上看(sglang_rollout.py),若目标模型名不在字典中或字典未设置,它会优雅地回退到默认 router(args.sglang_router_ip:args.sglang_router_port),因此自定义 rollout 函数即使只写单模型逻辑也不会崩。

4. 多模型 + PD 分离

将多模型与 PD 分离结合,实现最大灵活性:

# sglang_full.yaml sglang: - name: actor update_weights: true server_groups: - worker_type: prefill num_gpus: 4 num_gpus_per_engine: 2 - worker_type: decode num_gpus: 8 num_gpus_per_engine: 4 - name: ref model_path: /path/to/ref_model update_weights: false server_groups: - worker_type: regular num_gpus: 4 num_gpus_per_engine: 2

5. 占位组用于 GPU 预留(Placeholder)

使用placeholder组来预留 GPU 而不创建引擎。这在训练与推理共置(co-location)场景中尤其有用——部分 GPU 需要预留给训练进程使用,SGLang 部署不应触碰:

sglang: - name: actor server_groups: - worker_type: regular num_gpus: 6 num_gpus_per_engine: 2 - worker_type: placeholder num_gpus: 2 # 预留 2 个 GPU(不创建引擎)

源码细节:engine_group.py中,placeholder组的 GPU 槽位照常占用偏移,但引擎列表为空(all_engines=[None] * num_engines if worker_type != "placeholder" else []),且 GPU 分配时跳过引擎创建。这样后续训练进程可以安全复用这些槽位,不会与推理引擎冲突。

6. 按组覆盖 ServerArgs(overrides)

使用overrides将 SGLangServerArgs字段应用到特定服务器组,而不影响其他组:

sglang: - name: actor server_groups: - worker_type: regular num_gpus: 8 num_gpus_per_engine: 4 overrides: mem_fraction_static: 0.85 context_length: 32768 chunked_prefill_size: 4096 enable_torch_compile: true

覆盖具有最高优先级:在_compute_server_args中,overrides会覆盖基础的--sglang-*CLI 参数与模型级默认值。典型应用场景:

  • 不同组使用不同的显存占比(mem_fraction_static
  • prefill 与 decode 组使用不同的 context length
  • 在特定组上启用实验性特性(如enable_torch_compile),而不影响其他组稳定性

7. 独立 SGLang 启动器 / 连接外部引擎

虽然--sglang-config是为 slime 的训练流水线设计的,但通过连接外部引擎地址,它也能服务于纯推理/生产部署场景。

使用预启动的外部引擎:

# 步骤 1:外部启动 SGLang 引擎 python -m sglang.launch_server --model-path /path/to/model --port 10090 ... python -m sglang.launch_server --model-path /path/to/model --port 10091 ... # 步骤 2:将 slime 连接到外部引擎 python train.py \ --rollout-external-engine-addrs host1:10090 host2:10091 \ ...

slime 会请求每个外部引擎的/server_info端点,自动推断rollout_num_gpus、单个引擎的 GPU 数、SGLang 并行参数以及 prefill/decode worker 类型。如果未提供--sglang-router-ip/--sglang-router-port,slime 会自行启动 router,并把外部引擎注册进去。

注意:--sglang-config--rollout-external-engine-addrs互斥:前者由 slime 管理完整引擎生命周期(创建、拉起、故障恢复),后者面向引擎已预部署的场景。选择标准很简单——是否希望 slime 接管引擎生命周期。

关于 external engine 的模型选择、update from disk 与 delta disk transport,详见 External Rollout Engines 配置路线图。


Router 配置

每个模型都有独立的 router(默认使用 SGLang Model Gateway)。router 相关 CLI 参数由add_sglang_router_arguments注册(见 arguments.py),包括--sglang-router-ip--sglang-router-port--sglang-router-request-timeout-secs(默认 14400 秒)等。

Router 策略

--router-policy round_robin # 简单轮询 --router-policy consistent_hashing # 多轮会话亲和 --router-policy cache_aware # 缓存感知路由(默认)

多轮 Agent 的会话亲和路由(Session-Affinity Routing)

对于多轮对话和 agentic 场景,会话亲和确保同一对话的所有请求路由到同一个 backend worker。这能显著提升 prefix cache 命中率——worker 已缓存了对话历史,后续轮次的 KV 前缀直接命中,既降低时延又减少重复计算。

工作原理(结合源码验证):

  1. 每个 sample 通过 UUID 分配唯一的session_id:在generate入口处,若sample.session_id is None,则赋值为str(uuid.uuid4())(见 sglang_rollout.py)。
  2. 每次请求时,若router_policy == "consistent_hashing",slime 在 HTTP header 中传递X-SMG-Routing-Key: <session_id>(见 sglang_rollout.py)。
  3. SGLang Model Gateway 的 consistent hashing 策略将该 key 映射到特定的 worker。
  4. 后续轮次复用相同的session_id,确保命中同一个 worker,实现 KV 前缀复用。
--router-policy consistent_hashing

解析规则(Resolution Rules)

加载配置时,slime 按以下优先级顺序解析(核心逻辑在ModelConfig.resolve()resolve_sglang_config(),见 sglang_config.py):

  1. 每引擎 GPU 数回退:num_gpus_per_engine→ 模型num_gpus_per_engineargs.rollout_num_gpus_per_engine。解析时还会把模型级model_path注入到各组的overrides["model_path"],供_compute_server_args统一读取。
  2. 模型路径回退:overrides.model_path→ 模型model_pathargs.hf_checkpoint
  3. 权重更新推断:如果update_weights未设置:有效 model path 与--hf-checkpoint匹配则为true,否则为false(并输出 warning,建议显式设置以消除告警)。
  4. GPU 总数校验:所有模型所有组的num_gpus总和必须等于--rollout-num-gpus,否则在resolve_sglang_config中直接断言失败(sglang_config total GPUs != rollout_num_gpus)。

模型路径一致性校验:resolve()还会断言同一模型内所有组的 model path 相同(取各组overrides["model_path"]的集合,长度必须为 1),这是 FAQ 中"同模型内不可混用不同 model path"的源码落点。


互斥关系(Mutual Exclusion)

--sglang-config与以下选项互斥,冲突会在参数校验阶段直接断言报错(见 arguments.py):

选项冲突原因
--prefill-num-serversPD 分离已通过 YAML 中的server_groups配置,二者语义重叠
--rollout-external-engine-addrs外部引擎自带拓扑;--sglang-config在内部管理生命周期

兼容性细节:旧参数--prefill-num-servers内部其实等价于一个由SglangConfig.from_prefill_num_servers()生成的单模型 PD 配置——它把总 GPU 拆分为 prefill 组与 decode 组。也就是说,--prefill-num-servers--sglang-config的一个特例;新部署应统一迁移到 YAML 配置以获得完整的模型/组编排能力。


完整示例:多模型 Agentic 训练(32 GPU)

下面是一个完整的实战示例:在 32 个 GPU 上,使用 actor(PD 分离)+ reference + reward 三模型拓扑进行 agentic RL 训练。

配置文件(sglang_agent.yaml):

sglang: - name: actor update_weights: true server_groups: - worker_type: prefill num_gpus: 4 num_gpus_per_engine: 2 overrides: chunked_prefill_size: 8192 - worker_type: decode num_gpus: 12 num_gpus_per_engine: 4 overrides: mem_fraction_static: 0.88 - name: ref model_path: /data/models/Qwen3-32B update_weights: false server_groups: - worker_type: regular num_gpus: 8 num_gpus_per_engine: 4 - name: reward model_path: /data/models/reward-model update_weights: false server_groups: - worker_type: regular num_gpus: 8 num_gpus_per_engine: 4

启动命令:

python train.py \ --sglang-config sglang_agent.yaml \ --hf-checkpoint /data/models/Qwen3-8B \ --rollout-num-gpus 32 \ --rollout-function-path my_agent.rollout.generate_rollout \ --custom-rm-path my_agent.reward.reward_func \ --advantage-estimator grpo \ --n-samples-per-prompt 8 \ ...

自定义 rollout 函数(my_agent/rollout.py):

from slime.rollout.sglang_rollout import get_model_url from slime.utils.http_utils import post async def generate_with_models(args, sample, sampling_params): """使用 actor 生成,用 reward 模型打分,与 reference 比较。""" # 从 actor 生成(PD 分离下的 prefill/decode 对用户透明) actor_url = get_model_url(args, "actor", "/generate") actor_output = await post(actor_url, { "text": sample.prompt, "sampling_params": sampling_params, "return_logprob": True, }) # 获取 reference logprobs 用于 KL penalty ref_url = get_model_url(args, "ref", "/generate") ref_output = await post(ref_url, { "text": sample.prompt + actor_output["text"], "sampling_params": {"max_new_tokens": 0, "temperature": 0}, "return_logprob": True, }) # 用 reward 模型打分(OpenAI 兼容接口) reward_url = get_model_url(args, "reward", "/v1/chat/completions") reward_output = await post(reward_url, { "model": "reward", "messages": [{"role": "user", "content": sample.prompt + actor_output["text"]}], }) # ... 处理输出并返回 Sample

这个示例体现了--sglang-config的核心价值:actor 走 PD 分离拓扑追求吞吐与延迟平衡(prefill 组显式配置chunked_prefill_size: 8192,decode 组单独调高mem_fraction_static: 0.88),ref 与 reward 作为冻结模型各自独立部署且绝不接收训练权重更新。


FAQ

Q: 同一模型内可以混用 PD 和 regular 组吗?

不可以。PD 分离要求一个模型的服务器组要么全部是 prefill/decode 对,要么全部是 regular。不支持在同一模型内混用regularprefill/decode。需要不同拓扑时,请拆分为独立的模型条目。

Q: 如果num_gpus不能被num_gpus_per_engine整除怎么办?

对于跨节点引擎(num_gpus_per_engine > num_gpus_per_node),引擎划分基于每节点的本地 GPU 数量num_gpus_per_engine_on_node = min(num_gpus_per_engine, args.num_gpus_per_node),引擎数 =num_gpus // num_gpus_per_engine_on_node。例如每节点 8 个 GPU 且num_gpus_per_engine: 16时,每个引擎横跨 2 个节点。

Q: 同一模型内的不同服务器组可以使用不同的 model path 吗?

不可以。同一模型内的所有服务器组必须共享相同的model_path,这在ModelConfig.resolve()中被显式校验(各组 model path 集合必须只有一个元素)。如果需要不同模型,请定义为独立的模型条目。

Q: 运行时如何获取特定模型的 router 地址?

使用slime.rollout.sglang_rollout中的get_model_url(args, "model_name", "/endpoint")。它从args.sglang_model_routers(一个{ model_name: (ip, port) }字典)中读取,该字典在引擎启动后自动填充;若模型名不存在,则回退到默认 router 地址。

Q: 可以不训练,只用--sglang-config做推理吗?

--sglang-config是为 slime 的训练循环设计的,但你可以通过仅配置 rollout 的运行(--rollout-num-gpus等推理参数)实现纯推理场景。对于完全独立的 SGLang 推理服务,建议直接使用 SGLang 原生的python -m sglang.launch_server,或使用--rollout-external-engine-addrs连接预部署的引擎。

Q:--sglang-config--prefill-num-servers是什么关系?

--prefill-num-servers是启用 PD 分离的旧方式——它内部构造一个带 prefill + decode 组的单模型配置(等价于SglangConfig.from_prefill_num_servers())。--sglang-config是更新、更灵活的方式,支持多模型、异构组与按组 overrides。两者互斥,推荐所有新部署迁移到--sglang-config


延伸阅读

  • 配置数据类与解析逻辑:slime/backends/sglang_utils/sglang_config.py
  • 参数注册与互斥校验:slime/backends/sglang_utils/arguments.py
  • 引擎组部署、placeholder 处理与故障恢复:slime/backends/sglang_utils/engine_group.py
  • get_model_urlsession_id与路由头注入:slime/rollout/sglang_rollout.py
  • 外部引擎部署路线:External Rollout Engines

【免费下载链接】slimeslime is an LLM post-training framework for RL Scaling.项目地址: https://gitcode.com/GitHub_Trending/slime12/slime

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询