PyTorch JIT与TorchScript

PyTorch JIT与TorchScript

转自:https://zhuanlan.zhihu.com/p/370455320

如果搜索 PyTorch JIT,找到的将会是「TorchScript」的文档,那么什么是 JIT 呢?JIT 和 TorchScript 又有什么联系?

文章只会关注概念的部分,如果关注细节或实现部分,文章最后有一个完整的 Demo 可供参考。


什么是 JIT

首先要知道 JIT 是一种概念,全称是 Just In Time Compilation,中文译为「即时编译」,是一种程序优化的方法,一种常见的使用场景是「正则表达式」。例如,在 Python 中使用正则表达式:

prog = re.compile(pattern)
result = prog.match(string)

result = re.match(pattern, string)

上面两个例子是直接从 Python 官方文档中摘出来的 ,并且从文档中可知,两种写法从结果上来说是「等价」的。但注意第一种写法种,会先对正则表达式进行 compile,然后再进行使用。如果继续阅读 Python 的文档,可以找到下面这段话:

using re.compile() and saving the resulting regular expression object for reuse is more efficient when the expression will be used several times in a single program.

也就是说,如果多次使用到某一个正则表达式,则建议先对其进行 compile,然后再通过 compile 之后得到的对象来做正则匹配。而这个 compile 的过程,就可以理解为 JIT(即时编译)。

在深度学习中 JIT 的思想更是随处可见,最明显的例子就是 Keras 框架的 model.compile,TensorFlow 中的 Graph 也是一种 JIT,虽然他没有显示调用编译方法。

那 PyTorch 呢?PyTorch 从面世以来一直以「易用性」著称,最贴合原生 Python 的开发方式,这得益于 PyTorch 的「动态图」结构。我们可以在 PyTorch 的模型前向中加任何 Python 的流程控制语句,甚至是下断点单步跟进都不会有任何问题,但是如果是 TensorFlow,则需要使用 tf.cond 等 TensorFlow 自己开发的流程控制,谁更简单一目了然。那么为什么 PyTorch 还需要引入 JIT 呢?


TorchScript

动态图模型通过牺牲一些高级特性来换取易用性,那到底 JIT 有哪些特性,在什么情况下不得不用到 JIT 呢?下面主要通过介绍 TorchScript(PyTorch 的 JIT 实现)来分析 JIT 到底带来了哪些好处。

  1. 模型部署

PyTorch 的 1.0 版本发布的最核心的两个新特性就是 JIT 和 C++ API,这两个特性一起发布不是没有道理的,JIT 是 Python 和 C++ 的桥梁,我们可以使用 Python 训练模型,然后通过 JIT 将模型转为语言无关的模块,从而让 C++ 可以非常方便得调用,从此「使用 Python 训练模型,使用 C++ 将模型部署到生产环境」对 PyTorch 来说成为了一件很容易的事。而因为使用了 C++,我们现在几乎可以把 PyTorch 模型部署到任意平台和设备上:树莓派、iOS、Android 等等…

  1. 性能提升

既然是为部署生产所提供的特性,那免不了在性能上面做了极大的优化,如果推断的场景对性能要求高,则可以考虑将模型(torch.nn.Module)转换为 TorchScript Module,再进行推断。

  1. 模型可视化

TensorFlow 或 Keras 对模型可视化工具(TensorBoard等)非常友好,因为本身就是静态图的编程模型,在模型定义好后整个模型的结构和正向逻辑就已经清楚了;但 PyTorch 本身是不支持的,所以 PyTorch 模型在可视化上一直表现得不好,但 JIT 改善了这一情况。现在可以使用 JIT 的 trace 功能来得到 PyTorch 模型针对某一输入的正向逻辑,通过正向逻辑可以得到模型大致的结构,但如果在 forward 方法中有很多条件控制语句,这依然不是一个好的方法,所以 PyTorch JIT 还提供了 Scripting 的方式,这两种方式在下文中将详细介绍。


TorchScript Module 的两种生成方式

1. 编码(Scripting)

可以直接使用 TorchScript Language 来定义一个 PyTorch JIT Module,然后用 torch.jit.script 来将他转换成 TorchScript Module 并保存成文件。而 TorchScript Language 本身也是 Python 代码,所以可以直接写在 Python 文件中。

使用 TorchScript Language 就如同使用 TensorFlow 一样,需要前定义好完整的图。对于 TensorFlow 我们知道不能直接使用 Python 中的 if 等语句来做条件控制,而是需要用 tf.cond,但对于 TorchScript 我们依然能够直接使用 if 和 for 等条件控制语句,所以即使是在静态图上,PyTorch 依然秉承了「易用」的特性。TorchScript Language 是静态类型的 Python 子集,静态类型也是用了 Python 3 的 typing 模块来实现,所以写 TorchScript Language 的体验也跟 Python 一模一样,只是某些 Python 特性无法使用(因为是子集),可以通过 TorchScript Language Reference 来查看和原生 Python 的异同。

理论上,使用 Scripting 的方式定义的 TorchScript Module 对模型可视化工具非常友好,因为已经提前定义了整个图结构。

2. 追踪(Tracing)

使用 TorchScript Module 的更简单的办法是使用 Tracing,Tracing 可以直接将 PyTorch 模型(torch.nn.Module)转换成 TorchScript Module。「追踪」顾名思义,就是需要提供一个「输入」来让模型 forward 一遍,以通过该输入的流转路径,获得图的结构。这种方式对于 forward 逻辑简单的模型来说非常实用,但如果 forward 里面本身夹杂了很多流程控制语句,则可能会有问题,因为同一个输入不可能遍历到所有的逻辑分枝。

此外,还可以混合使用上面两种方式。

一个完整的例子

我简单写了一个简单的 MNIST demo,从使用 Python 训练到用 JIT 将 Python 模型转换为 TorchScript Module,然后用 C++ 加载 TorchScript Module 做推断的完整的过程:

https://github.com/louis-she/torchscript-mnist

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

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

相关文章

DVWA Cross Site Request Forgery (CSRF) -------WP

CSRF: 介绍 CSRF跨站点请求伪造(Cross—Site Request Forgery),跟XSS攻击一样,存在巨大的危害性,你可以这样来理解: 攻击者盗用了你的身份,以你的名义发送恶意请求,对服务器来说这个请求是完全合法的&…

PyTorch C++ API libtorch 简介

PyTorch C API libtorch 简介 翻译自 PyTorch 官方文档:https://pytorch.org/cppdocs/index.html#acknowledgements 整体划分 根据 PyTorch 官方文档 的介绍,PyTorch的C API可以粗略分为以下五个部分: ATen:基础的张量和数学计…

DVWA upload

LOW medium high impossible

安装 PyTorch C++ API libtorch 及一个最小例子

安装 PyTorch C API libtorch 及一个最小例子 翻译自:https://pytorch.org/cppdocs/installing.html 我们提供依赖 PyTorch 所需的所有头文件、库和 CMake 配置文件的二进制分发版。我们将此发行版称为 LibTorch,您可以在我们的网站上下载包含最新 Lib…

ImageNet 1K 类别名与索引的对应关系

ImageNet 1K 类别名与索引的对应关系 转自:http://befree2008.github.io/2018/10/05/20181005_ImageNet1000%E5%88%86%E7%B1%BB%E5%90%8D%E7%A7%B0%E5%92%8C%E7%BC%96%E5%8F%B7/ ImageNet 2012 1000个类名称和编号。ILSVRC2012_img_train.tar 这个文件解压出来都是…

sqlilab--writeup (5~6) 布尔盲注

1.# 和 – (有个空格)表示注释,可以使它们后面的语句不被执行。在url中,如果是get请求**(记住是get请求,也就是我们在浏览器中输入的url)** ,解释执行的时候,url中#号是用来指导浏览器动作的&am…

PyTorch导出JIT模型并用C++ API libtorch调用

PyTorch导出JIT模型并用C API libtorch调用 本文将介绍如何将一个 PyTorch 模型导出为 JIT 模型并用 PyTorch 的 CAPI libtorch运行这个模型。 Step1:导出模型 首先我们进行第一步,用 Python API 来导出模型,由于本文的重点是在后面的部署…

sqli-lab--writeup(7~10)文件输出,时间布尔盲注

前置知识点: 1、outfile是将检索到的数据,保存到服务器的文件内: 格式:select * into outfile “文件地址” 示例: mysql> select * into outfile ‘f:/mysql/test/one’ from teacher_class; 2、文件是自动创建…

树莓派4B (aarch64) 安装PyTorch 1.8 的可行方案

树莓派4B (aarch64) 安装PyTorch 1.8 的可行方案 最终可行方案 试了一堆方案(源码编译、Fast.ai的安装文件等)之后,终于找到一个可行的方案。是在 PyTorch 官方讨论社区的一个帖子中找到的,在回复中一个大佬给出了自己在2021年1…

sqli-lab———writeup(11~17)

less11 用户名提交单引号显示sql语法错误,故存在sql注入 根据单引号报错,在用户名和密码任意行输入 万能密码:‘ or 11# 输入后username语句为:SELECT username, password FROM users WHERE username or 11; 双引号 password语…

深入理解Python中的全局解释锁GIL

深入理解Python中的全局解释锁GIL 转自:https://zhuanlan.zhihu.com/p/75780308 注:本文为蜗牛学院资深讲师卿淳俊老师原创,首发自公众号https://mp.weixin.qq.com/s/TBiqbSCsjIbNIk8ATky-tg,如需转载请私聊我处获得授权并注明出处…

sqli-lab————Writeup(18~20)各种头部注入

less18 基于错误的用户代理,头部POST注入 admin admin 登入成功(进不去重置数据库) 显示如下 有user agent参数,可能存在注入点 显示版本号: 爆库:User-Agent:and extractvalue(1,concat(0x7e,(select …

Python GIL

转自:https://blog.csdn.net/weixin_41594007/article/details/79485847 Python GIL 在进行GIL讲解之前,我们可以先回顾一下并行和并发的区别: 并行:多个CPU同时执行多个任务,就好像有两个程序,这两个程序…

sqli-lab——Writeup21~38(各种过滤绕过WAF和)

Less-21 Cookie Injection- Error Based- complex - string ( 基于错误的复杂的字符型Cookie注入) base64编码,单引号,报错型,cookie型注入。 本关和less-20相似,只是cookie的uname值经过base64编码了。 登录后页面:…

Libtorch报错:terminate called after throwing an instance of ‘c10::Error‘ what():isTensor()INTERNAL ASS

Libtorch报错:terminate called after throwing an instance of ‘c10::Error’ what(): isTensor() INTERNAL ASSERT FAILED 报错 问题出现在笔者想要将 yolov5 通过 PyTorch 的 C 接口 Libtorch 部署到树莓派上。 完整报错信息: terminate called …

sqli-lab——Writeup(38~over)堆叠等......

知识点: 1.堆叠注入原理(stacked injection) 在SQL中,分号(;)是用来表示一条sql语句的结束。试想一下我们在 ; 结束一个sql语句后继续构造下一条语句,会不会一起执行?因此这个想法…

mysql常规使用(建立,增删改查,视图索引)

目录 1.数据库建立 2.增删改查 3.视图建立: 1.数据库建立 mysql> mysql> show databases; ----------------------------------- | Database | ----------------------------------- | information_schema | | ch…

php操作mysql数据库

phpmyadmin phpadmin是一个mysql图形化管理工具,是一款实用php开发的mysql苦户端软件,基于web跨平台的管理系统,支持简体中文,官网:www.phpmyadmin.net可以下载免费最新版。提供图形化操作界面,完成对mysq…

C:C++ 函数返回多个参数

C/C 函数返回多个参数 转自:https://blog.csdn.net/onlyou2030/article/details/48174461 笔者是 Python 入门的,一直很困惑 C/C 中函数如何返回多个参数。 如果一个函数需要返回多个参数,可以采用以下两种方法: 传引用或指针…

sql预编译

一.数据库预编译起源: 数据库接受sql语句,需要解析和制定执行,中间需要花费一段时间. 有时候同一语句可能会多次执行, 那么就会造成资源的浪费 如何减少编译执行的时间 ? 就有了预编译,预编译是将这类语句提前用占位符替代,一次编译,多次执行. 预编译后的执行代码会被缓存下来…