本文由刘裕忠和张文波两位作者联合创作。
在这个飞速发展的时代,我们有幸的见证了互联网的萌芽到爆发,移动互联网的兴起到鼎盛,目睹了诺基亚雅虎的兴衰,也见证了腾讯阿里走到全球市值十强;随着谷歌AlphaGo的横空出世,又让我们快速的切换到一个新的AI时代,而在这个AI时代,图像识别技术作为其基础能力之一,也在快速发展中,今天来聊聊图像识别的服务运行框架。
在聊框架之前,先简单说一下背景知识,图像识别作为人工智能领域中最基础的能力之一,是每个互联网巨头及AI公司的兵家必争之地,小到广告图片过滤大到国家安全宇宙探索都有着非常广阔的应用场景,例如在广告图片过滤、纸质文档电子化、聊天/网页图片鉴黄、银行证券自助开户、人脸门禁安防等业务中都有了比较普及的应用,在这些业务中图像识别技术扮演着非常重要的角色,用好了图像识别,一方面能大大提高工作效率,另一方面能提供更好的用户体验。例如在广告图片过滤的业务中,从人工处理到自动处理,在效率和准确率都有显著的提升。
不同的应用场景会有不同的识别类型,而不同的识别类型自然会有不同的算法,按我们现有的业务大概做了梳理,分为如下几类,当然这只是其中一部分,就不班门弄斧了,毕竟这个范围太广了。
文字识别技术
图像内容理解
其它分类…
在这些不同的算法中,又有不同的构成方式,如采用传统的文字识别,是单阶段处理的,即一个算法即可完成识别处理;而在采用深度学习算法后,识别的过程大部分拆分为两个阶段:文字检测,获取图像中文字的所在位置,文字识别,分析所在位置的文字内容,即多阶段算法;还有更多阶段的算法类型,如gif分为图像拆分、检测、识别、结果合并等阶段。
图像识别从算法研究、模型训练到规模化的提供服务,卷入的资源及处理的流程都是非常多的,但在开发阶段主要分为如下两个阶段:
我们都知道C++在运算密集型的程序中优势比较大,所以在算法的实现上大部分都采用了C++,而在服务框架的编写上,实现方式就比较多样化了,有用C++也有java的或者其它语言实现的, 这方面我们综合对比了java和c++的性能及稳定性,两者其实相差无几,而java因为其生态的强大,在编写效率上有很大的优势,能快速开发完成,且有更好的移植性,所以在服务框架的实现上,我们采用了java,通过jni调用SO来实现。简单调用流程如下:
JavaServer -> Jni框架SO -> 算法SO.
一个系统的成型并不是孤立存在的,如果要规模化的提供稳定服务,必须是完备的一个系统,这里简单描述一下我们的整体实现方案,系统架构上主要分为三层:接入层、系统层、算法层,再加上存储系统、告警监控系统、日志系统等构成一套完整的解决方案。
在打造一个框架之前,先来理一下图像识别服务的核心需求:
针对上述的要求,我们借鉴了业界及公司内的架构方案,打造了轻量级图像识别服务框架,架构图如下:
为了更好的说明这个框架,需要对运行态进行解剥,这里先分解一下这个框架的配置信息,主要分为静态和动态两种,静态配置由运维进行配置,动态信息由运行时决定。
master -> worker1 - > master -> worker2 -> master
一个好的算法运行框架,应该尽可能减少对算法的干扰,而自身又要也少受算法的影响,这样就能为算法研究和系统开发提供一种高效的合作方式,为此我们对算法和框架做了解耦,框架的部署不依赖于算法,算法的开发也不依赖于框架,只需要把算法在生成SO时做一层简单的适配即可。如下是框架与算法SO的关系:
框架部署好之后,worker会启动SO的扫描线程,只需把算法SO及模型文件放入到指定目录,框架就会进行加载完成SO的上线。
业务形态的各式各样,也决定了框架应该有更灵活的支撑模式,如不同的业务对同一识别类型有不同的侧重点,那么算法的版本也会有差别,框架对此做了一些调整,如下图所示,各个业务的银行卡算法是采用了不同的版本。
一个好的系统,应该是稳定可靠的,容灾是必须的,在这方面,我们借助了zookeeper这个典型的分布式一致性软件,实现了快速恢复的容错机制:
通过这几个角色的配合,在worker节点出现异常的情况下,master在迅速就完成了切换,保证了系统的稳定。这种机制也支持了集群的热更新,在需要对某个worker进行更新时,先对worker进行下线,master感知后不向此worker发请求,完成更新启动后,master再跟其重新建立连接并发送请求。
虽然说框架具备了高可靠,但是很多情况下还是无法避免算法内部的core dump,在这种情况下,恢复服务是第一的,这里我们做了进程的监听,如果发现进程core dump会立刻拉起;但在恢复服务之后,问题的复现及分析又是一个难点,在这里,我们做了一个全链路的跟踪,在框架的参数构造中增加了traceId这个参数,能从接入、系统、算法、存储跟踪到这个请求,快速拿到错误图片进行沙箱环境的复现及分析。
在上述过程中,基本上把系统的实现方式描述了一遍,可能很多人会有疑问,为什么说这个框架是轻量级的,归纳了几点,认为这个框架还算是比较轻量的。
此次采集java/c++混合语言编程来实现图像识别服务的提供,还是我们在框架上的第一次探索,虽然当前满足了稳定的服务提供,但是框架的提升还有很多路要走,这个会结合着业务的推广而不断提升。同时也为我们的框架设计提供了新的思路,利用好编程语言的优势在业务支撑上能事半功倍。
再者为了支持深度学习版本的算法,我们也开发了docker版本,方便于后续快速部署到gpu集群,同时提供了单机版及SDK版为一些业务的快速接入提供更多的可选方式。罗马并非一日建成,我们会持续优化架构,力争提供一个稳定高效的图像识别服务,为更多的业务提供优质的服务。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。