跳转至正文

为 llm-d 做出贡献

贡献指南

感谢您有兴趣为 llm-d 做出贡献。社区参与受到高度重视,对项目的成长和成功至关重要。llm-d 项目通过 GitHub 的 pull request 接受贡献。本文概述了相关流程,以帮助您的贡献获得采纳。

为了确保项目的明确方向和凝聚力,项目负责人对所有贡献拥有最终决定权。不过,这些指南概述了您如何有效地为 llm-d 做出贡献。

您可以如何做出贡献

您可以通过以下几种方式为 llm-d 做出贡献

  • 报告问题: 通过清晰简明地报告错误,帮助我们识别并修复 Bug。
  • 建议新功能: 分享您对新功能或改进的想法。
  • 完善文档: 通过增强文档使项目更易于使用。
  • 提交代码贡献(需考虑): 虽然项目负责人保留最终决定权,但始终欢迎符合项目愿景的代码贡献。

行为准则

本项目遵守 llm-d 行为准则和公约。通过参与本项目,您应维护这些准则。

社区与沟通

贡献流程

我们遵循懒惰共识 (lazy consensus)方法:由负责某一问题的相关人员提出的更改,在同行的限定审查时间内如果没有其他人反对,则应被接受。

贡献类型

1. 涉及公共 API 或新组件的功能

所有涉及公共 API、核心组件间行为或新的核心存储库/子系统的功能,必须附带一份已获批准的项目提案

流程

  1. ./docs/proposals 下创建一个 pull request,添加一个具有描述性名称的 markdown 文件(例如 docs/proposals/disaggregated_serving.md
  2. 使用位于 ./docs/proposals/PROPOSAL_TEMPLATE.md 的模板,包含以下章节
    • 摘要 (Summary):一两句话,便于任何贡献者或用户理解提议的更改及结果
    • 动机 (Motivation):要解决的问题,包括目标/非目标以及任何必要的背景信息
    • 提案 (Proposal):可以包含用户故事(“作为用户,我想 X”),应有足够的细节让审查者确切了解您的提议,但不应包含 API 设计或具体实现等内容。预期的结果是什么,我们如何衡量成功?
    • 设计细节 (Design Details):应包含足够的信息,使您的更改细节易于理解。这可能包括 API 规范(虽然并非总是必需)甚至是代码片段。如果关于提案将“如何”实现存在任何歧义,应在此处进行讨论。
    • 备选方案 (Alternatives):提供备选的实现方式/提案,并简要说明被拒绝的原因
  3. 获取受影响组件维护者的审查
  4. 获取项目维护者的批准

提案必须由受影响的组件维护者审查,并由项目维护者批准。提案审查应执行总体原则,并确保项目的一致性和连贯性。提案的批准应反映懒惰共识,即该提案是正确的路径,且该提案应具有较高的审查优先级。

2. 修复、议题和 Bug

适用于修复错误代码或在组件内添加微小更改的情况

  • 所有 Bug 和 commit 必须对 Bug 有清晰的描述、重现方法以及更改的具体方式
  • 任何其他更改可以通过向组件提交 pull request 或在 llm-d/llm-d 中提交 issue 来提出,维护者必须批准该更改(需符合组件设计精神和更改范围)
    • 引起中等规模更改关注的一个好方法是在 GitHub 中创建一个 RFC issue,然后在 Slack 中进行交流
    • 在组件内部,当更改范围较大或对用户影响较高时,请使用项目提案

功能测试

测试功能或修复 Bug 的第一个关键步骤是确定您正在测试技术栈的哪一层。以下是一些测试用例

  • 更换 GIE helm chart 版本和 inference-scheduler 镜像升级 - 检查 inference-scheduler 容器日志
    • 检查您的 InferencePool 是否存在 (kubectl get InferencePool.inference.networking.k8s.io)
  • 升级 Infra helmchart 或任何影响网关 (Gateway) 基础设施的更改
    • 检查 gateway 对象 (kubectl get gateway -o yaml)
      • 检查 status 部分,确保它有一个 address,并且有一条消息显示 "Resource programmed, assigned to service(s) "
      • 检查 gateway infrastructureparametersRef 是否存在 (kubectl get gateway wide-ep-inference-gateway -o yaml | yq .spec.infrastructure.parametersRef,然后检查确保该资源本身存在)
    • 如果使用 istio,还需检查您的 DestinationRule 是否存在
  • 检查 httpRoute 对象的 status 部分 (kubectl get httpRoute -o yaml | yq '.status.parents[]')
    • 确保 conditions 中有一条消息声明:"Route was valid"
    • 确保 httpRoute 上有一个 parent ref,指向 httpRoute 已正确附加到 gateway
  • Modelservice helm chart 升级
    • 确保 vLLM pods 已启动
    • 如果启用了指标,确保已部署 prefilldecodepodmonitor

容器镜像构建更改和升级

  • 内核升级和更改(pplx, deepep, deepgemm) - 忽略 flash-infer
    • 要测试这些,请确保通过 VLLM_ALL2ALL_BACKEND 环境变量使用正确的 vLLM 后端
      • 对于 pplx,您可以将 prefilldecodeVLLM_ALL2ALL_BACKEND 都设置为 pplx
        • 这可以在任何示例中运行
      • 对于测试 deepseek 内核,您可以将 prefill 的后端设置为 deepep_high_throughput,并将 decode 后端设置为 deepep_low_latency
        • 这需要在 pd-dissagregation 或更好的 wide-ep-lws 中进行测试
  • UCX + NIXL 版本提升和更改
    • 这可以在 pd-dissagregationwide-ep-lws 中进行测试
    • 目前我们从源码构建 UCX,然后针对我们的 UCX 构建版本来构建 NIXL
  • LMCache 版本提升和更改(即将推出)
    • 目前没有直接使用 LMCache 代码路径的功能,这将作为 KVCache 卸载 (offloading) 史诗任务的一个子集出现
  • vLLM 版本提升和更改
    • 默认情况下,我们使用来自上游 vLLM wheels 索引的预编译二进制文件构建 vLLM
    • 这可以在任何示例中进行测试
  • EFA
    • 要在 NIXL 上测试 libfabric 插件本身,您可以在支持 EFA 的容器镜像内执行以下操作(不需要 GPU 或 EFA)
export NIXL_LOG_LEVEL=debug
python3 - <<'EOF'
from nixl._api import nixl_agent, nixl_agent_config
agent_config = nixl_agent_config(backends=["LIBFABRIC"])
nixl_agent1 = nixl_agent("target", agent_config)
EOF
  • 要在 AWS P5+ 实例中通过 EFA 测试实际推理,请确保通过环境变量 UCX_TLS 包含具有高优先级的 EFA 加速选项
  - name: UCX_TLS
value: "efa,sockcm,sm,self,cuda_copy,cuda_ipc"
  • 确保容器请求了 EFA 资源实例
  requests:
vpc.amazonaws.com/efa: 1

容器镜像清单

  • inference-scheduler 指南
  • precise-kv-cache-aware 示例
  • pd-dissagregation 示例(也涵盖 deepseek 内核)
  • wide-ep-lws 示例(也涵盖 deepseek 内核)
  • 使用 guidellm 基准测试进行负载测试以检查性能回归(任何示例均可)
  • 使用 pplx 后端运行指南
  • 使用 deepseek 内核运行 pd-dissagregationwide-ep-lws(对于 prefillVLLM_ALL2ALL_BACKEND 设置为 deepep_high_throughput,并将 decodeVLLM_ALL2ALL_BACKEND 设置为 deepep_low_latency

代码审查要求

  • 所有代码更改必须作为 pull request 提交(禁止直接 push)
  • 所有更改必须由作者以外的维护者进行审查和批准
  • 所有存储库必须以编译和通过测试作为合并的门槛
  • 所有实验性功能默认必须关闭,且需要显式选择开启

Commit 和 Pull Request 风格

  • Pull request 应简洁地描述问题
  • 在合并前进行 Rebase 和 squash
  • 使用最少的 commit,并将大型更改分解为不同的 commit
  • Commit 消息应包含
    • 简短且具描述性的标题
    • 描述为什么需要此更改
    • 提供足够的细节,以便查看 git 历史记录的人能理解其范围
  • DCO 签署 (Sign-off):所有 commit 必须包含有效的 DCO 签署行 (Signed-off-by: Name )

代码组织与所有权

组件与维护者

  • 组件 (Components) 是代码组织的主要单元(可以是仓库范围,也可以是仓库内的目录/包/模块)
  • 维护者 (Maintainers) 拥有组件并负责批准更改
  • 贡献者 (Contributors) 可以通过提供充分的贡献证明来成为维护者
  • 代码所有权反映在 OWNERS 文件中,与 Kubernetes 项目惯例保持一致

核心组件 vs 孵化组件

  • 核心组件 (Core components):由项目支持,具有严格的生命周期控制和向前兼容性
  • 孵化组件 (Incubating components):快速迭代,尚未准备好用于生产,允许在测试想法时有更大的自由度

实验性功能与孵化

我们鼓励在以下约束条件下进行快速迭代和探索

  1. 明确标识:在代码和文档中明确标识为实验性
  2. 默认关闭:需要显式启用
  3. 尽力而为支持:仅提供尽力而为的支持
  4. 无人维护则移除:如果没有人继续推进,则会被移除
  5. 无偏见:实验性或孵化状态不代表水平低下

孵化组件流程

  1. llm-d-incubation GitHub 组织中创建存储库,并确定维护者和明确目标
  2. 定义实验的时间周期
  3. 与初始用户一起迭代和测试
  4. 对于属于“成熟路径”的组件:
    • 创建涵盖集成的项目提案
    • 定义毕业的成功标准
    • 批准后添加到“成熟路径”中
  5. 对于独立组件:
    • 创建包含毕业标准的项目提案
    • 组件可以在带有实验性标签的情况下使用
  6. 毕业:移至核心 llm-d 组织并遵循核心流程
  7. 若未毕业:在移除前存档 3 个月以上

核心组件中的实验性功能

  1. 向现有核心组件提交 pull request
  2. 维护者将其归类为实验性,并强制执行“默认关闭”门禁
  3. 为开启和关闭两种状态提供测试
  4. 毕业时,默认设为开启,并在一个版本发布后移除条件逻辑

命名规范:实验性标记必须在名称中包含 experimental(例如 --experimental-disaggregation-v2=true

API 更改与弃用

  • 禁止破坏性更改:一旦 API/协议进入 GA 版本(非实验性),则不得移除或更改行为
  • 包含范围:所有协议、API 端点、内部 API、命令行标记/参数
  • 例外情况:不影响大量消费者的 Bug 修复(随着项目的成熟,我们将对这类更改更加严格——海勒姆定律 Hyrum's Law 是客观存在的)
  • 版本控制:所有协议和 API 都应该是可版本化的,具有明确的前向和后向兼容性要求。新版本可以更改行为和字段。
  • 文档:所有 API 必须有描述预期行为的文档化规范

测试要求

我们使用三层测试

  1. 单元测试 (Unit tests):快速验证代码片段,测试不同参数
    • 最适合快速验证部分代码,测试不同参数
    • 不涵盖代码间的交互
  2. 集成测试 (Integration tests):测试组件间的协议和构建产物
    • 最适合测试组件间的协议和约定
    • 可能无法模拟组件在部署时的完整交互
  3. 端到端 (e2e) 测试:全系统测试,包括基准测试
    • 最适合防止端到端回归并验证整体正确性
    • 执行速度可能较慢

已部署的系统需要强大的 e2e 覆盖以防止性能回归。适当的测试覆盖率是代码审查的重要组成部分。

安全

在生产服务中保持适当的安全意识。项目将设立一个专门的邮件地址用于安全问题的负责任披露,该地址将由项目维护者审查。在第一个 GA 版本发布之前,我们将正式确定安全组件和流程。

项目结构

核心组织 (llm-d)

  • 位于“成熟路径”上的生产级代码
  • 遵循 API 更改与弃用流程
  • 所有重大更改都需要项目提案

孵化组织 (llm-d-incubation)

  • 尚未完全支持的实验性组件
  • 倾向于接受具有明确目标的实验
  • 每个仓库必须有描述目的和目标的 README
  • 毕业后的组件移至 llm-d 组织
内容来源

此内容自动同步自 llm-d/llm-d 仓库 main 分支下的 CONTRIBUTING.md

📝 如需建议更改,请编辑源文件创建 issue