九月份杂谈:把不安,写进一行行 diff 里
九月份杂谈:把不安,写进一行行 diff 里
“Given enough eyeballs, all bugs are shallow.” — Linus’s Law
按我给自己定的节奏,杂谈是三月、六月、九月各一篇,年末再补一篇年终,一季度一封长信,把这三个月的碎片收拢起来。这一篇,自然该写七、八、九这三个月。六月的杂谈里,我还在杭州的期待中收尾;等真正坐下来动笔,一个完整的夏天已经过完了。这三个月几乎没有停下来过:不是那种被论文和答辩追赶的”停不下来”,而是一种主动的、近乎固执的忙碌,把时间一块块切给不同的仓库,用 commit 填满每一天。如果焦虑有形状,那大概就是我这三个月的贡献图,一大片深绿,绿得有点用力。
开源的夏天:在 vLLM、FlashInfer 与 ncnn 之间来回横跳🔧
七月是从腾讯云 CubeSandbox 开始的。我给沙箱示例生态补了一套 Rust 运行环境的模板,四百多行,最后 PR(#748)被关闭了。说不失落是假的,但写完、改完、答辩式地解释完自己的设计,这套流程本身就已经把”我能不能给别人交东西”这个问题回答了一遍。

紧接着一头扎进腾讯混元的 Hy3 生态。我给官方仓库提了五份东西: #43 是一份 API quickstart 加六个可运行示例、还配了 mock 测试;#52 补齐了 OpenRouter、CodeBuddy、WorkBuddy、Claude Code、Dify 五个工具的接入指南,配了 SVG 流程图;#74 用 MCP 协议把 Hy3 的能力包装成三个即插即用的工具;#75 更进一步,做了个”AI 视频剪辑助手”:你用自然语言描述剪辑需求,Hy3 当大脑去驱动 ffmpeg 执行。把一个模型从一个”能聊天”的 API,变成别的工具里可以调用的零件,这种”接水管”的活儿意外地让人上头。
八月的主战场换成了 vLLM 和 FlashInfer 这两个 LLM 推理框架。在 vLLM 上,我前后修了四个 bug:
- #47681:DeepSeek-V4-Flash 的 SWA 窗口只有 128 token,行内的 system message 会把用户 query 挤掉,所以得在 渲染前做合并;
- #48926:Marlin 的 W4A8 路径把有符号的 scale 当成无符号读,负 scale 被零扩展成了大正数,约一半的分组会 算错;
- #49039:AutoRound(INC) 量化路径没有把
VLLM_MARLIN_INPUT_DTYPE透传下去,Marlin kernel 永远进不了 int8 分支; - #50680:GDN attention 的 cudagraph padding 分支只 guard 了 decode 数量,却按
batch_size去切预分配 的缓冲区,越界。
在 FlashInfer 上同样修了四个: #4312 给 FA2 prefill 补上了 “head_dim 必须能被 64 整除”的校验; #4316 让 Qwen2.5-Math-7B 这类 28 头 / 4 KV 头、group_size=7 的 GQA 模型能在非张量并行的解码核上跑起来; #4356 修正了 split-KV 的 tmp_v 工作区按 FP32 预留、实际却存 DTypeO 的尺寸错配; #4700 则是在隔离构建 flashinfer-cubin 时补上了缺失的 nvidia-cutlass-dsl 依赖。
唯一一个顺利合并的推理框架 PR,反而是 ncnn 的 #6882:src/gpu.cpp 里打印 SPIR-V 编译错误的代码,把 shader 源码当成了以 \0 结尾的 C 字符串来用,而它并不是,于是越界读取,报错信息全成了乱码。改完之后,我自己都忍不住想笑:这种”把别人的噩梦拆成一页一页”的活儿,居然成了这个夏天最踏实的事。
还有一些零散的:给 vooya(一个 Rust-first 的 WASM islands 运行时)提了 RFC 的实现 PR(#62);给 Minecraft 模组 Lucid-Advancements(#36)做了配置界面与成就条的中文本地化,这次顺利合了进去。整个八月,我有一半时间是在盯着 CI 跑、等 maintainer 的 review、被 bot 揪出一堆边角问题,然后再改一轮。到写这篇文章为止,大部分 PR 还开着,它们像春天插下的秧,还没等到那场雨,可能永远等不到吧。
网易雷火 GameJam:一款”做完了”的游戏🎮
七月下旬,我参加了网易雷火的 GameJam。我们做的是《雪莉的午夜药水铺》(Sherry’s Midnight Apothecary),一款用 Godot 做的经营游戏:白天探索、夜晚炼药与经营,形成”白天 / 夜晚”的双运行时,玩家要在 30 天里把自己的小铺子一天天撑起来。

这一次,我们真的做完了。七月二十五日建仓,通宵出了第一版,之后的几周我又回来继续打磨:登记关卡、修被重构弄坏的资源路径、把回归测试一条条对齐。结算那天,它拿到了一个安慰奖。
说实话,这个结果我并不意外。我们的问题不在于”没做完”,而在于”做完了,却不好看”:美术素材是从各处东拼西凑来的,风格乱七八糟;几个系统的视觉语言也各说各话。它像一个所有零件都装对了、却怎么也拼不出统一气质的机器人,能动,但没人愿意多看两眼。上一回六月的 GameJam 教会我”按时交付”,这一次又补上了第二课:交付不等于完成,一款作品可以正好卡在”做完了”和”做成了”之间。
杭州 AdventureX 与 Pillowline📱
AdventureX 2026 在杭州未来科技城,八百个开发者,72 小时。六月的杂谈里我还在犹豫要不要去,现在可以回答了:去了,而且值。
我们在那里做的是 Pillowline,一个围绕”睡前交接 → 安静休息 → 自主回看”的移动端产品原型。它由三块拼起来:Flutter 负责移动端宿主和原生能力,React/Vite 负责主要界面,Go 写了一个只依赖 net/http 的后端 API,用 PostgreSQL 落库。我主要写后端:事务性 outbox、游标分页、webhook、积分与奖励系统、账号与 session,甚至接上阿里云的 ASR 做了语音输入。前端那边,也是我第一次正经用上 Flutter 和 Vite 的组合。

这更是我第一次在一套真正的多人协作链路上跑:在别人的分支上 rebase、在子模块之间对齐版本、把集成仓库和两个独立子仓库分开维护。一个人写代码追求的是”对”,一群人写代码追求的是”接得上”,这是我这个夏天学到的最重要的一课。
自己造的工具:FableGRE🧸
八月的个人项目是 FableGRE,一个完全离线的 GRE 双语故事 App。当时我正在备考 GRE,每天雷打不动要去 A+gre 上刷题,一刷就是一两个小时;单词背得头大,就干脆动了自己写一个背单词应用的念头。我用 Expo 和 React Native 从头搭起,塞进去 24 篇原创故事和配套词库,做了按需查词加预测预取、无尽的词汇测试、上滑复习上一词的手势,还有一堆抽屉动画。这是我第一次正经写 React Native,从数据预编译、列表虚拟化到安全区适配,几乎把跨端开发的坑踩了个遍。看着它在自己的手机上跑起来、翻页丝滑的那一刻,那种”我造出了一个真东西”的满足感,和发一篇 PR 被合并是一样的。

好在最后考试顺利通过,按规则应该还能申请英语免修。回头再看,这大概是我做过的回报率最高的一次 side project:既救了眼前的单词,又练了跨端开发。
把博客当工程来修🧹
先是三个新的脚本:check-math.js 用 KaTeX 的严格模式逐条校验公式;check-site.js 检查每篇文章引用的图片是否存在、日期和目录是否对得上、标签分类有没有重复;format-md.js 则基于 AST 把公式和删除线自动规范化。顺带修了一个困扰很久的老问题:粗体、斜体紧挨着中文标点时无法渲染。除此之外,还加了 CJK 软换行的过滤器,把 markdownlint 的 disable 例外一条条删掉,接上了 pre-commit 和 dependabot,最后把所有源码里的中文注释翻译成了英文。
这三个月我也不是只折腾工具,正文写了几篇:MiniMax 推理优化实习生的面经、一篇讲 Normalization 与 Quantization 隐秘战争的综述、那个把我坑了一整晚的 Docker 网桥与校园网冲突、以及从源码出发读懂 uv 的环境管理。把博客当成一个工程项目来维护,说好听点叫”匠心”,说难听点就是强迫症。但在这段说不上有多确定的日子里,能亲手把一件事收拾得干干净净,本身就是一种安慰。
桌面的缝缝补补🐧
dwm 上,我把 dmenu 换成了 rofi 当启动器,补齐了一批 MIME 类型,写了个 HDMI 自动检测与连接/断开的脚本,把主题色抽成独立的配色文件,顺手把 README 和文档补全。neovim 那边,我狠下心卸掉了 treesitter,改用 vim-closetag 处理标签自动闭合,补上了 LaTeX 和 Markdown 的支持,换上 noice.nvim,还加了 fcitx5 输入法自动切换和 smear-cursor 的光标动画。
朋友常问我:这些配置能提升多少生产力?说实话,提升有限。但折腾这些,某种程度上是在确认”有些事情我还能控制”:窗口怎么摆、光标怎么动、颜色是什么,全由我说了算。在一个大部分事情都不由我说了算的世界里,这种掌控感贵得离谱。
B 站周更:AI 生图配纯音乐🎵
除了代码,这三个多月我还在 B 站上坚持做了一件没什么”技术含量”的事:周更一个叫 「惰池的周更歌单」的合集。从八月中旬更到十月初,前后一共 8 期,几乎每周一条,合集简介上写着”能周更就算胜利~”。做法很简单:用 AI 生成的插画铺一张场景,配上一首纯音乐,剪成两三分钟的短视频。标题都很轻:「你那边也下雨了吗?来这里坐坐吧~」「沙滩,阳光,冰棍,海风~」「晚上一个人爬上了屋顶,抬头看见了满天繁星~」「从慵懒的午觉当中醒来~夏天,结束了啊」。播放量从一千多到四千多,谈不上什么成绩,但它们是我在写代码之外,另一种”把东西做出来”的方式。(视频的剪辑合成,多亏了朋友 @月川有点困zzZ。)

这种割裂其实挺有意思:白天我在给别人的推理框架修越界 bug,晚上却在给一首纯音乐配一张发呆的画面。理性与感性,在这个夏天居然没有打起来。
武大读博:报道、班长竞选与一群福瑞🐱🐶
报道那几天,事情就一件接一件地涌来。我报了志愿者,迎新、搬东西、指路,忙得脚不沾地;又跑去竞选班长,虽然最后没选上,但站上讲台把想说的话讲完的那一刻,心里居然有点莫名的畅快。比起”开启一段新旅程”这种宏大的叙事,我的读博开局更像被塞进了一台高速运转的洗衣机:转得头晕,但也热热闹闹。
研究生的课我还是提不起劲去上。坐在教室里,心思飘在别处;签到是应付,笔记是空白,很多时候干脆不想去。它们更像是为了应付审查而摆出来的门面,内容陈旧、与实际研究脱节,一学期下来真正能学到的东西少得可怜,甚至不如我随手逛一次 GitHub 来得多。 既然坐在那儿也长不了本事,那”去不去上课”这个问题,我心里其实早就有了答案。
但课外的部分,却意外地热闹。我认识了新的学长和朋友,也认识了武大这边的福瑞们——砂糖、跃金、byte、灰湫、繁华、深蓝、诺斯……这串名字念出来,像是某部作品的角色表。🐾 我们一起约饭、去 KTV,也约着健身;日程排得比本科还满,事情多到常常晕头转向。
有时候我确实乐在其中:KTV 里唱到嗓子发哑,聚餐时笑到肚子疼,健身房里互相盯着把最后一组做完。🐶 可也有别的时候——夜深下来,一个人对着论文的空白页发呆,那个熟悉的、什么都没发生却像被抽走颜色的沮丧,又会悄悄回来找我。忙是真的,开心是真的,焦虑和低落也是真的,它们就这样在同一段日子里轮番出现,谁也没能把谁彻底赶走。
更让我不安的还是一种割裂。这几个月我在 GitHub 上花的时间,比以往任何时候都多;可当我试图把它们写进简历时,却发现自己卡了壳:这些 commit、这些 pull request,很难被翻译成 HR 表格里的一行。 与此同时,那篇早该动笔的论文,被我一拖再拖。绿格子越攒越多,论文的空白页却一天没少。
不过想清楚了也就那样:武大不是一道需要反复论证的选择题,读博不过是一段很长很长的路。 路还很长,我还要一直走、一直走。
尾声:健身、绿格子,与还没写的论文💌
不过,这段日子也不是全是灰的。九月,我至少坚持了一件事:健身。规律地去,规律地出汗,那种身体层面的确定感,比任何一次 commit 都更直接地告诉我”我还在”。当脑子里的事一团乱麻时,能把自己拖去举铁,是我为数不多仍能兑现的承诺。 💪

写到这儿,我不想给这篇杂谈收一个漂亮的尾。武大的路还很长,长到看不见尽头,但我会一直走下去;论文还在拖;简历上还是那几行项目;GitHub 上那片深绿,也不一定照得亮哪里。但我至少确认了一件事:我确实喜欢”把东西做出来”的过程本身,无论它是三行代码、一款游戏,还是一个睡前的 App。也许未来的路怎么走,我依然没有答案;但我知道,在新的答案出现之前,我还能继续写下去。
国庆的假期刚过,风已经凉了。下一站还没想好,但今天的铁,还得去举。