Github 开源贡献入门,第一次给 SGLang 提 PR 的全过程
从“围观”到“提交”:我的 SGLang PR 历险记
以前总觉得开源社区是大神们的俱乐部,像我这种只会调包、跑 Demo 的“伸手党”,顶多也就是给项目点个 Star。直到最近,我在尝试用 AMD MI300X 部署大模型时,撞上了一堵墙:SGLang 在长序列推理下的吞吐量死活上不去,显存带宽利用率低得可怜。查了一圈文档没找到答案,那一刻我突然意识到,与其在论坛里发帖问“怎么办”,不如直接去代码里找原因。于是,我硬着头皮开始了第一次给 SGLang 提 PR 的旅程。
发现异常:当性能曲线“掉链子”
事情起因很简单。我在复现一个长文本生成任务时,发现同样的 Batch Size,在 NVIDIA H100 上跑得飞起,到了 AMD 平台上却像是被踩了刹车。起初我以为是环境配置问题,反复检查了 ROCm 版本、驱动号,甚至重装了容器,但性能瓶颈依然存在。
为了定位问题,我打开了 rocprof 进行性能分析。日志显示,关键的 Attention 算子在加载权重时,频繁触发全局内存访问,而本该高速运转的 LDS(本地数据共享)却处于闲置状态。这就好比高速公路修好了,车流却还在走泥泞小道。通过对比 SGLang 源码中针对 CUDA 的实现逻辑,我怀疑是现有的分块(Tiling)策略没有适配 AMD GPU 的 Wavefront 尺寸,导致线程束发散,计算单元空转。
为了验证猜想,我写了一个最小的复现脚本,固定输入长度和并发数,分别记录不同架构标识(gfx90a vs gfx942)下的 Kernel 执行时间。数据不会撒谎:在 gfx942 架构下,默认配置的耗时比理论最优值高出了近 40%。拿着这份详实的 Profiling 数据和复现脚本,我心里有了底,决定不再只做问题的反馈者,而是尝试成为解决者。
迈出第一步:在 Github 上创建 Issue
很多新手不敢提 PR,其实是卡在第一步——不知道怎么说。其实,一个高质量的 Issue 就是最好的敲门砖。
我没有急着写代码,而是先在 SGLang 的 Issues 区搜索了关键词"ROCm"、"MI300"和"Performance"。确认没有重复报告后,我点击了"New Issue"。标题我写得非常直白:[ROCm] Performance degradation on MI300X due to suboptimal tiling strategy in Attention kernel。
正文部分,我严格遵循了社区的模板:
- 环境信息:明确列出 OS、ROCm 版本、GPU 型号、SGLang 版本号。
- 复现步骤:贴上了那段最小化测试代码,并附带了运行命令。
- 预期与实际:用表格对比了期望的带宽利用率和实际监测到的数据。
- 初步分析:附上了
rocprof的截图,指出 LDS 利用率低的问题,并猜测可能与 Block Size 设置有关。
发出 Issue 不到两小时,就收到了维护者的回复。他没有打官腔,而是直接指出:“你的观察很敏锐,确实目前的 Tiling 逻辑是沿用了 CUDA 的默认值,没有针对 CDNA 架构做特化。”这句话瞬间让我信心倍增,原来社区真的在看每一个认真提出的问题。
动手修复:Fork、调试与 TileLang 的魔法
得到肯定后,我正式进入了代码贡献环节。
首先是 Fork 仓库。在 SGLang 的主页点击右上角的 Fork 按钮,将代码克隆到本地。为了方便管理,我新建了一个分支 fix/rocm-tiling-mi300x,所有的修改都在这个分支上进行,保持主分支干净。
核心修改位于算子定义的文件中。SGLang 底层大量使用了 Triton 和 TileLang 来编写高性能算子。我需要调整矩阵分块的参数,使其匹配 MI300X 的硬件特性。具体来说,是将原本的 BLOCK_SIZE_M 和 BLOCK_SIZE_N 从通用的 128 调整为更适合 AMD Matrix Cores 的 64x128 组合,并增加了针对 gfx942 架构的条件编译宏。
# 伪代码示例:针对 AMD 架构的特化分块策略
if target_arch == "gfx942":
BLOCK_SIZE_M = 64
BLOCK_SIZE_N = 128
# 优化 LDS 使用,减少 bank conflict
use_shared_memory = True
else:
# 保持原有 CUDA 逻辑
BLOCK_SIZE_M = 128
BLOCK_SIZE_N = 128
修改完成后,最紧张的环节来了:本地验证。我在本地服务器上重新编译了 SGLang,再次运行之前的复现脚本。盯着终端跳动的数字,当看到吞吐量提升了约 28%,且显存占用曲线变得平滑时,我知道方向对了。为了确保稳健性,我又跑了几个不同长度的序列测试,确认没有引入回归错误。
提交与协作:Pull Request 的诞生
代码验证无误后,我将改动 Commit 并 Push 到自己的远程仓库。Commit Message 我写得很详细,遵循了 feat(backend): optimize tiling for MI300X 的格式,并在描述中引用了之前创建的 Issue 编号。
接下来就是创建 Pull Request (PR)。在 Github 上点击"Compare & pull request",目标分支选择 SGLang 的 main。在 PR 描述中,我再次强调了这次修改的背景、具体的优化手段以及性能提升的数据对比图表。
真正的考验在于 Code Review。维护者提出了一些细致的建议,比如:“是否可以将这个架构判断逻辑抽象成一个公共配置函数,方便后续扩展其他 AMD 型号?”还有另一位贡献者提醒我注意某个边缘情况下的数值精度问题。
这些反馈非常有价值。我根据建议重构了代码,提取了配置函数,并增加了一组精度对齐的单元测试。经过两轮迭代,我的 PR 终于获得了"LGTM"(Looks Good To Me)的标记,并被合并进了主分支。看着自己的 ID 出现在贡献者列表中,那种成就感是无法言喻的。
结语:开源生态需要每一个“你”
这次经历让我明白,开源并不是遥不可及的神坛。它是由一个个具体的 Issue、一行行经过推敲的代码、一次次真诚的讨论构建起来的。哪怕你只是修正了一个文档错别字,或者像这样优化了一个特定的算子参数,都是在为整个生态添砖加瓦。
AMD ROCm 生态正在飞速发展,从 HIPify 的自动迁移,到 SGLang、TileLang 的性能攻坚,再到 LLaMA-Factory 的上层应用,这里有太多的机会等待开发者去挖掘。不要担心自己不够强,社区欢迎每一个愿意动手解决问题的伙伴。
如果你也想尝试在大模型领域大展身手,却苦于没有合适的算力资源,现在机会来了。200 小时 GPU 算力已就位,快来领取:https://marketing.csdn.net/questions/Q2604140858304426315?utm_source=AIpaper
(注:上方为活动海报示意,扫码或点击链接即可参与)
拿起键盘,你的第一次 Commit,也许就在今天。
更多推荐



所有评论(0)