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封请求数据,服务端接收到请求时,找到需要调用调 ...
随机推荐
- 关于CSS3背景渐变色无效问题
无效的css[linear-gradient]写法 .loginbox{ background-color: linear-gradient(#D0D0D0, #E0E0E0, white); wid ...
- php和mysql数据库防SQL注入的有效解决办法
<?php$mysqli = new mysqli("localhost", "my_user", "my_password", &q ...
- ZOJ3261并查集逆向处理
题意: 给你一些点,还有一些边,每个点上都有一个权值,然后有一些询问,分为两种, query a 询问与a直接或者间接想连的点中最大权值的是那个点,输出那个点,如果那个点的权值小于等于a的 ...
- 学习Canvas绘图与动画基础 canvas入门(一)
一.创建canvas 1 <!DOCTYPE html> 2 <html> 3 <head lang="en"> 4 <meta char ...
- SpringBoot程序后台运行
使用nohup命令让进程后台运行 nohup java -jar 自己的springboot项目.jar >日志文件名.log 2>&1 & >日志文件名.log : ...
- 【TensorFlow】Win7下使用Object Detection API 训练自己的数据集,并视频实时检测
说明: 图片:自己开的摄像头,截取的图片.选择了200张图片.下面会有截取的脚本. 使用labelImg工具进行图片进行标注.产生PascalVOC格式的XML文件.[labelImg工具的安装和使用 ...
- Java筑基 - JNI到底是个啥
在前面介绍Unsafe的文章中,简单的提到了java中的本地方法(Native Method),它可以通过JNI(Java Native Interface)调用其他语言中的函数来实现一些相对底层的功 ...
- linux 查看运行java所在目录
通过ps及top命令查看进程信息时,只能查到相对路径,查不到的进程的详细信息 需要查看pos_service.jar的绝对路径(在哪里目录下) 使用:ll /proc/PID Linux在启动一个进 ...
- 03.28,周六,12:00-17:00,ICPC训练联盟周赛,选用试题:UCF Local Programming Contest 2016正式赛。
A. Majestic 10 题意:三个数均大于10则输出"triple-double",如果两个数大于10则输出"double-double",如果一个大于1 ...
- SE_Work2_交点个数
项目 内容 课程:北航-2020-春-软件工程 博客园班级博客 要求:求交点个数 个人项目作业 班级:005 Sample GitHub地址 IntersectProject 一.PSP估算 在开始实 ...