flask部署深度学习模型
flask部署深度学习模型
作为著名Python web框架之一的Flask,具有简单轻量、灵活、扩展丰富且上手难度低的特点,因此成为了机器学习和深度学习模型上线跑定时任务,提供API的首选框架。
众所周知,Flask默认不支持
非阻塞IO的,当请求A还未完成时候,请求B需要等待请求A完成后才能被处理,所以效率非常低。但是线上任务通常需要异步、高并发等需求,本文总结一些在日常使用过程中所常用的技巧。
一、前沿
异步和多线程有什么区别?其实,异步是目的,而多线程是实现这个目的的方法。异步是说,A发起一个操作后(一般都是比较耗时的操作,如果不耗时的操作就没有必要异步了),可以继续自顾自的处理它自己的事儿,不用干等着这个耗时操作返回。
实现异步可以采用多线程技术或则交给另外的进程来处理,详解常见这里。
二、实现方法
- Flask启动自带方法
采用gunicorn部署
1、Flask中自带方法实现
run.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2018-12-01 16:37
# @Author : mokundong
from flask import Flask
import socket
from time import sleep
myhost = socket.gethostbyname(socket.gethostname())
app = Flask(__name__)
@app.route('/job1')
def some_long_task1():
print("Task #1 started!")
sleep(10)
print("Task #1 is done!")
@app.route('/job2')
def some_long_task2(arg1, arg2):
print("Task #2 started with args: %s %s!" % (arg1, arg2))
sleep(5)
print("Task #2 is done!")
if __name__ == '__main__':
app.run(host=myhost,port=5000,threaded=True)
app.run(host=xxx,port=xx,threaded=True)
中threaded开启后则不需要等队列。
2、gunicorn部署
Gunicorn 是一个高效的Python WSGI Server,通常用它来运行 wsgi application 或者 wsgi framework(如Django,Paster,Flask),地位相当于Java中的Tomcat。gunicorn 会启动一组 worker进程,所有worker进程公用一组listener,在每个worker中为每个listener建立一个wsgi server。每当有HTTP链接到来时,wsgi server创建一个协程来处理该链接,协程处理该链接的时候,先初始化WSGI环境,然后调用用户提供的app对象去处理HTTP请求。
关于gunicorn的详细说明,可以参考这里。使用命令行启动gunicorn有两种方式获取配置项,一种是在命令行配置,一种是在配置文件中获取。
run.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2018-12-01 17:00
# @Author : mokundong
from flask import Flask
from time import sleep
app = Flask(__name__)
@app.route('/job1')
def some_long_task1():
print("Task #1 started!")
sleep(10)
print("Task #1 is done!")
@app.route('/job2')
def some_long_task2(arg1, arg2):
print("Task #2 started with args: %s %s!" % (arg1, arg2))
sleep(5)
print("Task #2 is done!")
if __name__ == '__main__':
app.run()
命令行配置
gunicorn --workers=4 --bind=127.0.0.1:8000 run:app
更多配置见官网
配置文件获取配置
gunicorn_config.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2018-12-01 17:10
# @Author : mokundong
import os
import socket
import multiprocessing
import gevent.monkey
gevent.monkey.patch_all()
myhost = socket.gethostbyname(socket.gethostname())
debug = False
loglevel = 'info'
hosts = get_host_ip()
bind = hosts+":5000"
timeout = 30 #超时
pidfile = "log/gunicorn.pid"
accesslog = "log/access.log"
errorlog = "log/debug.log"
daemon = True #意味着开启后台运行,默认为False
workers = 4 # 启动的进程数
threads = 2 #指定每个进程开启的线程数
worker_class = 'gevent' #默认为sync模式,也可使用gevent模式。
x_forwarded_for_header = 'X-FORWARDED-FOR'
启动命令如下
gunicorn -c gunicorn_config.py run:app
三、补充
1、关于线程的补充
在工作中我还遇到一种情况,当一个请求过来后,我需要两种回应,一个是及时返回app运行结果,第二个响应是保存数据到日志或者数据库。往往我们在写数据的过程中会花销一定的时间,导致结果返回会有所延迟,因此我们需要用两个线程处理这两个任务,那么我们如下处理。
run.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2018-12-01 17:20
# @Author : mokundong
from flask import Flask,request
from time import sleep
from concurrent.futures import ThreadPoolExecutor
executor = ThreadPoolExecutor(2)
app = Flask(__name__)
@app.route('/job')
def run_jobs():
executor.submit(some_long_task1)
executor.submit(some_long_task2, 'hello', 123)
return 'Two jobs was launched in background!'
def some_long_task1():
print("Task #1 started!")
sleep(10)
print("Task #1 is done!")
def some_long_task2(arg1, arg2):
print("Task #2 started with args: %s %s!" % (arg1, arg2))
sleep(5)
print("Task #2 is done!")
if __name__ == '__main__':
app.run()
2、关于获取IP的补充
上述代码中通过获取
hostname,然后再通过hostname反查处机器的IP。这个方法是不推荐的。因为很多的机器没有规范这个hostname的设置。
另外就是有些服务器会在/etc/hosts中添加本机的hostname的地址,这个做法也不是不可以,但是如果设置成了127.0.0.1,那么获取出来的IP就都是这个地址了。
这里给出一种优雅的方式获取IP,利用 UDP 协议来实现的,生成一个UDP包,把自己的 IP 放如到 UDP 协议头中,然后从UDP包中获取本机的IP。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2018-12-01 17:30
# @Author : mokundong
# 可以封装成函数,方便 Python 的程序调用
import socket
def get_host_ip():
try:
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(('8.8.8.8', 80))
ip = s.getsockname()[0]
finally:
s.close()
return ip
总结
当然推荐使用gunicorn部署多线程,Flask自带的,emmmm,测试玩儿玩儿吧。
在写作过程中才发现自己知识漏洞不是一般多,共勉!
flask部署深度学习模型的更多相关文章
- PyTorch如何构建深度学习模型?
简介 每过一段时间,就会有一个深度学习库被开发,这些深度学习库往往可以改变深度学习领域的景观.Pytorch就是这样一个库. 在过去的一段时间里,我研究了Pytorch,我惊叹于它的操作简易.Pyto ...
- Apple的Core ML3简介——为iPhone构建深度学习模型(附代码)
概述 Apple的Core ML 3是一个为开发人员和程序员设计的工具,帮助程序员进入人工智能生态 你可以使用Core ML 3为iPhone构建机器学习和深度学习模型 在本文中,我们将为iPhone ...
- 用 Java 训练深度学习模型,原来可以这么简单!
本文适合有 Java 基础的人群 作者:DJL-Keerthan&Lanking HelloGitHub 推出的<讲解开源项目> 系列.这一期是由亚马逊工程师:Keerthan V ...
- CUDA上深度学习模型量化的自动化优化
CUDA上深度学习模型量化的自动化优化 深度学习已成功应用于各种任务.在诸如自动驾驶汽车推理之类的实时场景中,模型的推理速度至关重要.网络量化是加速深度学习模型的有效方法.在量化模型中,数据和模型参数 ...
- 用TVM在硬件平台上部署深度学习工作负载的端到端 IR 堆栈
用TVM在硬件平台上部署深度学习工作负载的端到端 IR 堆栈 深度学习已变得无处不在,不可或缺.这场革命的一部分是由可扩展的深度学习系统推动的,如滕索弗洛.MXNet.咖啡和皮托奇.大多数现有系统针对 ...
- CUDA上的量化深度学习模型的自动化优化
CUDA上的量化深度学习模型的自动化优化 深度学习已成功应用于各种任务.在诸如自动驾驶汽车推理之类的实时场景中,模型的推理速度至关重要.网络量化是加速深度学习模型的有效方法.在量化模型中,数据和模型参 ...
- TVM将深度学习模型编译为WebGL
使用TVM将深度学习模型编译为WebGL TVM带有全新的OpenGL / WebGL后端! OpenGL / WebGL后端 TVM已经瞄准了涵盖各种平台的大量后端:CPU,GPU,移动设备等.这次 ...
- AI佳作解读系列(一)——深度学习模型训练痛点及解决方法
1 模型训练基本步骤 进入了AI领域,学习了手写字识别等几个demo后,就会发现深度学习模型训练是十分关键和有挑战性的.选定了网络结构后,深度学习训练过程基本大同小异,一般分为如下几个步骤 定义算法公 ...
- 『高性能模型』Roofline Model与深度学习模型的性能分析
转载自知乎:Roofline Model与深度学习模型的性能分析 在真实世界中,任何模型(例如 VGG / MobileNet 等)都必须依赖于具体的计算平台(例如CPU / GPU / ASIC 等 ...
随机推荐
- tomcat access日志
每次看access log都会记不住pattern里的各个标识代表的什么意思,记录下,备忘! tomcat的access log是由实现了org.apache.catalina.AccessLog接口 ...
- POJ 2763"Housewife Wind"(DFS序+树状数组+LCA)
传送门 •题意 一对夫妇居住在 xx村庄,给村庄有 $n$ 个小屋: 这 $n$ 个小屋之间有双向可达的道路,不会出现环,即所构成的图是个树: 从 $a_i$ 小屋到 $b_i$ 小屋需要花费 $w_ ...
- P1096 4个数的全排列
题目描述 输入4个有序的个位数.按照字典序输出它们的全排列. 输入格式 输入四个数字a,b,c,d.(0<=a,b,c,d<10) 输出格式 输出它们的全排列.每个排列占一行.而且每个排列 ...
- Laravel5 call to undefined function openssl cipher iv length() 报错 PHP7开启OpenSSL扩展失败
在安装laravel5.5后, 访问显示报错. call to undefined function openssl cipher iv length() 经查为php7.1的OpenSSL扩展加载失 ...
- 2019-8-31-AutoHotKey-用打码的快捷键
title author date CreateTime categories AutoHotKey 用打码的快捷键 lindexi 2019-08-31 16:55:58 +0800 2019-06 ...
- H3C使用tracert命令--用户视图
<H3C>tracert ? -a 指明 ...
- Apache工具集
commons-collections-3.2.jar 转自:http://www.open-open.com/lib/view/open1384437456993.html
- 11大Java开源中文分词器的使用方法和分词效果对比,当前几个主要的Lucene中文分词器的比较
本文的目标有两个: 1.学会使用11大Java开源中文分词器 2.对比分析11大Java开源中文分词器的分词效果 本文给出了11大Java开源中文分词的使用方法以及分词结果对比代码,至于效果哪个好,那 ...
- navicat for mysql连接本地数据库
navicat for mysql连接本地数据库 打算使用navicat连接本地数据库,连接的时候,一直连接不上.然后猜想是不是本地数据库没有设置好.输入mysql,出错内容:access denie ...
- vue依赖
ajax:vue-resource moke数据:body-parser