0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

深度学习应用的服务端部署—PyTorch模型部署

电子设计 来源:电子设计 作者:电子设计 2020-12-08 22:29 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

文章转载于微信公众号:GiantPandaCV
作者: 阿呆

【GiantPandaCV导读】这篇文章包含与PyTorch模型部署相关的两部分内容:

  • PyTorch-YOLOv3模型的Web页面展示程序的编写
  • 模型的服务接口相关工具的使用

0. 环境依赖:

系统:Ubuntu 18.04
Python版本:3.7
依赖Python包:1. PyTorch==1.3 2. Flask==0.12 3. Gunicorn

需要注意的是Flask 0.12中默认的单进程单线程,而最新的1.0.2则不是(具体是多线程还是多进程尚待考证),而中文博客里面能查到的资料基本都在说Flask默认单进程单线程。

依赖工具 1. nginx 2. apache2-utils

nginx 用于代理转发和负载均衡,apache2-utils用于测试接口

1. 制作模型演示界面

图像识别任务的展示这项工程一般是面向客户的,这种场景下不可能把客户拉到你的电脑前面,敲一行命令,等matplotlib弹个结果窗口出来。总归还是要有个图形化界面才显得有点诚意。
为了节约时间,我们选择了Flask框架来开发这个界面。

上传页面和展示页面

做识别演示需要用到两个html页面,代码也比较简单,编写如下:

上传界面







使用Flask上传本地图片

展示界面






使用Flask上传本地图片

{{ url_for('static', filename= path,_t=val1) }}

上传界面如下图所示,觉得丑的话可以找前端同事美化一下:

flask上传图片及展示功能

然后就可以编写flask代码了,为了更好地展示图片,可以向html页面传入图片地址参数。

fromflaskimportFlask,render_template,request,redirect,url_for,make_response,jsonifyfromwerkzeug.utilsimportsecure_filenameimportosimportcv2importtimefromdatetimeimporttimedeltafrommainimportrun,confALLOWED_EXTENSIONS=set(["png","jpg","JPG","PNG","bmp"])defis_allowed_file(filename):return'.'infilenameandfilename.rsplit('.',1)[1]inALLOWED_EXTENSIONSapp=Flask(__name__)#静态文件缓存过期时间app.send_file_max_age_default=timedelta(seconds=1)@app.route("/upload",methods=['POST','GET'])defupload():ifrequest.method=="POST":f=request.files['file']ifnot(fandis_allowed_file(f.filename)):returnjsonify({"error":1001,"msg":"请检查上传的图片类型,仅限于png、PNG、jpg、JPG、bmp"})user_input=request.form.get("name")basepath=os.path.dirname(__file__)upload_path=os.path.join(basepath,"static/images",secure_filename(f.filename))f.save(upload_path)detected_path=os.path.join(basepath,"static/images","output"+secure_filename(f.filename))run(upload_path,conf,detected_path)#returnrender_template("upload_ok.html",userinput=user_input,val1=time.time(),path=detected_path)path="/images/"+"output"+secure_filename(f.filename)returnrender_template("upload_ok.html",path=path,val1=time.time())returnrender_template("upload.html")if__name__=="__main__":app.run(host='0.0.0.0',port=8888,debug=True)

目标检测函数

原项目中提供了detection.py来做批量的图片检测,需要稍微修改一下才能用来做flask代码中的接口。

from__future__importdivisionfrommodelsimport*fromutils.utilsimport*fromutils.datasetsimport*importosimportsysimporttimeimportdatetimeimportargparsefromPILimportImageimporttorchfromtorchvisionimportdatasetsfromtorch.autogradimportVariableimportmatplotlib.pyplotaspltimportmatplotlib.patchesaspatchesfrommatplotlib.tickerimportNullLocatorclasscustom_dict(dict):def__init__(self,d=None):ifdisnotNone:fork,vind.items():self[k]=vreturnsuper().__init__()def__key(self,key):return""ifkeyisNoneelsekey.lower()def__str__(self):importjsonreturnjson.dumps(self)def__setattr__(self,key,value):self[self.__key(key)]=valuedef__getattr__(self,key):returnself.get(self.__key(key))def__getitem__(self,key):returnsuper().get(self.__key(key))def__setitem__(self,key,value):returnsuper().__setitem__(self.__key(key),value)conf=custom_dict({"model_def":"config/yolov3.cfg","weights_path":"weights/yolov3.weights","class_path":"data/coco.names","conf_thres":0.8,"nms_thres":0.4,"img_size":416})defrun(img_path,conf,target_path):device=torch.device("cuda"iftorch.cuda.is_available()else"cpu")os.makedirs("output",exist_ok=True)classes=load_classes(conf.class_path)model=Darknet(conf.model_def,img_size=conf.img_size).to(device)ifconf.weights_path.endswith(".weights"):#Loaddarknetweightsmodel.load_darknet_weights(conf.weights_path)else:#Loadcheckpointweightsmodel.load_state_dict(torch.load(conf.weights_path))model.eval()img=Image.open(img_path).convert("RGB")img=img.resize(((img.size[0]//32)*32,(img.size[1]//32)*32))img_array=np.array(img)img_tensor=pad_to_square(transforms.ToTensor()(img),0)[0].unsqueeze(0)conf.img_size=img_tensor.shape[2]withtorch.no_grad():detections=model(img_tensor)detections=non_max_suppression(detections,conf.conf_thres,conf.nms_thres)[0]cmap=plt.get_cmap("tab20b")colors=[cmap(i)foriinnp.linspace(0,1,20)]plt.figure()fig,ax=plt.subplots(1)ax.imshow(img_array)ifdetectionsisnotNone:#Rescaleboxestooriginalimagedetections=rescale_boxes(detections,conf.img_size,img_array.shape[:2])unique_labels=detections[:,-1].cpu().unique()n_cls_preds=len(unique_labels)bbox_colors=random.sample(colors,n_cls_preds)forx1,y1,x2,y2,conf,cls_conf,cls_predindetections:print("/t+Label:%s,Conf:%.5f"%(classes[int(cls_pred)],cls_conf.item()))box_w=x2-x1box_h=y2-y1color=bbox_colors[int(np.where(unique_labels==int(cls_pred))[0])]#CreateaRectanglepatchbbox=patches.Rectangle((x1,y1),box_w,box_h,linewidth=2,edgecolor=color,facecolo)#Addthebboxtotheplotax.add_patch(bbox)#Addlabelplt.text(x1,y1,s=classes[int(cls_pred)],colo,verticalalignmen,bbox={"color":color,"pad":0},)#Savegeneratedimagewithdetectionsplt.axis("off")plt.gca().xaxis.set_major_locator(NullLocator())plt.gca().yaxis.set_major_locator(NullLocator())filename=img_path.split("/")[-1].split(".")[0]plt.savefig(target_path,bbox_inches='tight',pad_inches=0.0)plt.close()if__name__=="__main__":run("data/samples/dog.jpg",conf)

展示效果

编写好了之后,启动server.py,在本地打开localhost:8888/upload就可以看到如下界面了,把图片上传上去,很快就能得到检测结果。
结果如下图所示:

2. 深度学习的服务接口编写

接下来介绍的是在生产环境下的部署,使用的是flask+gunicorn+nginx的方式,可以处理较大规模的请求。
下面以图像分类模型为例演示一下深度学习服务接口如何编写。

对于深度学习工程师来说,学习这些内容主要是了解一下自己的模型在生产环境的运行方式,便于在服务出现问题的时候与开发的同事一起进行调试。

flask服务接口

接口不需要有界面显示,当然也可以添加一个API介绍界面,方便调用者查看服务是否已经启动。

fromflaskimportFlask,requestfromwerkzeug.utilsimportsecure_filenameimportuuidfromPILimportImageimportosimporttimeimportbase64importjsonimporttorchfromtorchvision.modelsimportresnet18fromtorchvision.transformsimportToTensorfromkeysimportkeyapp=Flask(__name__)net=resnet18(pretrained=True)net.eval()@app.route("/",methods=["GET"])defshow():return"classifierapi"@app.route("/run",methods=["GET","POST"])defrun():file=request.files['file']base_path=os.path.dirname(__file__)ifnotos.path.exists(os.path.join(base_path,"temp")):os.makedirs(os.path.join(base_path,"temp"))file_name=uuid.uuid4().hexupload_path=os.path.join(base_path,"temp",file_name)file.save(upload_path)img=Image.open(upload_path)img_tensor=ToTensor()(img).unsqueeze(0)out=net(img_tensor)pred=torch.argmax(out,dim=1)return"result:{}".format(key[pred])if__name__=="__main__":app.run(hos,port=5555,debug=True)

在命令行输入python server.py即可启动服务。

gunicorn启动多个实例

新版的flask已经支持多进程了,不过用在生产环境还是不太稳定,一般生产环境会使用gunicorn来启动多个服务。
使用如下命令即可启动多个图像分类实例

gunicorn -w 4 -b 0.0.0.0:5555 server:app

输出如下内容代表服务创建成功:

[2020-02-11 14:50:24 +0800] [892] [INFO] Starting gunicorn 20.0.4[2020-02-11 14:50:24 +0800] [892] [INFO] Listening at: http://0.0.0.0:5555 (892)[2020-02-11 14:50:24 +0800] [892] [INFO] Using worker: sync[2020-02-11 14:50:24 +0800] [895] [INFO] Booting worker with pid: 895[2020-02-11 14:50:24 +0800] [896] [INFO] Booting worker with pid: 896[2020-02-11 14:50:24 +0800] [898] [INFO] Booting worker with pid: 898[2020-02-11 14:50:24 +0800] [899] [INFO] Booting worker with pid: 899

如果配置比较复杂,也可以将配置写入一个文件中,如:

bind='0.0.0.0:5555'timeout=10workers=4

然后运行:

gunicorn -c gunicorn.conf sim_server:app

nginx负载均衡

如果有多个服务器,可以使用nginx做请求分发与负载均衡。
安装好nginx之后,修改nginx的配置文件

worker_processes auto;error_log /var/log/nginx/error.log;pid /run/nginx.pid;# Load dynamic modules. See /usr/share/nginx/README.dynamic.include /usr/share/nginx/modules/*.conf;events {    worker_connections 1024;}http {    server    {        listen 5556; # nginx端口        server_name localhost;        location / {            proxy_pass http://localhost:5555/run; # gunicorn的url        }    }}

然后按配置文件启动

sudo nginx -c nginx.conf

测试一下服务是否正常

启动了这么多服务之后,可以使用apache2-utils来测试服务的并发性能。
使用apache2-utils进行上传图片的post请求方法参考:
https://gist.github.com/chill...

严格参照,注意一个标点,一个符号都不要错。使用这种方法传输图片的base64编码,在服务端不需要解码也能使用

然后使用下面的方式访问
gunicorn 接口

ab -n 2 -c 2 -T "multipart/form-data; boundary=1234567890" -p turtle.txt http://localhost:5555/run

nginx 接口

ab -n 2 -c 2 -T "multipart/form-data; boundary=1234567890" -p turtle.txt http://localhost:5556/run

- END -

推荐阅读

更多嵌入式AI技术干货请关注嵌入式AI专栏。

审核编辑:符乾江
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 深度学习
    +关注

    关注

    73

    文章

    5590

    浏览量

    123896
  • pytorch
    +关注

    关注

    2

    文章

    813

    浏览量

    14692
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    DeepSeek模型如何在云服务器上部署

    随着大型语言模型(LLM)的应用日益普及,许多开发者和企业希望将像DeepSeek这样的优秀模型部署到自己的云服务器上,以实现私有化、定制化服务
    的头像 发表于 10-13 16:52 557次阅读

    vision board部署模型到openmv的代码导致连接超时怎么解决?

    在env终端中勾选了tiflte support后烧录mdk到板子上后就开始显示连接不到 无法部署模型
    发表于 09-19 07:59

    Arm方案 基于Arm架构的边缘侧设备(树莓派或 NVIDIA Jetson Nano)上部署PyTorch模型

    本文将为你展示如何在树莓派或 NVIDIA Jetson Nano 等基于 Arm 架构的边缘侧设备上部署 PyTorch 模型
    的头像 发表于 07-28 11:50 2489次阅读

    企业部署AI大模型怎么做

    当下,AI大模型已成为驱动决策自动化、服务智能化与产品创新的核心引擎。然而,企业面对动辄数百亿参数的大模型部署时,常陷入算力不足、响应延迟高、成本失控等困境。如何突破瓶颈,实现高效、稳
    的头像 发表于 06-04 09:26 671次阅读

    如何使用Docker部署模型

    随着深度学习和大模型的快速发展,如何高效地部署这些模型成为了一个重要的挑战。Docker 作为一种轻量级的容器化技术,能够将
    的头像 发表于 05-24 16:39 795次阅读

    如何在RAKsmart服务器上实现企业AI模型部署

    AI模型的训练与部署需要强大的算力支持、稳定的网络环境和专业的技术管理。RAKsmart作为全球领先的服务器托管与云计算服务提供商,已成为企业部署
    的头像 发表于 03-27 09:46 758次阅读

    【幸狐Omni3576边缘计算套件试用体验】DeepSeek 部署及测试

    、RKLLM 库、编译和运行、效果演示等。 简介 介绍了板部署的 DeepSeek 模型及其部署方案。 DeepSeek DeepSeek 是由杭州
    发表于 03-21 19:31

    K230D部署模型失败的原因?

    MicroPython部署的无法正常运行,采用C++版本的无法实现部署 尝试解决过程 1.考虑到可能是固件不匹配的问题,重新烧录了流程(生成模型后给的readme)中要求的固件,依旧无法成功
    发表于 03-11 06:19

    添越智创基于 RK3588 开发板部署测试 DeepSeek 模型全攻略

    方法的优缺点与操作要点。 01-使用Ollama工具部署-便捷但有短板 Ollama 是一个开源的大模型服务工具,可以支持最新的deepseek模型,以及Llama 3,Phi 3,M
    发表于 02-14 17:42

    摩尔线程宣布成功部署DeepSeek蒸馏模型推理服务

    近日,摩尔线程智能科技(北京)有限责任公司在其官方渠道发布了一则重要消息,宣布公司已经成功实现了对DeepSeek蒸馏模型推理服务部署。这一技术突破,标志着摩尔线程在人工智能领域迈出了坚实的一步
    的头像 发表于 02-06 13:49 1183次阅读

    【ELF 2学习板试用】ELF2开发板(飞凌嵌入式)搭建深度学习环境部署(RKNN环境部署

    模型进行量化部署转换为rknn模型,并编译好基本脚本上传至开发板。 模型工具的介绍 RKNN-Toolkit2    RKNN-Toolkit2 是由瑞芯微电子开发的一套
    发表于 02-04 14:15

    Flexus X 实例 ultralytics 模型 yolov10 深度学习 AI 部署与应用

    模型迭代,让 AI 智能触手可及。把握此刻,让创新不再受限! ���本实验演示从 0 到 1 部署 YOLOv10 深度学习 AI 大模型
    的头像 发表于 12-24 12:24 1293次阅读
    Flexus X 实例 ultralytics <b class='flag-5'>模型</b> yolov10 <b class='flag-5'>深度</b><b class='flag-5'>学习</b> AI <b class='flag-5'>部署</b>与应用

    企业AI模型部署攻略

    当下,越来越多的企业开始探索和实施AI模型,以提升业务效率和竞争力。然而,AI模型部署并非易事,需要企业在多个层面进行细致的规划和准备。下面,AI部落小编为企业提供一份AI模型
    的头像 发表于 12-23 10:31 1291次阅读

    AI模型部署边缘设备的奇妙之旅:目标检测模型

    以及边缘计算能力的增强,越来越多的目标检测应用开始直接在靠近数据源的边缘设备上运行。这不仅减少了数据传输延迟,保护了用户隐私,同时也减轻了云端服务器的压力。然而,在边缘部署高效且准确的目标检测
    发表于 12-19 14:33

    AI模型部署边缘设备的奇妙之旅:如何实现手写数字识别

    新的数据样本,另一个是判别器用来判断这些样本的真实性。两者相互竞争,共同进化,最终实现高质量的数据合成。 2.4 模型优化技术 在将深度学习模型部署
    发表于 12-06 17:20