两行配置提速一倍,然后被平台更新一夜打回原形
这是一个当天发生、当天记录的真实事件。
先交代背景:我的双机分布式推理服务(两台 Jetson Thor T5000,跑 DeepSeek V4 Flash,NVFP4 量化,320K 上下文),默认配置下长对话体验很差,首轮等很久,多轮每轮都像重新开始。
逐层测量后,问题锁定在两个参数上。
我改了两行配置。
第一行:max-num-batched-tokens 从 512 改到 4096。这是 A/B 测出来的:23K token 的长提示词,prefill 首字延迟 71.1 秒降到 43.1 秒,1.65 倍。8192 也试了,中间激活挤占 KV 池,vLLM 启动直接拒绝,4096 就是这个内存预算下的实测上限。
第二行:删掉 --no-enable-prefix-caching,也就是打开前缀缓存。多轮对话从"每轮重新计算"回到"增量计算"。
改完我把 .bak 备份留在同目录,心满意足地下线了。
然后,9 月 12 日下午 4 点 37 分
平台的 Agent 组件自动更新了。
下午 5 点 40 分,两台节点上的 docker-compose.yml 被重新生成。
max-num-batched-tokens 回到 512。
--no-enable-prefix-caching 重新出现。
我的 .bak-20260912 备份文件,也被清理掉了。
容器 17:40 重启,直接运行回退后的参数。
我不信邪,做了双重核实:把两台节点的进程 cmdline 逐项导出来比对,两台都是回退后的参数。不是缓存问题,不是显示问题。
是真实的回退。
最讽刺的细节是时间线:组件更新是 16:37,compose 被重新生成是 17:40。更新和破坏之间隔了一个小时,你连"更新完立刻检查"这种反应窗口都不一定赶得上。
如果不是例行检查,这个静默回退可能几周都不会被发现:服务照常跑,只是又变回了没有缓存的慢。
三个教训
教训一:备份放在会被重写的目录里,等于没备份。覆巢之下无完卵,这次 .bak 就是这么没的。
教训二:平台自动更新的本质是"恢复大多数人的默认"。你的手工定制在它的优先级里不存在。这不是平台的错,是托管交易的一部分,你让渡了配置定义权,换运维成本下降。但我之前没意识到让渡的范围这么大:连"删掉某个开关参数"这种事它都会恢复。
教训三:更新后必须核查。关键配置 diff、进程启动参数抽查、性能基线回放,三步五分钟。核查要挂在平台更新事件上,不是挂在你的记忆上,记忆不可靠,事件才可靠。
现在的治理方案
调优内容(改哪几行、为什么、验证数据)全部存到平台更新范围之外的独立位置。
重新应用做成可重复执行的脚本,更新发生后,一条命令恢复全部调优。
能持久化到平台模板源的参数,进模板源,从根上绕开"每次更新打一仗"。
每次平台更新后,跑一遍三分钟核查清单。清单里还留着当时的实测细节:批处理 4096 的增益边界、投机解码开启时 scheduled tokens 被钳制在 4096、8192 在 1M 上下文预算下引擎拒绝启动的确切报错。
方法论价值
这件事可迁移到一切"平台 + 手工定制"的混合场景:SaaS 配置、低代码平台、托管数据库、CDN 规则。
三句话:平台更新的本质是恢复默认,你的定制在它的优先级里不存在;定制资产必须存放在平台写权限之外;核查动作挂在更新事件上,不挂在记忆上。
发现"性能回落"的具体排查手法,见 推理性能漂移实录;"慢"的三段归因框架,见 慢的三层真相。
← 返回博客列表 · 相关阅读:推理"慢"的三层真相 · 双机部署实录