【AI系统】布局转换原理与算法

简介: 数据布局转换技术通过优化内存中数据的排布,提升程序执行效率,特别是对于缓存性能的影响显著。本文介绍了数据在内存中的排布方式,包括内存对齐、大小端存储等概念,并详细探讨了张量数据在内存中的排布,如行优先与列优先排布,以及在深度学习中常见的NCHW与NHWC两种数据布局方式。这些布局方式的选择直接影响到程序的性能,尤其是在GPU和CPU上的表现。此外,还讨论了连续与非连续张量的概念及其对性能的影响。

数据布局转换目前已经越来越多地用于编译器的前端优化,将内部数据布局转换为后端设备友好的形式。数据布局转换主要影响程序的空间局部性,所谓空间局部性指的是如果一个内存位置被引用了一次,那么程序很可能在不远的将来引用其附近的一个内存位置,它会影响到程序执行中的缓存及其他性能。目前已经有许多数据布局转换技术:数组维度的排列,数据分块等等。

接下来,我们将简单介绍数据布局转换,包括数据在内存如何排布,张量数据在内存中如何排布,以及数组维度排列的具体应用如 NCHW 与 NHWC 这两种数据排布方式。

数据内存排布

在内存中,数据的排布主要依赖于操作系统的内存管理机制和数据结构的实现方式。内存主要分为栈,堆,数据段,代码段等几个主要区域,数据在内存空间中按照字节进行划分,那么从理论上来说对于任何类型的变量访问都可以从任意地址开始。

但实际情况中,在访问特定类型变量的时候经常需要在特定的内存地址访问,接下来我们将通过内存对齐这个概念详细解释这一现象。

内存对齐

如下图所示,右侧代表着数据,左侧代表着内存的多个地址,数据存放在内存的某个地址中。内存对齐指的是数据元素按照一定的规则在空间上排列,而不是顺序的一个接一个的排放。

数据在内存中存储时相对于起始地址的偏移量是数据大小的整数倍,称为自然对齐,相对应的通过编译器或语言的指令强制变量按照特定的对齐方式存储,称为强制对齐。

内存中数据示意图

内存对齐的原因:从硬件的层面来看,虽然数据在内存中是按照字节进行存储,但是处理器从内存中读取数据是通过总线通信,总线默认传输的是字,即处理器按照字节块的方式读取内存。

举个例子,比如 32 位系统从内存中以 4 字节为粒度进行读取,64 位系统从内存中以 8 字节为粒度进行读取,所以当在处理器上进行未对齐的地址访问时,处理器将读取多个字,还有些处理器平台不支持访问任意地址上的任意数据。

详细展开来讲,以 4 字节存取粒度的处理器为例,如下图所示,我们现在要读取一个 int 变量,其有 4 个字节,假如没有内存对齐机制,将一个 int 放在地址为 1 的位置,那么我们需要读取的有地址 1234,具体操作时首先需要从地址 0 开始读取,然后取其较高的三位 123,剔除首字节 0,第二次从地址 4 开始读取,然后只取其较低的一位 4,之后将两个数据合并。

无内存对齐机制示意图

总体上来说,如果有内存对齐,如下图所示,我们只需读取一次,而没有内存对齐机制,将导致访问请求数据所需的内存事务数增加至 2 倍。

内存对齐机制示意图

总结一下,现代处理器上的内存子系统仅限于以其字大小的粒度和对齐方式访问内存,下面我们来总结一下内存中字粒度访问和内存对齐的原因:

  1. 读取速度

    现代处理器具有多个级别的高速缓存,数据必须通过这些缓存;支持单字节读取将使内存子系统的吞吐量与执行单元的吞吐量紧密地绑定,会消耗大量 CPU 资源,成为瓶颈。

    CPU 总是以其字的大小进行内存读取,进行未对齐的内存访问时,处理器将读取多个字,需要读取变量所跨越内存的所有字,同时进行处理。将导致访问请求数据所需要的内存事务增加 2 倍。

  2. 原子性

    CPU 可以在一个对齐的内存字上操作,意味着没有指令可以中断该操作。这对于许多无锁数据结构和其他并发范式的正确性至关重要。除此之外,内存对齐还可以用于优化缓存和 SIMD 指令,内存对齐有助于利用缓存行的特性。

    缓存通常以固定大小的缓存行存储数据,如果数据按照缓存行对齐,可以最大程度地减少对内存的访问次数,提高缓存的命中率。对齐的内存访问对于使用 SIMD 指令集的操作更为重要。这些指令集通常要求数据在内存中按照一定的对齐方式排列,以便能够一次性处理多个数据。

大小端存储

数据在内存中是按照字节进行存储,但是有些数据类型的长度是超过 1 个字节的,比如 C/C++中,short 类型一般是 2 个字节,int 类型一般 4 个字节等,存在着一个如何安排多个字节数据中各字节存放顺序的问题。

  • 大端存储:大端模式,是指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中,这样的存储模式有点儿类似于把数据当作字符串顺序处理:地址由小向大增加,而数据从高位往低位放,更符合人们阅读的习惯。

  • 小端存储:小端模式,是指数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中。

假设目前有一个 4 字节数据为 0x12 34 56 78,大端模式按照地址从低到高的顺序为 0x12 | 0x34 | 0x56 | 0x78,小端模式按照地址从低到高的顺序则为 0x78 | 0x56 | 0x34 | 0x12,计算机总是从内存低地址到高地址的顺序,按字节读取。

无论是大端存储还是小端存储,两者各有其优缺点。

大端模式优点:符号位在所表示的数据的内存的第一个字节中,便于快速判断数据的正负和大小。

小端模式优点:

  1. 内存的低地址处存放低字节,所以在强制转换数据时不需要调整字节的内容(比如把 int 的 4 字节强制转换成 short 的 2 字节时,就直接把 int 数据存储的前两个字节给 short 就行,因为其前两个字节刚好就是最低的两个字节,符合转换逻辑);

  2. CPU 做数值运算时从内存中依顺序依次从低位到高位取数据进行运算,直到最后刷新最高位的符号位,这样的运算方式会更高效。

张量数据布局

张量的数据维度

如下图所示,张量可以有零维,一维,二维,三维等等多种形式,张量可以看作是一个多维数组,其在内存中排布为按字节存储。

张量示意图

零维张量只有一个数,我们称为标量。一维张量有多个数,我们称为向量,这两者在内存中的存储并没有什么疑议,是按顺序存储。二维张量是一个矩阵,其有两个维度,那么在内存中排布是按照行的维度,还是按照列的维度优先进行存储,这个也就是我们接下来要讲的行优先排布方式与列优先排布方式。

在 AI 研究中,经常会有图片格式的数据的存在,如果其是彩色图像,那么其每个像素点包括[r,g,b]三个通道,此时就需要三个维度来进行描述,那么其在内存排布的时候是优先行,列还是通道进行存储呢,接下来我们来详细介绍一下高维张量在数据中的排布方式。

行/列优先排布方式

如下图的左侧所示,我们针对的案例是一个 $3\times 2\times 2 \quad\quad\quad$ 的三维张量,在图形中它可以轻松表示为三个维度,但是在计算机内存里存储的时候,是线性的存储,也就是说所有三个维度的元素都被存储到了一行。下图右侧所示为行优先排布方式,按行的顺序依次存储红行橙行,然后第二个通道绿行蓝行这些颜色的元素。

3 维张量行优先示意图

下图为列优先排布方式,按列的顺序以红橙红橙红橙的排布方式,第二个通道绿蓝绿蓝绿蓝的排布方式进行存储。

3 维张量列优先示意图

行优先存储和列优先存储并没有绝对的好坏关系,相对比较通用的结论是:对于行优先遍历的,使用行优先存储,对于列优先遍历的,使用列优先存储。相邻操作访存地址应该尽可能接近。

通常根据这个原则去排布数据能够得到较优的访存。这是由缓存的结构决定的。这个原则被称为访存的空间局部性,也即相近的代码(指令)最好访问相邻的数据,这样硬件能够提供更好的性能。

三维张量的数据布局方式实际上并不止行优先排布方式和列优先排布方式,按照排列组合来进行计算,三个维度按顺序排列共有六种排列方式,如下图所示,我们将三个维度按照横行,列,通道分别定义为 D1,D2,D3,那么按照图示我们有 D1,2,3、D1,3,2、D2,1,3、D2,3,1、D3,1,2、D3,2,1 足足六种排列方式,可见高维张量在内存中的数据排布方式的选择相当复杂和多样。

3 维张量数据布局方式列举图

NCHW 与 NHWC

在深度学习领域中,多维数据通过多维数组存储,比如卷积神经网络的特征图通常用四维数组保存:四个维度分别为“N”batch 批量大小,一般指图像数量,“C”channels 特征图通道数,“H”height 特征图的高度,和“W”width 特征图的宽度。

我们可以将数据分为多个维度,然而对于计算机而言,数据的存储只能是线性的,数据的不同排布方式会导致数据访问特性不一致,所以为了考虑程序的执行性能,我们接下来讨论在哪些情况下数据排布方式适合 NCHW,哪些情况下适合 NHWC。

NCHW 格式

下面,我们来举个 NCHW 数据排布方式的例子,如下图所示,这个例子中的图片分为红绿蓝三个通道,假设我们使用的是"NCHW"的数据排布方式,这里我们先将各方向的定义在这个图中详细说明,1 2 3 这个方向为 W,1 4 这个方向为 H,1 7 13 这个方向为 C,N 方向只有一个图片,暂时不讨论。

NCHW 示意图

因此,"NCHW"的数据排布方式,是先取 W 方向的数据,即 123,再取 H 方向的数据,即 123 456,再取 C 方向的数据,即 123456 789/10/11/12 13/14/15/16/17/18,在计算机中存储时即为图示下侧的序列。

简单地来说,也就是先在一个通道中,按照 W 方向/H 方向存储数据,接着再到剩余通道中按同样方式存储数据,其突出特点是同一个通道的数值连续排布,更适合需要对每个通道单独运算的操作,如 MaxPooling 最大池化操作,"NCHW"的计算时需要的存储更多,一次存储对应一个通道的数据,适合 GPU 运算,正好利用了 GPU 内存带宽较大并且并行性强的特点,其访存与计算的控制逻辑相对简单。

如下图所示,按照"NCHW"的数据排布方式,目标是计算灰度值,那么我们需要先将通道一的数据加载进内存,乘以 0.299,然后每次计算都可能需要加载一整个完整通道的数据,通道二所有数据值乘以 0.587,通道三所有数据值乘以 0.114,最后将三个通道结果相加得到灰度值,三个操作是独立的,可以在 GPU 上并行完成。

NCHW 计算灰度值示意图

NHWC 格式

同样的图片,假设我们使用的是"NHWC"的数据排布方式,按照上文定义的方向,我们先取 C 方向的数据,即 17/13,再取 W 方向的数据,即 17/13 28/14 39/15,再取 H 方向的数据,即 17/13 28/14 39/15 4/10/16 5/11/17 6/12/18。

在计算机中存储时即为下图所示下侧的序列,简单地来说,先把不同通道中同一位置的元素存储,再按照 W 方向/H 方向按照同样方式存储数据,其突出特点为不同通道中的同一位置元素顺序存储,因此更适合那些需要对不同通道的同一数据做某种运算的操作。

NHWC 示意图

如“Conv1x1”1x1 卷积操作:"NHWC"更适合多核 CPU 运算,CPU 的内存带宽相对较小,每个像素计算的时延较低,临时空间也很小,有时计算机采取异步的方式边读边算来减小访存时间,计算控制灵活且复杂。如下图所示,按照"NHWC"的数据排布方式,目标是计算灰度值,假设我们现在有 3 个 cpu 的核,那么就可以通过 3 个核分别并行处理这三个通道的同一位置元素,最后进行累加得到灰度值。

NHWC 计算灰度值示意图

AI 框架排布

常用的 AI 框架中默认使用 NCHW 的有 caffe、NCNN、PyTorch、mxnet 等,默认使用 NHWC 的有 TensorFlow、OpenCV 等,设置非默认排布格式只需要修改一些参数即可。

非连续与连续

如果元素在存储的逻辑结构上相邻,在存储的物理结构中也相邻,则称为连续存储的张量。如果元素在存储的逻辑结构上相邻,但是在存储的物理结构中不相邻,则称为不连续存储的张量,即非连续张量。如下图所示,元素 123456 在存储逻辑上 12 相邻,23 相邻,34 相邻等等,其在存储的物理结构上也相邻,这就是连续张量。

连续张量示意图

我们对其进行了转置操作,但实际上并没有改变其实际的存储,换句话说,交换维度后的张量与原始张量共享同一块内存,那么此时元素在存储逻辑上 14 相邻,42 相邻,25 相邻等等,但其在存储的物理结构上还是 12 相邻,23 相邻。

如下图所示,即为非连续张量,转置操作、索引操作、部分赋值操作、重新排序操作以及对非连续内存的张量进行进一步操作,这些操作都会导致张量的内存变为非连续。对不连续存储的张量执行连续变换,也就是重新开辟内存,按逻辑结构填入对应的物理结构。

非连续张量示意图

如果您想了解更多AI知识,与AI专业人士交流,请立即访问昇腾社区官方网站https://www.hiascend.com/ 或者深入研读《AI系统:原理与架构》一书,这里汇聚了海量的AI学习资源和实践课程,为您的AI技术成长提供强劲动力。不仅如此,您还有机会投身于全国昇腾AI创新大赛和昇腾AI开发者创享日等盛事,发现AI世界的无限奥秘~

目录
相关文章
|
2天前
|
机器学习/深度学习 人工智能
SNOOPI:创新 AI 文本到图像生成框架,提升单步扩散模型的效率和性能
SNOOPI是一个创新的AI文本到图像生成框架,通过增强单步扩散模型的指导,显著提升模型性能和控制力。该框架包括PG-SB和NASA两种技术,分别用于增强训练稳定性和整合负面提示。SNOOPI在多个评估指标上超越基线模型,尤其在HPSv2得分达到31.08,成为单步扩散模型的新标杆。
35 10
SNOOPI:创新 AI 文本到图像生成框架,提升单步扩散模型的效率和性能
|
4天前
|
机器学习/深度学习 存储 人工智能
【AI系统】模型转换基本介绍
模型转换技术旨在解决深度学习模型在不同框架间的兼容性问题,通过格式转换和图优化,将训练框架生成的模型适配到推理框架中,实现高效部署。这一过程涉及模型格式转换、计算图优化、算子统一及输入输出支持等多个环节,确保模型能在特定硬件上快速、准确地运行。推理引擎作为核心组件,通过优化阶段和运行阶段,实现模型的加载、优化和高效执行。面对不同框架的模型文件格式和网络结构,推理引擎需具备高度的灵活性和兼容性,以支持多样化的应用场景。
16 4
【AI系统】模型转换基本介绍
|
3天前
|
人工智能 前端开发 PyTorch
【AI系统】动态图与静态图转换
从 TensorFlow、PyTorch 到 PaddlePaddle、MindSpore、MegEngine,主流 AI 框架经历了动静分离、动静结合到动静统一的发展过程。这些框架通过动态图转静态图技术,实现了计算效率与灵活性的平衡,显著提升了 AI 开发效率和产品应用的便利性。
34 14
|
3天前
|
机器学习/深度学习 人工智能 PyTorch
【AI系统】计算图原理
本文介绍了AI框架中使用计算图来抽象神经网络计算的必要性和优势,探讨了计算图的基本构成,包括标量、向量、矩阵、张量等数据结构及其操作,并详细解释了计算图如何帮助解决AI工程化中的挑战。此外,文章还通过PyTorch实例展示了动态计算图的特点和实现方法,包括节点(张量或函数)和边(依赖关系)的定义,以及如何通过自定义Function实现正向和反向传播逻辑。
28 7
|
12天前
|
存储 人工智能 编译器
【AI系统】昇腾数据布局转换
华为昇腾NPU采用独特的NC1HWC0五维数据格式,旨在优化AI处理器的矩阵乘法运算和访存效率。此格式通过将C维度分割为C1份C0,适应达芬奇架构的高效计算需求,支持FP16和INT8数据类型。此外,昇腾还引入了NZ分形格式,进一步提升数据搬运和矩阵计算效率。AI编译器通过智能布局转换,确保在不同硬件上达到最优性能。
38 3
|
17天前
|
机器学习/深度学习 人工智能 算法
强化学习在游戏AI中的应用,从基本原理、优势、应用场景到具体实现方法,以及Python在其中的作用
本文探讨了强化学习在游戏AI中的应用,从基本原理、优势、应用场景到具体实现方法,以及Python在其中的作用,通过案例分析展示了其潜力,并讨论了面临的挑战及未来发展趋势。强化学习正为游戏AI带来新的可能性。
50 4
|
16天前
|
机器学习/深度学习 人工智能 自然语言处理
深度学习中的兼容性函数:原理、类型与未来趋势
深度学习中的兼容性函数:原理、类型与未来趋势
|
2月前
|
机器学习/深度学习 人工智能 自然语言处理
扩散引导语言建模(DGLM):一种可控且高效的AI对齐方法
DGLM(Diffusion Guided Language Modeling)是一种新型框架,结合了自回归模型的流畅性和扩散模型的灵活性,解决了现有引导生成方法的局限性。DGLM通过扩散网络生成语义提案,并使用轻量级提示生成器将嵌入转化为软提示,引导自回归解码器生成文本。该方法无需微调模型权重,易于控制新属性,并在多个基准数据集上表现出色。实验结果显示,DGLM在毒性缓解、情感控制和组合控制等方面优于现有方法,为可控文本生成提供了新的方向。
52 10
扩散引导语言建模(DGLM):一种可控且高效的AI对齐方法
|
3月前
|
人工智能 算法 自动驾驶
用AI自动设计智能体,数学提分25.9%,远超手工设计
【9月更文挑战第18天】《智能体自动设计(ADAS)》是由不列颠哥伦比亚大学等机构的研究者们发布的一篇关于自动化设计智能体系统的最新论文。研究中提出了一种创新算法——“Meta Agent Search”,此算法通过迭代生成并优化智能体设计,从而实现更高效的智能体系统构建。实验表明,相比人工设计的智能体,Meta Agent Search生成的智能体在多个领域均有显著的性能提升。然而,该方法也面临着实际应用中的有效性与鲁棒性等挑战。论文详细内容及实验结果可于以下链接查阅:https://arxiv.org/pdf/2408.08435。
96 12
|
4月前
|
机器学习/深度学习 编解码 自然语言处理
Sora视频重建与创新路线问题之更高解析度的视频输出该如何实现
Sora视频重建与创新路线问题之更高解析度的视频输出该如何实现