乐趣区

关于paddle:飞桨框架v24-API新升级全面支持稀疏计算图学习语音处理等任务

‍‍
作者 | 飞桨

导读

飞桨框架 2.4 版本迎来正式公布啦!相比飞桨框架 2.3 版本,飞桨框架 v2.4 减少了 167 个功能性 API,新增稠密计算 (paddle.sparse)、图学习(paddle.geometric) 和语音解决 (paddle.audio) 等更多畛域 API,同时也进一步欠缺了 loss 计算、张量计算、分布式和视觉变换等类别的 API,在提供了更加丰盛的 API 体系的同时更好地反对深度学习稠密计算、图学习、语音畛域的疾速迭代和翻新、一直扩大对 3D 点云、Sparse Transformer 等场景利用的反对,减速翻新,让基于深度学习的利用开发更简略!

全文 9947 字,预计浏览工夫 25 分钟.

一、全面反对支流模型稠密化训练及推理

以后越来越多的场景有稠密计算的需要,例如 3D 点云图像处理和 NLP 中的稠密 Attention 等。神经网络的稠密化能够进步网络的性能,缩小计算量及内存 / 显存的占用,已成为深度学习的钻研热门之一。飞桨 v2.4 新增了如下稠密类 API,反对支流稠密模型的训练和推理,并反对多种稠密 Tensor 格局及稠密 Tensor 与浓密 Tensor 的混合计算,同时其名称和应用形式与惯例浓密 Tensor 的 API 保持一致,不便记忆且容易上手。

稠密根底计算 API:

  • 一元计算:

    paddle.sparse.sin/sinh/tan/tanh/expm1/log1p/pow/square/sqrt/abs/cast/neg…

  • 二元计算:

    paddle.sparse.add/substract/multiply/divide…

  • 矩阵和向量计算:

    paddle.sparse.matmul/masked\_matmul/addmm/mv…

  • 数据变形:

    paddle.sparse.transpose/reshape…

稠密组网 API:

  • 网络层:

    paddle.sparse.nn.Conv3D/SubmConv3D/MaxPool3D/BatchNorm…

  • 激活层:

    paddle.sparse.nn.ReLU/ReLU6/LeakyReLU/Softmax…

Part1 笼罩稠密计算支流利用场景

3D 点云指标检测

CenterPoint 是一种物体检测器,以点云作为输出,将三维物体在 Bird-View 下的中心点作为关键点,基于关键点检测的形式回归物体的尺寸、方向和速度。

飞桨框架 v2.4 残缺提供了这类模型须要的稠密 SubmanifoldConv3D/Conv3D、稠密 BatchNorm 和稠密 ReLU 等 API。模型的训练评估、动转静及推理的各项性能均已齐全实现,欢送试用。实测比业界同类竞品提速 4%,训练精度晋升 0.2%。

  • CenterPoint 模型介绍

https://github.com/PaddlePadd…

Sparse Transformer

稠密 Transformer 与经典的浓密 Transformer 相比,能反对更长的输出序列,失去更好的网络性能。

稠密 Attention 的外围计算逻辑为:

飞桨框架 v2.4 提供稠密矩阵乘、稠密 softmax 等运算,可残缺反对 SparseTransformer 的运算。在高稠密度场景下,相比应用 DenseTensor 提速 105.75%,相比同类产品稠密计算提速 4.01%~58.55%,极致节俭显存并晋升性能。

Part2 反对多种稠密 Tensor 格局及稠密 Tensor 与浓密 Tensor 的混合计算 **

飞桨 API 反对最常应用的稠密数据 COO 和 CSR 格局。COO 为稠密数据坐标格局,CSR 为压缩行信息格式。不同格局的稠密数据应用场景不同,其中 SparseConv3D 更适宜解决 COO 格局的数据,SparseTransformer 中有较多取整行的操作,更适宜解决 CSR 格局的数据,能更好升高计算复杂度。尽管这些 API 有不同的格局偏向,然而飞桨稠密 API 在设计时,每个都尽可能反对多种稠密格局,这样在不同模型场景下解决不同的数据格式时都能够应用雷同的 API,不必批改代码,更灵便且更能极致晋升性能。

以 ReLU 激活函数为例,其反对解决不同的稠密 Tensor:

# 稠密 COO Tensorcoo = paddle.sparse.sparse_coo_tensor(indices = [[0, 1, 2],                    [1, 2, 0]],        values  = [1., 2., 3.],        shape   = [3, 3])out = paddle.sparse.nn.functional.relu(coo)# 稠密 CSR Tensorcsr = paddle.sparse.sparse_csr_tensor(crows  = [0, 1, 2, 3],        cols   = [1, 2, 0],        values = [1., 2., 3.],        shape  = [3, 3])out = paddle.sparse.nn.functional.relu(csr)

除了反对不同的稠密格局外,对于二元计算及矩阵向量计算等 API,还反对多种稠密格局和惯例的浓密格局 (Dense Tessor) 的混合计算,网络能够局部应用传统组网,局部应用稠密,更不便已有模型的优化:

# COO 与 Dense 矩阵乘,返回浓密 Tensorcoo = paddle.sparse.sparse_coo_tensor(indices = [[0, 1, 2],                    [1, 2, 0]],        values  = [1., 2., 3.],        shape   = [3, 3])dense = paddle.rand([3, 2])out = paddle.sparse.matmul(coo, dense)# CSR 与 Dense 矩阵乘,返回浓密 Tensorcsr = paddle.sparse.sparse_csr_tensor(crows  = [0, 1, 2, 3],        cols   = [1, 2, 0],        values = [1., 2., 3.],        shape  = [3, 3])dense = paddle.rand([3, 2])out = paddle.sparse.matmul(csr, dense)# Dense 与 Dense 矩阵乘,返回稠密 Tensorx = paddle.rand([3, 5])y = paddle.rand([5, 4])mask = paddle.sparse.sparse_csr_tensor(crows = [0, 2, 3, 5],        cols  = [1, 3, 2, 0, 1],        values= [1., 2., 3., 4., 5.],        shape = [3, 4])out = paddle.sparse.masked_matmul(x, y, mask)

Part3 名称和应用形式与惯例浓密 Tensor 的 API 保持一致,不便记忆且容易上手

个别模型中应用的 API 都是解决浓密数据 (Dense Tensor) 的 API。飞桨 SparseAPI 在设计之初就思考尽可能升高了解老本,与惯例解决浓密数据 (Dense Tensor) 的 API 放弃格调统一,不便用户疾速上手。

以模型中一段 ResNet 稠密网络的代码为例:

import paddlefrom paddle import sparsefrom paddle.sparse import nnclass SparseBasicBlock(paddle.nn.Layer):    def __init__(self,            in_channels,            out_channels,            stride=1,            downsample=None,):        super(SparseBasicBlock, self).__init__()        self.conv1 = nn.SubmConv3D(                        in_channels,                        out_channels,                        kernel_size=3,                        stride=stride,                        padding=1)        self.bn1 = nn.BatchNorm(out_channels, epsilon=1e-3, momentum=0.01)        self.relu = nn.ReLU()        self.conv2 = nn.SubmConv3D(                        out_channels,                        out_channels,                        kernel_size=3,                        stride=stride,                        padding=1)        self.bn2 = nn.BatchNorm(out_channels, epsilon=1e-3, momentum=0.01)        self.downsample = downsample    def forward(self, x):        identity = x        out = self.conv1(x)        out = self.bn1(out)        out = self.relu(out)        out = self.conv2(out)        out = self.bn2(out)        if self.downsample is not None:            identity = self.downsample(x)        out = sparse.add(out, identity)        out = self.relu(out)        return out

能够看到,ResNet 稠密网络的代码和惯例 ResNet 网络代码简直没有差异,只须要通过 paddle.sparse.* 代替 paddle.* 即可,源于飞桨 Sparse 系列 API 在整体应用上与 Dense 系列 API 高度一致。如果可能减少 import 门路替换,甚至原网络代码都无需改变。例如通过 frompaddle.sparseimportnn,则可放弃与原来的 nn.* 写法完全一致,更易于上手。

二、新增图学习类 API,反对高效图学习计算

近几年,图学习相干钻研倒退迅速,在自然语言解决、计算机视觉、举荐零碎、生物化学等畛域具备较为宽泛的利用和倒退。图学习逐步成为机器学习畛域的关键技术,本次飞桨框架 v2.4 新增 paddle.geometric 图学习类 API,提供更好的图学习建模和高效图学习计算体验。

Part1 高效图消息传递

现有的大多数图学习框架在进行图模型设计时,通常采纳图消息传递机制的经典范式。飞桨框架 v2.4 新增图学习消息传递 API,反对高效图消息传递。其中,新增的 send\_u\_recv、send\_ue\_recv、send\_uv 共计 3 个 API,通过实现原子级别的音讯发送与接管,大大减少了冗余的两头显存变量占用,从而带来显著的显存收益。在浓密图场景下,GCN、GAT 等经典图神经网络模型可节俭 50%+ 的显存,并可进一步晋升训练速度约 20%。各个 send\_recv 系列 API 反对 sum、mean、max、min 共计 4 个音讯聚合形式,在节点特色与边特色交互时则反对 add、sub、mul、div 共计 4 种计算形式。应用形式示例如下:

import paddlex = paddle.to_tensor([[0, 2, 3], [1, 4, 5], [2, 6, 7]], dtype="float32")y = paddle.to_tensor([1, 1, 1, 1], dtype="float32")indexes = paddle.to_tensor([[0, 1], [1, 2], [2, 1], [0, 0]], dtype="int32")src_index, dst_index = indexes[:, 0], indexes[:, 1]out = paddle.geometric.send_ue_recv(x, y, src_index, dst_index, message_op="add", reduce_op="sum")

Part2 高性能图采样

图采样步骤对于图采样模型特地是在大图场景下是十分有必要的,但同时也是图模型训练的性能瓶颈。本次新增了高性能图采样 API,反对高并发图采样,放慢图采样模型采样和训练效率,经典图模型 Graphsage 的采样速度可晋升 32~142 倍,训练速度可晋升 12~57 倍。除了反对纯 GPU 采样和 CPU 采样之外,还能够反对借助 UVA(Unified Virtual Addressing,对立虚构寻址)技术,将图构造搁置在内存中进行 GPU 采样,该实现形式在大图场景下十分无效。简略示例如下:

import paddlefrom paddle.fluid import corerow = np.array([3, 7, 0, 9, 1, 4, 2, 9, 3, 9, 1, 9, 7])colptr = np.array([0, 2, 4, 5, 6, 7, 9, 11, 11, 13, 13])row = core.eager.to_uva_tensor(row)colptr = core.eager.to_uva_tensor(colptr)nodes = paddle.to_tensor([0, 8, 1, 2])sample_size = 2# 街坊采样 API 的输出要求图构造信息为 CSC 格局 neighbors, neighbor_count = paddle.geometric.sample_neighbors(row, colptr, nodes, sample_size=sample_size)# 生成重编号后的边 reindex_src, reindex_dst, out_nodes = paddle.geometric.reindex_graph(nodes, neighbors, neighbor_count)

三、新增语音畛域类 API

近几年,智能语音畛域疾速迅速,深度学习畛域产生了很多语音训练解决根底能力的需要。本次飞桨框架 v2.4 新增 paddle.audio 类 API 提供了语音根底解决能力,晋升了语音建模和学习便捷性。

Part1 高效的特征提取模块

特征提取模块是深度学习语音畛域最根底的模块,特地在大规模数据训练和推理过程中,其速度为一个性能瓶颈。本次新增 MFCC、Spectrogram、LogMelSpectrogram 等特征提取 API,反对 GPU 计算,相比 CPU 实现解决性能晋升 15 倍以上,可大幅晋升语音模型训练 GPU 利用率,达到疾速训练和推理的成果。应用示例如下:

import paddlefrom paddle.audio.features import LogMelSpectrogram# 设置音频相干参数 sample_rate = 16000wav_duration = 0.5num_channels = 1num_frames = sample_rate * wav_durationwav_data = paddle.linspace(-1.0, 1.0, num_frames) * 0.1waveform = wav_data.tile([num_channels, 1])# 设置特色提起器相干参数 feature_extractor = LogMelSpectrogram(sr=sample_rate, n_fft=512, window = 'hann', power = 1.0)feats = feature_extractor(waveform)

Part2 音频解决根底模块

深度学习语音畛域,除了传统的经典模型外,还有很多语音前端解决的试验须要进行,定制化语音特色的需要应运而生。本次新增窗函数、离散余弦变换等特征提取根底 API,不便用户自定义语音特征提取,不便实现定制化需要。应用示例如下:

import paddle#cosine 窗函数示例 n_fft = 512cosine_window = paddle.audio.functional.get_window('cosine', n_fft)# 高斯窗函数 std = 7gaussian_window = paddle.audio.functional.get_window(('gaussian',std), n_fft)# 离散余弦变换示例 n_mfcc = 23n_mels = 257dct = paddle.audio.functional.create_dct(n_mfcc, n_mels)

Part3 语音 IO 模块

对各种语音数据进行读取是音频解决的根底。事实场景中语音的编码格局各式各样,所以须要 IO 模块灵便地反对多种格局。飞桨框架 v2.4 新增语音 IO 模块,提供 2 种音频 I /Obackend,反对 6 种编解码,便捷地实现语音数据的加载。应用示例如下:

import osimport paddle# 设置相干参数,生成示例音频 sample_rate = 16000wav_duration = 0.5num_channels = 1num_frames = sample_rate * wav_durationwav_data = paddle.linspace(-1.0, 1.0, num_frames) * 0.1waveform = wav_data.tile([num_channels, 1])base_dir = os.getcwd()filepath = os.path.join(base_dir, "test.wav")# 保留和提取音频信息 paddle.audio.save(filepath, waveform, sample_rate)wav_info = paddle.audio.info(filepath)#wav_info 中会有 sample_rate, num_frames, num_channels 等信息

Part4 语音分类数据集

在训练深度学习语音模型的时候,不便地下载解决数据集会为模型训练带来便捷。飞桨框架 v2.4 新增 TESS、ESC50 语音分类数据集。用户不用进行简单的预处理,能够不便地启动训练流程,便捷地实现训练。用户也能够按照此代码,不便定制本人的数据集。应用示例如下:

import paddlemode = 'dev'esc50_dataset = paddle.audio.datasets.ESC50(mode=mode,                                        feat_type='raw')for idx in range(5):    audio, label = esc50_dataset[idx]    # do something with audio, label    print(audio.shape, label)    # [audio_data_length] , label_idesc50_dataset = paddle.audio.datasets.ESC50(mode=mode,                                        feat_type='mfcc',                                        n_mfcc=40)for idx in range(5):    audio, label = esc50_dataset[idx]    # do something with mfcc feature, label    print(audio.shape, label)    # [feature_dim, length] , label_id

四、其它新增的 API

除了以上形容的几类新增 API,飞桨框架 v2.4 还对已有的一些 API 类别进行了裁减。

Part1 loss 计算 API

为了更不便地反对各种组网的 loss 计算需要,飞桨框架 v2.4 裁减了多个 loss 计算的 API,包含:

  • paddle.nn.functional.cosine\_embedding\_loss依据 label 类型,计算 2 个输出之间的 CosineEmbedding 损失。
  • paddle.nn.functional.soft\_margin\_loss计算输出和 label 间的二分类 softmargin 损失。
  • paddle.nn.functional.multi\_label\_soft\_margin\_loss计算输出和 label 间的多分类最大熵损失。
  • paddle.nn.functional.triplet\_margin\_losspaddle.nn.functional.triplet\_margin\_with\_distance\_loss 计算输出与正样本和负样本之间的绝对相似性,后者可自定义间隔计算函数。

Part2 张量计算 API

飞桨框架 2.3 之前的版本实现了很多根底的张量计算 API,飞桨框架 2.4 版本基于这些根底 API,通过组合的形式裁减了张量计算 API,不便用户间接应用,包含:

  • 新增 paddle.sgn 取复数的单位值和实数的符号。
  • 新增 paddle.count\_nonzero 沿给定的轴统计输出张量中非零元素的个数。
  • 新增 paddle.take 将输出张量视为一维,返回指定索引上的元素汇合。
  • 新增 paddle.bucketize 依据给定的一维桶划分,失去输出张量对应的桶索引。
  • 新增 paddle.triu\_indicespaddle.tril\_indices别离取二维张量 (矩阵) 中上 / 下三角矩阵元素的行列坐标。
  • 新增 paddle.heaviside 计算赫维赛德阶跃函数。
  • 新增 paddle.nanmedianpaddle.nanquantile疏忽张量中的 nan 值,别离计算出中位数和分位数值。

Part3 分布式 API

新增 10 个分布式通信 API,如 paddle.distributed.communication.stream.all\_gather 等,反对在主计算流上做通信,升高了在流切换、事件期待时的性能开销,可能使分布式 GPT3 模型训练提速 11.35%。

Part4 视觉变换 API

基于飞桨根底 API,裁减了 paddle.vision.transforms 中视觉变换 API,包含:

  • paddle.vision.transforms.affinepaddle.vision.transforms.RandomAffine 对图像进行仿射变换,后者应用随机产生的仿射变换矩阵参数。
  • paddle.vision.transforms.erasepaddle.vision.transforms.RandomErasing 应用给定的值擦除输出图像中的像素,前者是选定区域,后者是随机区域。
  • paddle.vision.transforms.perspectivepaddle.vision.transforms.RandomPerspective 对图像进行透视变换,前者是选定区域,后者是随机区域,两者都能够抉择插值办法。

除了下面的介绍外,飞桨框架 v2.4 还裁减了一些组网类 (如 paddle.nn.ChannelShuffle)、辅助类(如 paddle.iinfo) 等 API,具体列表可 点击下方链接 或者 浏览链接 参考 Release Note。

  • Release Note 地址

https://github.com/PaddlePadd…

五、结语

飞桨框架的建设除了来自百度的工程师外,还有一批酷爱飞桨、酷爱开源的开发者,他们正在用本人的形式参加飞桨框架的建设,与飞桨独特成长。在飞桨框架 v2.4 中,有约三分之一的新增 API 由社区开发者奉献,飞桨的凋敝离不开宽广开发者的应用与反对。

飞桨框架 v2.4 逐步形成了成熟的 API 开发范式,框架的开发难度继续升高。配合官网提供的规范开发环境,飞桨社区开发者能够更加顺畅地实现飞桨 API 开发与奉献。具体体现在:

  • 简化 API 开发步骤:飞桨框架 v2.4 实现了根底框架算子体系重构,结构高可复用的 PHI 算子库(Paddle HIgh reusability operator library),反对基于已有的算子内核以及 Kernel Primitives API 组合实现新的算子,反对插件式接入新硬件或者新减速库。PHI 算子库的成熟,晋升了飞桨 API 的开发效率,并造成了通用的 API 开发流程,使得开发者能够更加简洁流畅地参加飞桨 API 的开发与奉献。
  • 公布规范 API 奉献指南:飞桨框架 v2.4 造成了规范的 API 奉献指南,包含奉献流程与操作指南、API 设计文档模板、API 代码模板、API 文档写作标准,为飞桨社区开发者提供清晰的文档指引与辅助,使得开发者能够疾速上手。
  • 提供规范开发环境:飞桨 AIStudio 平台推出规范开发环境,为开发者提供飞桨镜像环境、在线 IDE 与专属 GPU 算力,登录即可开发调试,免去环境配置与算力限度,随时随地参加飞桨框架的开发与奉献。

飞桨框架 v2.4 提供了更加丰盛的 API 体系,不仅更好地反对深度学习稠密计算、图学习、语音畛域的疾速迭代和翻新,而且一直扩大对 3D 点云、Sparse Transformer 等场景利用的反对,同时也一直优化飞桨 API 的应用体验,更好地反对业界论文中模型的实现,减速翻新,让基于深度学习的利用开发更简略!

—— END——

举荐浏览:

百度工程师带你理解 Module Federation

巧用 Golang 泛型,简化代码编写

Go 语言 DDD 实战高级篇

Diffie-Hellman 密钥协商算法探索

贴吧低代码高性能规定引擎设计

浅谈权限零碎在多利熊业务利用

退出移动版