DLPack构建跨框架的深度学习编译器
DLPack构建跨框架的深度学习编译器
Tensorflow,PyTorch和ApacheMxNet等深度学习框架提供了一个功能强大的工具包,可用于快速进行原型设计和部署深度学习模型。易用性通常是以碎片为代价的:孤立地使用每个框架是很容易的。垂直集成已使常见用例的开发流程简化了,但是冒险走过的路可能很棘手。
一个支持不佳的方案是将张量直接从一个框架传递到内存中的另一个框架,而没有任何数据重复或复制。支持这种用例使用户能够将管道串联在一起,其中某些算子在一个框架中得到比在另一个框架中得到更好的支持(或更快速)。框架之间共享的数据表示形式也将弥合这一差距,并在为算子生成代码时,允许编译器堆栈以单一格式为目标。
DLPack是用于张量数据结构的中间内存表示标准。使用DLPack作为通用表示,传统上只能依赖供应商提供的库的框架编写的脚本中利用TVM。TVM打包函数可以在DLPack张量上运行,提供包装程序以桥接带有零数据副本的框架(例如PyTorch和MxNet)中的张量数据结构。
DLPack提供了一种简单的可移植内存数据结构:
/*!
* \brief Plain C Tensor object, does not manage memory.
*/
typedefstruct
{
/*!
* \brief The opaque data pointer points to the allocated data.
* This will be CUDA device pointer or cl_mem handle in OpenCL.
* This pointer is always aligns to 256 bytes as in CUDA.
*/
void*
data;
/*! \brief The device context of the tensor */
DLContext
ctx;
/*! \brief Number of dimensions */
int
ndim;
/*! \brief The data type of the pointer*/
DLDataType
dtype;
/*! \brief The shape of the tensor */
int64_t*
shape;
/*!
* \brief strides of the tensor,
* can be NULL, indicating tensor is compact.
*/
int64_t*
strides;
/*! \brief The offset in bytes to the beginning pointer to data */
uint64_t
byte_offset;
}DLTensor;
例如,在TVM中声明并编译一个矩阵乘法算子,并构建一个使用DLPack表示形式的包装器wrapper,允许该算子支持PyTorch张量。还使用MxNet重复此演示。此扩展使机器学习开发人员可以在不牺牲性能的情况下,将代码快速移植到相对不受支持的硬件平台上。
DLPack如何提供框架和TVM之间共享的中间包wrapper的说明:
图1
首先,在PyTorch中计算参考输出:
import
torch
x
=
torch.rand(56,56)
y
=
torch.rand(56,56)
z
=
x.mm(y)
然后,使用默认调度定义并构建TVM矩阵乘法算子:
n
=
tvm.convert(56)
X
=
tvm.placeholder((n,n),
name='X')
Y
=
tvm.placeholder((n,n),
name='Y')
k
=
tvm.reduce_axis((0,
n),
name='k')
Z
=
tvm.compute((n,n),
lambda
i,j
:
tvm.sum(X[i,k]*Y[k,j],
axis=k))
s
=
tvm.create_schedule(Z.op)
fmm
=
tvm.build(s,
[X,
Y,
Z],
target_host='llvm',
name='fmm')
为简便起见,没有涵盖可用于优化矩阵乘法的TVM大量的调度原语集合。如果希望使自定义GEMM算子在的硬件设备上快速运行,请参考详细的教程。
然后,将TVM函数转换为支持PyTorch张量的函数:
from
tvm.contrib.dlpack
import
to_pytorch_func
# fmm is the previously built TVM function (Python function)
# fmm is the wrapped TVM function (Python function)
fmm_pytorch
=
to_pytorch_func(fmm)
z2
=
torch.empty(56,56)
fmm_pytorch(x,
y,
z2)
np.testing.assert_allclose(z.numpy(),
z2.numpy())
并验证结果是否匹配。
可以重复相同的示例,但是使用MxNet代替:
import
mxnet
from
tvm.contrib.mxnet
import
to_mxnet_func
ctx
=
mxnet.cpu(0)
x
=
mxnet.nd.uniform(shape=(56,56),
ctx=ctx)
y
=
mxnet.nd.uniform(shape=(56,56),
ctx=ctx)
z
=
mxnet.nd.empty(shape=(56,56),
ctx=ctx)
f
=
tvm.build(s,
[X,
Y,
Z],
target_host='llvm',
name='f')
f_mxnet
=
to_mxnet_func(f)
f_mxnet(x,
y,
z)
np.testing.assert_allclose(z.asnumpy(),
x.asnumpy().dot(y.asnumpy()))
在PyTorch示例的幕后
由于TVM提供了将dlpack张量转换为tvm的功能,NDArray
反之亦然,因此,通过wrapper功能,所需的只是一些语法 syntactic sugar 。 convert_func
是用于使用具有dlpack支持的张量的框架的通用转换器,可以用于实现方便的转换器,例如 to_pytorch_func
。
defconvert_func(tvm_func,
tensor_type,
to_dlpack_func):
assert
callable(tvm_func)
def
_wrapper(*args):
args
=
tuple(ndarray.from_dlpack(to_dlpack_func(arg))
\
if
isinstance(arg,
tensor_type)
else
arg
for
arg
in
args)
return
tvm_func(*args)
return
_wrapper
defto_pytorch_func(tvm_func):
import
torch
import
torch.utils.dlpack
return
convert_func(tvm_func,
torch.Tensor,
torch.utils.dlpack.to_dlpack)
DLPack构建跨框架的深度学习编译器的更多相关文章
- 通过 DLPack 构建跨框架深度学习编译器
通过 DLPack 构建跨框架深度学习编译器 深度学习框架,如Tensorflow, PyTorch, and ApacheMxNet,快速原型化和部署深度学习模型提供了强大的工具箱.不幸的是,易用性 ...
- go微服务框架go-micro深度学习-目录
go微服务框架go-micro深度学习(一) 整体架构介绍 go微服务框架go-micro深度学习(二) 入门例子 go微服务框架go-micro深度学习(三) Registry服务的注册和发现 go ...
- go微服务框架go-micro深度学习(四) rpc方法调用过程详解
上一篇帖子go微服务框架go-micro深度学习(三) Registry服务的注册和发现详细解释了go-micro是如何做服务注册和发现在,服务端注册server信息,client获取server的地 ...
- go微服务框架go-micro深度学习 rpc方法调用过程详解
摘要: 上一篇帖子go微服务框架go-micro深度学习(三) Registry服务的注册和发现详细解释了go-micro是如何做服务注册和发现在,服务端注册server信息,client获取serv ...
- 大数据下基于Tensorflow框架的深度学习示例教程
近几年,信息时代的快速发展产生了海量数据,诞生了无数前沿的大数据技术与应用.在当今大数据时代的产业界,商业决策日益基于数据的分析作出.当数据膨胀到一定规模时,基于机器学习对海量复杂数据的分析更能产生较 ...
- go微服务框架go-micro深度学习(二) 入门例子
上一篇帖子简单介绍了go-micro的整体框架结构,这一篇主要写go-micro使用方式的例子,中间会穿插一些go-micro的源码,和调用流程图,帮大家更好的理解go-micro的底层.更详细更具体 ...
- go微服务框架go-micro深度学习(一) 整体架构介绍
产品嘴里的一个小项目,从立项到开发上线,随着时间和需求的不断激增,会越来越复杂,变成一个大项目,如果前期项目架构没设计的不好,代码会越来越臃肿,难以维护,后期的每次产品迭代上线都会牵一发而动全身.项目 ...
- go微服务框架go-micro深度学习(三) Registry服务的注册和发现
服务的注册与发现是微服务必不可少的功能,这样系统才能有更高的性能,更高的可用性.go-micro框架的服务发现有自己能用的接口Registry.只要实现这个接口就可以定制自己的服务注册和发现. go- ...
- go微服务框架go-micro深度学习(五) stream 调用过程详解
上一篇写了一下rpc调用过程的实现方式,简单来说就是服务端把实现了接口的结构体对象进行反射,抽取方法,签名,保存,客户端调用的时候go-micro封请求数据,服务端接收到请求时,找到需要调用调 ...
随机推荐
- 动态地绑定到它的 is 特性,可以实现动态组件
前面的话 让多个组件使用同一个挂载点,并动态切换,这就是动态组件.本文将详细介绍Vue动态组件 概述 通过使用保留的 <component> 元素,动态地绑定到它的 is 特性,可以实现动 ...
- 【Scrapy(三)】Scrapy 中的 logging 模块
logging模块的使用: 1.在scrapy中使用 2.在普通项目中使用
- android调用号和libc
调用号(以arm平台为例)在/bionic/libc/kernel/uapi/asm-arm/asm/unistd.h: /* WARNING: DO NOT EDIT, AUTO-GENERATED ...
- UVA11549计算器谜题
题意: 有一个计算机只能保留数字的前n位,你有一个数字k(k<=9),反复平方后在计算机上显示的最大数字是多少. 思路: 显然这个题目是有循环节的,为什么有循环节?首先 ...
- Tomcat PUT方法任意文件上传(CVE-2017-12615)
目录 漏洞复现: 漏洞利用工具: 漏洞环境:当 Tomcat运行在Windows操作系统,且启用了HTTP PUT请求方法(例如,将 readonly 初始化参数由默认值设置为 false),攻击者将 ...
- Intel汇编程序设计-高级过程(上)
第八章 高级过程 8.1 简介 本章主要讲: 堆栈框架 变量作用域和生存期 对战参数的类型 通过传递值或者传递引用来传递参数 在堆栈上创建和初始化局部变量 递归 编写多模块程序 内存模型和语言关键字 ...
- vscode 终端操作命令npm报错
错误: 如果没有安装的node.js ,则需要安装. node.js官网下载地址: https://nodejs.org/zh-cn/ 安装node.js 后会看到C:\Users\XXX\AppDa ...
- MFC Object 与 Windows Object
MFC Object 和 Windows Object的含义 Window Object(Window对象)是Win32下用句柄表示的Windows操作系统对象.MFC Object(MFC对象)是C ...
- (转)netcore原生websocket客户端写法(ClientWebSocket)
代码: using System; using System.Net.WebSockets; using System.Text; using System.Threading; using Syst ...
- 消息队列RabbitMQ(五):死信队列与延迟队列
死信队列 引言 死信队列,英文缩写:DLX .Dead Letter Exchange(死信交换机),其实应该叫做死信交换机才更恰当. 当消息成为Dead message后,可以被重新发送到另一个交换 ...