我在很多文章里都有吐槽大规模预训练模型的性能差,落地成本高,这一期就和大家讲讲,怎么评估算法的性能的。
当然,这篇文章应该是比较科普的,主要是为了让大家树立一个性能意识,在进行方案选型和最终检测的时候,能有关注性能的这个意识。
性能的意义
这里所谓的性能,本质是对执行速度、执行资源消耗的一种评估。在现实的落地场景,一个模型最终能不能用起来,除了和算法效果有关,即类似准确率召回率,还和依赖的资源以及速度是相关的。
我们可以把运行环境比作一个空间有限的房间,如果你的刀是40米长的,其实很难在这个房间里使的舒服,即使他的伤害很高很强,与之相反,一把短一些的到在有限空间内,用起来会更得心应手。这就是性能的意义,在预训练模型逐步热门之后,这个问题会更加尖锐,预训练无论是计算复杂度,还是空间需求,都很大,先不说训练,就是推理,单机推理还算可以,但是耗时,还是高并发需求下,并非所有的组织都能支持,因此,我们需要对性能有足够的敏感性,否则会很可能会出现,一顿操作效果调优一个月的预训练模型,最终因为上不了线功亏一篑的尴尬情况,当然,这也是作为一名算法工程师,必备的一种能力。
性能评估的观测指标
要评估性能好坏,有哪些评估项,又有那些评估指标,详细介绍下。
首先是单机速度的评估。即单进程下,每次推理所需要的时间,或者单位时间下能处理的计算次数,一般评估的是rt(Reaction Time,响应时间)或者qps/tps(query per second,transaction per second)。但是,由于很多时候,不同的输入可能会影响这个时间,所以一般使用和在线分布接近的样本或者query来批量请求,求平均值,而常见的,耗时长度的分布服从二八法则,因此我们要关注的是TOP耗时的情况,因此我们还会看不同位置的分位点情况,例如90%、95%或者99%分位点。另外还有种评估的方式,用合格率之类的方法,例如最高耗时不能超过200ms,超过的算失败,然后计算成功率,成功率99%以上。
对于互联网环境,除了单机速度,还必须考虑并发能力,并发能力是指当同时很多请求同时或者接近同时请求的时候的性能状态,很多时候,因为热点事件的出现,大家会大量开始在网上检索请求,对计算机而言,完不成的任务就会开始排队(这个和银行柜台类似的),排队太长系统自然就难堪重负崩溃了,例如微博、B站、知乎这种偶尔的崩溃就很多是因为这个原因。指标上,其实更多是和单机的评估类似,只是评估的时候,一般是用多进程同时请求以模拟在线情况,例如4进程、8进程这种,然后来看速度还能不能保证在合格范围内。
除了速度之外,偶尔还要看看其他的问题,例如内存,有没有内存泄漏(在服务运行期间内存有没有持续增加),在高峰期内存是否在正常范围内(例如80%以内),都是需要关注的。
从批跑到压测
前面有提到,评估性能最简单的方式就是批量跑case,简单的性能评估,其实就是找一批和query批量跑,然后掐时间。这里,先说下这个query需要有什么要求:
数量得足够,否则均值和分位点计算就达不到统计意义。
而且尽可能和现实场景匹配,这样测得时间和在线实际时间比较接近(这个其实没那么难,直接捞日志抽样即可)
这个时间的评估其实不难,简单的用tqdm,上面就显示平均时间(X item/s),但是如果要算分位点了,肯定要把每个case的时间都记录下来再统计,例如弄numpy里面的函数计算,写起来并不算困难。
但是,一旦要考虑并发能力了,那就要压测了,即压力测试,所谓的压测,其实就是计算机模拟N个用户,同时不断向服务发送请求,当然,要压测的话,通常需要把模型打包成服务,例如grpc或者http的。然后和观测上面提的指标,耗时、qps、成功率、内存等。一般情况,我们不需要用所有服务器来实验,一般也是对一台机器即可,因为多台机器,如果有做负载均衡,其实性能就是多台机器求和而已。python实现上,先是对模型打包成服务形成服务端,而压测脚本这边写一个客户端来请求服务端,上压测的话就弄个多进程触发即可,网上有很多样例代码,直接搜,当然别指望能照搬,肯定是需要自己服务的情况来修改额,毕竟接口不尽相同。
小结
本文给大家简单介绍了算法这边需要关注的性能,以及评估的主要方式,能让大家对性能树立一个基本的概念,让大家清楚性能是什么,怎么观测等,后续会给大家介绍一些性能调优的手段,帮助大家更好地优化性能,成功把自己心心念念的模型推上线。
全部0条评论
快来发表一下你的评论吧 !