Taichi 和 PyTorch 的数据容器存在哪些差异?
时间:2022-11-06 22:15:41 阅读:78
在上一篇博客《一文看懂Taichi&PyTorch,它们有哪些相似与不同?》中,前PyTorch核心开发者,现Taichi编译器工程师Ailing带大家了解Taichi Lang和Torch的基本概念和组件,共同了探寻两者之间微妙的相似与差异。在这篇博客中,作者将聚焦Taichi和Torch两种框架中的多维数组容器field和tensor,解析这两种容器间的差异,以帮助用户理清它们的用法。
Taichi与Torch的数据接口
关于Taichi
在图形学领域,工程师经常遇到需要使用多个分量来描述一个属性的情形,对于熟悉如GLSL等着色语言(shading language)的同学可能对这个概念并不陌生。比如可以通过定义RGBA四个分量来描述一个颜色,或者通过定义xyz坐标描述三维空间的一个位置。因此,Taichi的数据容器field中的元素既可以是标量,也可以是向量或矩阵,以便于灵活地适配图形学的各种应用场景。以向量元素为例,对于它的访问既可以使用数组下标,如field[0],也可以使用如field.r,field.g,field.x,field.y等Swizzle操作。
举个例子,要表示一张512 x 512大小的图片中每个像素点的颜色(RGB),你可以在Taichi中创建一个由三维向量组成的field:
ti_image=ti.Vector.field(n=3,shape=(512,512),dtype=ti.f32)
这样你就可以通过x[10,20]访问到横坐标为10,纵坐标为20的像素点的颜色,并且可以通过x[10,20].r来访问到该像素R通道的值。这样用户可以用一种符合直觉的方式便捷地进行位置、向量或者颜色向量的数学运算。
p.s.Taichi的向量和矩阵元素会在编译时被展开。为避免展开影响整体性能,Taichi field只支持小的向量和矩阵如vec3,mat4x4等。
关于Torch
在机器学习领域使用频繁的是基于Tensor的如矩阵乘法等操作,因此torch.Tensor的元素只允许是标量(包括复数),这样更符合数学上的张量定义。当然如果Tensor的某些维度有对应的物理含义,就需要用户来记住这些信息。
比如在PyTorch中,你可以创建一个tensor表示和上面field ti_image类似的一张512 x 512大小的图片中每个像素点的颜色,常用的做法是创建下面这样一个三维张量,由最后一维的三个值来隐式代表RGB三个通道的值。
torch_image=torch.zeros((height,width,3),dtype=torch.float)
Taichi与Torch的内存读取方式
除了定义数据的接口不同,Taichi和PyTorch都支持用户灵活调整field或Tensor的内存排布,从而优化性能。
Pytorch Tensor默认的内存排布是NCHW,可以通过指定memory_format改变内存排布。机器学习应用中常用的两种格式包括:
「NHWC」的排列顺序为[batch,height,width,channels],比如torch.channels_last
「NCHW」的排列顺序为[batch,channels,height,width],比如torch.contiguous_format
通常来说,机器学习的不同layer的性能会受到输入tensor的内存排布的影响。比如对于NVDIA的Tensor Core GPU上的卷积层来说,输入tensor是NHWC的排布时计算效率最高[1]。因为每个像素点的所有channel值同时被访问,NHWC的数据排布更符合这种访问规律。但是,对于Batchnorm这样的layer来说,通常你会归纳H、W两个维度,则NCHW的排布计算效率是最高的。因此PyTorch提供了不同的memory_format以及它们之间灵活的转换,以方便用户能够在不同场景下使用最优的内存排布。
input=torch.randn(1,10,32,32)
model=torch.nn.Conv2d(10,20,1,1)
model=model.to(memory_format=torch.channels_last)
output=model(input)
相应地,Taichi默认的ti.Layout.AOS(array of struct)排布将field的vector元素中的每个标量在内存中连续排布。比如当用户想要同时对位置向量的x,y,z值加1的时候,AOS的排布可以保证读取内存的效率是最高的。而且Taichi还通过structure node支持了SOA(structure of arrays)排布和更高级(甚至是稀疏)的分层数据结构。比如下面这个例子展示了如何优化一个简单的应用场景。
如果我们已知该应用将逐个遍历很多大小为8x8的图片,taichi我们就可以通过将8x8像素作为一个cell连续排布,从而最大化内存读写效率。同时由于Taichi实现了算法和数据的分离,用户可以灵活地改变数据排布但无需改动ti.kernel内的计算代码,使得通过实验对不同的应用找到对其性能友好的数据排布变得非常简单。由于篇幅有限,感兴趣的读者可以查看文档了解更多细节[2]。taichi https://taichi-lang.cn/
Taichi与Torch的数据接口
关于Taichi
在图形学领域,工程师经常遇到需要使用多个分量来描述一个属性的情形,对于熟悉如GLSL等着色语言(shading language)的同学可能对这个概念并不陌生。比如可以通过定义RGBA四个分量来描述一个颜色,或者通过定义xyz坐标描述三维空间的一个位置。因此,Taichi的数据容器field中的元素既可以是标量,也可以是向量或矩阵,以便于灵活地适配图形学的各种应用场景。以向量元素为例,对于它的访问既可以使用数组下标,如field[0],也可以使用如field.r,field.g,field.x,field.y等Swizzle操作。
举个例子,要表示一张512 x 512大小的图片中每个像素点的颜色(RGB),你可以在Taichi中创建一个由三维向量组成的field:
ti_image=ti.Vector.field(n=3,shape=(512,512),dtype=ti.f32)
这样你就可以通过x[10,20]访问到横坐标为10,纵坐标为20的像素点的颜色,并且可以通过x[10,20].r来访问到该像素R通道的值。这样用户可以用一种符合直觉的方式便捷地进行位置、向量或者颜色向量的数学运算。
p.s.Taichi的向量和矩阵元素会在编译时被展开。为避免展开影响整体性能,Taichi field只支持小的向量和矩阵如vec3,mat4x4等。
关于Torch
在机器学习领域使用频繁的是基于Tensor的如矩阵乘法等操作,因此torch.Tensor的元素只允许是标量(包括复数),这样更符合数学上的张量定义。当然如果Tensor的某些维度有对应的物理含义,就需要用户来记住这些信息。
比如在PyTorch中,你可以创建一个tensor表示和上面field ti_image类似的一张512 x 512大小的图片中每个像素点的颜色,常用的做法是创建下面这样一个三维张量,由最后一维的三个值来隐式代表RGB三个通道的值。
torch_image=torch.zeros((height,width,3),dtype=torch.float)
Taichi与Torch的内存读取方式
除了定义数据的接口不同,Taichi和PyTorch都支持用户灵活调整field或Tensor的内存排布,从而优化性能。
Pytorch Tensor默认的内存排布是NCHW,可以通过指定memory_format改变内存排布。机器学习应用中常用的两种格式包括:
「NHWC」的排列顺序为[batch,height,width,channels],比如torch.channels_last
「NCHW」的排列顺序为[batch,channels,height,width],比如torch.contiguous_format
通常来说,机器学习的不同layer的性能会受到输入tensor的内存排布的影响。比如对于NVDIA的Tensor Core GPU上的卷积层来说,输入tensor是NHWC的排布时计算效率最高[1]。因为每个像素点的所有channel值同时被访问,NHWC的数据排布更符合这种访问规律。但是,对于Batchnorm这样的layer来说,通常你会归纳H、W两个维度,则NCHW的排布计算效率是最高的。因此PyTorch提供了不同的memory_format以及它们之间灵活的转换,以方便用户能够在不同场景下使用最优的内存排布。
input=torch.randn(1,10,32,32)
model=torch.nn.Conv2d(10,20,1,1)
model=model.to(memory_format=torch.channels_last)
output=model(input)
相应地,Taichi默认的ti.Layout.AOS(array of struct)排布将field的vector元素中的每个标量在内存中连续排布。比如当用户想要同时对位置向量的x,y,z值加1的时候,AOS的排布可以保证读取内存的效率是最高的。而且Taichi还通过structure node支持了SOA(structure of arrays)排布和更高级(甚至是稀疏)的分层数据结构。比如下面这个例子展示了如何优化一个简单的应用场景。
如果我们已知该应用将逐个遍历很多大小为8x8的图片,taichi我们就可以通过将8x8像素作为一个cell连续排布,从而最大化内存读写效率。同时由于Taichi实现了算法和数据的分离,用户可以灵活地改变数据排布但无需改动ti.kernel内的计算代码,使得通过实验对不同的应用找到对其性能友好的数据排布变得非常简单。由于篇幅有限,感兴趣的读者可以查看文档了解更多细节[2]。taichi https://taichi-lang.cn/
郑重声明:文章内容来自互联网,纯属作者个人观点,仅供参考,并不代表本站立场 ,版权归原作者所有!
上一篇:胡渊鸣:import一个“太极”库,让Python代码提速100倍!
下一篇:Taichi尝试解决什么 问题?
相关推荐