心法利器
本栏目主要和大家一起讨论近期自己学习的心得和体会,与大家一起成长。具体介绍:仓颉专项:飞机大炮我都会,利器心法我还有。
2022年新一版的文章合集已经发布,累计已经60w字了,获取方式看这里:CS的陋室60w字原创算法经验分享-2022版。
往期回顾
上一期文章的目标是为了让大家对性能有一些基本的概念,并告诉大家如何检测现在自己的算法的实际性能:心法利器[66] | 算法性能评估指南。这一期给大家介绍一下给算法性能优化指南。
开始之前,我先介绍下几个方案的分类:
设备升级。
编译方式处理。
模型结构的优化和压缩。
外部方式降低模型压力。
不首先考虑使用大模型。
当然了,这块的研究其实非常广泛,我也只是懂些皮毛,聊一些自己日常用的方案吧,如果有没讲到的,欢迎大家补充。
设备升级
所谓的性能不足,除了模型的问题,另一方面就是没有那么好的设备,只要升级设备,在假设设备没有技术瓶颈的前提下,其实都不会存在性能问题了。
首先,如果是单机耗时就不够,其实很大程度就和机器本身自己的能力有关了,跑深度学习CPU肯定不如GPU,如果CPU机器瓶颈较大,那其实换GPU就能很大程度提升性能力,而换GPU,也有高低之分,当然是越强跑的就越快了。另外是内存,内存这事本质上决定的是一个可行性问题,例如训练上能不能放这么大的数据batch,模型上能不能放得下这么大的模型结构,那内存就会是硬伤。
第二,如果是并发能力不够,对机器能很大程度解决这个问题,注意是并发能力。一般地,技术上通过多机器的并行,能很快处理好并发问题。
但是,这个方案也有很大的缺陷,一方面,这个方案是有天花板的,不存在无敌的设备,只有目前技术下最好的设备,所以即使是现在,弄超大的,上亿十亿甚至百亿的预训练模型,也不是光靠堆砌机器就能搞定的,另一方面,好设备是需要花钱的。
编译方式处理
编译这个方案相信很多人都有听说过,说白了其实就是将模型结构编译成更加适合特定设备执行的模式,如ONNX、TVM等,类似这些技术能让模型的推理速度快,这点其实普及度远比大家想象的要高,而且收益也不低。
有兴趣的,大家可以学下。我这块不是很深,给大家一些官方的链接吧:
TVM:https://tvm.apache.org/docs/
ONNX:https://github.com/onnx/onnx
模型结构的优化和压缩
自预训练模型兴起,尤其是大规模的预训练模型,就已经开始有很多人开始研究预训练模型的压缩了,毕竟这个大东西很大,要一下子用在现实任务上,其实不那么容易,大家懂的都懂。
在模型结构上的优化,主要有这些吧:
参数层面的优化,例如大家熟知的albert,就是通过共享参数来压缩整体的参数量,这无疑让内存得到喘息。
通过蒸馏的方式,把预训练模型蒸馏到小的学生模型上,然后在线跑的是小模型,例如层数较少的transformer,甚至是CNN。这应该是比较常用的技巧了。(tiny-bert)
在比较复杂的NLP系统中,有多个NLP任务要用预训练,可以通过统一表征的方式,来减少在线预训练模型的使用。(https://blog.csdn.net/m0_59407274/article/details/125601261)
外部方式降低模型压力
当然还有一些别的方式,这里我简单总结为通过外部的方式降低模型压力吧,说白了就是让模型抗的压力变小,或者是不在线跑,这里列举一下。
高频query离线计算好,存入数据库中。
cache机制,计算完后存入数据库,每次请求先检测数据库内有没有原来算好的结果。
在模型前建立过滤机制,不要让所有请求都过模型,例如做一些简单规则、黑名单等,减轻模型压力。
不首先考虑使用大模型
在之前的一篇文章里,其实我有建议大家,在进行方案设计的时候,不要首先考虑使用大模型,大模型的上线以来很多基础工作,如果记住工作不好的话,上线绝对是事倍功半的,所以大模型更多是一个迭代和优化得到的方案,而不是一个很好的从零开始的baseline。
早期,我们可以用规则甚至词典之类的来快速启动,然后上小模型,再到大模型这块的进化,这样性能也能按需逐步升级。
小结
本期给大家讲了一些性能优化策略,即使是算法,也是一名工程师,性能的敏感度和警惕性还是需要有的,可用是一个服务最基本的要求,只有可用了,后面的各种更优秀的预测和推理能力,才能够被展示出来。
另外,有关性能优化,慢慢的有不少团队开始储备这方面的人才,以提升算法的性能,上线更多更强的模型方案,为用户提供更强的算法能力,属于人力需求大但是供给量少的位置,有兴趣大家可以自行了解一下。