一次多模态微调中的生成退化、输出表示与语义诊断

完成一轮多模态微调后,四项验证损失都下降了。我让模型独立标注一张工程图,期待看到一个还不完美、但至少能抓住主要结构的结果。

模型确实写出了一份完整 JSON。它输出了实例、几何框、尺寸和关联,程序也成功解析了这份答案。但把预测叠加回原图后,问题变得很明显:沉孔被识别成槽,尺寸绑定到了错误位置,多个不同实例共用一个大框,文字标注又缺少位置。

训练完成了,文件保存了,验证指标也变好了。可我真正关心的问题——模型能否看着图纸,可靠地找到物理特征并定位——仍然没有解决。

这篇文章记录随后的一组诊断:检查训练与推理的信息差异,拆开坐标换算和定位错误,观察训练图上的自由生成,再分别测试解码策略和紧凑输出表示。最后一个对照中,紧凑组在固定四张图上的生成 token 少了约 31%,生成耗时少了约 34%,但孔槽误判依然存在。

这是一次小规模开发实验的复盘。它没有建立新的识别准确率纪录,却让我更清楚地知道:哪些指标回答了问题,哪些没有。

生成能力的四项独立检查

图 1|从生成结束到图像事实一致,需要分别检查。图中的几何例子为自制示意,不是实际工程图或模型预测。通过前面的检查,并不能替代后面的验证。

1. 我们希望模型输出的,不只是文字

工程图中的一个圆,不一定就是一个孔。同一个物理结构可以在不同视图中出现;一条尺寸可能约束一个孔段,也可能适用于一组实例;多个投影还可能重叠。只读出文字,或者只检测几个圆框,都不足以表达这些关系。

因此,我把任务组织为四类:局部物理特征识别、标注绑定、跨视图匹配和整图联合输出。模型需要区分类别、位置、身份与关系,而不只是生成一段听起来合理的说明。

主实验使用 Qwen3.5-27B,通过语言侧 LoRA 做监督微调(SFT),视觉编码器冻结。基座模型的公开说明见 Qwen 官方模型卡。本文中的效果来自我们的具体微调和解码配置,不能视为对基座能力的全面评测。

数据包含 60 张不同原图,按 50 张训练、10 张开发划分。四类任务导出了 3,058 条训练样本,但这不意味着我们拥有 3,058 张独立图纸:同一原图会贡献多个裁图、绑定样本和跨视图样本。数据来源中包含模型预标与后续审核、修订版本;部分修订尚未独立人工核验,因此下文用“参考标注”而非统一称为人工真值。

任务训练时提供的信息目标输出
局部识别概览或固定裁图、任务提示物理实例、区域、局部归一化框及歧义信息
标注绑定图像、参考标注文字和位置、参考候选实体标注与实例、孔段、表面或集合的关系
跨视图匹配图像、两个视图中的参考候选框投影对应的实例身份与歧义关系
整图联合图像概览、固定分块、整图提示特征、证据、标注、关联等完整 JSON

主实验的采样目标比例为 55%/20%/15%/10%,优先局部识别;有效 batch size 为 2,累计完成 200 次参数更新。中途发生保存故障,恢复 adapter 后重建了优化器,因此这是累计 200 步训练,不是保留全部状态的连续断点续训。

这里最容易忽略的是表格中第二列。绑定任务是在已有候选上作判断,跨视图任务也是如此。它们没有独立承担“先从图像中找到所有候选”的工作。

2. 很低的验证 loss,回答的是一个有条件的问题

训练采用答案 token 的交叉熵。直观地说,每一步都让模型看着图像、提示和正确答案的前文,预测下一个 token。其形式可以写成:

L_CE = -(1/T) × Σ log Pθ(y_t | 图像, 提示, y_1, …, y_(t-1))

这里的前文来自参考答案,这就是 teacher forcing。自由生成时,前文则来自模型自己。实例数量或身份一旦生成错误,后续内容就可能在错误上下文上继续展开。

主实验后期,局部识别、标注绑定、跨视图和整图联合的监测 loss 分别约为 0.377、0.489、0.00874 和 0.281。这些值说明模型对相应验证序列的预测情况,却不能直接互相比较任务能力,更不能转换成准确率。跨视图的输入条件和输出长度,与整图联合都不同。

尤其是 0.00874 这个很小的数。它不意味着模型可以从完整工程图中自动定位所有投影,再正确建立实例关系。它衡量的是给定参考候选、在正确答案前缀条件下的 token 预测。

训练信息与部署信息的区别

图 2|条件任务在训练和实际使用中可能面对不同质量的候选。下方是待接通、待评测的完整流程示意,不代表当前系统已完成端到端实现。

CE 本身也没有直接规定几何距离。假设目标坐标是 1000,999 与 1500 的空间误差差别很大;文本 CE 按目标 token 的概率计罚,不保证前一种偏差一定获得更小的损失。字段和标点预测得更熟练,也可能使平均 loss 下降,而实例与坐标仍然错误。

但由此跳到“交叉熵不适合定位”同样过早。Pix2Seq 就提供了把视觉任务表达为序列建模问题的参考。更合理的问题是:在当前数据规模、表示方式和训练覆盖下,CE 是否已经充分学到了任务;如果没有,瓶颈在哪里?

验证 loss 应继续记录,但需要与自由生成的实例、几何和关系评测一起看。

3. 先拆开三件事:定位、坐标换算与训练覆盖

第一次整图实标使用开发图 D032。模型输入概览和固定分块,输出原图像素坐标。一次推理用时约 14.4 分钟,生成 5,927 token,正常结束;结果包含 9 个物理实例、20 个几何实体和 21 条标注及关联。

结构完整没有掩盖实际问题。逐项检查发现沉孔被叫成键槽,φ47、φ64 等尺寸绑定错误,21 条标注均缺少框,轴测视图的多个实例共用大框,还漏掉了制造要求。这些是单图定性诊断,不能据此推算整个开发集的错误率。

首先要排除展示和变换错误。已有数据导出的坐标往返误差最大约 0.002 像素,这证明了那条转换链的数值一致性,但既不证明原参考框准确,也不证明模型预测正确。实际预测中的偏移、缩放并不一致,不能靠一次整体平移解决。

随后我改用模型已有的局部识别任务,让它输出当前输入裁图内的 0~1 坐标。裁图起点和宽高由预处理程序记录,恢复原图坐标时只需:

x_original = crop_x + u × crop_width
y_original = crop_y + v × crop_height

例如,裁图为 [100, 200, 500, 1200],局部框为 [0.25, 0.20, 0.75, 0.80],程序恢复的原图框就是 [200, 400, 400, 1000]。这里每组四个数依次表示左上角和右下角坐标。

这一步把确定性的算术交给程序。预测框越界、宽高为负或单位不符时,直接标记错误,不猜测模型“可能想表达什么”。不过,如果模型已经把左边的孔框到了右边,正确的坐标变换也只会忠实地保留错误。

另一个问题是曝光次数。200 步、有效 batch size 为 2,只对应 400 次训练样本抽取。按当时采样序列重建,覆盖如下:

任务抽取次数不重复样本数/训练样本总数
局部识别200132/241
标注绑定8685/2,457
跨视图6249/310
整图联合5233/50

采样比例是目标权重,有限次抽样不保证精确等于设定百分比。一张原图出现在训练集中,也不代表它的每一条派生任务都得到过充分训练。所谓“训练集效果”,必须进一步说清是哪个输入、哪个任务、实际出现过几次。

这些事实支持继续检查覆盖和学习进度,却还不足以单独诊断为欠拟合。

4. 八图诊断:训练图也会生成失控

为了减少变量,我固定已有最终 adapter,选取四张训练图和四张开发图。每图只输入一个概览,使用局部识别提示,greedy 解码,输出上限为 8,192 token,不提供参考候选或答案。

分组正常 EOS,JSON 可解析重复后达到长度上限
训练图D016D001、D002、D008
开发图D031、D032、D033D034

正常 EOS 指模型输出结束符,达到长度上限则由外部预算终止,两者要分开统计。失败样例持续枚举实例,最终 JSON 被截断;正常结束的 D032 仍存在实例数量和孔槽类型错误。

这轮最重要的发现并不是“4/8 成功”,而是失败也发生在训练图上。只用“开发集泛化不好”解释不够了,还需要检查实际样本覆盖、实例枚举和停止行为。

同时,4/8 只是这组输入的生成完成情况。我们没有完整评完所有框,也没有对正常 JSON 的全部语义进行独立判定,不能把它写成 50% 的识别准确率。

5. 换解码策略,能修好多少问题?

重新训练之前,我先固定模型和输入,在 D032、D034 上比较采样解码与 XGrammar 结构约束。前者参照 Qwen 官方建议调整采样;后者通过语法约束限制生成形式。XGrammar 官方项目面向结构化生成,但语法约束本身并不提供图像中的物理事实。

D034 在旧 greedy 下重复到 8,192 token;采样后用 2,388 token 正常结束,耗时约 5.8 分钟。但盲腔与通孔、孔径与螺纹等语义错误仍然存在。D032 的采样输出将安装孔枚举为四个,却仍误报内环槽。

结构约束组也没有给出我们期待的解决方案:D034 仍达到长度上限,D032 的解析结果与旧 greedy 相同,继续误报安装孔和槽。

语法可以约束键、值和括号,却不必然约束“这个孔是否已经数过”“这里是否真的有槽”。这些需要图像证据、实例身份与更强的语义约束。有限长度、ID 唯一性等规则也可以另外设计,但本轮没有据此构成可靠的物理实例约束。

这组测试让我收回了一个过强的期待:改善解码可以改变生成行为,但两张图上的正常结束不能作为识别能力提升的证据。

6. 把输出写短:一次配对训练实验

接下来,我尝试把坐标、类别和实例信息放在更接近的位置,减少重复字段和可恢复的默认值。实例首次出现时定义,后续通过 ID 引用,同时保留复合孔段、共同成员和歧义信息。

这仍然是文本序列生成。它没有引入检测头,没有增加几何损失,也没有从机制上禁止重复。

为了确认转换没有直接丢掉监督信息,先对完整局部数据执行还原检查:241 条训练样本加 46 条开发样本,共 287 条均通过。这里的“通过”只表示按转换契约能恢复已有内容,不代表这些内容已被人工确认正确。两种格式都保留原始坐标精度,没有新增坐标量化。

真正用于配对训练的是四张训练图的 19 条局部样本,另选两张开发图的概览。实验安排如下:

控制项两组共同设置
初始模型同一个 Qwen3.5-27B 基座,各自新建 LoRA,不继承旧 adapter
LoRArank 32,alpha 64;视觉编码器冻结
训练目标普通 token CE
数据顺序相同 80 次预定样本轮转,每条出现 4~5 次
训练预算有效 batch size 2,40 步,学习率 5e-5,warmup 3 步
随机种子42
检查点第20步和第40步
生成测试每检查点:训练图 D002、D016;开发图 D032、D034
解码greedy,最多 8,192 token,不提供答案

两组分别在两张 A100 上运行。改变的是输出组织方式及对应格式提示,所以这是一组表示方案对照,不能把收益独立归因于字段名或字段顺序。两组样本曝光相同,但 token 预算不同;也没有多 seed 或交换 GPU 的重复计时。

尤其要注意:这次40步局部训练与前面的200步多任务训练是两个实验。数据范围、任务、初始化路径都不同,不能把它们直接串成“新方法相对旧模型的准确率提升”。

第20步和第40步给出了不同答案

紧凑组第20步,D002 仍重复到 8,192 token 被截断。D032 虽然正常 EOS,却因重复定义而无法恢复标准结构。后者很容易被“是否正常结束”这个单一指标漏掉。

到第40步,紧凑组四张图都正常结束,并通过标准结构还原。旧格式组最终也全部通过。

两个检查点的结构状态矩阵

图 3|16次生成的结构状态。绿色仅表示可解码为标准结构,不表示框、类别或关系正确。紧凑组第20步同时暴露了截断与重复定义两种问题。

如果只看第20步,可以说这次格式变化没有保证消除重复;却不能说它必然学不会。如果只看第40步,又可能误以为它从一开始就解决了重复。保留中间检查点,让我们看到了训练过程中不同层面的变化。

输出更短了,但训练没有更快

最终检查点在同样四张图上的总量如下:

指标旧格式紧凑格式
生成 token8,1195,578
生成耗时1,187.4 秒784.0 秒
正常结束4/44/4
标准结构解码通过4/44/4
训练耗时817.7 秒818.8 秒

各样例生成长度与耗时

图 4|最终检查点的逐图实测。前两张是训练图,后两张是开发图。D016 的输出长度接近,说明收益并非每张图相同。耗时为该次运行记录,无重复测量误差条,不包含模型加载等完整部署成本。

合计生成 token 减少 31.3%,生成耗时减少 34.0%。但这组训练耗时几乎相同,没有观察到训练加速。较短输出在这组生成测试中表现出了时间收益,不应推广为训练吞吐的同比提升。

还要区分三种“变短”:

统计对象旧格式 → 紧凑格式减少幅度
配对预检21条样本的参考目标 token29,596 → 24,81816.14%
同21条样本的输入+目标 token70,177 → 66,9114.65%
最终四图自由生成 token8,119 → 5,57831.30%

前两行统计的是参考序列,第三行统计的是模型自己生成的内容。新的格式提示使输入 token 从 40,581 增至 42,093,抵消了部分目标压缩。因此,目标少16%不能直接等同于训练成本少16%。

同样,两组自由生成的实例和内容并不完全一致。31%的减少不一定全来自更简洁的表达,也可能包含预测内容差异。在完成质量核查之前,这只能称为本轮观测到的生成效率差异,不能称为等质量压缩收益。

结构通过之后,错误仍留在图像语义里

最终输出的定性检查仍发现:紧凑组在 D032 上虚构半圆槽,D034 存在孔槽误判,训练图 D016 枚举出12个弧槽,而现有参考为6个。两组都尚未达到可靠识别的要求。

实际诊断发现的语义错误类型

图 5|根据定性检查绘制的错误类型示意。不是原图、不是预测框叠加,也不表示真实几何位置;“参考6、预测12”来自 D016 的检查记录,其余几何形状仅用于说明概念。

“格式已经学会”也需要限定范围:我们只知道最终四条输出通过了检查,不能据此保证所有输入都合法。更关键的是,语法合法、框在0~1范围内、引用存在,都不能回答这个框是否盖住了真正的孔。

紧凑表示在这里帮助减少了输出负担,却没有替代物理实例的识别。继续缩短 JSON 也许还有工程价值,但当前没有证据说明它会消除剩余的语义错误。

7. 下一步,先把错误量清楚

现在最需要补的是按区域和实例的评价。先选择参考明确的区域,把漏检、重复、类别错和定位偏差分开记录;对未标区域和歧义关系单独处理,不能直接把它们变成背景或负例。

几何匹配需要固定协议,例如先按位置建立预测与参考的对应,再分别统计类别与关系。不能为了给类别评分,先用待评分的类别答案帮助匹配;关系评价也不应偷偷用关系答案决定实例对应。具体匹配协议的选择会影响结果,需要一起报告。

在此基础上,下一轮每次只改变一个主要因素:

如果主要错误是……优先比较什么
概览中的小结构不可辨相同目标下的概览与细节裁图,检查视觉证据是否足够
可辨认但类别或计数持续错对应样本覆盖、标签一致性、实例定义与训练进度
类别基本对但框位置不准保留纯 CE 基线,增加可微几何预测及定位监督
候选正确时关系好,预测候选时关系差参考候选与预测候选的分开测试,量化前级错误传播

冻结视觉编码器可能限制领域适应,几何监督也可能更直接地改善定位,但二者目前都是待验证方向。不能因为文本 CE 没有直接表达 IoU,就断言几何损失一定有效。

实现时还有一个区别:把生成后的 JSON 解析出来计算 IoU,可以用来评测,却不会自动变成可反向传播的训练目标。要用它指导学习,需要可微的几何分支,或明确设计序列级优化。新增模块之后也要保持相同输入条件和可比较的训练预算。

8. 我会怎样重新开始这类实验

如果重新做一次,我会更早保存固定样例的自由生成结果,让训练图和开发图都参与诊断,并记录对应样本实际曝光次数。每个检查点同时记录 loss、终止原因、结构状态、实例错误和耗时,而不是等训练结束才第一次把框画出来。

当前实验的限制也很明确:图纸数量有限,开发集已反复用于分析,参考标注并非全部独立人审;紧凑对照只有一个 seed,最终只比较了四张图;定位与关系的完整量化评测尚未完成。因此,本文适合支持诊断方法和有限的实验观察,不支持泛化性能或某种方法普遍优越的结论。

这轮实验最终给我的收获,是把几个原本混在一起的问题分开了:模型能否结束、结构能否使用、内容是否符合图像,以及完成这些事情需要多少时间。

当一个输出变短、变快,却仍然把孔识别成槽时,下一步要做的是追踪这个错误,而不是让速度图表替模型回答它是否看懂。

附录:训练跑通,也有自己的验证边界

长序列多模态训练中,LoRA 减少可训练参数和相关状态开销,但不会消除所有激活与 logits 开销。工程图分块和长 JSON 叠加后,序列长度仍可能很大。

我们在实现上使用分块 CE 和 CPU 卸载,避免同时保留完整序列的大词表 logits。一个最长样本的两步真实训练诊断中,驱动观测 GPU 峰值约59.7 GiB,CPU进程观测峰值约149 GiB,并完成了验证和 adapter 保存。这是特定配置的可运行性记录,不是完整数据集的质量验证或通用显存承诺。

保存故障也提醒我:预检成功不代表检查点可用。此次预检缓存意外把 processor 的绑定方法保留在实例属性中,导致序列化失败。修复后,需要真正完成保存、重载与继续执行,才算验证到故障点。恢复权重但没有优化器状态时,应明确记录训练连续性的变化。

这些工程工作很重要,但它们与“模型识别正确”是两套验收条件。

参考资料

本文数字来自固定实验日志与原始生成记录;方法链接用于说明背景,不代表我们已完整复现这些工作。所有插图由实验统计或自制示意生成,未包含原始客户图纸。

Last modification:September 11, 2026
如果觉得我的文章对你有用,请随意赞赏