贡献指南#

欢迎来到 SGLang!感谢您对项目的关注。本指南提供了如何设置环境、运行测试、构建文档以及提交 Pull Request (PR) 的简要概述。无论您是修复小型错误还是开发主要功能,我们都鼓励您遵循这些步骤,以确保贡献过程顺利。

从源码安装 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。

运行和添加单元测试#

如果您添加新功能或修复错误,请添加相应的单元测试以确保覆盖范围并防止回归。 SGLang 使用 Python 内置的 unittest 框架。 有关运行测试并将其集成到 CI 的详细说明,请参考 test/README.md

编写文档#

我们建议新贡献者从编写文档开始,这有助于您快速了解 SGLang 代码库。 有关更多详细信息,请参考 docs/README.md

测试准确性#

如果您的代码更改了模型输出,请运行准确性测试。快速验证是少样本 GSM8K。

# 启动服务器
python3 -m sglang.launch_server --model Qwen/Qwen2-7B-Instruct

# 评估
python3 -m sglang.test.few_shot_gsm8k --num-questions 200

请注意,上述脚本主要用于快速验证,不是严格的准确性或速度测试。 由于批处理和推理引擎的非确定性,此测试的准确性可能会有显著差异(1%-5%)。 另外,不要依赖此脚本中的"延迟/输出吞吐量",因为它不是适当的速度测试。

如今,GSM8K 对于最先进的模型来说太简单了。请尝试使用自己更具挑战性的准确性测试。 您可以在以下位置找到额外的准确性评估示例:

基准测试速度#

请参考基准测试和性能分析

请求审查以合并#

您可以遵循 MAINTAINER.md 中描述的 Pull Request 合并流程。 您需要与合并值班人员、代码所有者和其他审查人员合作以获得他们的批准。 然后您的 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 的单个命令。

如果您有权限,斜杠命令处理器 将运行您的命令并在您的评论中回复 👍。反应可能需要几分钟时间出现。这是用法示例

为了避免在 PR 中发布过多的 /rerun-failed-ci 评论,您还可以通过编辑现有评论并添加任何后缀(例如 /rerun-failed-ci 再试一次)来触发命令。

如果您没有权限,请要求维护者为您触发 CI。

CI 速率限制#

我们应用 CI 速率限制以防止滥用并确保 CI 资源的公平使用。

每个 CI 工作流在工作流配置文件中都有一个默认限制。例如,在 pr-gate.yml 中,默认冷却期为 120 分钟,每个工作流都可以通过 cool-down-minutes 输入参数覆盖它:

cool-down-minutes:
  description: "默认冷却期(分钟);0 禁用速率限制"
  type: number
  default: 120

列在 CI_PERMISSIONS.json 中的用户可能有特定用户的冷却间隔。实际上,我们使用工作流的默认窗口和用户特定间隔之间的最小值。

代码风格指导#

  • 避免代码重复。如果相同的代码片段(超过五行)出现多次,请将其提取为共享函数。

  • 最小化设备同步。尽可能减少昂贵的 CPU-GPU 同步操作,如 tensor.item()tensor.cpu()。使用向量化代码。

  • 优先考虑极致效率。SGLang 是一个运行时,您的大部分代码都在每个请求的关键路径上运行。尽可能优化所有小的开销,特别是在模型前向代码中。

    • 一种常见模式是在模型前向传递中进行一些运行时检查(例如这个)。这些对于每一层都可能是相同的。请尽可能将结果缓存为单个布尔值。

  • 尽可能使函数更纯粹。避免对参数进行就地修改。

  • 保持文件简洁。如果文件超过 2000 行代码,请将其拆分为多个较小的文件(例如 scheduler.pyscheduler_output_processor_mixin.py)。

  • 保持测试运行快速。

    • 如果单个测试文件运行时间超过 500 秒,请将其拆分为多个较小的文件(例如 test_eagle_infer_a.pytest_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。

请遵循以下步骤:

  1. 提交一个 PR 来更新 sgl-kernel 源代码,而不在 sglang python 包中使用它(例如 #8884)。

  2. 提升 sgl-kernel 的版本(例如 #9220)。

    • 一旦合并,这将触发自动将 sgl-kernel wheel 发布到 PyPI。

    • 如果不紧急,您可以等待其他人发布 wheel。新版本通常会在一周内发布。

  3. 应用更改:

    • 更新 sglang/python/pyproject.toml 中的 sgl-kernel 版本以使用修改后的内核。

    • 更新 sglang 中的相关调用代码以使用新内核。

新手提示#

如果您想参与贡献但没有具体想法,请选择标记为"good first issue"或"help wanted"的问题。这些任务通常复杂性较低,并且为代码库提供了很好的介绍。也请查看这个代码 walkthrough以更深入了解 SGLang 的工作流程。

如果您有任何问题或想要开始讨论,请随时在我们的 Slack 频道 中提问。

感谢您对 SGLang 的关注。祝编码愉快!