三层版本轴的兼容窗口与适配结论的版本指纹
「这个模型在 **** 上能跑」不足以支撑交付。适配结论绑定的是模型加一组同时成立的版本约束:设备驱动、基础软件栈(运行时)、上层框架各自按自己的节奏发布并维护兼容区间。任意两层的支持区间不重合,整组组合就落在未验证区域。同一个模型、同一张卡,换一个基础软件栈版本,旧结论是否仍成立需要重新判定。
一、三条彼此独立的版本轴
| 轴 | 管什么 | 版本载体 |
|---|---|---|
| 设备驱动 | 设备注册、显存管理、卡间互联拓扑上报 | ****-smi 报出的驱动版本、内核模块版本 |
| 基础软件栈 / 运行时 | 算子注册与实现选择、集合通信库(NCCL 或厂商集合通信库)、编译工具链与 codegen、量化算子库 | 运行时版本号、框架适配层动态库、通信库版本 |
| 上层框架 | 模型加载、权重格式识别、调度与批处理、KV cache 布局(PagedAttention block 大小、MLA / GQA 路径) | vLLM 或厂商框架分支的 tag |
三条轴演进速度不同,组合空间里只有一部分被官方公开验证,其余是失配高发区。
二、「能跑」与「在窗口内」是两件事
窗口外组合的失败形态并不统一:
- 算子未注册:抛
No available kernel(报错关键字示意); - 符号缺失:报
undefined symbol(报错关键字示意),运行时与上层框架 ABI 不对齐; - 模型加载失败:权重格式或字段名不被识别;
- 精度异常:与参考实现偏差超阈值,过程不报错;
- 性能异常:无报错,吞吐与首 token 延迟偏离窗口内基线。
典型场景是驱动装得上、设备可见,框架能启动、最小样例也跑过,但组合不在正式支持窗口内,日志也不会写「版本不兼容」。此时结论容易被写成「能跑,所以支持」。窗口外能跑只能记为「观察」,不能记为「能力」。
三、静默回退:从版本角度看
框架解析执行路径时先选定期望后端,再解析出实际后端,对应日志字段 target_backend 与 resolved_backend;两者不一致即发生回退。成因有两类:运行时升级后某算子在当前版本未注册或未编入当前 codegen 目标;框架与运行时的支持区间错位,请求的算子只剩参考实现。这类回退未必伴随告警。起服务时把两字段打进日志、在压测下比对其取值,是判定回退的第一步。
四、升级与回退:两个方向都要记账
窗口边界不是静止的。基础软件栈演进时,窗口内组合可能掉出窗口,窗口外组合也可能随新版本进入支持,版本结论因此带有有效期。两个方向的判定动作不同:
- 升级之后:用同一份负载重跑最小复现。原结论仍成立则保留;组合移出窗口则把「支持」降级为「观察」;新版本纳入支持则升级为「支持」并更新版本字段。
- 回退之后:写明退回窗口内某个具体版本组合,还是退进未验证区域;后者等价窗口外,只能记为「观察」。
五、版本指纹的字段
结论要可复现,先把版本从单值还原成一份清单。
# 示意:一条适配结论记录的版本指纹(字段为示意,不指向任何具体产品)
driver: # 设备驱动版本,取 ****-smi 报出的驱动版本号
runtime: # 基础软件栈 / 运行时版本,取算子库与集合通信库的版本号
framework: # 上层框架版本,取 vLLM 或厂商框架分支的 tag
path_config: # 决定算子路径选择的关键配置,如 attention backend、MoE 实现开关、KV cache dtype
window: # 该组合是否落在正式支持窗口内,取官方兼容矩阵的判定结果
status: # 窗口内 / 窗口外仅作观察;窗口外注明是否仅最小样例可复现
六、一个具体场景
在 **** 的 ****(8 卡,单卡 64GB HBM,卡间互联 392 GB/s)上,用 **** 的基础软件栈配合 vLLM 起 OpenAI 兼容服务,以 BF16 加载 671B 级 MoE 模型(MLA 注意力)。改动运行时版本后,resolved_backend 若从期望算子路径切到参考实现,吞吐明显下降而日志无异常,此时先核对 window,再决定是否回退到已验证组合。
小结
适配结论的有效范围由三层版本轴的兼容窗口共同决定。把版本记成一份清单、把 window 与 status 写进结论,并在每次升级或回退后重判一次,结论才能在版本演进中保持可复现。