基于OpenGL ES 的深度学习框架编写

背景与工程定位

背景

项目组基于深度学习实现了视频风格化和人像抠图的功能,但这是在PC/服务端上跑的,现在需要移植到移动端,因此需要一个移动端的深度学习的计算框架。

同类型的库

caffe-Android-lib 目前应该是最便于集成使用的深度学习框架库。 
tensorflow和mxnet据说也有对应的android库,因时间原因暂未测试。 
CNNdroid,网址https://zhuanlan.zhihu.com/p/25259452,这个是用 
renderscript 作优化的深度学习框架,不过就代码实现和实际测试结果来看,性能一般。

工程定位

实现可实时、体积小、通用的深度学习预测框架。

可实时

跟PC或服务器不同,移动设备上的GPU可不一定有CPU强悍(多线程+neon/vfp),但在需要实时计算的场景(主要是相机预览和视频播放),往往都是基于OpenGL渲染环境的。 
实时的情况下,深度学习框架的输入和输出都在GPU端,使用CPU进行计算往往需要拷贝图像出来,算好后再传到GPU端,因此基于GPU实现的深度学习的库能持平CPU版本的效率就有足够优势了。

对每一帧相机预览产生的数据,系统将其映射为opengl 的一个external
texture,然后需要 计算出一个 mask texture,与原先的texture作混合,显示出来。如果mask texture
的计算在cpu上进行,则需要每帧先把 graphicbuffer 的数据拷贝出来,计算出mask后上传到 mask texture
去,产生一来一回两次额外拷贝。

通用

本工程需要支持 caffe 产出的模型文件,支持常见的网络如lenet、ResNet等等。这个工作量包括编写相应层的算子,设计网络结构,解析caffe模型的参数等。 
所幸的是,目前在移动端做好深度学习的预测就足够了,相比于兼顾训练的结构至少省去2/3的工作量。

工程实现

方案选型

GPU加速的API

使用GPU加速有如下一些方案: 
CUDA、OpenCL、OpenGL(ES)、RenderScript、Metal 
CUDA只适用到NVIDIA的GPU,Metal只适用于apple系列,这两个对android设备而言基本不用考虑。 
对于OpenCL,虽然有不少移动GPU已经支持,比如 Arm 的 mali
系列(T628之后),且有相应的支持库。但是,一方面由于Android在系统层面上没有支持,没有相应的系统API,兼容性还是比较差,另一方面,OpenCL
操作完成后的内存传到OpenGL还是需要同步一下,会影响效率。 
RenderScript 这个坑比较多,文档极少,而且会有跟OpenCL一样的需要跟OpenGL同步的问题,不做考虑。 
最后就只剩下 OpenGL ES,为了开发方便,用 Computer shader 实现,尽管会有一定的兼容性牺牲(Android 5.1 及以上,GPU支持openGLES 3.1),但考虑到下面两点是值得的: 
1、走渲染管线去实现通用计算,编程复杂且容易出错,调优也很麻烦。有 computer shader之后,编程就跟opencl、metal类似,这些工作量可以大幅降低,大大加快开发。 
2、支持OpenGLES 3.1版本的GPU一般都是相对较新的,性能不会太差,能够实现加速的目的。

运算的分配

CNNdroid中仅用GPU加速卷积层的运算,其他还是由CPU+多线程执行。以前我们在早期作gpu加速的预研时,也有过类似的尝试,但是数据传输和同步的性能消耗远大于协同计算带来的性能提升。因此这个工程中,网络中的计算全部由GPU完成,避免数据在CPU和GPU之间反复传输或同步。

另外,GPU驱动在申请内存(分配纹理所需要内存空间)的时间消耗在移动设备端是不可忽略的,因此,不能在运算过程中临时创建纹理或其他Buffer,必须事先分配好。

优化注意点

1、向量化运算 
预测时,我们输入神经网络的数据可表示为 w∗h∗d的三维数据。我们将输入数据用一个RGBA32F格式的3D纹理存维,由于每一个像素有4个数值,得到的纹理大小是w∗h∗ceil(d4)。 
对于卷积层和内积层,我们把参数存储为mat4的数组,然后其计算就完全是vec4级的向量化运算。

2、合适的localsize设计 
与OpenCL不一样,computer shader 必须手动指定 workgroup 的大小,并且指定运行的 workgroup 数量。这两组维度,都是越大越好。 
local size 一般而言越大越好,但 computer shader 所需要的寄存器越多,local size 的最大值就越小,考虑到最耗时的卷积shader所能使用的local size 一般也就 64,保守起见都定为64(8乘8)。 
不能对齐的情况在shader中处理,比如下面的代码:

void main()
{
    ivec3 pos = ivec3(gl_GlobalInvocationID);
    if (pos.x < MAX_WIDTH && pos.y < MAX_HEIGHT)
    {
        /*Do something*/
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

3、适当地合并/去除layer 
如正则层可以直接和上一层合并(末尾加个max处理就行),dropout层可以直接丢弃。 
合并可以提升性能(不过不会太多),但最重要的是减少了中间内存。

框架设计

分为两个子模块,引擎模块在客户端上运行,工具模块用来转换caffe的模型文件。

引擎模块

1、数据层 
Image 为一个RGBA32F格式的2D Array纹理,SSBO为一种vbo, 
全称为GL_SHADER_STORAGE_BUFFER,用于存储自定义类型的数据(主要就是卷积层和内积层的参数)。 
Program 为 着色器链接而成的 opengl program,NetInfo 由 proto 定义,用于规定网络结构。 
在 shader 中,image 和 SSBO 示例如下:

layout(rgba32f, binding = 0) writeonly uniform highp image2DArray uOutput;//Image
layout(rgba32f, binding = 1) readonly uniform highp image2DArray uInput;//Image
layout(binding = 2) readonly buffer kernel {
    mat4 values[];
} uKernel;//SSBO
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

2、算子层 
包括各类layer的实现,如卷积,正则,内积(全连接),Softmax等。 
每一个layer要负责申请自己的输出内存(image)。

3、结构层 
根据 NetInfo 的信息,创建各类算子并构成DAG(有向无环图),执行运算并输出结果。

工具模块

包括一个结构转换器、参数初始化和拷贝工具。拷贝工具是比较容易出错的,因为卷积层和内积层的参数需要补零对齐及重排。

性能与效果

跟开源的 caffe-android-lib 对比 
https://github.com/sh1r0/caffe-android-lib

库大小

caffe-android-lib 11M 
DeeplearningOGL 440K 
全自主开发的,毫无疑问要小很多很多。

运行效率

Oppo R9 (MT6755, GPU: Mali-T860)上的测试结果: 
连续运行十次,去除第一次的结果(移动设备上一般都是动态调频的,第一次跑的时候CPU/GPU的频率还没调起来,会比较慢)。 
Lenet 网络: 
caffe-android-lib:5.0~5.2ms(线程设为4) 
DeeplearningOGL:3.6-3.8 ms

较CPU版本(包含了neon与多线程优化)提升了 50%左右的效率,已经大大超出预期了,在GPU更好的机器上(如mate8上)表现会更佳。 
相比于 CNNdroid 更是好很多了。

人像抠图的场景很流畅,且不需要隔帧计算。

作者:佚名

来源:51CTO

时间: 2024-11-08 17:29:03

基于OpenGL ES 的深度学习框架编写的相关文章

BNN - 基于low-bits量化压缩的跨平台深度学习框架

写在最前     本文介绍阿里IDST部门研发.基于low-bits量化压缩的深度学习框架BNN(Binary Neural Network),BNN具有以下特点:     1) 跨平台:BNN可以在不同的主流硬件平台上进行部署,包括ARM系列移动端处理器.Intel系列服务器以及正在开发中的NVidia的图形处理器:     2)压缩比高:使用了自研发low-bits量化压缩技术,在算法精度几乎无损的前提下能达到40-100倍压缩率,而且我们也提供无需重新训练的压缩方式,极大简化了迭代周期:

Intel开源了基于Apache Spark的分布式深度学习框架BigDL

Intel开源了基于Apache Spark的分布式深度学习框架BigDL.BigDL借助现有的Spark集群来运行深度学习计算,并简化存储在Hadoop中的大数据集的数据加载. 在Xeon服务器上运行的测试结果表明,BigDL比其他开源框架Caffe.Torch和TensorFlow有显著的性能提升.BigDL速度可与主流GPU匹敌,而且能够扩展到数十个Xeon服务器. BigDL库支持Spark 1.5.1.6和2.0版本,并容许将深度学习嵌入在现有的Spark程序中.BigDL库中有把Sp

财富:亚马逊采用 MXNet ,巨头间深度学习框架之争白热化

随着人工智能的发展,现代科技公司的终极目标是构建无需人类介入.能够自我思考的 AI 软件. 亚马逊首席技术官 Werner Vogels 在周二的一篇博客文章中表示,亚马逊网络服务公司(AWS)刚刚选择 MXNet 作为其最主要的深度学习框架. <财富>今年 9 月的一篇深度长文回溯了深度学习推动的人工智能在整个计算生态系统引发的革命,如文章所述,深度学习是 AI 的一个子集,包含神经网络的使用.神经网络在算法(而非人类程序员)的帮助下通过处理大量数据来学习并解决问题. Vogels 表示,A

缺乏支持!Caffe深度学习框架未来堪忧

文章讲的是缺乏支持!Caffe深度学习框架未来堪忧,Caffe是由贾扬清在伯克利上学期间开发的,该项目已经开放源码,目前已获得社区贡献以及伯克利视觉和学习中心(BVLC)赞助.广泛来说,BVLC现在是伯克利人工智能研究(BAIR)实验室的一部分.同样,Caffe也已经超出了视觉范围,包括非视觉深度学习部分,虽然已发布的Caffe模型绝大多数仍然与图像和视频相关. Caffe是一个由表达式,速度和模块化组成的深度学习框架.其优势在于Caffe的模型和优化是通过没有硬编码的配置来定义的,以及在GPU

TensorFlow和Caffe、MXNet、Keras等其他深度学习框架的对比

Google 近日发布了 TensorFlow 1.0 候选版,这第一个稳定版将是深度学习框架发展中的里程碑的一步.自 TensorFlow 于 2015 年底正式开源,距今已有一年多,这期间 TensorFlow 不断给人以惊喜.在这一年多时间,TensorFlow 已从初入深度学习框架大战的新星,成为了几近垄断的行业事实标准. 主流深度学习框架对比 深度学习研究的热潮持续高涨,各种开源深度学习框架也层出不穷,其中包括 TensorFlow.Caffe.Keras.CNTK.Torch7.MX

TensorFlow和Caffe、CNTK、MXNet等其他7种深度学习框架的对比

主流深度学习框架对比 深度学习研究的热潮持续高涨,各种开源深度学习框架也层出不穷,其中包括TensorFlow.Caffe8.Keras9.CNTK10.Torch711.MXNet12.Leaf13.Theano14.DeepLearning415.Lasagne16.Neon17,等等.然而TensorFlow却杀出重围,在关注度和用户数上都占据绝对优势,大有一统江湖之势.表2-1所示为各个开源框架在GitHub上的数据统计(数据统计于2017年1月3日),可以看到TensorFlow在st

Spark与深度学习框架——H2O、deeplearning4j、SparkNet

引言:你可能对使用Spark服务比较感兴趣.Spark已经提供了很多功能,也有一个好用的界面,而且背后有强大的社区,开发者十分活跃,这也是人们对Spark寄予厚望的原因.深度学习是当前正在进行中的Spark项目之一.本文我们将介绍一些Spark能用的深度学习框架. 本文选自<Spark:大数据集群计算的生产实践>. 深度学习因其高准确率及通用性,成为机器学习中最受关注的领域.这种算法在2011-2012年期间出现,并超过了很多竞争对手.最开始,深度学习在音频及图像识别方面取得了成功.此外,像机

深度学习框架Caffe源码解析

相信社区中很多小伙伴和我一样使用了很长时间的Caffe深度学习框架,也非常希望从代码层次理解Caffe的实现从而实现新功能的定制.本文将从整体架构和底层实现的视角,对Caffe源码进行解析. Caffe总体架构 Caffe框架主要有五个组件,Blob,Solver,Net,Layer,Proto,其结构图如下图1所示.Solver负责深度网络的训练,每个Solver中包含一个训练网络对象和一个测试网络对象.每个网络则由若干个Layer构成.每个Layer的输入和输出Feature map表示为I

解析:深度学习框架Caffe源码

雷锋网按:本文作者薛云峰,主要从事视频图像算法的研究,于浙江捷尚视觉科技股份有限公司担任深度学习算法研究员. 相信很多小伙伴和我一样使用了很长时间的Caffe深度学习框架,也非常希望从代码层次理解Caffe的实现从而实现新功能的定制.本文将从整体架构和底层实现的视角,对Caffe源码进行解析. 1.Caffe总体架构 Caffe框架主要有五个组件,Blob,Solver,Net,Layer,Proto,其结构图如下图1所示.Solver负责深度网络的训练,每个Solver中包含一个训练网络对象和