停止到目前,工作中遇到至少5次的一致性比较任务。此中4次是本身亲身到场的,有1次则是观看者的身份。本篇文章是对这一典范任务的梳理。
一致性比较的问题来源
可以将这5次一致性比较问题的来源划分为4大类:编程语言gap(x2)、框架gap(x1)、空间gap(x1)、时间gap(x1)。
编程语言gap:python开发方便,c++性能较高,对于算法工程师来讲,这两者是日常工作中使用的语言。两次编程语言gap导致的一致性问题,恰好集齐了python库向c++库对齐和c++库向python库对齐两种模式。编程语言gap1是c++库先存在,而且已经成为公司的主流部署库很长一段时间。然而隔壁组由于定制项目较多,对快速开发、修复bug从而相应客户的重视水平高于对库的运行性能好坏。(事实上,这种who cares的定制现象在算法领域是一个较普遍的现象)。因此隔壁组盼望开发一个对等的pyhton-engine库。编程语言gap2是本身亲身经历的一个任务,产品侧同事盼望能够在模型练习完毕后,快速的提供一个可运行的服务版本,而且能够有较完善的效果可视化功能。以检测任务-yolov11为例,假如要写一个基于python语言的推理脚本,仅需from ultralytics import YOLO即可。即使有附加的后处置惩罚业务逻辑代码大概可视化效果需求,python语言也能够较快的开发出来,这样可以快速的让对方看到效果便于测试。但产品同事终极盼望在不久的将来高性能的c++版本也能够提供,而且保持与python版本完全的一致性,无感替换。
框架gap: 目前随着开源的兴起,国内以商汤mm系列、百度paddle系列为代表的开源社区,险些囊括了所有经典的算法。与之对应的,所在的公司也有本身的自研练习库,有的时间必要在开源框架中吸代替码到自研练习库中。这里称之为框架gap。
空间gap:算法的开发者与算法的使用者不是同一拨人。就会出现典范的开发侧的指标很好,但产品侧反映效果一样平常。
时间gap: 自研算法推理库当前测试效果无法与一年前推理效果一致,且有较大的指标下降。这一样平常是由于某次的代码merge测试不敷充分导致的。
不同一致性比较场景的解决履历
编程语言gap1场景由于仅是一个观看者的角度,细节不是很相识,在此不做阐述。针对编程语言gap2,其痛点在于c++版本的推理库本身流程和逻辑不复杂,但c++语言导致该事物的复杂性上升,具体表现为假如直接由该库向yolov11库对齐,c++代码的添加、改动和调试都会较困难;另外一方面,以python语言编写的yolov11库本身语言不复杂,但由于pip的安装方式,以及所必要的推理代码仅仅是yolov11库的一部分,导致代码的调式方式复杂和信噪比较低。总结下来,就是在一个复杂的事物上向另外一个复杂事务靠近。效果就可能掉在一个“毛线团”里面,在这个毛线团里面,当无法对齐的时间,会猜疑统统:c++的opencv和python的opencv会引入差异?有什么超参没注意到?c++的内存分配是否有问题导致某些内存中的数据被异常改动、覆盖。最后的解决方案是:不要同时对付两个复杂的事物。具体说来,起首,用python语言写一个仅基于onnx库的裸推理脚本(这里的裸是指不适用yolov11库),来尝试向c++的推理效果对齐,此时python的快速开发性能被使用起来,较快就对齐上c++的推理效果。这阐明c++的opencv和python的opencv没什么差异,且c++的代码无内存相关的缺陷。接下来,就是用该裸的python推理脚本去对齐yolov11推理,此时python的易于开发、更新和调试的特性依然存在,同样较快的找到了超参以及一些具体的操作实现差异。最后,c++对应的代码同样的修复掉这些超参和代码逻辑操作差异,就可以做到效果小数点后级别的一致性对齐。总结起来就是,1. 不要同时处置惩罚两个复杂的事物;2. 将一个复杂的任务拆解为3个简单的任务;3. 每一次都是易于开发、调试的对象向不易开发、调试的对象对齐。
框架gap场景与编程语言gap2场景其本质是一样的:试图从一个复杂的事物向另外一个复杂的事物对齐。自研库的复杂性在于其必要考虑到“矩形框”–“旋转矩形框”–“任意四边形”、“agnostic_nms”—"specific_nms"等等兼容场景。尝试“硬刚”的时间,一旦效果不符合预期,同样的会有众多的因素值得猜疑:场景兼容问题、代码逻辑问题、练习的随机性问题、多卡分布式问题等。其较好的解决思路,仍旧是先通过python实现一个与自研库无关、但是和框架的练习效果能够对齐的版本。然后再反过来,该版本向自研库对齐。最后找到差异,更新自研库。
空间gap场景的大抵原因在于硬件/体系环境原因和接口/配置参数原因。针对硬件/体系环境原因建议通过镜像的方式来交付;而接口/配置参数则通过openapi和公共规范的文档的方式来克制。
时间gap场景其本质可以归结为软件工程领域中的“回归测试”的缺失。该问题的克制,起首肯定要有git-tag这样的代码版本管理机制在,这样便于找到首个出现异常的tag版本,缩小代码变动范围。其次就是快速过有问题测试集,筛选出问题的图片。最后则是取一张异常测试图片,排查出未颠末回归测试代码的位置。时间gap的问题,当遇到的时间会给人比较大的生理压力,一方面年代久远另外一方面感觉无从查起。然而看似比较复杂,但其实终极找到的原因大概率是一个不经意的代码改动。通过这三板斧,大概率能找到原因,但可能更多的是必要一个强盛的心态以及必要投入一点精力和耐心。
比较好的一致性问题pipeline
一致性问题可以划分为四部分。一致性问题的克制、一致性问题的解决、一致性问题的验证和一致性问题的善后。
假如要想克制一致性问题,起首是“结对编程”,表现在代码的每次merge要有第三方的review;每个新的feat(只管)必要有配套的单元测试;代码版本的git-tags管理必不可少方便回溯;文档尤其是对外接口文档要严谨;代码交付要通过镜像交付。
一致性问题的解决,假如感觉陷入“毛线团”逆境,可能对问题进行拆解、降维:化难为多易、以易对难。再有就是看似很大的不一致性,每次仅必要抓住一个case,极有可能,大的不一致性只是由几个典范的case导致的(有点类似于解决编译器爆出来的程序错误,可能一下子爆出100个error,但真正的解决仅仅必要2~3轮,每次解决遇到的第一个error即可)。
一致性问题的验证,对于一致性问题一个必不可少的操作是在代码的合适位置添加“桩代码”,适时的保存中心效果。本来这一操作时排盘问题的手段,但履历是它大概率是一个验证手段。
一致性问题的善后。一致性问题解决后,记得善后。值得存档的以文档的形式存档,值得添加单元测试用例的以测试用例的方式添加,防止再犯。
rethink
找好合适的切入角度,本来一周乃至数周的问题,可能1~2天就能解决。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |