【模型压缩系列】一:模型替换

bert问世以来,相关研究和改进如雨后春笋般涌现,预训练模型得到了飞速的发展,并在NLP很多任务中取得了统治地位。工业界也对此产生了浓厚的兴趣,各大公司纷纷试图在搜索、推荐、分类等领域中引入bert。然而,效果较好的深层bert模型复杂度较高,难以在具有较多低耗时场景的工业界直接使用,能不能使小模型有接近large级bert系模型的表现,同时又可以满足时间需求呢?模型压缩会给你答案。

一、背景

贝壳找房是一家科技驱动的品质居住服务平台,为了更好地服务消费者,我们今年推出了小贝助手2.0产品,包括咨询助手、培训助手、带看助手、房客源助手等来帮经纪人赋能提效。文本理解能力是这些助手所核心依赖的能力,但是随着业务场景越来越复杂,对文本理解的能力和实时性都提出了很高的要求,因此我们结合贝壳的语料特点做了预训练,为了保证线上的实时推理需求进一步做了模型压缩的工作。

二、技术介绍

一个复杂的深层的神经网络模型,参数量百万级别甚至更大,推理时间可想而知。直觉上,要想降低推理时间可以怎么做?

  • 减少结点个数

  • 降低权值精度

基于上述直观想法,有了两个研究方向:剪枝和量化。剪枝相对比较复杂,即使在学术界也研究较少,而量化在效果上往往不如人意。

根据各种计算去剪枝确实困难,可如果以层为单位直接舍弃,能极大地减少模型的计算量,这就是模型替换的出发点。

此外,在分类模型中,无论模型有多少个中间层,多少个参数,直接决定分类结果的是最后全连接层的输出结果(soft targets),如果我们去训练一个小模型,使得小模型的logits逼近大模型的logits,那么我们的小模型同样会有不错的效果。这就是模型蒸馏的思想,由于用到了大模型的logits(知识),因此又叫知识蒸馏。

在知识蒸馏过程中,我们通常称大模型为teacher模型,小模型为student模型,teacher可以在自己知识储备最丰富(训练完成)时指导student(蒸馏),也可以在学习的过程中与student进行交互,共同学习,我们把后者称为协同训练

综上所述,我们以直观的思路引出3种模型压缩方法:

  • 模型替换

  • 模型蒸馏

  • 协同训练

我们会分别对其进行原理介绍,实验分享与总结。本篇主要介绍模型替换。

三、模型压缩之模型替换

如上文所述,模型替换算是剪枝的一种,只不过剪得比较彻底,直接剪掉了若干层。可见,小模型和大模型不仅都要是transformer-based模型,而且小模型的hidden_size和intermediate_size与大模型对应部分也必须是一致的。

同时,模型替换又很像蒸馏。其初始化需要用到大模型的知识,又通过隐层替换的形式,不断利用大模型的信息来训练替换后的隐层参数。正如其名字的含义,最终每个隐层都不同于原来的隐层,但又拥有接近原模型的表现。下面让我们来深入了解其原理吧。

3.1 原理

模型替换的思想来自2020年EMNLP会议的论文[1],在模型压缩方向,各种知识蒸馏方法相互角逐,我们能看到这样一篇新颖的论文实属不易。

3.1.1 步骤

bert-of-theseus
Stage1:
  1. 根据压缩比确定prd和scc,如上图所示,压缩比为2:1,大模型的1-2,3-4,5-6层分别对应小模型的1,2,3层,分别用prd1,prd2,prd3和scc1,scc2,scc3表示。prd(predecessor)代表可能被替换的模块,scc(successor)代表替换模块

  2. 假设小模型是n层,用大模型的前n层初始化小模型,feed forward过程中,每层都以概率p决定是否用scc层替换prd层,pred层的参数是固定不变的,通过下游任务学习scc层的参数

Stage2:

如上图b所示,在同一个下游任务中,直接在所有的scc层finetune

上述两个阶段执行完之后,就得到了模型压缩后的小模型。

3.1.2 描述

不同于许多蒸馏方法,需要在预训练阶段就开始实施,更不需要设计loss,整个过程都在下游任务中直接finetune,突出一个简洁。我们需要提前在下游任务中训练好一个大模型,并且设计好替换概率,接下来就可以执行上述两阶段操作了。

由于第一阶段每个scc层都是以一定概率替换prd模块,所有的scc层并没有直接全部在下游任务中训练,因此就有了第二阶段的scc层微调,后面实验表明,第二步是很有必要的,能够提升小模型的表现。

具体到替换部分,每个prd, scc相对应的模块都通过一个伯努利分布采样一个随机变量,假设当前是第 个模块,对应的,随机变量,也就是替换概率, ,其中采样的概率为 的概率为1, 的概率为0。

假设scc模块输出为 ,prd模块输出为 ,那么本模块的最终输出 取决于上述随机变量的取值。

当遍历完所有的对应模块,即训练完一个epoch。

3.2 实验

我们分别在小贝的技能分类任务和智能话务意图分类任务上做实验。

小贝数据取自线上im对话,其中用户意图有几百类,为了提高识别的准确率,我们在意图上层定义了13个技能,每个技能对应一部分意图,把一个复杂的分类任务分解成了两步,每步都是相对简单的分类任务,下面的实验是对技能层分类的实践。

智能话务数据来自招聘场景中的语音对话,经asr转换成文本,我们定义了77个意图类别,不同于小贝数据,我们直接对意图做预测。

两个任务一个类别较少,文本较规整,另一个类别较多,文本存在噪声,我们通过实验验证模型替换在两种特性数据下的效果。所有实验结果都是运行5次取的最大值。

实验1

我们将压缩前后的大小模型分别称为 teacherstudent,实验所用的大模型均由加入了公司内部语料的公开中文预训练模型继续训练而来。其参数如下所示。

teacher: layer=12, hidden_size=768, intermediate_size=3072, attention_heads=12

student: layer=4, hidden_size=768, intermediate_size=3072, attention_heads=12

小贝技能13分类结果

模型precisionrecallf1-scoresupport
teacher0.88150.88130.881110582
前4层finetune0.86270.86260.862210582
student0.86760.86750.866910582

智能话务意图77分类

模型precisionrecallf1-scoresupport
teacher0.84210.83880.83884703
前4层finetune0.83230.82970.82904703
student0.84010.83840.83764703

分析

实验中,前4层finetune的参数值同student模型一样,都是由teacher模型的前四层初始化而来。从结果来看,直接finetune比模型替换后的结果要差一些的。两个任务中,student结果精度损失不同,技能13分类损失达到1.4%,而意图77分类精度损失只有0.2%,说明类别较少,文本较规整的技能分类任务对模型复杂度敏感,而对于77分类任务,虽然更复杂的模型能够提升效果,但受任务本身难度制约,提升比较有限,使得teacher模型,前4层finetune以及student结果都较为接近。这说明在更难的任务上使用复杂度更高的模型以及模型压缩收益更高。

问题

模型替换有其固有的问题,其仅缩小了模型层数,每层的结点个数并没有减少,响应时间能满足要求吗?我们与线上正在使用的4层albert做对比。结果如下。

albert: layer=4, hidden_size=312, intermediate_size=1248, attention_heads=12

bert-of-theseus: layer=4, hidden_size=768, intermediate_size=3072, attention_heads=12

模型响应时间
albert28ms
bert-of-theseus88ms

其中,响应时间表示测试的1万条数据中99%的请求在该时间内响应完成。

结果表明,仅减少层数并不足以使模型压缩到响应时间满足需求的程度,如果我们将teacher模型的中间结点也缩小呢?如果压缩后的小模型效果接近上面的表现,我们可以着手训练层数高,中间结点少的“瘦高”模型。效果究竟怎样呢?为此,我们做了实验二。

实验二

本实验为模型替换在“瘦高”模型上的探索,所谓“瘦高”模型,就是隐层和中间层结点较少,而层数比较高。

“瘦高”模型参数如下:

teacher: layer=12, hidden_size=256, intermediate_size=1024, attention_heads=4

对应的,压缩后的小模型参数:

student: layer=4, hidden_size=256, intermediate_size=1024, attention_heads=4

小贝技能13分类结果

模型precisionrecallf1-scoresupport
teacher0.8771(0.8815)0.8769(0.8813)0.8766(0.8811)10582
前4层finetune0.8584(0.8627)0.8569(0.8626)0.8572(0.8622)10582
student0.8602(0.8676)0.8594(0.8675)0.8590(0.8669)10582

智能话务意图77分类

模型precisionrecallf1-scoresupport
teacher0.8356(0.8421)0.8316(0.8388)0.8310(0.8388)4703
前4层finetune0.8247(0.8323)0.8214(0.8297)0.8209(0.8290)4703
student0.8272(0.8401)0.8229(0.8384)0.8231(0.8376)4703

其中,括号内为标准bert-base参数下的系列实验结果。

分析

最为直观的结果就是,“瘦高”模型的系列实验中,所有结果全面下降,我们知道技能分类任务上,student和teacher的gap很大,在本实验中,其差距并没有被缩小。在意图分类上,甚至标准bert-base压缩后的小模型表现都好于“瘦高”teacher模型结果,因为这个任务更难,更需要模型有更高的复杂度。看来中间结点的减少相对于层数的缩小代价更大,两个任务都表现出某种程度的欠拟合,尤其是层数又少,中间结点又少的student模型,比实验一的结果下降了很多。因此,“瘦高”模型不会成为训练的重点,模型替换并不能实际解决我们的问题。

四、进阶

从上面的实验可以看出,我们每次都会和小模型直接finetune做对比,这是因为在调研方法的时候看到网上对模型替换是有争议的,尤其在中文数据集上。在一些实验中,模型替换结果与小模型直接finetune结果相差无几。在我们的实验中,从概率论的角度,替换后的结果是显著好于直接finetune的,不过提升均在1%以内。如果你在实验中,模型替换未能好于直接finetune,不妨做如下尝试。

  • 降低stage2学习率

  • 引入数据增强

stage2,即替换后的小模型在下游任务finetune阶段,是进一步训练模型的有效手段,然而实验初期,我们发现经过stage2后,模型效果下降,从效果变化来看像是步长过大导致,降低学习率后,效果回归正常,表现稳定的优于stage1结果。

数据增强,在这里作为引导模型学习的手段,增强方式为引入大模型预测了伪标签的数据。这部分数据直接加到小模型finetune上效果提升并不显著,但在模型替换中效果明显。我认为,在漫长的finetune过程中这部分数据可能难以充分发挥效用;而在模型替换stage1后,模型已经有了不错的预测性,此时增强的数据可能能够更好地指导参数向大模型学习。我们实验初期应用数据增强能够有效提升表现,不过上述实验为了保持finetune与模型替换的一致性,两个实验均未使用数据增强。

此外,我们尝试了修改替换概率,效果变化并不明显。尝试了在替换过程中引入映射矩阵,使替换后的小模型隐层可以映射到任意大小,效果表现不佳。

五、总结

综上可得,模型替换有如下特点:

优势:

  • 直接在下游任务上压缩,方法非常简洁,易于操作

  • 结果相对稳定且效果不错

劣势:

  • 模型中间层size不可变,比较依赖大模型的结构

  • 不能蒸到cnn等异构模型

至于模型替换相较于其他模型压缩方法,效果怎样呢?我们没有直接对比过,因为二者的场景不同,研究正常large的模型替换是没有意义的(从响应时间考虑),中间结点不能减少使得其需要“瘦高”模型的支持。而从本篇的实验也可以看到,作为teacher的大模型需要尽可能“高胖”。

本篇介绍了我们在实际业务中,对模型替换的探索,除此之外,在蒸馏和协同训练的实践中,我们也积累了一些经验,取得了一些进展,你是否对此感到好奇呢?后面我们没有继续在bert-base上研究,teacher模型统一使用了24层的large模型,敬请期待系列文章的后续吧。

六、参考文献

[1] Xu C, Zhou W, Ge T, et al. BERT-of-Theseus: Compressing BERT by Progressive Module Replacing[J]. arXiv, 2020: arXiv: 2002.02925.

[2] https://zhuanlan.zhihu.com/p/112787764.

[3] https://kexue.fm/archives/7575

[4] https://github.com/ymcui/Chinese-BERT-wwm

作者介绍

杨蕴凯,2019年6月毕业于武汉大学计算机学院,毕业后加入贝壳找房人工智能中心业务智能部,主要从事自然语言理解相关工作。

来自:贝壳智搜

说个正事哈

由于微信平台算法改版,公号内容将不再以时间排序展示,如果大家想第一时间看到我们的推送,强烈建议星标我们和给我们多点点【在看】。星标具体步骤为:

(1)点击页面最上方深度学习自然语言处理”,进入公众号主页。

(2)点击右上角的小点点,在弹出页面点击“设为星标”,就可以啦。

感谢支持,比心

投稿或交流学习,备注:昵称-学校(公司)-方向,进入DL&NLP交流群。

方向有很多:机器学习、深度学习,python,情感分析、意见挖掘、句法分析、机器翻译、人机对话、知识图谱、语音识别等。

记得备注呦

推荐两个专辑给大家:

专辑 | 李宏毅人类语言处理2020笔记

专辑 | NLP论文解读

专辑 | 情感分析


整理不易,还望给个在看!
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 关于TensorFlow v1的替换模块,我可以回答你的问题。TensorFlow v1中的替换模块是tf.contrib模块,它包含了一些实验性质的功能和算法,同时也包含了一些已经过时的API。在TensorFlow v2中,很多tf.contrib模块中的实验性质的功能已经被整合到核心库中,并且已经有了更好的实现方式。因此,TensorFlow v2中不再支持tf.contrib模块。如果你需要使用tf.contrib模块中的某些功能,你需要使用TensorFlow v1。 ### 回答2: TensorFlow是一个非常强大的开源机器学习框架,但随着时间的推移,它的发展也在不断演进。TensorFlow v1是第一个正式发布的版本,但现在已经有了许多替换模块。 TensorFlow v2是TensorFlow的下一个主要版本,相比于v1,它有很多重要的改进和功能增强。首先,v2具有更好的易用性和更简洁的API设计。v2引入了eager execution,这使得编码更加直观,能够立即运行操作,而无需构建计算图。它还使用了Keras作为高级API来简化模型构建部分,使得创建和训练模型更加简单。 另外,TensorFlow v2还强调了模块化设计和向后兼容性。新的模块化设计使得使用者可以根据需要灵活选择所需的组件,而无需加载整个框架。而且,TensorFlow v2确保了向后兼容性,这意味着从TensorFlow v1迁移到v2的过程中将保持代码的可用性。 此外,TensorFlow v2还加入了一些新的特性,比如集成了TensorFlow Extended(TFX),这是一个用于端到端机器学习的平台。TFX通过提供特定任务的组件集合,如数据预处理、模型训练、模型评估和模型部署,使得机器学习工作流程更加高效和方便。 总结而言,TensorFlow v2是TensorFlow v1的替换模块,它具有更好的易用性、简洁的API设计、模块化的架构、向后兼容性以及新的功能增强。它是一个不断发展和改进的框架,为开发者提供更加强大和高效的机器学习工具。 ### 回答3: TensorFlow v1的替代模块是TensorFlow v2。 TensorFlow v2是TensorFlow的最新版本,于2019年发行。它引入了许多改进和新特性,旨在提高开发者的生产力,并提供更好的性能和易用性。 与TensorFlow v1相比,TensorFlow v2具有以下几个主要的替代模块: 1. Eager Execution(即时执行):TensorFlow v2默认启用了Eager Execution,这意味着可以立即执行TensorFlow操作,而无需构建图。这种模式更直观,使得调试和开发更加容易。 2. Keras作为默认高级API:TensorFlow v2将Keras作为其默认的高级API,用于构建、训练和部署机器学习模型。Keras提供了一种简单而强大的接口,使得模型的创建和使用更加方便。 3. 更简化的API:TensorFlow v2删除了一些在v1中存在的冗余和过时的API,简化了代码的编写和使用。这使得新手用户更容易上手并开始使用TensorFlow。 4. 改进的性能:TensorFlow v2集成了TensorFlow v1中的许多性能优化,以及一些新的特性,以提高模型训练和推理的速度和效率。 5. 跨平台支持:TensorFlow v2增加了对移动和嵌入式设备的支持,如Android和iOS。这意味着可以将训练好的模型部署到这些设备上,以进行推理和应用开发。 综上所述,TensorFlow v2是TensorFlow v1的替代模块,并为开发者提供了更好的易用性、性能和功能,使得构建和部署机器学习模型更加简单和高效。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值