output怎么用_性能领先,即训即用,快速部署,飞桨首次揭秘服务器端推理库

允中 发自 凹非寺
量子位 编辑 | 公众号 QbitAI

假如问在深度学习实践中,最难的部分是什么?猜测80%的开发者都会说:

“当然是调参啊。”

为什么难呢?因为调参就像厨师根据食材找到了料理配方,药剂师根据药材找到了药方,充满了玄幻色彩。

但是,掌握了调参,顶多算深度学习的绝学掌握了一半。而另一半就是“模型部署”。

模型部署有什么难的?举个例子:前面这位大厨在培训学校,经过各种训练掌握了很多料理配方,终于要到酒店上任了,却发现酒店的厨房环境和训练时不一样,就餐高峰时手忙脚乱,客户等了1个小时还没上菜,结果第一天上岗就被投诉了。

虽然比喻略有夸张,却也道出了深度学习模型训练和推理部署的关系。

我们知道,深度学习一般分为训练和推理两个部分,训练是神经网络“学习”的过程,主要关注如何搜索和求解模型参数,发现训练数据中的规律。

有了训练好的模型之后,就要在线上环境中应用模型,实现对未知数据做出预测,这个过程在AI领域叫做推理

在实际应用中,推理阶段可能会面临和训练时完全不一样的硬件环境,当然也对应着不一样的计算性能要求。我们训练得到的模型,需要能在具体生产环境中正确、高效地实现推理功能,完成上线部署。

所以,当我们千辛万苦训练好模型,终于要上线了,但这个时候可能会遇到各种问题,比如:

  • 线上部署的硬件环境和训练时不同

  • 推理计算耗时太高, 可能造成服务不可用

  • 模型上的内存占用过高无法上线

对工业级部署而言,要求的条件往往非常繁多而且苛刻,不是每个深度学习框架都对实际生产部署上能有良好的支持。一款对推理支持完善的的框架,会让你的模型上线工作事半功倍。

飞桨作为源于产业实践的深度学习框架,在推理部署能力上有特别深厚的积累和打磨,提供了性能强劲、上手简单的服务器端推理库Paddle Inference,帮助用户摆脱各种上线部署的烦恼。

e58f6f28b36c915799f0ac9820549701.png

Paddle Inference是什么

飞桨框架的推理部署能力经过多个版本的升级迭代,形成了完善的推理库Paddle Inference。Paddle Inference功能特性丰富,性能优异,针对不同平台不同的应用场景进行了深度的适配优化,做到高吞吐、低时延,保证了飞桨模型在服务器端即训即用,快速部署。

Paddle Inference的高性能实现

内存/显存复用提升服务吞吐量

在推理初始化阶段,对模型中的OP输出Tensor 进行依赖分析,将两两互不依赖的Tensor在内存/显存空间上进行复用,进而增大计算并行量,提升服务吞吐量。

细粒度OP横向纵向融合减少计算量

在推理初始化阶段,按照已有的融合模式将模型中的多个OP融合成一个OP,减少了模型的计算量的同时,也减少了 Kernel Launch的次数,从而能提升推理性能。目前Paddle Inference支持的融合模式多达几十个。

内置高性能的CPU/GPU Kernel

内置同Intel、Nvidia共同打造的高性能kernel,保证了模型推理高性能的执行。

子图集成TensorRT加快GPU推理速度

Paddle Inference采用子图的形式集成TensorRT,针对GPU推理场景,TensorRT可对一些子图进行优化,包括OP的横向和纵向融合,过滤冗余的OP,并为OP自动选择最优的kernel,加快推理速度。

子图集成Paddle Lite轻量化推理引擎

Paddle Lite 是飞桨深度学习框架的一款轻量级、低框架开销的推理引擎,除了在移动端应用外,还可以使用服务器进行 Paddle Lite 推理。Paddle Inference采用子图的形式集成 Paddle Lite,以方便用户在服务器推理原有方式上稍加改动,即可开启 Paddle Lite 的推理能力,得到更快的推理速度。并且,使用 Paddle Lite 可支持在百度昆仑等高性能AI芯片上执行推理计算。

支持加载PaddleSlim量化压缩后的模型

PaddleSlim是飞桨深度学习模型压缩工具,Paddle Inference可联动PaddleSlim,支持加载量化、裁剪和蒸馏后的模型并部署,由此减小模型存储空间、减少计算占用内存、加快模型推理速度。其中在模型量化方面,Paddle Inference在X86 CPU上做了深度优化,常见分类模型的单线程性能可提升近3倍,ERNIE模型的单线程性能可提升2.68倍。

【性能测一测】通过比较resnet50和bert模型的训练前向耗时和推理耗时,可以观测到Paddle Inference有显著的加速效果。

a2577109caba59fb85b98f404585de02.png

说明:测试耗时的方法,使用相同的输入数据先空跑1000次,循环运行1000次,每次记录模型运行的耗时,最后计算出模型运行的平均耗时。

Paddle Inference的通用性

主流软硬件环境兼容适配

支持服务器端X86 CPU、NVIDIA GPU芯片,兼容Linux/Mac/Windows系统。支持所有飞桨训练产出的模型,完全做到即训即用。

多语言环境丰富接口可灵活调用

支持C++, Python, C, Go和R语言API, 接口简单灵活,20行代码即可完成部署。对于其他语言,提供了ABI稳定的C API, 用户可以很方便地扩展。

Paddle Inference怎么用

下面我们一起来看看如何使用飞桨完成服务器端推理部署。

“一个函数”搞定模型保存

飞桨框架提供了一个内置函数 save_inference_model, 将模型保存为推理用的模型格式。save_inference_model可以根据推理需要的输入和输出, 对训练模型进行剪枝, 去除和推理无关部分, 得到的模型相比训练时更加精简, 适合进一步优化和部署。

from paddle import fluid

place = fluid.CPUPlace()
executor = fluid.Executor(place)

image = fluid.data(name="image", shape=[None, 28, 28], dtype="float32")
label = fluid.data(name="label", shape=[None, 1], dtype="int64")

feeder = fluid.DataFeeder(feed_list=[image, label], place=place)
predict = fluid.layers.fc(input=image, size=10, act='softmax')

loss = fluid.layers.cross_entropy(input=predict, label=label)
avg_loss = fluid.layers.mean(loss)

executor.run(fluid.default_startup_program())

# 保存模型到model目录中, 只保存与输入image和输出与推理相关的部分网络
fluid.io.save_inference_model("model", feed_var_names=["image"],
    target_vars=[predict]. executor=executor)

“一个配置管理器”搞定部署设置

保存推理模型之后, 就可以使用推理库了, Paddle Inference提供了 AnalysisConfig 用于管理推理部署的各种设置,比如设置在CPU还是GPU部署、加载模型路径、开启/关闭计算图分析优化、使用MKLDNN/TensorRT进行部署的加速等,用户可以根据自己的上线环境, 打开所需优化配置。同时,可配置采用zero copy的方式管理输入和输出, 推理执行时可跳过feed op和fetch op,减少多余的数据拷贝,提高推理性能。

from paddle.fluid.core import AnalysisConfig

# 创建配置对象
config = AnalysisConfig("./model")
# 配置采用zero copy的方式
config.switch_use_feed_fetch_ops(False)
config.switch_specify_input_names(True)

“一个预测器”搞定高性能推理

定义好部署的配置后,就可以创建预测器了。Paddle Inference提供了多项图优化的方式,创建预测器时将会加载推理模型并自动进行图优化,以增强推理性能。

# 创建预测器
from paddle.fluid.core import create_paddle_predictor
predictor = create_paddle_predictor(config)

创建好预测器之后,只需要传入数据就可以运行推理计算预测结果了。这里假设我们已经将输入数据读入了一个numpy.ndarray数组中,飞桨提供了简单易用的API来管理输入和输出。

# 获取并传入数据
input_names = predictor.get_input_names()
input_tensor = predictor.get_input_tensor(input_names[0])
input_tensor.copy_from_cpu(input_data.reshape([1, 28, 28]).astype("float32"))

# 运行预测器, 这里将会执行真正的预测
predictor.zero_copy_run()

# 输出预测结果
ouput_names = predictor.get_output_names()
output_tensor = predictor.get_output_tensor(output_names[0])
output_data = output_tensor.copy_to_cpu()

接下来以一个完整的Python API的实例,来实践一下使用飞桨部署模型的全流程。我们以在P4 GPU服务器上部署resnet模型为例。

  • (1)安装PaddlePaddle。

可以参考官网下载并安装PaddlePaddle。

b04c1688e4b4a979f386a1cccb80ebb3.png

  • (2)获取模型。

wget http://paddle-inference-dist.bj.bcebos.com/resnet50_model.tar.gz && tar -xzf resnet50_model.tar.gz
  • (3)准备模型部署代码,并将代码保存到infer_resnet.py文件中。

import argparse
import argparse
import numpy as np
from paddle.fluid.core import AnalysisConfig
from paddle.fluid.core import create_paddle_predictor

def main():   

    args = parse_args()

    # 设置AnalysisConfig
    config = set_config(args)

    # 创建PaddlePredictor
    predictor = create_paddle_predictor(config)

    # 获取输入的名称
    input_names = predictor.get_input_names()
    input_tensor = predictor.get_input_tensor(input_names[0])

    # 设置输入
    fake_input = np.random.randn(args.batch_size, 3, 318, 318).astype("float32")
    input_tensor.reshape([args.batch_size, 3, 318, 318])
    input_tensor.copy_from_cpu(fake_input)

    # 运行predictor
    predictor.zero_copy_run()

    # 获取输出
    output_names = predictor.get_output_names()
    output_tensor = predictor.get_output_tensor(output_names[0])
    output_data = output_tensor.copy_to_cpu() # numpy.ndarray类型
    for i in range(args.batch_size):
        print(np.argmax(output_data[i]))

def parse_args():

    # 模型路径配置
    parser = argparse.ArgumentParser()
    parser.add_argument("--model_file", type=str, help="model filename")
    parser.add_argument("--params_file", type=str, help="parameter filename")
    parser.add_argument("--batch_size", type=int, default=1, help="batch size")

    return parser.parse_args()

def set_config(args):
    config = AnalysisConfig(args.model_file, args.params_file)
    config.enable_use_gpu(100, 0)
    config.switch_use_feed_fetch_ops(False)
    config.switch_specify_input_names(True)
    return config

if __name__ == "__main__":
main()
  • (4)执行推理任务。

# model为模型存储路径
python3 infer_resnet.py --model_file=model/model --params_file=model/params

以上就是使用Paddle Inference的Python API进行模型部署的完整流程,可从官网获取代码。如果想了解C++部署,可以参考官网提供的C++示例。

Python示例:https://www.paddlepaddle.org.cn/documentation/docs/zh/advanced_guide/inference_deployment/inference/python_infer_cn.html#id6

C++示例:https://www.paddlepaddle.org.cn/documentation/docs/zh/advanced_guide/inference_deployment/inference/native_infer.html#a-name-c-c-a

Paddle Inference如何进一步优化性能?

到这里已经完成一个基本的推理服务,是否可以交差了?对于精益求精的开发者们来说显然还不够,飞桨还可通过下面这些方法,帮助用户进一步提高推理性能:

启用MKLDNN加速CPU推理

在X86 CPU上, 若硬件支持, 可以打开DNNL (Deep Neural Network Library, 原名MKLDNN) 优化, 这是一个Intel开源的高性能计算库, 用于Intel架构的处理器和图形处理器上的神经网络优化, 飞桨可自动调用,只需要在配置选项中打开即可。

config.enable_mkldnn()

切换到GPU推理

若需要使用NVIDIA GPU,只需一行配置,就可自动切换到GPU上。

# 在 GPU 0 上初始化 100 MB 显存。这只是一个初始值,实际显存可能会动态变化。
config.enable_use_gpu(100, 0)

启动TensorRT加快GPU推理速度

TensorRT是一个高性能的深度学习推理加速库,可为GPU上的深度学习推理应用程序提供低延迟和高吞吐量的优化服务。Paddle Inference采用子图的形式对TensorRT 进行了集成。在已经配置使用 GPU 推理的基础上, 只需要一行配置就可以开启 Paddle TensorRT加速推理:

config.enable_tensorrt_engine(workspace_size=1 <30,
                              max_batch_size=1,
                              min_subgraph_size=3,
                              precision_mode=AnalysisConfig.Precision.Float32,
                              use_static=False,
                              use_calib_mode=False)

开启Paddle Lite轻量化推理引擎

针对一些计算量较小,实际推理耗时很少的小模型,如果直接使用Paddle Inference,框架耗时可能与模型耗时在同一量级,此时可选用Paddle Lite子图的方式来运行以减少框架耗时。Paddle Inference采用子图的形式集成 Paddle Lite,只需要添加一行配置即可开启 Paddle Lite 的推理加速引擎。

config.enable_lite_engine(precision_mode=AnalysisConfig.Precision.Float32)

飞桨在工业部署领域覆盖哪些场景?

工业级部署可能面临多样化的部署环境,针对不同应用场景,飞桨提供了三种推理部署方案:

  • Paddle Inference作为飞桨深度学习框架原生的高性能推理库,可应用于本地服务器端部署场景,做到即训即用。

  • 针对服务化部署场景,飞桨提供Paddle Serving部署方案。该场景将推理模块作为远程调用服务,客户端发出请求,服务端返回推理结果。是云端部署必不可少的方案。

  • 针对移动端、嵌入式芯片等端侧硬件部署的场景,飞桨提供Paddle Lite部署方案,满足高性能、轻量化的部署需求。

更多介绍可访问如下飞桨项目地址,一起探索飞桨强大的工业部署实践能力。

相关资料

飞桨Paddle Inference项目地址:https://github.com/PaddlePaddle/Paddle/tree/develop/paddle/fluid/inference

飞桨Paddle Lite项目地址:https://github.com/PaddlePaddle/Paddle-Lite

飞桨Paddle Serving项目地址:https://github.com/PaddlePaddle/Serving

飞桨PaddleSlim项目地址:https://github.com/PaddlePaddle/PaddleSlim

如果您加入官方QQ群,您将遇上大批志同道合的深度学习同学。

官方QQ群:703252161。

如果您想详细了解更多飞桨的相关内容,请参阅以下文档。

官网地址:https://www.paddlepaddle.org.cn

飞桨核心框架项目地址:

GitHub: https://github.com/PaddlePaddle/Paddle

Gitee: https://gitee.com/paddlepaddle/Paddle

高能直播 | 云体验无人车试乘+顶级技术专家拆解仿真系统

5aadc107aa360c21e6bd31f26a9890ed.png9703782364082afbe2a2a39d8904b9e0.png

量子位 QbitAI · 头条号签约作者

վ'ᴗ' ի 追踪AI技术和产品新动态

喜欢就点「在看」吧 !

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/246101.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

GPU架构杂乱备忘——IMR、TBR、TBDR

原文&#xff1a;https://juejin.cn/post/6844904132864655367 GPU架构杂乱备忘——IMR、TBR、TBDR 之前觉得涉及到gpu架构相关的问题只需要知道个大概就好&#xff0c;毕竟在图形api的层面上应该把硬件的细节给隐蔽掉&#xff0c;gpu的架构千千万万&#xff0c;每家厂商每个…

requests下载大文件_11种方法教你用Python高效下载资源!

在本教程中&#xff0c;你将学习如何使用不同的Python模块从web下载文件。此外&#xff0c;你将下载常规文件、web页面、Amazon S3和其他资源。最后&#xff0c;你将学习如何克服可能遇到的各种挑战&#xff0c;例如下载重定向的文件、下载大型文件、完成一个多线程下载以及其他…

android自定义push通知_20个海外Web和App推送通知服务工具

在App和网站中使用推送通知有不同的原因&#xff0c;并且在提高流量和与客户互动方面有很多好处。推送通知是一种交互式可点击消息&#xff0c;可将访问者直接引导至你的网站。它们可以帮助你以指数方式增加流量和参与率。因此&#xff0c;营销人员&#xff0c;广告商&#xff…

linux 删除文件_Linux删除文件夹命令有哪些

今天要和大家分享的Linux常用命令是Linux删除文件夹命令,Linux删除文件夹很简单,常用的命令有rmdir和rm,以下分别介绍一下,大家根据情况选择使用即可。 Linux删除文件夹命令有哪些 ①Linux删除文件夹命令:rmdir rmdir命令使用场景: 当有空目录要删除时,可使用rmdir指令。…

url上接收到 el表达式 不渲染_一文摸透从输入URL到页面渲染的过程

一文摸透从输入URL到页面渲染的过程从输入URL到页面渲染需要Chrome浏览器的多个进程配合&#xff0c;所以我们先来谈谈现阶段Chrome浏览器的多进程架构。一、Chrome架构目前Chrome采用的是多进程的架构模式&#xff0c;可分为主要的五类进程&#xff0c;分别是&#xff1a;浏览…

模拟弱网工具的使用

https://zhuanlan.zhihu.com/p/98185153 https://www.jianshu.com/p/5e35a3585df5 今年5G技术开始铺开并进入商用。随着5G的到来&#xff0c;不知道大家有没有和我一样的感受&#xff0c;希望是我心理作用吧&#xff0c;我发现作为一个4G用户&#xff0c;最近我的手机网速是不…

c语言计算a+aa+aaa_物业服务企业信用等级公布,42家获AAA级!你家小区物业怎么样?...

杭州住保房管 根据《浙江省物业服务企业信用信息管理办法》和《浙江省行业信用监管责任体系构建工作方案》&#xff0c;日前&#xff0c;省建设厅公布了 2020年度浙江省物业服务企业信用等级结果名单&#xff0c;杭州165家物业服务企业上榜&#xff0c;绿城物业服务集团有限公司…

python 可视化_python可视化基础

常用的python可视化工具包是matplotlib&#xff0c;seaborn是在matplotlib基础上做的进一步封装。入坑python可视化&#xff0c;对有些人来说如同望山跑死马&#xff0c;心气上早输了一节。其实学习一门新知识&#xff0c;首先要掌握的是这门知识的最少最核心知识&#xff0c;剩…

使用post访问不到接口_Postman工具使用说明

一、工具说明接口测试工具&#xff0c;支持post&#xff0c;get&#xff0c;请求的接口测试&#xff1b;支持参数中带token&#xff0c;带cookie等接口测试。印度阿三开发的产品&#xff0c;稳定性较好&#xff0c;强烈推荐&#xff0c;屡试很爽。适用&#xff1a;前后端分离的…

java正则表达式判断手机号_正则表达式学习之简单手机号和邮箱练习

正则表达式的组成规则在java中&#xff0c;正则表达式的编译是类java.util.regex.Pattern正则表达式的构造摘要1.字符x包括所有大写和小写字母、所有数字、所有标点符号和一些其他符号的普通字符。比如之前的例子可以将[1-9][0-9]{4,12}改成1[0-9]{4,12}或者a[0-9]{4,12}此时就…

unity 解决引入dlopen api的问题

打包出来的ipa在腾讯的wetest的ios预审中报以下错误。 对于dlopen api, 是苹果禁用的&#xff0c;对Unity项目痛苦的挨个二分排查后&#xff0c;发现很多都有可能引入。 1.和XML或Excel相关的C# API极有可能引入。https://blog.csdn.net/qq_36622009/article/details/10388285…

运营体系_用户运营系统论:解构复杂产品的大规模用户运营体系

本文介绍了大规模用户运营体系中的三大原则——数据驱动、精细化运营、自动化(或叫产品化)&#xff0c;以及用户运营体系中的三个子系统——用户生命周期管理系统、用户分层运营系统、用户行为激励系统。我们在实际的产品工作中&#xff0c;经常会用到各种各样的运营体系&#…

ShaderToy效果学习(转成Unity URP) - MathEye

来自IQ大神的小教程&#xff0c;效果图&#xff1a; shaderToy源码&#xff1a;https://www.shadertoy.com/view/lsfGRr 教程视频&#xff1a;https://www.bilibili.com/video/BV1KK4y1K7wM/ Unity项目代码Git地址&#xff1a;https://github.com/Dejavu0709/Graphics.git Sh…

asp 退出登录修改cookie能进入后台_深入浅出让你理解跨域与SSO单点登录原理与技术...

一&#xff1a;SSO体系结构SSOSSO英文全称Single Sign On&#xff0c;单点登录。SSO是在多个应用系统中&#xff0c;用户只需要登录一次就可以访问所有相互信任的应用系统。它包括可以将这次主要的登录映射到其他应用中用于同一个用户的登录的机制。它是目前比较流行的企业业务…

是可改写的随机存储器_关于存储器的一些基础知识整理

RAMRandom-Access-Memory,随机存储存储器&#xff0c;可读可写&#xff0c;分为SRAM和DRAM&#xff0c;即静态随机存储器和动态随机存储器&#xff0c;理解上静动态主要体现是否需要刷新&#xff0c;通常DRAM需要刷新&#xff0c;否则数据将丢失;SRAM的效率较好&#xff0c;而成…

fpga供电电压偏低会怎样_[走近FPGA]之开发板介绍篇

开发板概述在走近FPGA预告篇中&#xff0c;我们已经提到了系列文章使用的开发平台&#xff0c;硬木课堂Xilinx Artix 7 FPGA板&#xff0c;如下图所示。它使用的FPGA芯片型号为Xilinx Artix-7 XC7A75T&#xff0c;具有电平开关、LED、矩阵键盘、数码管等基本外设&#xff0c;同…

使用arm-linux-androideabi-addr2line 定位Unity Android 段错误

arm-linux-androideabi-addr2line是NDK中提供的将内存地址转换成行号的一个工具&#xff0c;通俗具体点就是根据各种日志&#xff0c;譬如trace日志和tomestone日志中包含的so库日志的中偏移内存地址&#xff0c;定位到具体是在那个文件的那一行。Unity的安装目录中&#xff0c…

springboot几种注入_Spring Boot中使用JdbcTemplate访问数据库

本文介绍在Spring Boot基础下配置数据源和通过JdbcTemplate编写数据访问的示例。数据源配置在我们访问数据库的时候&#xff0c;需要先配置一个数据源&#xff0c;下面分别介绍一下几种不同的数据库配置方式。首先&#xff0c;为了连接数据库需要引入jdbc支持&#xff0c;在pom…

搜索重复代码_LeetCode专题——详解搜索算法中的搜索策略和剪枝

今天是LeetCode专题第20篇文章&#xff0c;今天讨论的是数字组合问题。描述给定一个int类型的候选集&#xff0c;和一个int类型的target&#xff0c;要求返回所有的数字组合&#xff0c;使得组合内所有数字的和刚好等于target。注意&#xff1a;所有的元素都是正数所有元素没有…

Unity内实现Android APK版本更新

最近做项目有个需求是要Android应用内强更包体。Google一波直接选了一个android原生开源项目 GitHub - yangchong211/YCUpdateApp: 轻量级版本更新弹窗&#xff0c;弹窗上支持更新进度条&#xff0c;可以设置普通更新或者强制更新。解决8.0以上通知栏不显示问题&#xff0c;解…