为 llm-d 做出贡献
贡献指南
感谢您有兴趣为 llm-d 做出贡献。社区参与受到高度重视,对项目的成长和成功至关重要。llm-d 项目通过 GitHub 的 pull request 接受贡献。本文概述了相关流程,以帮助您的贡献获得采纳。
为了确保项目的明确方向和凝聚力,项目负责人对所有贡献拥有最终决定权。不过,这些指南概述了您如何有效地为 llm-d 做出贡献。
您可以如何做出贡献
您可以通过以下几种方式为 llm-d 做出贡献
- 报告问题: 通过清晰简明地报告错误,帮助我们识别并修复 Bug。
- 建议新功能: 分享您对新功能或改进的想法。
- 完善文档: 通过增强文档使项目更易于使用。
- 提交代码贡献(需考虑): 虽然项目负责人保留最终决定权,但始终欢迎符合项目愿景的代码贡献。
行为准则
本项目遵守 llm-d 行为准则和公约。通过参与本项目,您应维护这些准则。
社区与沟通
- 开发者 Slack: 加入我们的开发者 Slack 工作区,与核心维护者和其他贡献者建立联系,提问并参与讨论。
- 每周会议: 项目更新、正在进行的工作讨论以及问答环节将在每周三东部时间下午 12:30 的项目会议中进行。请通过添加共享日历来加入。您也可以加入我们的 Google Group 以访问共享图表和其他内容。
- 在 llm-d 公共 Google 云端硬盘上访问会议录像和会议记录
- SIG: 加入我们的某个特别兴趣小组 (SIGs),为项目的特定领域做出贡献并与领域专家协作。
- 在 公共 SIG 文档 Google 云端硬盘上访问 SIG 会议录像和项目文档
- 代码:托管在 llm-d GitHub 组织中
- 问题:项目范围内的 Bug 或问题应在 llm-d/llm-d 中报告
- 邮件列表:llm-d-contributors@googlegroups.com 用于文档共享和协作
- 社交媒体: 在社交媒体上关注我们,获取最新新闻、公告和更新
- X: https://x.com/_llm_d_
- LinkedIn: https://linkedin.com/company/llm-d
- Reddit: https://www.reddit.com/r/llm_d/
- YouTube @llm-d-project
贡献流程
我们遵循懒惰共识 (lazy consensus)方法:由负责某一问题的相关人员提出的更改,在同行的限定审查时间内如果没有其他人反对,则应被接受。
贡献类型
1. 涉及公共 API 或新组件的功能
所有涉及公共 API、核心组件间行为或新的核心存储库/子系统的功能,必须附带一份已获批准的项目提案。
流程
- 在
./docs/proposals下创建一个 pull request,添加一个具有描述性名称的 markdown 文件(例如docs/proposals/disaggregated_serving.md) - 使用位于
./docs/proposals/PROPOSAL_TEMPLATE.md的模板,包含以下章节- 摘要 (Summary):一两句话,便于任何贡献者或用户理解提议的更改及结果
- 动机 (Motivation):要解决的问题,包括目标/非目标以及任何必要的背景信息
- 提案 (Proposal):可以包含用户故事(“作为用户,我想 X”),应有足够的细节让审查者确切了解您的提议,但不应包含 API 设计或具体实现等内容。预期的结果是什么,我们如何衡量成功?
- 设计细节 (Design Details):应包含足够的信息,使您的更改细节易于理解。这可能包括 API 规范(虽然并非总是必需)甚至是代码片段。如果关于提案将“如何”实现存在任何歧义,应在此处进行讨论。
- 备选方案 (Alternatives):提供备选的实现方式/提案,并简要说明被拒绝的原因
- 获取受影响组件维护者的审查
- 获取项目维护者的批准
提案必须由受影响的组件维护者审查,并由项目维护者批准。提案审查应执行总体原则,并确保项目的一致性和连贯性。提案的批准应反映懒惰共识,即该提案是正确的路径,且该提案应具有较高的审查优先级。
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)" - 检查
gatewayinfrastructure的parametersRef是否存在 (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
- 确保 conditions 中有一条消息声明:
- Modelservice helm chart 升级
- 确保
vLLMpods 已启动 - 如果启用了指标,确保已部署
prefill和decode的podmonitor
- 确保
容器镜像构建更改和升级
- 内核升级和更改(
pplx,deepep,deepgemm) - 忽略flash-infer- 要测试这些,请确保通过
VLLM_ALL2ALL_BACKEND环境变量使用正确的 vLLM 后端- 对于
pplx,您可以将prefill和decode的VLLM_ALL2ALL_BACKEND都设置为pplx- 这可以在任何示例中运行
- 对于测试 deepseek 内核,您可以将
prefill的后端设置为deepep_high_throughput,并将decode后端设置为deepep_low_latency- 这需要在
pd-dissagregation或更好的wide-ep-lws中进行测试
- 这需要在
- 对于
- 要测试这些,请确保通过
UCX+NIXL版本提升和更改- 这可以在
pd-dissagregation或wide-ep-lws中进行测试 - 目前我们从源码构建
UCX,然后针对我们的UCX构建版本来构建NIXL
- 这可以在
LMCache版本提升和更改(即将推出)- 目前没有直接使用
LMCache代码路径的功能,这将作为 KVCache 卸载 (offloading) 史诗任务的一个子集出现
- 目前没有直接使用
vLLM版本提升和更改- 默认情况下,我们使用来自上游 vLLM wheels 索引的预编译二进制文件构建
vLLM。 - 这可以在任何示例中进行测试
- 默认情况下,我们使用来自上游 vLLM wheels 索引的预编译二进制文件构建
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-dissagregation或wide-ep-lws(对于prefill将VLLM_ALL2ALL_BACKEND设置为deepep_high_throughput,并将decode的VLLM_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)- 使用
git commit -s自动添加 - 有关配置详情,请参阅 PR_SIGNOFF.md
- 根据 开发者原产地证书 (DCO),所有贡献均需执行此操作
- 使用
代码组织与所有权
组件与维护者
- 组件 (Components) 是代码组织的主要单元(可以是仓库范围,也可以是仓库内的目录/包/模块)
- 维护者 (Maintainers) 拥有组件并负责批准更改
- 贡献者 (Contributors) 可以通过提供充分的贡献证明来成为维护者
- 代码所有权反映在 OWNERS 文件中,与 Kubernetes 项目惯例保持一致
核心组件 vs 孵化组件
- 核心组件 (Core components):由项目支持,具有严格的生命周期控制和向前兼容性
- 孵化组件 (Incubating components):快速迭代,尚未准备好用于生产,允许在测试想法时有更大的自由度
实验性功能与孵化
我们鼓励在以下约束条件下进行快速迭代和探索
- 明确标识:在代码和文档中明确标识为实验性
- 默认关闭:需要显式启用
- 尽力而为支持:仅提供尽力而为的支持
- 无人维护则移除:如果没有人继续推进,则会被移除
- 无偏见:实验性或孵化状态不代表水平低下
孵化组件流程
- 在
llm-d-incubationGitHub 组织中创建存储库,并确定维护者和明确目标 - 定义实验的时间周期
- 与初始用户一起迭代和测试
- 对于属于“成熟路径”的组件:
- 创建涵盖集成的项目提案
- 定义毕业的成功标准
- 批准后添加到“成熟路径”中
- 对于独立组件:
- 创建包含毕业标准的项目提案
- 组件可以在带有实验性标签的情况下使用
- 毕业:移至核心
llm-d组织并遵循核心流程 - 若未毕业:在移除前存档 3 个月以上
核心组件中的实验性功能
- 向现有核心组件提交 pull request
- 维护者将其归类为实验性,并强制执行“默认关闭”门禁
- 为开启和关闭两种状态提供测试
- 毕业时,默认设为开启,并在一个版本发布后移除条件逻辑
命名规范:实验性标记必须在名称中包含 experimental(例如 --experimental-disaggregation-v2=true)
API 更改与弃用
- 禁止破坏性更改:一旦 API/协议进入 GA 版本(非实验性),则不得移除或更改行为
- 包含范围:所有协议、API 端点、内部 API、命令行标记/参数
- 例外情况:不影响大量消费者的 Bug 修复(随着项目的成熟,我们将对这类更改更加严格——海勒姆定律 Hyrum's Law 是客观存在的)
- 版本控制:所有协议和 API 都应该是可版本化的,具有明确的前向和后向兼容性要求。新版本可以更改行为和字段。
- 文档:所有 API 必须有描述预期行为的文档化规范
测试要求
我们使用三层测试
- 单元测试 (Unit tests):快速验证代码片段,测试不同参数
- 最适合快速验证部分代码,测试不同参数
- 不涵盖代码间的交互
- 集成测试 (Integration tests):测试组件间的协议和构建产物
- 最适合测试组件间的协议和约定
- 可能无法模拟组件在部署时的完整交互
- 端到端 (e2e) 测试:全系统测试,包括基准测试
- 最适合防止端到端回归并验证整体正确性
- 执行速度可能较慢
已部署的系统需要强大的 e2e 覆盖以防止性能回归。适当的测试覆盖率是代码审查的重要组成部分。
安全
在生产服务中保持适当的安全意识。项目将设立一个专门的邮件地址用于安全问题的负责任披露,该地址将由项目维护者审查。在第一个 GA 版本发布之前,我们将正式确定安全组件和流程。
项目结构
核心组织 (llm-d)
- 位于“成熟路径”上的生产级代码
- 遵循 API 更改与弃用流程
- 所有重大更改都需要项目提案
孵化组织 (llm-d-incubation)
- 尚未完全支持的实验性组件
- 倾向于接受具有明确目标的实验
- 每个仓库必须有描述目的和目标的 README
- 毕业后的组件移至
llm-d组织
此内容自动同步自 llm-d/llm-d 仓库 main 分支下的 CONTRIBUTING.md。