☰
SEMA按需生长机制:让预训练模型持续扩展而不遗忘
2026/10/1 16:12:00 网站建设 项目流程

上个月我把一个训练好的视觉模型部署到产线上,跑了两周一切正常。结果新来的合作方提了一批新需求——识别类别多了三分之一,而且某些样本的形态和训练集完全不是一个路数。当时我面临一个很现实的选择:换一个更大的预训练模型重训,还是在现有模型上做增量扩展。重训意味着重新标注数据、重新调参、重新过一遍漫长的验证流程;但如果继续沿用现有模型,精度又会明显下滑。后来在备赛和读论文的过程中,我看到了CVPR 2025 的 SEMA,它给出的回答很直接:模型不一定非要整体换血,按需长出新 Adapter 就够了。这篇就来拆一拆 SEMA 的思路,以及它在实际项目里到底能怎么用。

不管你是做视觉、做 NLP,还是做多模态的,只要手里有已经部署好的预训练模型,都会遇到“模型不够用了”的时刻。SEMA 的核心不是教你重新训练一个大模型,而是给出一种让已有模型动态扩展能力边界的机制。全文我会围绕五个方面展开:模型为什么需要长大、SEMA 的生长逻辑、预训练知识怎么保留、适配器生长的触发与路由策略,以及我落地过程中总结的几条实操经验。

1. 预训练模型为什么需要“长大”:三个典型场景

1.1 任务范围扩展:新类别、新域、新任务同时出现

模型长大最直接的需求来自任务本身的变化。假设你原来用 ResNet 预训练模型做工业质检,只识别产品表面的划痕、脏污、缺胶。半年后客户要求增加对焊接点虚焊、元器件极性反装、PCB 板弯折这些新缺陷的识别。表面看只是类别数量从 5 类变成 12 类,但实际难点在别处:新增类别和原有类别在特征空间里高度重叠,比如虚焊和脏污都可能表现为局部颜色差异,如果直接在原有模型的输出层上加几个节点重新训练,旧类别的特征分布会被新类别的梯度更新推着跑,最终出现“学到新类,忘了旧类”的灾难性遗忘。

这种情况下,最省事但也最费钱的做法是收集全部新旧数据,重头微调一个更大的模型。问题是工业场景的数据往往分散在不同产线、不同时间段,历史数据的分布和当前真实分布已经产生偏移。我见过不止一个项目栽在“重新标注全部数据”这一步,标注成本、人力成本、时间成本全都要翻倍。

SEMA 的做法是在冻结原始模型参数的前提下,为新需求长出新的 Adapter 模块。每个 Adapter 只对应一组增量能力,原始模型的主干参数一概不动。这样旧类别不会因为新类别到来而退化,新增类别也能在专门的旁路里获得足够的拟合能力。对于“任务边界清晰”的扩展场景,这个思路特别合适。

1.2 数据分布漂移与原领域失效

第二个典型场景是输入数据的分布发生了整体漂移。以我自己做过的字符识别项目为例,训练数据来自扫描仪成像,字符比较干净,背景也比较统一。到了线上,用户上传的照片大多是手机在弱光、倾斜、遮挡条件下拍的,字体、光照、噪声分布和原先的数据集差距很大。直接在原模型上做有监督微调,模型会逐渐把注意力从“字符结构”偏移到“光照模式”这类非稳定特征上,短时间内看起来精度回升了,换一批数据又会掉回去。

更隐蔽的问题是领域漂移往往不是一次性发生的,而是随着摄像头更换、环境光照季节变化、生产批次切换,隔一段时间就漂一点。如果每次漂移都用旧模型的全部参数重新微调,模型会被最新的数据分布牵着走,最终丢失掉对早期数据的泛化能力。SEMA 把“内存”和“处理器”分开:原有参数负责稳定的公共知识,新增 Adapter 负责吸收当前分布里的特异性模式。这样一来,即便分布漂移了好几次,公共知识依然锁定在原始主干里,不会被反复覆盖。

1.3 多租户场景下的个性化需求

还有一种需求是同一个模型要服务多个差异很大的用户群体,但又不能互相干扰。比如给电商平台做商品识别,平台 A 主营服装,平台 B 主营数码配件,服装类的背景复杂度、拍摄风格和数码类完全不同。传统做法要么为每个租户单独训练一个模型,浪费存储和计算资源;要么大家共用一个模型,各自需求都被平均化,谁都不满意。

把 Adapter 的思路套进来就很清晰:所有租户共享同一个预训练主干,每个租户配一个独立的 Adapter 模块。公共主干负责通用的视觉特征提取,租户 Adapter 负责本域的个性化映射。SEMA 进一步解决了“什么时候该为新租户添加新适配器、什么时候可以复用已有适配器”的问题,这是靠路由和生长策略来完成的,后面我会详细展开。

2. SEMA 的核心思路:把模型变大这件事,从“换发动机”改成“加外挂”

2.1 Adapter 不是新概念,但 SEMA 把它做成了动态决策问题

Adapter 本身是参数高效微调里的成熟方法:在预训练模型的主干层之间插入小型瓶颈模块,微调时只更新 Adapter 的参数,冻结主干权重。这么做的好处很直观——需要训练的参数量可能只有全量微调的 1% 到 5%,训练速度快、显存占用小,而且每个任务只需要保存一个小小的 Adapter 权重文件。

但传统 Adapter 的做法是“预先铺好”:在主干模型里提前插入若干 Adapter 层,用训练数据统一更新。SEMA 的不一样之处在于,它把“是否真的需要新增 Adapter”变成一个运行时决策。模型先以原始预训练权重跑,当它判断现有能力不足以覆盖当前输入时,再动态分配、初始化新的模块。这个思想的转变值得细说。

2.2 “按需生长”到底在生长什么:宽度、深度,还是另一条旁路?

要理解 SEMA 里的“长大”,先要理解模型能力瓶颈到底卡在哪。一个预训练模型在遇到新任务时表现不佳,通常有三类原因:特征表示不够、映射关系太复杂、决策边界不合适。

如果想通过增加模型参数量来缓解,常规思路是增加网络的宽度或者深度。但在已部署模型上直接改主干结构会带来一连串麻烦:得重新适配推理引擎、重新量化、重新验证延迟。SEMA 选择的是第三条路——保持原有网络结构完全不变,在旁边接一条或者多条并行通路。每条并行的 Adapter 通路可以看作一个小型专用网络,它的输入来自主干的中间特征,输出再合并回主干的后续层。

这种设计的好处是极强的兼容性:原模型该怎么推理就怎么推理,新长出来的 Adapter 只是额外计算路径。加了 Adapter 之后,整个模型仍然可以当作一个整体进行端到端训练,也可以单独微调某一支路。

2.3 和“直接微调大模型”“加网络层重训”两种路线的对比

为了把 SEMA 的位置讲清楚,我画过一张对比表,基本能说明问题:

方案是否冻结原始权重新增参数规模对原有能力的影响增量扩展性训练成本
全量微调大模型否无新增,全部更新可能导致灾难性遗忘差,每来一个新任务几乎都要全面重训高
主干加层后重训部分冻结视加层规模而定改动主干结构,影响面大一般,加层位置难选中高
固定 Adapter 微调冻结很小几乎不影响中等,模块固定后不易增删低
SEMA 按需生长 Adapter冻结按触发情况动态增加几乎不影响,且有隔离机制强,可随新任务动态添加/冻结低

从这张表能看出,SEMA 真正改善的是“增量扩展性”和“对原有能力的影响”。它没有追求一种包打天下的新结构,而是把 Adapter 技术的使用方式从“一次性规划好”升级为“动态按需分配”,这是我认为它最有价值的地方。

2.4 一个很容易被忽略的细节:模块不是越新越好,新旧知识要能协同

SEMA 里长出的 Adapter 并不是彼此孤立的。每个新模块在初始化时,会参考已有模块在相关任务上的表现,选择性地继承一部分旧模块的投影参数。这个细节很关键,它让模型在扩展时具备了“迁移”的属性,而不是每次从零搭建一套新知识。

我用一个生活化的类比来帮助理解:一个成熟的工程师团队,最开始两三个人。项目变复杂了,团队不会立刻招十个新人,而是先看现有成员的任务饱和度——确实忙不过来了,就招一个新成员,且让新成员先跟着老成员熟悉业务。SEMA 也一样:先评估已有 Adapter 的能力覆盖情况,判断是不是新增模块就能解决当前问题,如果能,就只调整路由分配;如果不行,再初始化新模块并让它从现有模块中获得初始化先验。

3. 预训练知识怎么保留:冻结主干,为什么是 SEMA 的安全底线

3.1 灾难性遗忘为什么会毁掉一个已经上线的模型

我在前面提到了灾难性遗忘,这里需要多说几句。神经网络用梯度下降更新参数时,新任务的梯度会改变共享特征提取层的权重,而某些对旧任务至关重要的特征方向在新任务的梯度里几乎没有贡献,于是逐渐被覆盖掉。这不是某个模型独有的问题,而是基于梯度学习的系统通病。

在已上线的系统里,灾难性遗忘的代价比在实验室里大得多。实验室里忘了旧任务,重新训练一遍就好;生产系统里旧任务的线上流量还在进来,你今天更新了模型,明天就可能收到一堆误报投诉。所以任何声称“支持持续学习”的方案,第一道考题都是旧能力保留得怎么样。SEMA 选择冻结主干,从机制层面把灾难性遗忘的最大来源切断了——既然主干权重一动都不动,旧任务的公共特征提取方式保持不变,那么旧任务的知识基础就还在。

3.2 主干保留到什么粒度:每层都接旁路,还是选定关键层?

实际操作中会遇到一个问题:主干几十上百层,总不能每一层旁边都挂一个 Adapter 吧?计算量吃不消,效果也可能过拟合。SEMA 的关键层选择逻辑,是依据主干内部特征在任务之间的“分歧程度”来决定的。

具体来说,它会在代表性样本集上统计各层输出的特征分布差异。当新任务和旧任务在浅层特征上差异不大、到深层特征才出现明显分歧时,就只在高层接入 Adapter;如果连浅层特征都差异显著(比如输入模态从自然图像换成了医学影像),那么从中间层开始就要接入旁路。这个选择和“迁移学习该冻结哪些层”的问题很像,只不过 SEMA 把决策过程自动化了。

我在实际复现类似逻辑时,通常用一个轻量级的分布距离计算(比如最大均值差异)来评估层间分歧,按阈值筛选需要“生长” Adapter 的层。这个方案简单有效,也容易解释给团队里的其他成员听。

3.3 公共知识和新知识的衔接:特征合并需要注意尺度问题

主干层输出的特征和 Adapter 支路输出的特征合并成最终输入时,存在一个尺度匹配问题。主干特征经过了几十层网络的归一化,数值范围相对稳定;新初始化的 Adapter 训练初期输出值可能偏大或者偏小,直接相加会让主干特征被淹没。

SEMA 给我的启发在于它对“合并权重”的处理:新 Adapter 在初始化阶段输出会被缩放系数压得很低,几乎不改变主干特征,然后在训练过程中逐步学习合适的输出强度。用不那么学术的话讲:新成员刚加入团队时先不让他做决定,让他观察学习一段时间,业务熟悉了再逐步放手。这个动态缩放策略对训练稳定性非常友好,我第一次尝试时省掉了大量调学习率的时间。

4. 按需生长的适配规则:什么信号触发新模块,怎么保持模型原有能力

4.1 第一个问题:模型怎么知道自己“不够用了”

这是整个 SEMA 设计里最有意思的部分。模型不是一个有自我认知的系统,它需要一种定量信号来判断现有能力是否已经无法覆盖当前输入。SEMA 的做法,是为已有 Adapter 建立一条“能力包络线”。

具体地,当一批新数据进来,模型先让现有模块集合给出预测结果,同时记录预测置信度、特征与已有模块原型之间的距离、以及输出结果在类别上的分布情况。如果这批数据的平均置信度低于预设阈值,或者大多数样本的特征都落在已有模块覆盖范围之外,系统就会判定“现有模块集合能力不足”,从而触发新 Adapter 的生成。

阈值的选择直接影响模型“长大”的频率。阈值设得太低,模型会频繁长出大量冗余模块,训练管理变得复杂;阈值设得太高,模型对新任务视而不见,精度一直处于欠拟合状态。我在实践中他们会用验证集上的性能增量来反向标定阈值:以新增一个模块能够带来的最小性能提升为基准,反向推导出触发阈值。这个方法不完美,但比拍脑袋定一个固定数要靠谱得多。

4.2 第二个问题:长出了新 Adapter,怎么知道谁该被激活

模型里可能有多个 Adapter 模块,输入一张图片时不可能全部激活,否则计算量爆炸,模块之间的响应也会互相干扰。SEMA 引入了一个简单的路由机制:每个输入样本会根据其特征嵌入与各个 Adapter 模块原型向量的相似度,选出最相关的 1 到 2 个模块激活。

路由机制听起来不复杂,但在设计时需要特别注意三个细节。一是路由本身不能参与 Adapter 的训练更新,否则路由会逐渐趋同,所有样本都指向同一个模块,失去“按需”的意义;二是新初始化的模块在一开始不应参与路由竞争,它有大约一个热身期的保护;三是路由判断的特征最好来自主干浅层,避免深层特征已经高度任务化后不具备跨任务可比性。

4.3 已有模块和新模块如何隔离,又如何协作

模块隔离是防止“新旧能力互相污染”的关键,也是持续学习场景下的核心问题。

SEMA 给出的策略可以归纳为两条:空间隔离和时间隔离。空间隔离强调不同 Adapter 模块的参数存放在不同子空间,彼此之间没有被强制共享的中间层;时间隔离则表现为重复训练时的交替冻结——新模块训练时,旧模块的参数保持冻结;当前模块稳定之后,路由参数才会进行一次整体微调。这套策略我之前在其他持续学习项目里也用过,但 SEMA 把它和动态生长机制组合在一起后,效果要稳定得多。

协作主要体现在推理阶段的特征叠加:多个模块被激活时,它们的输出会按照路由权重加权再合并。为了防止加权平均导致特征被“稀释”,SEMA 推荐使用加权拼接而不是加权求和,两个支路的特征先各自归一化,拼接后再经过一层线性压缩。这个细节改起来很便宜,但真能带来几个点的精度提升。

4.4 模块数量的上限:无限生长不现实,剪枝和合并是必须的

虽然 SEMA 强调“按需生长”,但没有任何系统能无限添加模块。模块数量增长到一定程度,内存占用变大,路由判断变慢,特征组合空间爆炸,最终得不偿失。

所以 SEMA 的完整方案里必须包含模块管理机制:当已有模块在连续一段时间内样本激活率低于阈值,说明它已经失去代表性,考虑冻结或移出候选集;当两个模块的参数相似度极高、在验证集上的表现也高度相关时,系统会建议合并这两个模块,由合并后的新模块重新学习一段短时间。这种动态平衡的设计,才让“生长”不会变成“失控”。

5. 落地时需要注意的几个坑:从论文思路到实际项目

5.1 不是每个场景都适合按需生长:处理好任务边界的识别

SEMA 最适用的场景是任务边界相对清楚、新任务会分批次涌入的情况。如果你的任务根本不分批,所有数据混在一起滚进来,模型每天都要连续决策是否新增模块,那么路由和触发的稳定性就面临巨大挑战。

我的建议是:在项目初期人工定义好任务边界,或者至少设置一个最小数据积累周期。比如每积累满 2000 张新类别数据才允许触发一次生长判断,避免单个异常 batch 导致模型抖动式生长。引入这个缓冲机制之后,模块平均数量明显收敛,重复模块大量减少。

5.2 触发信号别只依赖置信度:多加一个特征分布指标更稳

我测试过只拿置信度作为触发信号的做法,效果不太好。深度模型的置信度本身就是校准不到的,尤其当输入样本落在分布外时,模型经常给出高置信度的错误预测。只用置信度判断,会漏掉很多真正需要扩展能力的情况。

后来我在触发机制里额外加了一个指标:输入样本特征与模型已备份的“代表性特征库”之间的最近邻距离。如果距离超过阈值,即使置信度看起来还行,也会被判定为潜在的新知识。代价是需要额外存储一些特征向量,内存开销一般几百 MB,大多数项目都承受得起,收益却很值得。

5.3 新模块的训练节奏:先冻结路由,再部分解冻,最后整体微调

新 Adapter 刚初始化并插入模型时,最稳妥的训练节奏是分三个阶段。第一阶段,新 Adapter 的参数先学习如何拟合当前任务数据,此时路由参数和主干参数完全冻结;第二阶段,当新 Adapter 在验证集上达到一个基本可用的精度后,再逐步解冻与新模块相关的路由参数,让样本能在新旧模块之间自然分配;第三阶段才考虑整个候选模块集合的联合微调,这一步要谨慎控制学习率,一般设为基础学习率的 0.1 倍。

这套节奏在多个任务上验证下来,稳定性比直接端到端联合训练好很多。直接联合训练很容易出现一个后果:新模块还没学好,旧模块的路由已经被带偏,最后老任务和新任务同时掉点。

5.4 与量化、剪枝等优化手段的兼容性:别到头来白折腾

现在部署视觉模型几乎避不开量化或剪枝。SEMA 动态生长的 Adapter 和这些优化手段的兼容性,需要提前验证。我的经验是:主干模型可以先量化完成再冻结,Adapter 模块保持浮点精度运行,单独量化;如果推理引擎不支持同一模型不同模块不同精度,那就做一个预处理工作,把主干中间层输出缓存下来,Adapter 单独走一个轻量级推理路径。

这件事做不做直接决定上线后的性能表现。我见过有团队把 Adapter 和主干一起量化,结果新模块的精度掉得比全量微调的基准还差,排查了很久才发现是量化误差在旁路合并时被放大了。量化的敏感性分析不要省,专治这种隐性坑。

5.5 评估机制要重新设计:不能只看整体精度,还要监测旧任务的表现

最后说评估。动态生长模型和生产系统需要的评估体系和普通模型不一样。你不能只盯着整体测试集上的平均精度,那样会把旧任务上的些许退化掩盖在新增任务的亮眼表现里。我建议做两张表:一张是新任务性能表,记录每次新增 Adapter 后的精度、召回、推理延迟;另一张是旧任务回归表,用一套固定的历史基准集持续监测,每当触发新模块生长或者路由调整时,跑一遍回归集,观察有没有掉点。

我在项目里还把回归表做成了自动化流程,每次模型版本更新都要过一遍,任何旧任务精度下降超过一个设定阈值,该版本就不能上线。这样做虽然增加了不少验证工作量,但它能在 SEMA 这类持续学习系统中守住最重要的一条底线:模型可以变强,但不能变“失忆”。

从整个方案来看,SEMA 并不追求用一套复杂的全新架构去替代主流预训练模型,而是把“模型什么时候该长大”这个问题直接摆到桌面上:有信号就长模块,没信号就保持原样,主干永远作为记忆底座。这种思路对生产环境尤其友好。我自己实际测试下来,它最大的价值不是提升了多少精度,而是让网站在面对新需求时不需要再反复经历“全量重训—评估—上线”的漫长折腾,也让我手里的旧模型真正变成了一块可以持续升级的基础设施。如果你正被“又该换模型了”这个问题反复折磨,不妨先别急着换发动机,试着看看到底该给模型加一个什么样的 Adapter 模块。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询