说明:本文的实验与整理使用了AI编程工具辅助。它来自自建界面的受控实验,不是客户生产案例。模型、输入适配和评分流程固定,结论只覆盖这组测试。
一个容易误判的现象
界面从“测试通过”变成“测试失败”,截图文件也被更新了,评分结果却还停留在旧画面。只看最后的回答,很容易怀疑模型没看懂图片;但这次排查要先回答一个更具体的问题:评分实际使用的是哪一次输入?
我们构造了8个界面状态,分成4对有先后关系的状态。每对先评分旧状态,再切换到新状态,分别使用以下方式做对照:
- 对当前图片重新计算,作为参照。
- 复用同一文件路径,更新路径对应的图片内容。
- 每次保存到新的不可变图片路径。
- 按内容寻址,并核对图片内容与请求的绑定。
这里使用固定版本的 Qwen3.5-0.8B-Base,以及同一位置编码兼容适配;没有进行训练。本次检查对象是这套评分管线的输入复用行为。
最小故障机制
下面是机制示意伪代码,不是实验实现的逐行摘录。假设复用器按文件路径缓存图片特征:
features = {}
def image_features(path):
if path not in features:
features[path] = encode_image(read_bytes(path))
return features[path]
save_image("screen.png", state_a)
first = image_features("screen.png")
save_image("screen.png", state_b) # 同一路径,图片内容已经变化
second = image_features("screen.png") # 仍命中旧内容的特征这里路径相同不代表内容相同。最简单的对照,是把两张图分别保存为不可变的 screen_a.png、screen_b.png。若需要复用缓存,应按实际读入的图片字节计算摘要,并把请求标识、图片摘要与返回结果一起记录。这段伪代码只演示旧特征如何被复用,不生成下文的模型评分结果。
分类正确与数值一致要分别检查
| 条件 | 这8个状态的分类正确数 |
|---|---|
| 对当前图片重新计算 | 8/8 |
| 同路径更新图片并复用缓存 | 4/8 |
| 每次使用新的不可变路径 | 8/8 |
| 按内容寻址并核对绑定 | 8/8 |
在这组测试里,4次切换都出现了沿用旧状态分类的问题;普通不可变路径已经能恢复正确分类。这支持优先检查输入身份与缓存绑定,而不能据此声称开发了更强的视觉模型。
另一个结果同样需要保留:与重新计算相比,普通不可变路径和内容寻址快照的预设数值容差检查都只有6/8通过。通过条件是最大 logit 差不超过0.0625、最大选项概率差不超过0.01,并且选择相同。两个失败状态的最大 logit 差都是0.125,尽管分类没变,仍然未通过事先设定的检查。
这组实验只有8个合成状态,4对状态之间有依赖关系。40次评分不能解释成40个独立真实任务,更不能换算成生产准确率。
后续还检查了请求与输入的对应关系
后续通过确定性 CPU 反例验证并修正了评分入口中的并发输入错绑。随后在同一组已经使用过的8个界面上,串行执行20组配对步骤;在这组模型回归里,修正后的入口与普通不可变路径参照一致。
CPU 并发检查和模型串行回归回答的是不同问题。这20组配对不是20个新独立样本,也不是模型并发压测;它不覆盖所有并发规模、长时间运行、真实用户操作或所有模型后端。两种缓存方式彼此一致,也不会把前一轮相对重新计算只有6/8通过的结果改写成全部通过。
遇到相似问题时可以怎么排查
先固定一个失败输入和预期结果,保留模型版本、提示词、图片字节摘要、请求标识与实际输出。然后用同一套条件比较:关闭复用后的重新计算、同路径替换、不可变路径。最后分别检查分类、数值差异和并发下的输入对应关系。
修复是否成立,应当由原来的失败样例再次运行来判断。若简单的输入版本管理已经解决问题,就先把它变成可重复检查;是否需要更复杂的缓存机制,留给后续证据。
这次案例没有证明生产提速、成本节省或跨任务泛化。它提供的是一个排查顺序,以及一组保留了失败边界的对照结果。
如果你也遇到过截图变化而输出不变,可以通过页面下方的工作联系入口,描述技术栈和最小复现步骤;请先去除密钥和真实用户资料。