文章主题:算法分析, 显存需求, 通信带宽, FireDetector
以下文章来源于微信公众号:所向披靡的张大刀
作者:Q记
链接:https://mp.weixin.qq.com/s/eot_jnRQ4n1k-VkvIuJtYw
本文仅用于学术分享,如有侵权,请联系后台作删文处理
导读在算法开发完成后,需要将算法部署起来,其中有两种方式,一种为部署在嵌入式设备上,这里会考虑实时性以及硬件资源;另外一种是部署在服务器上,以服务的方式供下游的系统侧调用,这里一般会考虑并发量、吞吐量等问题。这里主要讲下在服务器上部署算法服务的过程,希望对大家有帮助。前言在一开始拿到算法需求需要以服务的方式部署在服务器上时,我们需要开始考虑哪些点呢,以及后面怎么设计操作呢,今天我们就来一一的说下。1
算法分析
在一开始拿到算法需求在服务器端部署时,需要考虑到以下几点;
1. 硬件资源的评估:主要是CPU和GPU的选择,CPU的核数会影响并行数,cpu的缓存、内存带宽以及容量等会影响数据的传输,这里大家可以基于需求来评估。而GPU要考虑后面的并发量等需要硬件资源支持的参数,如果并发量要求不大的情况下,只要选择一般的推理卡即可,如T4,3090等,这里大家需要了解的是,因为部署时只做推理,只要选择推理卡,不需要训练卡。(训练卡和推理卡的区别在于,训练的需求更高,一个是🌟当进行深度学习模型训练时,内存需求至关重要!首先,存储梯度等中间状态需要庞大的空间,就像攀登高峰需要稳固的立足之地。其次,频繁的数据加载与处理要求高速的带宽,如同在战场上快速传递信息以保持行动力。对于多卡协作的训练,数据交换更是考验通信速度,犹如军队间的无缝配合。相比之下,推理阶段的需求相对轻松,只需算法和显存相当,就像短跑选手只需跑道和起跑点即可。记得优化你的系统配置,让每一步都流畅无阻!💪
2. 算法代码框架的设计;算法代码框架的设计主要考虑到各个层的解耦,主要分成算法模型开发,算法功能开发以及算法服务的开发。
根据上图,一般在算法系统框架设计的时候,底层是各个算法模型的开发,开发完成后,向上输出各个模块的输出的结果,如果需要各个模块之间的逻辑处理,这里一般会出现在多个算法模块之间需要串联以及并联以完成算法功能的情况,一般建议所有的逻辑处理在功能层处理,这样功能和模型的开发互不干扰,只要接口固定就可以。再往上,基于功能输出算法功能模块的结果给服务端,服务端一般对接上下游,对输入服务的接口参数解析好后,并传输算法功能需要的参数,同时对算法功能的输出结果,打包成响应接口格式,完成响应的输出。3. 算法接口的设计;接口的设计,主要涉及到以下几个方面,一个是http的定义,一个是请求响应接口的定义,一个是算法服务内部的各个模块之间的接口,以及错误码的定义等。对http的定义,如定义http中的头部headers以及方法method等,一般算法系统中常用的头部信息是Content-Type:application/json,它指示请求或响应的主体内容是JSON格式的数据。method 是http请求中定义了要执行的操作类型的标识,如GET/POST/PUT/DELETE等,一般我们用的是POST,主要用于提交数据,向服务器发送数据并处理。对于第二个请求响应接口的定义,对于请求的参数接口,一般对于算法的系统开发而言,传入图片、文本或者视频段,如果有并发、多进程或者校验时,一般会加个id参数来定位,在响应参数时,会把这个id也输出,同时输出算法的输出结果。对于算法服务中各个模块之间的接口定义,主要是为了开发自测时相互不干扰。接口的定义尽量保证明了,以及一定的拓展性。错误码的定义主要是为了客户端在响应输出时,如果报错,能根据错误码和错误信息知道哪里出问题。2
算法实践
现在我们拿一个烟火识别应用的来实践上述步骤。
首先对于烟火识别需求分析,这里的烟火识别的需求并非要实时的检测出烟火并报警,而是为了取证用,看着火是从哪个位置和器件开始的,为后期的火灾排查定位提供便利。01 硬件选择
因为到时候会有多路摄像头介入,这里我们选择16c cpu, 同时内存为32G方便传输,因为取证用,一般只保存一个月的图片,这里的硬盘选择1T,显卡选择常用的3090.02 算法代码框架设计
算法代码框架的设计按照算法模型开发,算法功能开发以及算法服务的开发三个部分设计,如下图所示,假如我们的烟火识别算法方案用了图像检测和图像分类两个算法模型。上图为整个project的一个目录,最里层1为core目录,为各个算法模块的前向推理,这里由烟火检测和烟火识别两个算法模块的前向推理,2为集成模块,将1中各个算法模块的逻辑处理放在2中处理,后面的cfg,py为1中各个算法模块的参数配置,如模型路径,输入size等,这样就整个构成了算法的功能模块3。模块4服务的一些接口模块,arguments.py文件中,主要是对请求参数进行解析,并定义好响应接口参数,error_code.py文件中,为各个错误码和错误信息的定义,如输入的参数不符合要求,推理错误等等。服务主控砥柱`:service.py`,服务启动初始化乾坤,万事俱备,一触即发。首先对各模型逐一温床,接受如星辰般璀璨的请求参数,巧手解析其奥秘,然后将智识传递至各个推理模块,它们以迅雷不及掩耳之势进行运算。逻辑严谨的后处理环节紧随其后,将精炼的成果打包成接口,熠熠生辉地呈现在客户端面前。所有模型均藏身于`models`文件夹中,共同构建出这套算法的宏伟体系。🌟
上图是为了举例,在实际中烟火识别算法只要一个检测模块即可,这样我们的代码框架就简化成以下形式:03 算法接口设计
1. http的定义这里我们定义http中的头部headers头部信息是Content-Type:application/json, method 用的是POST,主要用于提交数据,向服务器发送数据并处理。2, 请求响应接口的定义请求的数据是需要给服务的参数,烟火识别里面是输入图片或者图片路径,这里如果输入图片的话,会输入图片的base64格式,防止网络在传输的过程中丢数据。如果是单路并发且不做定位req_id也可以不需要。
同理响应返回接口,一般返回状态码、状态信息以及对应的结果。对于结果的接口定义要有拓展性和明确性。
一个是算法服务内部的各个模块之间的接口,以及错误码的定义等。因烟火识别算法只涉及到一个算法模块,所以接口很简单。错误码的定义是在解析数据和推理过程中出现的一些错误定义。这样整体的前期工作完成,后面就是具体的开发工作了。如service.py:importbase64
importtime
importdataclasses
from flask importFlask, request
from flask importjsonify
from functions.core importFireDetector
import numpy asnp
importcv2
from functions importcfg
from webapi import*
from werkzeug.exceptions importHTTPException
app = Flask(__name__)
# 实例化模型对象detector = FireDetector(**cfg.det_cfg)
@app.route(/fire_detector, methods=[“POST”])def fire_detector(): # get data try:
# http的解析 if request.headers.get(Content-Type) is None:
raise AlgoError(AlgoErrorCodeEnum.ERROR_REQUEST_NOT_JSON, content-type error)
if request.headers.get(Content-Type).lower() != “application/json” and request.headers.get(Content-Type).lower() != “application/x-www-form-urlencoded”:
raise AlgoError(AlgoErrorCodeEnum.ERROR_REQUEST_NOT_JSON, content-type error)
# 获取输入数据 post_data = request.get_json(silent=True)
# 解析输入数据 request_arg = RequestArgument.from_post_data(post_data) # paraser input data to formatalgo_arg = AlgorithmArgument.from_request_arg(request_arg)
# 前向推理,输出结果algo_result = detector(algo_arg.data)
# 返回结果 except (ServiceError, AlgoError) ase:
response_arg = ResponseArgument(
req_id = “”,
err_no=e.code,
err_msg=e.message,
result=None)
returnjsonify(dataclasses.asdict(response_arg))
except HTTPException ase:
response_arg = ResponseArgument(
req_id = “”,
err_no=e.code,
err_msg=f{e.name}: {e.description},
result=None)
returnjsonify(dataclasses.asdict(response_arg))
except Exception ase:
response_arg = ResponseArgument(
req_id = “”,
err_no=AlgoErrorCodeEnum.ERROR_UNKNOWN.code,
err_msg=AlgoErrorCodeEnum.ERROR_UNKNOWN.message,
result=None)
returnjsonify(dataclasses.asdict(response_arg))
response_arg = ResponseArgument(
err_no=ServiceErrorCodeEnum.SUCCESS.code,
err_msg=ServiceErrorCodeEnum.SUCCESS.message,
req_id = algo_arg.request_id,
result=algo_result)
returnjsonify(dataclasses.asdict(response_arg))
if __name__ == __main__:
app.run(host=0.0.0.0,
port=2222,
debug=True)这一部分因涉及篇幅有限,我们下次再涉及,主要为各个模块开发、服务的多线程和多进程以及并发性测试等。结语以上为算法以服务的方式部署时,需要考虑涉及的点,希望对大家有帮助,欢迎一起沟通交流。推荐阅读
AIHIA | AI人才创新发展联盟2023年盟友招募
AI同学会 | AI同学会开启试运营,快来Pick你的AI同学
AI融资 | 智能物联网公司阿加犀获得高通5000W融资
Yolov5应用 | 家庭安防告警系统全流程及代码讲解
江大白 | 这些年从0转行AI行业的一些感悟
注意:大白梳理对接AI行业的一些中高端岗位,年薪在50W~120W之间,图像算法、搜索推荐等热门岗位,欢迎感兴趣的小伙伴联系大白,提供全流程交流跟踪,各岗位详情如下:《AI未来星球》陪伴你在AI行业成长的社群,各项福利重磅开放:
(1)198元《31节课入门人工智能》视频课程;
(2)大白花费近万元购买的各类数据集;
(3)每月自习活动,每月17日星球会员日,各类奖品送不停;
(4)加入《AI未来星球》内部微信群;
还有各类直播时分享的文件、研究报告,一起扫码加入吧!
人工智能行业,研究方向很多,大大小小有几十个方向。
为了便于大家学习交流,大白创建了一些不同方向的行业交流群。每个领域,都有各方向的行业实战高手,和大家一起沟通交流。目前主要开设:Opencv项目方面、目标检测方面、模型部署方面,后期根据不同领域高手的加入,建立新的方向群!大家可以根据自己的兴趣爱好,加入对应的微信群,一起交流学习!© THE END大家一起加油!
AI时代,掌握AI大模型第一手资讯!AI时代不落人后!
免费ChatGPT问答,办公、写作、生活好得力助手!
扫码右边公众号,驾驭AI生产力!