Pytorch v0.3.0版本发布--pytorch性能优化提速,支持ONNX,高阶梯度以及SparseAdam优化器

Song • 8188 次浏览 • 0 个回复 • 2017年12月13日

目录

  • 突破变化:删除reinforce(),关于此函数你可以在自动差异化包 - torch.autograd找到
  • 新功能
  • 未减少的损失
  • autograd引擎的分析器
  • 更多的功能支持高阶梯度
  • 优化器中的新功能
  • 新的图层和nn功能
  • 新的张量功能和特点
  • 其他补充

  • API更改
  • 性能改进
  • 大大减少了框架开销(帮助小型模型)
  • 比Softmax / LogSoftmax快4倍到256倍
  • 更多...
  • 框架互操作性
  • DLPack互操作性
  • 模型出口到ONNX(运送PyTorch到Caffe2,CoreML,CNTK,MXNet,Tensorflow)
  • 错误修正(很多)

突破变化

随机功能,即Variable.reinforce()由于功能有限和性能影响广泛而被删除。随机函数的动机是避免对采样值进行记录。实际上,由于各种原因,用户仍然在代码中记录。我们构建了一个替代的,同样有效的API,但没有一个合理的弃用路径到新的API。因此这个删除是一个突破性的变化。

我们引入了torch.distributions包来替代随机函数。

以前的代码通常是这样的:

probs = policy_network(state)
action = probs.multinomial()
next_state, reward = env.step(action)
action.reinforce(reward)
action.backward()

这是新的等效代码:

probs = policy_network(state)
# NOTE: categorical is equivalent to what used to be called multinomial
m = torch.distributions.Categorical(probs)
action = m.sample()
next_state, reward = env.step(action)
loss = -m.log_prob(action) * reward
loss.backward()

新功能

未减少的损失

现在,一些损失函数可以计算每个样本的小批量损失

  • 默认情况下,PyTorch在小批量上累计损失,并返回一个标量损失。这对用户是有限制的。
  • 现在,损失函数的一个子集允许指定reduce=False在小批量中为每个样品返回单个损失
  • 例:loss = nn.CrossEntropyLoss(..., reduce=False)
  • 目前支持的损失:MSELossNLLLossNLLLoss2dKLDivLossCrossEntropyLossSmoothL1LossL1Loss
  • 下一个版本将包含更多的损失函数

autograd引擎中的一个内置的分析器

我们构建了一个低级别的分析器来帮助您识别模型中的瓶颈

让我们从一个例子开始:

>>> x = Variable(torch.randn(1, 1), requires_grad=True)
>>> with torch.autograd.profiler.profile() as prof:
...     y = x ** 2
...     y.backward()
>>> # NOTE: some columns were removed for brevity
... print(prof)
--------------------------------  ----------  ---------
Name                               CPU time   CUDA time
-------------------------------   ----------  ---------
PowConstant                        142.036us    0.000us
N5torch8autograd9GraphRootE         63.524us    0.000us
PowConstantBackward                184.228us    0.000us
MulConstant                         50.288us    0.000us
PowConstant                         28.439us    0.000us
Mul                                 20.154us    0.000us
N5torch8autograd14AccumulateGradE   13.790us    0.000us
N5torch8autograd5CloneE              4.088us    0.000us

更高阶梯度

为以下图层添加了高阶渐变支持

  • ConvTransposeAvgPool1dAvgPool2dLPPool2dAvgPool3dMaxPool1dMaxPool2dAdaptiveMaxPoolAdaptiveAvgPoolFractionalMaxPool2dMaxUnpool1dMaxUnpool2dnn.UpsampleReplicationPad2dReplicationPad3dReflectionPad2d
  • PRELUHardTanhL1LossSoftSignELURReLUHardshrinkSoftplusSoftShrinkLogSigmoidSoftminGLU
  • MSELossSmoothL1LossKLDivLossHingeEmbeddingLossSoftMarginLossMarginRankingLossCrossEntropyLoss
  • DataParallel

优化器

  • optim.SparseAdam:实现适用于稀疏张量的Adam算法的懒惰版本。在这个变体中,只有在渐变中出现的时刻才会更新,只有渐变的那些部分才会应用于参数。
  • 优化器现在有一个add_param_group函数,可以让您将新的参数组添加到已构建的优化器中。

新的图层和nn功能

  • 添加了AdpativeMaxPool3dAdaptiveAvgPool3d
  • 增加了LPPool1d
  • F.pad现在支持:1d,2d,3d信号的“反射”和“复制”填充(3D,4D和5D张量)在nd信号上不断的填充
  • nn.Upsample现在适用于一维信号(即B x C x L张量)nearestlinear模式。
  • grid_sample现在允许通过填充边界值padding_mode="border"grid_sample期望在范围内的网格[-1, 1],并且如果值超出这些边界,0.0则默认应用用值填充。但在很多情况下,使用边界值(即最接近的有效值)有助于提高整体模型的准确性。
  • 介绍nn.utils.parameters_to_vectornn.utils.vector_to_parametersparameters_to_vector接收net.parameters()并返回包含所有参数的一维向量vector_to_parameters取一个扁平参数向量,并将这些值复制到网络参数中方便一些强化学习算法,如交叉熵法,TRPO等,需要将所有的网络参数作为一个大的矢量,修改它们,把修改后的矢量放回去。
  • 允许用户不指定某些输入维度,AdaptivePool*d并在运行时推断它们。例如:#目标输出大小为 10x7 m = nn.AdaptiveMaxPool2d(( None, 7))
  • CPU上的DataParallel容器现在是空操作(而不是错误)

新的张量功能和特点

  • 引入torch.erftorch.erfinv计算了张量中每个元素的误差函数和反函数误差。
  • 增加了对按位运算符的广播支持
  • 添加Tensor.puttorch.take类似于numpy.takenumpy.puttake函数可以让您线性索引为张量,而不必先将其视为一维张量。输出具有与指数相同的形状。put函数也使用线性索引将值复制到张量中。与numpy等价物的差异:numpy.take有一个可选的轴参数,其行为像index_select。这个axis说法还没有出现。numpy.put重复的价值,如果需要,使他们只要指数。此行为尚未复制。
  • 添加zeroszeros_like稀疏张量。
  • 1元素张量现在可以投射到Python标量。例如:int(torch.Tensor([5]))现在工作。

其他补充

  • 添加torch.cuda.get_device_nametorch.cuda.get_device_capability实现如下功能。例:
    >>> torch.cuda.get_device_name(0)
    'Quadro GP100'
    >>> torch.cuda.get_device_capability(0)
    (6, 0)
  • 如果设置torch.backends.cudnn.deterministic = True,则CuDNN卷积使用确定性算法
  • torch.cuda_get_rng_state_alltorch.cuda_set_rng_state_all引入,让您一次保存/加载随机数生成器的状态在所有GPU
  • torch.cuda.emptyCache()释放PyTorch的缓存分配器中的缓存内存块。当与其他进程共享GPU时,这是有用的长期运行ipython笔记本。

API更改

  • softmaxlog_softmax现在来dim指定,其中切片取供SOFTMAX操作的尺寸参数。dim也允许负面的维度(dim = -1将是最后一个维度)
  • torch.potrf (乔列斯基分解)现在可以区分和定义 Variable
  • 删除所有实例device_id并将其替换device,以使事物保持一致
  • torch.autograd.grad现在允许您指定在自动格式图中未使用的输入如果您使用allow_unused=True这个torch.autograd.grad输入/输出列表的大图中使用这将有用例如:
    x, y = Variable(...), Variable(...)
    torch.autograd.grad(x * 2, [x, y]) # errors
    torch.autograd.grad(x * 2, [x, y], allow_unused=True) # works
  • pad_packed_sequence现在允许padding_value可以使用而不是零填充的参数
  • Dataset现在有一个+运营商(使用ConcatDataset)。你可以做一些事情MNIST(...) + FashionMNIST(...),例如,你会得到一个包含两个样本的连接数据集。
  • torch.distributed.recv允许从任何发件人收到张量(因此src是可选的)。recv返回发件人的等级。
  • 添加zero_()Variable
  • Variable.shape返回张量的大小(现在与张量一致)
  • torch.version.cuda指定PyTorch编译的CUDA版本
  • random_CUDA添加缺少的功能。
  • torch.loadtorch.save现在可以获取一个pathlib.Path对象,这是一个标准的Python3类型的文件路径对象
  • 如果要将模型加载state_dict到另一个模型(例如,对预先训练的网络进行微调),load_state_dict则严格匹配参数的键名称。现在我们提供一个strict=False选项load_state_dict,只在其中的键匹配参数加载,并忽略其他参数键。
  • 补充nn.functional.embedding_bag说相当于nn.EmbeddingBag

性能改进

  • torch变量函数的开销大约为10微秒。通过使用我们的ATen库将大部分核心autograd公式移动到C ++中,这已经被降低到〜1.5微秒。这种加速模型非常小,比如在NLP中看到的小型LSTM和其他常见模型。
  • 在重写gpu内核之后,softmaxlog_softmax现在在GPU快4倍到 256 
  • 通过启用GPUDirect,分布式AllReducegloo后端)的性能提高了2.5倍到3倍
  • nn.Embeddingrenorm选项在GPU上要快得多。要嵌入维度100k x 128和批量大小为1024,速度要快33倍。
  • 现在所有的点对点操作都使用OpenMP,并获得多核CPU的好处
  • 增加专用的CUDA内核用于组卷积groups == nInputPlane(深度卷积)。对于测试的图层大小,加速范围从5倍到1000倍。有关更多详细信息以及此表,请参阅基准
  • 修复optim.SGD了稀疏梯度的内存使用情况(例如nn.Embedding(..., sparse=True)),将用户提供的测试脚本的使用量减少了10倍。
  • 可选的NNPack集成更快的CPU卷积(不是二进制文件的一部分)
  • 如果张力不能广播,则减少广播的开销
  • torch.nn.utils.weight_norm 在最右边的维度更快
  • 后面torch.norm加速〜1.5
  • 提高性能pack_padded_sequence
  • 添加一个单参数版本torch.arange。例如torch.arange(10)

框架互操作性

DLPack互操作性

DLPack张量是交叉框架张量格式。我们现在有torch.utils.to_dlpack(x)torch.utils.from_dlpack(x)DLPackTorch张量格式之间进行转换。转换有没有缓存所以非常高效。

模型导出到ONNX

ONNX是一种常见的模型交换格式,可以在Caffe2CoreMLCNTKMXNetTensorflow中执行。现在可以将类似ConvNetRNN(静态图)的PyTorch模型运送到ONNX格式。

  • 有一个新的模块torch.onnxhttp://pytorch.org/docs/0.3.0/onnx.html),它提供了用于导出ONNX模型的API
  • 本版本支持的操作是:addsub(非零不支持alpha),muldivcatmmaddmmnegtanhsigmoidmeanttransposeviewsplitsqueeze
  • expand(仅在广播ONNX运营商之前使用;例如,添加)
  • prelu(不支持输入通道的单个权重)
  • threshold(不支持非零阈值/非零值)
  • ConvConvTransposeBatchNormMaxPoolRNNDropoutConstantPadNdNegate
  • eluleaky_reluglusoftmaxlog_softmaxavg_pool2d
  • unfoldATen-Caffe2集成的实验支持)
  • Embedding(不支持可选参数)
  • RNN
  • FeatureDropout(不支持训练模式)
  • Index(支持常量整数和元组索引)

可用性改进

  • 张量/变量索引期间更有说服力的错误信息突变
  • 在没有尺寸的张量上添加适当的错误信息来指定尺寸
  • Conv * d输入形状检查的更好的错误信息
  • 用于LongTensor索引的更多用户友好的错误消息
  • Conv * d例程的更好的错误消息和参数检查
  • 试图从变量构造一个张量更合适
  • 如果您使用的是CUDA版本不足的PyTorch二进制文件,则会将a warning打印到用户。
  • 修复了不连贯的错误信息 load_state_dict
  • 修复了与稀疏张量类型不匹配的错误消息

Bug修复

Torch

  • 修复CUDA延迟初始化,以便在调用时不触发torch.manual_seed(而是在CUDA初始化时调用排队并运行)

张量

  • 如果x2Dx[[0, 3],]则需要触发高级索引。尾随的逗号不再需要,你可以做x[[0, 3]]
  • x.sort(descending=True)用于错误地拒绝张量。修正了在参数检查逻辑中允许这个错误。
  • numpy输入的张量构造函数: torch.DoubleTensor(np.array([0,1,2], dtype=np.float32))火炬现在将数组的内容复制到适当类型的存储中。如果类型匹配,它将共享底层数组(no-copy),用等价的语义来用另一个张量初始化一个张量。在CUDA上,torch.cuda.FloatTensor(np.random.rand(10,2).astype(np.float32))现在将通过复制工作。
  • ones_likezeros_like现在创建相同的设备上张量与原张量
  • torch.multinomialCPU上将重新形成prob_dist就地输入。修正了这个问题,以确保prob_dist调用后输入的形状不变multinomial
  • expandexpand_as允许扩展一个空张量到另一个空张量
  • [..., None, ...]被赋予时(即,在指定索引中的新轴放置),PyTorchNumPy具有不同的行为。在所有情况下这与NumPy一致。
  • 修复指数分布实现从不采样无穷大 - cuRAND返回(0,1]
  • torch的.HalfTensor支持numpy()torch.from_numpy
  • 添加额外的大小检查torch.scatter
  • 修复torch.triltorch.triuGPU上的存储偏移张量(将返回不正确的结果)。
  • 修复CUDA qr分解中的内存泄漏
  • 修复THCUNN内核中的流识别问题
  • 修复kwargs解析torch.topk
  • 固定random_CPU(以前的最大值为2 ^ 32)的DoubleTensorLongTensor
  • 修正ZeroDivisionError: float division by zero打印某些张量时
  • torch.gelsm > nCPU上发生截断错误并返回不正确的结果时。固定。
  • tensor.numpy()中添加一个检查,检查是否没有传递位置参数
  • 在将张量移至CUDA固定内存之前,添加了一个检查以确保它是 contiguous
  • anyallCPU上的空张量(以前出错)
  • 修复symeig大型矩阵的CUDA。缺点是没有足够的空间分配给工作区,导致一些未定义的行为。
  • 改进的数值稳定性torch.var,并torch.std通过使用维尔福德的算法
  • 随机数生成器返回uniform具有不一致边界的样本(在cpu实现中不一致并运行到cublas bug)。现在,所有uniform采样的数字将[0, 1)在所有类型和设备的范围内返回
  • 修复torch.svd大型CUDA张量中的不段错误(修正了岩浆绑定中的溢出错误)
  • 允许空索引张量index_select(而不是错误)
  • 在此之前eigenvector=Falsesymeig为特征向量返回一些未知值。现在我们把它们归零。

sparse

  • 修复了在cadd中稀疏张量的合并coalesced计算错误
  • 修复.type()不转换索引张量。
  • 修复在角落情况下GPU上的稀疏张量聚合

autograd

  • 修复了在使用requires_grad = False的叶变量上向后调用时的崩溃问题
  • 修正type()非默认GPU输入的变量。
  • torch.norm返回时0.0,渐变是NaN。我们现在使用梯度0.0,所以梯度是0.0
  • 使用高级索引和更高阶梯度修正正确性问题
  • torch.prod由于类型错误的原因,GPU的落后是失败的。
  • 先进的变量索引现在允许索引是一个LongTensor支持的变量
  • Variable.cuda()Tensor.cuda()kwargs选项中是一致的

Optim

  • torch.optim.lr_scheduler现在默认导入。

NN

  • 现在支持从nn.Module的转发函数返回字典(用于引发错误)
  • 什么时候register_buffer("foo", ...)被调用,并且self.foo已经存在,那么不是默默地失败,现在引发一个KeyError
  • 修复了缺少_data_ptrs属性的旧RNN/LSTM检查点的加载。
  • nn.Embedding使用该max_norm选项时出现严重错误。这现在已经修复了。
  • 当使用该max_norm选项时,传入的索引被写入(由底层实现)。为了解决这个问题,将索引的克隆传递给renorm内核。
  • F.affine_grid现在可以采取非连续的投入
  • EmbeddingBag现在可以接受1D2D输入。
  • CuDNN BatchNorm中,批次大于131070CuDNN错误解决方法
  • 修复nn.init.orthogonal在行<cols时正确返回正交向量
  • 如果BatchNorm总共只有1每个通道的值,则在训练模式下产生错误。
  • 使cuDNN绑定尊重当前的cuda流(以前引起不连贯的错误)
  • gradOutput是零跨度张量时,修复grid_sample
  • 当反射填充超出张量界限时修复分段错误。
  • 如果LogSoftmax只有一个元素,-inf则返回。现在这个正确的返回0.0
  • 修复pack_padded_sequence接受任意大小的输入(不只是3D输入)
  • 检测cuDNN RNN flatten_parameters中的指针别名,并避免该路径。
  • 固定ELU更高阶梯度时适用
  • 解决半精确度的CuDNN RNN错误
  • 防止数值的问题poisson_nll_loss时,log_input=False通过增加一个小小量

分布式和多GPU

  • 只允许kwargs输入DataParallel。这曾经失败:n = nn.DataParallel(Net()); out = n(input=i)
  • DistributedDataParallelpython2中正确计算num_samples
  • 当使用每个进程1-GPU时,修复DistributedDataParallel的情况。
  • 修复了DataParallel以指定不包含GPU-0GPU
  • 分布式数据并行的退出不会出错,守护进程标志被设置。
  • 修复DistributedDataParallel中的一个错误,当模型没有时buffers(以前引起非连贯错误)
  • 修复__get_state__功能DistributedDataParallel(没有返回)
  • GILCudaFreeMutex互相挨饿时,修复NCCL绑定中的死锁

其他

  • model.zoo.load_url现在首先尝试使用requests library,然后回落到urllib
  • 解决错误,当default_collate传递的集合numpy.str_

原创文章,转载请注明 :Pytorch v0.3.0版本发布--pytorch性能优化提速,支持ONNX,高阶梯度以及SparseAdam优化器 - pytorch中文网
原文出处: https://ptorch.com/news/94.html
问题交流群 :168117787
提交评论
要回复文章请先登录注册
用户评论
  • 没有评论
Pytorch是什么?关于Pytorch! torch.onnx.export使用方法详解以及pytorch和caffe2/MXNet/Tensorflow/CoreML/CNTK模型之间的相互转化