贡献指南#
欢迎来到 SGLang!感谢您有兴趣为本项目做出贡献。本指南简要概述了如何设置环境、运行测试、构建文档以及提交 Pull Request (PR)。无论您是修复一个小 bug 还是开发一个重大功能,我们都建议遵循这些步骤,以确保贡献过程顺利进行。
从源码安装 SGLang#
Fork 并克隆仓库#
注意:新贡献者没有直接向 SGLang 官方仓库推送代码的写权限。请在您的 GitHub 账号下 fork 该仓库,然后将您的 fork 克隆到本地。
git clone https://github.com/<your_user_name>/sglang.git
从源码构建#
请参考 从源码安装 SGLang。
使用 pre-commit 格式化代码#
我们使用 pre-commit 来维持一致的代码风格检查。在推送更改之前,请运行:
pip3 install pre-commit
pre-commit install
pre-commit run --all-files
pre-commit run --all-files会手动运行所有配置好的检查,并尽可能应用修复。如果第一次运行失败,请重新运行以确保 lint 错误已完全解决。在创建 Pull Request 之前,请确保您的代码通过了所有检查。不要直接提交到
main分支。请务必创建一个新分支(例如feature/my-new-feature),推送您的更改,然后从该分支开启 PR。
运行并添加单元测试#
如果您添加了新功能或修复了 bug,请添加相应的单元测试以确保覆盖率并防止回归。SGLang 使用 Python 内置的 unittest 框架。有关运行测试并将其集成到 CI 中的详细说明,请参考 test/README.md。
编写文档#
我们建议新贡献者从编写文档开始,这有助于您快速了解 SGLang 的代码库。更多详情请参考 docs/README.md。
测试准确性#
如果您的代码更改了模型输出,请运行准确性测试。few-shot GSM8K 是一个快速的完整性检查方法。
# Launch a server
python3 -m sglang.launch_server --model Qwen/Qwen2-7B-Instruct
# Evaluate
python3 -m sglang.test.few_shot_gsm8k --num-questions 200
请注意,上述脚本主要用于完整性检查,而非严谨的准确性或速度测试。由于批处理和推理引擎的非确定性,该测试的准确性可能会有较大波动(1%–5%)。此外,不要依赖该脚本中的“Latency/Output throughput”,因为它不是正式的速度测试。
如今 GSM8K 对于最先进的模型来说过于简单。请尝试您自己更具挑战性的准确性测试。您可以在以下文件中找到额外的准确性评估示例:
测试速度基准#
参考 基准测试与性能分析。
请求合并审查#
您可以遵循 MAINTAINER.md 中描述的 Pull Request 合并流程。您需要与合并值班人员(Merge Oncall)、代码所有者(Codeowner)以及其他审阅者合作以获得批准。之后您的 PR 才能被合并。
如何触发 CI 测试#
虽然我们有很多开放的 PR,但 CI 机器资源有限,因此只有顶层且受信任的贡献者才有权限触发 CI 测试。拥有权限的用户列表见 CI_PERMISSIONS.json
若要在 Pull Request 上运行 CI,必须带有 “run-ci” 标签。授权用户可以通过在 PR 中回复以下命令来添加标签或重新运行失败的测试:
/tag-run-ci-label:添加 “run-ci” 标签。此后的每一次提交都会触发 CI。/rerun-failed-ci:重新运行最近一次提交中失败或不稳定的测试。/tag-and-rerun-ci:一个执行/tag-run-ci-label和/rerun-failed-ci两个操作的组合命令。/rerun-stage <stage-name>:重新运行特定的测试阶段,而不必等待其依赖项。当您想要快速验证针对特定测试失败的修复,而不想等待约 30 分钟让前置阶段完成时,这非常有用。
如果您拥有权限,斜杠命令处理器 (Slash Command Handler) 将运行您的命令并在您的评论下回复 👍。该反应可能需要几分钟才会显示。这里有一个使用示例。
为了避免在 PR 中产生过多的 /rerun-failed-ci 评论,您也可以通过编辑现有评论并添加任何后缀(例如 /rerun-failed-ci try again)来触发命令。
重新运行单个测试阶段的示例:/rerun-stage unit-test-backend-4-gpu。
如果您没有权限,请请求维护者为您触发 CI。
CI 速率限制#
我们实施了 CI 速率限制,以防止滥用并确保 CI 资源的公平使用。
每个 CI 工作流在其配置文件中都有一个默认限制。例如,在 pr-gate.yml 中,默认冷却时间为 120 分钟,每个工作流可以通过 cool-down-minutes 输入参数来覆盖它。
cool-down-minutes:
description: "Default cooldown period in minutes; 0 disables rate limiting"
type: number
default: 120
CI_PERMISSIONS.json 中列出的用户可能拥有个人的冷却时间间隔。在实践中,我们取工作流默认窗口和用户特定间隔中的最小值。
代码风格指南#
避免代码重复。如果同一代码段(超过五行)多次出现,请将其提取为共享函数。
尽量减少设备同步。尽可能减少昂贵的 CPU-GPU 同步操作,如
tensor.item()或tensor.cpu()。使用向量化代码。优先考虑极致效率。SGLang 是一个运行时(runtime),您的代码大多运行在每个请求的关键路径上。尽可能优化所有细微的开销,尤其是在模型的前向传播代码中。
一个常见的模式是在模型前向传播中进行运行时检查(例如 这里)。这些检查对于每一层极可能都是相同的。请尽可能将结果缓存为单个布尔值。
使函数尽可能纯净。避免对参数进行原地修改。
保持文件简练。如果一个文件超过 2000 行代码,请将其拆分为多个较小的文件。(例如
scheduler.py,scheduler_output_processor_mixin.py)保持测试快速运行。
如果单个测试文件的运行时间超过 500 秒,请将其拆分为多个较小的文件(例如
test_eagle_infer_a.py,test_eagle_infer_b.py)。如果 GitHub 工作流中的单个作业运行时间超过 30 分钟,请将其拆分为更小的作业/步骤。
在单元测试中重用服务器启动以加快测试运行速度。
在支持新硬件或新功能时,请遵循以下准则:
不要大幅改动现有代码。
总是首选新建文件来引入针对新硬件的特定组件(例如
allocator_ascend.py)。如果您为新功能编写了多个 if/else 块,请确保通用路径(例如 NVIDIA 硬件或现有代码路径)位于第一个分支。
如何更新 sgl-kernel#
由于 sglang 和 sgl-kernel 是独立的 Python 包,我们目前的 GitHub CI 基础设施不支持在同一个 Pull Request (PR) 中更新内核并立即使用它。若要在 sgl-kernel 包中添加新内核或修改现有内核,必须使用多个 PR。
请遵循以下步骤:
给新手的建议#
如果您想做出贡献但没有具体的想法,请选择带有 “good first issue” 或 “help wanted” 标签的任务。这些任务通常复杂度较低,是了解代码库的绝佳入口。此外,可以查看此 代码详解 以深入了解 SGLang 的工作流程。
如果您有任何问题或想发起讨论,请随时在我们的 Slack 频道 中提问。
感谢您对 SGLang 的关注。祝编码愉快!