跳转到主要内容

Nervana GPU核的Python绑定

项目描述

简介

nervanagpu 是一个用于深度学习的Python模块。它包括,

  • 矩阵乘法(GEMM)、卷积和池化内核,使用自定义 汇编器 优化,

  • 元素级和广播操作,这些操作会自动组合成高效的内核,

  • 一个简单但功能强大的数组类,利用并部分借用自 pycuda1 的代码,

  • 用于构建网络的层类,以进行基准测试,

  • 完整的汇编源代码,以鼓励社区贡献。

设计目标

nervanagpu 是从Nervana用于内部硬件努力的工具发展而来的。它已重新打包供社区使用。 nervanagpu 的目标是提供,

  • 接近理论峰值性能,

  • numpy功能以方便使用,

  • 与cuDNN2 相同的卷积内核功能和参数,

  • 集成到Nervana的完整深度学习库 neon 中,

  • 一个用于使用替代数值格式的算法探索的工具,

  • 无缝过渡到Nervana硬件的路径,

  • 容易集成到其他深度学习框架中。

仅支持NVIDIA Maxwell和未来的架构。旧架构不适合此处使用的汇编级优化。

数值格式

当前支持的数值格式包括,

  • fp32: 标准32位浮点,

  • fp16: 16位浮点内存格式,底层操作为32位。

  • int8uint8: 在元素级和作为第一卷积层的输入。

还有更多即将到来(例如 这个)。

额外功能

我们的内核有一些额外的有用功能

  • 3D卷积和4D池化(包括输出特征图维度)

  • 可选的ReLU已经内置到GEMM和卷积操作中

  • 支持对fp16进行随机舍入3

  • 可配置以返回有用的统计数据,以避免数值问题(即将推出)

  • 支持深度学习中常见的矩阵大小,显著优于cuBLAS

这样的小优化可以带来显著的速度和性能提升。

使用方法

nervanagpu包括一个工厂类NervanaGPU和一个类似NumPy的数组类GPUTensor。张量和GEMM操作的内存布局为行顺序。以下是如何使用它们的示例。

矩阵乘法示例

以下是一个使用16位浮点数进行基本GEMM操作的完整示例

import numpy as np
import pycuda.autoinit
from nervanagpu import NervanaGPU

# initialize factory class
ng = NervanaGPU(stochastic_round=False)

m, n, k  = 10, 20, 10
dtype = np.float16

# create matrices on host
cpuA = np.random.randn(k,m)
cpuB = np.random.randn(k,n)

# transfer to device
devA = ng.array(cpuA, dtype=dtype)
devB = ng.array(cpuB, dtype=dtype)
devC = ng.empty((m,n), dtype=dtype)

# do GEMM operation
ng.dot(devA.T, devB, devC, relu=False)

# get from device
cpuC = devC.get()

逐元素操作

nervanagpu将张量算术表达式编译成高效的CUDA内核,这些内核在赋值时才会被懒加载。例如,沿一个轴计算方差包括一系列逐元素、归约和广播操作,这些操作编译为单个内核

# import and initialize NervanaGPU, transfer matrix from cpu to dev as above

devC[:] = ng.mean(ng.square(devA - ng.mean(devA, axis=1)), axis=1)

可以通过计算批次(n)维度的均值和方差来执行批量归一化,并自动利用广播来减去和除以原始数据。

# import and initialize NervanaGPU as above

eps  = .001
A    = ng.empty((128, 32), dtype=np.float16)
A[:] = ng.rand() # generate uniform random on device between 0 and 1

# Normalize batch data by batch mean and variance,
A[:] = ng.reciprocal(ng.sqrt(ng.var(A, axis=1) + eps)) * (A - ng.mean(A, axis=1))

上面的最后一个表达式自动合并为一个单独的GPU内核。两个mean(A,axis=1)表达式自动简化为一个。为了能够将归约操作广播到后续操作,归约操作必须在表达式的*后缀*版本中出现在广播操作之前。因此,使用倒数操作而不是除法。

构建

nervanagpu包含内核的完整汇编代码。要构建内核,安装**maxas**,Nervana为NVIDIA Maxwell提供的汇编器。然后可以通过运行以下命令构建模块

make kernels      # build the kernels
make python       # build python bindings
make test         # run nosetests
make doc          # build sphinx docs

简单的make将执行前两个步骤。

目前文档和测试较少。请贡献力量。

性能

nervanagpunervanagpu/benchmarks下附带一组基准脚本。还包括验证内核结果与cuBLAS和cuDNN的脚本来验证。

以下是使用Soumith Chintala的基准页面上列出的网络在单个TitanX上以默认时钟和功率限制运行的benchmarks/convnet-benchmarks.py的示例运行

---------------------------------------------
Alexnet (dtype=float16, N=128)  Results:
---------------------------------------------
Avg(10) fprop:   29.498 msecs 6043.698 gflops
Avg(10) bprop:   66.562 msecs 5356.689 gflops
Avg(10) total:   96.059 msecs 5567.654 gflops
---------------------------------------------
Alexnet (dtype=float32, N=128)  Results:
---------------------------------------------
Avg(10) fprop:   31.251 msecs 5704.698 gflops
Avg(10) bprop:   77.567 msecs 4596.660 gflops
Avg(10) total:  108.818 msecs 4914.869 gflops

---------------------------------------------
Overfeat (dtype=float16, N=128)  Results:
---------------------------------------------
Avg(10) fprop:  116.723 msecs 6134.994 gflops
Avg(10) bprop:  242.084 msecs 5916.054 gflops
Avg(10) total:  358.807 msecs 5987.277 gflops
---------------------------------------------
Overfeat (dtype=float32, N=128)  Results:
---------------------------------------------
Avg(10) fprop:  124.569 msecs 5748.559 gflops
Avg(10) bprop:  278.408 msecs 5144.192 gflops
Avg(10) total:  402.977 msecs 5331.015 gflops

---------------------------------------------
VGG (dtype=float16, N=64)  Results:
---------------------------------------------
Avg(10) fprop:  162.186 msecs 5978.348 gflops
Avg(10) bprop:  357.850 msecs 5419.051 gflops
Avg(10) total:  520.036 msecs 5593.481 gflops
---------------------------------------------
VGG (dtype=float32, N=64)  Results:
---------------------------------------------
Avg(10) fprop:  170.822 msecs 5676.112 gflops
Avg(10) bprop:  438.031 msecs 4427.108 gflops
Avg(10) total:  608.853 msecs 4777.533 gflops

致谢

感谢百度曹立森和Bryan Catanzaro,Bengio实验室的Matthieu Courbariaux和Frédéric Bastien,谷歌的Vincent Vanhoucke以及Facebook的Soumith Chintala对早期版本库的反馈。我们还要感谢NVIDIA慷慨地为我们提供几个TitanX用于基准测试。

参考文献

  1. Andreas Klöckner,Nicolas Pinto,Yunsup Lee,Bryan Catanzaro,Paul Ivanov,Ahmed Fasih。*PyCUDA and PyOpenCL: A scripting-based approach to GPU run-time code generation* Parallel Computing,Volume 38,Issue 3,2012年3月,第157-174页。[PDF]

  2. Chetlur,Sharan,Cliff Woolley,Philippe Vandermersch,Jonathan Cohen,John Tran,Bryan Catanzaro,和Evan Shelhamer。*cuDNN: Efficient primitives for deep learning.* arXiv预印本arXiv:1410.0759(2014)。[PDF]

  3. Gupta,Suyog,Ankur Agrawal,Kailash Gopalakrishnan,和Pritish Narayanan。*Deep Learning with Limited Numerical Precision.* arXiv预印本arXiv:1502.02551(2015)。[PDF]

项目详情


下载文件

下载适合您平台的文件。如果您不确定该选择哪个,请了解更多关于安装包的信息。

源分发

nervanagpu-0.3.1.tar.gz (103.7 kB 查看哈希值)

上传时间 源码

由以下支持