本文将介绍如何使用Flask搭建一个基于PyTorch的图片分类服务以及并行处理的相关技术。作为一个深度学习工程师,学习这些内容是为了方便对服务化的模型进行debug,因为web开发的同时常常表示他们很难定位到深度学习服务的bug的位置。

1. 环境


系统: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用于测试接口

2. 搭建异步服务

对于做算法的读者,不着急搭建深度学习模型,因为算法工程师普遍对web开发不太熟悉,可以先搭建一个最简单的web服务,并验证其功能无误之后再加入深度学习模型。

2.1 Flask搭建图片上传服务

因为图片分类服务需要从本地上传图片,可以先搭建一个用于图片上传的服务

# sim_server.py
from flask import Flask, request
from werkzeug.utils import secure_filename
import uuid
from PIL import Image
import os
import timeapp = Flask(__name__)@app.route("/run",methods = ["GET"])
def run():# 用于测试服务是否并行time.sleep(1)return "0"if __name__ == "__main__":app.run(host="0.0.0.0",port=5555,debug=True)

启动服务:

python sim_server.py

此时可以使用apache-utils测试接口是否是异步运行

ab -c 2 -n 10 http://localhost:5555/run

得到一长串结果,其中有一行是:

Requests per second: 1.00 [#/sec] (mean)

这行显示的是服务每秒钟能处理几个请求,如果是单进程单线程的话,每秒钟只能处理一个请求,服务的处理能力会随着进程数的增加而增加,但是由于计算机性能限制,增加进程数带来的处理能力提升会越来越小。

2.2 使用gunicorn启动多个进程

使用gunicorn可以快速启动多个进程:

gunicorn -w 4 -b 0.0.0.0:5555 sim_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

再次使用apache-utils进行测试,可以看到处理能力的提升:

ab -c 4 -n 10 http://localhost:5555/run

得到处理能力:Requests per second: 3.33 [#/sec] (mean)

可以看到,开启四个进程之后,服务的处理能力并没有达到4requests/second。

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

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

然后运行:

gunicorn -c gunicorn.conf sim_server:app

3. 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

启动之后就可以在新的地址上访问了:

ab -c 4 -n 10 http://localhost:5556/run

3. 将PyTorch分类模型接入服务

from flask import Flask, request
from werkzeug.utils import secure_filename
import uuid
from PIL import Image
import os
import time
import base64
import jsonimport torch
from torchvision.models import resnet18
from torchvision.transforms import ToTensorfrom keys import keyapp = Flask(__name__)
net = resnet18(pretrained=True)
net.eval()@app.route("/",methods=["GET"])
def show():return "classifier api"@app.route("/run",methods = ["GET","POST"])
def run():file = request.files['file']base_path = os.path.dirname(__file__)if not os.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(host="0.0.0.0",port=5555,debug=True)

4. 并发测试

使用apache2-utils进行上传图片的post请求方法参考:

https://gist.github.com/chiller/dec373004894e9c9bb38ac647c7ccfa8

严格参照,注意一个标点,一个符号都不要错。
使用这种方法传输图片的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

有了gunicorn和nginx就可以轻松地实现PyTorch模型的多机多卡部署了。

最后,对pytorch和模型部署感兴趣的话,来交个朋友吧,群号:747537854

pytorch argmax_PyTorch深度学习模型的服务化部署相关推荐

  1. 【项目实战课】从零掌握安卓端Pytorch原生深度学习模型部署

    欢迎大家来到我们的项目实战课,本期内容是<从零掌握安卓端Pytorch原生深度学习模型部署>.所谓项目课,就是以简单的原理回顾+详细的项目实战的模式,针对具体的某一个主题,进行代码级的实战 ...

  2. 训练好的深度学习模型是怎么部署的?

    训练好的深度学习模型是怎么部署的? 来源:https://www.zhihu.com/question/329372124 作者:田子宸 先说结论:部署的方式取决于需求 需求一:简单的demo演示,只 ...

  3. 训练好的深度学习模型原来这样部署的!(干货满满,收藏慢慢看)

    点击上方蓝字关注我们 计算机视觉研究院专栏 作者:Edison_G 当我们辛苦收集数据.数据清洗.搭建环境.训练模型.模型评估测试后,终于可以应用到具体场景,但是,突然发现不知道怎么调用自己的模型,更 ...

  4. 深度学习模型的Android部署方法

    使用背景: 将python中训练的深度学习模型(图像分类.目标检测.语义分割等)部署到Android中使用. Step1:下载并集成Pytorch Android库 1.下载Pytorch Andro ...

  5. C++环境下部署深度学习模型方案

    目录 一.问题背景 二.解决方案 2.1 C++调用python 2.2 Python服务接口 2.3 Python转c++(不推荐) 2.4 深度学习部署框架(推荐) 三.总结 3.1 接口形式分类 ...

  6. 深度学习模型部署技术方案

    深度学习模型部署技术方案 训练好的深度学习模型如何进行部署的相关技术方案 1 什么是模型部署? 2 数据科学项目整个开发流程 3 使用flask 将 Keras深度学习模型部署为Web应用程序 4 T ...

  7. 深度学习模型部署之模型优化

    文章目录 前言 模型剪枝 MNIST 常规训练 Setup 常规训练模型 模型评估 Pruning 模型定义 训练模型 评估模型 pruning your model API prune_low_ma ...

  8. PyTorch学习系列教程:构建一个深度学习模型需要哪几步?

    导读 继续PyTorch学习系列.前篇介绍了PyTorch中最为基础也最为核心的数据结构--Tensor,有了这些基本概念即可开始深度学习实践了.本篇围绕这一话题,本着提纲挈领删繁就简的原则,从宏观上 ...

  9. Transfer Learning Toolkit (TLT) + DeepStream (DS)快速部署深度学习模型(以口罩检测为例)

    文章目录 简介 TLT DS 基于TLT进行迁移学习 环境准备 模型训练 基于DS的模型部署 总结 最近在做一个深度学习的横向,被实时性搞的很头疼,遂打算研究研究新的技术路线,做点技术储备.TLT+D ...

最新文章

  1. 2019秋第三周学习总结
  2. cwntos新建目录挂载磁盘_centos6修改挂载磁盘目录的方法
  3. .git文件夹_将Git存储库中的文件夹转换为全新的存储库
  4. 下一个排列—leetcode31
  5. 404 Not Found: Requested route ('jerrylist.cfapps.eu10.hana.ondemand.com') does not exist
  6. kafka 消费端 api_在消费者的眼中:您真的需要为您的API提供客户端库吗?
  7. CICD详解(十一)——sonar详解
  8. 常用免费DEM数据汇总(含下载使用方法)
  9. pon移动家庭网关有虚拟服务器吗,电信、移动、联通家庭网关对比分析
  10. 快速了解安卓四大组件
  11. 【彩票】彩票预测算法(一):离散型马尔可夫链模型C#实现
  12. 区块链三加一告诉你如何快速了解区块链入门技术?
  13. 网络抖动多少ms算正常_如何测试网络稳定
  14. 将image对象转成BufferedImage
  15. Codeforces Round #822 (Div. 2) C Removing Smallest Multiples(复杂度为调和级数级别的暴力)
  16. 软件测试:三角形问题
  17. 论对B/S模式外贸电子商务系统的规划和设计
  18. WPF基础之XAML----(XAML 根元素和 xmlns,事件和 XAML 代码隐藏)
  19. C++函数声明和函数定义
  20. 图像语义分割——利用DeeplabV3+预测单张照片

热门文章

  1. Python爬虫项目--爱拍视频批量下载
  2. memcpy 作用(C++)
  3. 字符串去空格符(c++)
  4. Maven 动态Web的创建 及 Tomcat的启动
  5. printf 格式字符串的 正则化表达式
  6. DPDK 20.05 | rte_pci_bus思维导图 | 第一版
  7. 如何用指针判定系统是32bit还是64bit?一次惨痛的经历,想想都脸红
  8. 用c语言运行Linux命令,使用execv(C语言)从linux命令提示符运行命令
  9. pl sql入门比较好的书_面试官问你SQL?这几本书足够了
  10. ora-oracle,oracle:ora-01507错误