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

基于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版本的效率就有足够优势了。

比如实时抠人像这个case:

对每一帧相机预览产生的数据,系统将其映射为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*/
    }
}

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

2、算子层

包括各类layer的实现,如卷积,正则,内积(全连接),Softmax等。

每一个layer要负责申请自己的输出内存(image)。

3、结构层

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

下图是lenet的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 更是好很多了。

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

时间: 2024-10-14 07:12:49

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

DeepLearning tutorial(6)易用的深度学习框架Keras简介

之前我一直在使用Theano,前面五篇Deeplearning相关的文章也是学习Theano的一些笔记,当时已经觉得Theano用起来略显麻烦,有时想实现一个新的结构,就要花很多时间去编程,所以想过将代码模块化,方便重复使用,但因为实在太忙没有时间去做.最近发现了一个叫做Keras的框架,跟我的想法不谋而合,用起来特别简单,适合快速开发.(其实还有很多其他的深度学习框架都是比较容易用的.) 1. Keras简介 Keras是基于Theano的一个深度学习框架,它的设计参考了Torch,用Pyth

TensorFlow【机器学习】:如何正确的掌握Google深度学习框架TensorFlow(第二代分布式机器学习系统)?

本文标签:   机器学习 TensorFlow Google深度学习框架 分布式机器学习 唐源 VGG REST   服务器 自 2015 年底开源到如今更快.更灵活.更方便的 1.0 版本正式发布,由 Google 推出的第二代分布式机器学习系统 TensorFlow一直在为我们带来惊喜,一方面是技术层面持续的迭代演进,从分布式版本.服务框架 TensorFlow Serving.上层封装 TF.Learn 到 Windows 支持.JIT 编译器 XLA.动态计算图框架 Fold 等,以及

一线开发者在Reddit上讨论深度学习框架:PyTorch和TensorFlow到底哪个更好?

本文标签:   机器学习 TensorFlow Google深度学习框架 分布式机器学习 PyTorch   近日,Reddit用户 cjmcmurtrie 发了一个主题为「PyTorch vs. TensorFlow」的讨论帖,想要了解这两大流行的框架之间各自有什么优势. 原帖地址:https://redd.it/5w3q74 帖子一楼写道: 我还没有从 Torch7 迁移到 TensorFlow.我玩过 TensorFlow,但我发现 Torch7 更加直观(也许是我玩得不够?).我也尝试了

TensorFlow与主流深度学习框架对比

引言:AlphaGo在2017年年初化身Master,在弈城和野狐等平台上横扫中日韩围棋高手,取得60连胜,未尝败绩.AlphaGo背后神秘的推动力就是TensorFlow--Google于2015年11月开源的机器学习及深度学习框架. TensorFlow在2015年年底一出现就受到了极大的关注,在一个月内获得了GitHub上超过一万颗星的关注,目前在所有的机器学习.深度学习项目中排名第一,甚至在所有的Python项目中也排名第一.本文将带我们简单了解下TensorFlow,并与其他主流深度学

十个值得一试的开源深度学习框架

IT168 评论本周早些时候Google开源了TensorFlow(GitHub),此举在深度学习领域影响巨大,因为Google在人工智能领域的研发成绩斐然,有着雄厚的人才储备,而且Google自己的Gmail和搜索引擎都在使用自行研发的深度学习工具. 1 无疑,来自Google军火库的TensorFlow必然是开源深度学习软件中的明星产品,登陆GitHub当天就成为最受关注的项目,当周获得评星数就轻松超过1万个. 对于希望在应用中整合深度学习功能的开发者来说,GitHub上其实还有很多不错的开

十个开源深度学习框架

来源:http://www.ctocio.com/ccnews/19687.html 本周早些时候Google开源了TensorFlow(GitHub),此举在深度学习领域影响巨大,因为Google在人工智能领域的研发成绩斐然,有着雄厚的人才储备,而且Google自己的Gmail和搜索引擎都在使用自行研发的深度学习工具. 无疑,来自Google军火库的TensorFlow必然是开源深度学习软件中的明星产品,登陆GitHub当天就成为最受关注的项目,当周获得评星数就轻松超过1万个. 对于希望在应用

推荐GitHub上10 个开源深度学习框架

推荐GitHub上10 个开源深度学习框架 日前,Google 开源了 TensorFlow(GitHub),此举在深度学习领域影响巨大,因为 Google 在人工智能领域的研发成绩斐然,有着雄厚的人才储备,而且 Google 自己的 Gmail 和搜索引擎都在使用自行研发的深度学习工具. 无疑,来自 Google 军火库的 TensorFlow 必然是开源深度学习软件中的明星产品,登陆 GitHub 当天就成为最受关注的项目,当周获得评星数就轻松超过 1 万个. 对于希望在应用中整合深度学习功

Ubuntu 搭建深度学习框架 keras

深度学习框架Keras是基于Tensorflow的所以,安装keras需要安装Tensorflow: 1. 安装教程主要参考于两个博客的教程: https://www.cnblogs.com/HSLoveZL/archive/2017/10/27/7742606.html https://www.jianshu.com/p/5b708817f5d8?from=groupmessage 2. 本教程开始: Ubuntu安装的教程就略过了,直接从深度学习所需的环境的搭建开始说起 (需要说明的是,之所

主流深度学习框架对比

深度学习研究的热潮持续高涨,各种开源深度学习框架也层出不穷,其中包括TensorFlow.Caffe.Keras.CNTK.Torch7.MXNet.Leaf.Theano.DeepLearning4.Lasagne.Neon,等等.然而TensorFlow却杀出重围,在关注度和用户数上都占据绝对优势,大有一统江湖之势.表2-1所示为各个开源框架在GitHub上的数据统计(数据统计于2017年1月3日),可以看到TensorFlow在star数量.fork数量.contributor数量这三个数