ysh329 / OpenCL-101

Learn OpenCL step by step.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

【年度总结】2020年opencl工作汇总

ysh329 opened this issue · comments

OpenCL 业务支持

LiteKit手机端OPENCL和CPU模型(已经开源)

2个GPU模型,手势检测与超分,1个cpu模型,人像分割;

  1. 视频超分模型增加opencl前后处理、uint8支持,PR内容详细:PaddlePaddle/Paddle-Lite#3049
  2. 对视频超分模型做了细致的内存占用比较Lite和Mobile:开启内存复用前后,输入规模越大,物理内存节省越多大概50%+,详见《超分模型与多层间内存复用》http://agroup.baidu.com/paddle-infer/view/office/2539063
  3. 超分模型支持OpenCL多层内存复用:PaddlePaddle/Paddle-Lite#3077
  4. 超分gpu模型执行期挂掉:更换模型与库匹配的版本后问题解决,库和模型版本不匹配,模型版本太老

手百lens手机端OPENCL和CPU业务(已经上线)

  1. 修复lens_mnasnet找不到kernel_func_name_导致挂的问题,PaddlePaddle/Paddle-Lite#3085
  2. 修复lens mnasnet加载模型时在高通手机上出现segfault问题。原因:模型固化的op和库的实现不兼容
  3. 发现头文件不同导致,模型加载挂掉,原因ios和android头文件不能共用
  4. 旧的int16模型不兼容新版lite在加载模型时的反量化fp32会出现Crash,更新模型后1.8Paddle另存重新转换修复
  5. lens_saoma_yolonano的cpu模型转换时出现conv-conv pass执行挂掉,原因是融合条件没有前置,判断条件出现过晚,找负责人解决;

男女变换GAN手机端OPENCL模型(未上线,算法未调整好)

  1. 修复模型转换出现layout pass找不到对应匹配layout kernel的问题;
  2. 修复/支持找不到tanh、exp的opencl kernel;
  3. 修复io_copy报错;

反黄反暴力手机端OPENCL模型(未上线,算法未调整好)

  1. 修复int16 opencl模型加载fc权重出错的问题
  2. 修复执行过程出现CL_INVALID_BUFFER_SIZE

图像修复手机端OPENCL模型

  1. conv3x3带group的情况不支持,增加支持;
  2. concat计算结果不对,已修复并提pr。特殊机型concat单测结果不对;
  3. 特殊机型骁龙625,网络计算结果错误,conv3x3 group的部分结果在内存写入时失败,低端opencl驱动版本不支持矢量数组;

如流人像分割手机端OPENCL模型(准备上线)

  1. 人像分割增加hard_sigmoid算子,性能提升37ms->26ms;
  2. 修复dropout注册缺失Mask的bug;
  3. 定位荣耀特定机型(荣耀V30)的内存泄露问题,原因是驱动有内存泄露bug;

如流人像分割PC端OPENCL模型(准备上线)

  1. 增加Mac对人像分割模型FP32类型的支持兼容:PaddlePaddle/Paddle-Lite#4827PaddlePaddle/Paddle-Lite#4757

OpenCL

增加op

kernel迁移进展:http://agroup.baidu.com/api/static/40/0243a9f31e7bc8dab29a523e69a6e0e50908a8?filename=OpenCL+%25E9%25AB%2598%25E4%25BC%2598+OP+.xlsx

  1. 增加opencl image2d relu6 kernel:PaddlePaddle/Paddle-Lite#2802
  2. 增加opencl image2d elementwise_mul的4种kernel:https://github.com/PaddlePaddle/Paddle-Lite/pull/2815、https://github.com/PaddlePaddle/Paddle-Lite/pull/2945
  3. 增加opencl image2d elementwise_add / fusion_elementwise_add_act kernel:PaddlePaddle/Paddle-Lite#2844
  4. 增加opencl image2d conv3x3 kernel以及修复conv3x3spl
  5. 增加activation_type4宏方法:PaddlePaddle/Paddle-Lite#2874
  6. 增加fc+relu的融合:PaddlePaddle/Paddle-Lite#3010
  7. 增强elementwise_mul的一种特殊情况:PaddlePaddle/Paddle-Lite#3268
  8. 新增hard_sigmoid;
  9. 新增conv与leaky relu融合计算;

10月支持模型统计

  • 统计目前支持的模型,目标是和arm cpu对齐(向明哲同步了arm cpu当前支持的fluid所有经典模型,涵盖onnx/tf/caffe等框架源头),并验证精度+性能;
  • 55个模型,52个有效模型,lite opencl可以跑通且正确26个。
    • 【模型转换】
      • 3个cpu int8量化模型,忽略跳过;
      • 11个模型转换失败,其中9个在type_layout_cast_pass.cc:172挂掉,2个是选kernel时找不到注册的kernel对应的input;
      • 41个转换gpu模型成功,有潜在性能问题的27个。潜在性能问题,是指存在可能融合的op如conv+prelu,elementwise_add+relu,以及缺乏GPU OP导致使用CPU继而的中间多次数据拷贝等。
        • 缺少的OPENCL OP有(CV模型)9个:shuffle_channel、split、prior_box、conv_transpose、reduce_mean、softmax、batchnorm、prelu、yolo_box;
        • 缺少的OPENCL OP有(NLP模型)17个:read_from_array、increment、less_than、mul、sequance_expand、sequance_softmax、sequance_pool、gru_unit、write_to_array、lod_reset、top_k、log、beam_search、is_empty、logical_not、logical_and、lookup_table;
        • 可能做融合的pass但现在没有或gpu没支持的情况:elementwise_add+relu、conv+prelu、fc+prelu、按理应被消掉的dropout、tfmv1/v2结构中尾巴的reshape2/squeeze2(明哲的模型和我源头不一样结构些许diff冗余结构Pass没成功消除)。
    • 【GPU模型执行】
      • 15个模型跳过(转换失败12,3个cpu量化模型);
      • 4个运行期segfault;
      • 9个运行期CHECK挂掉;
      • 1个计算错误;
      • 26个计算正确且运行成功,有7个cpuv7-st比gpu快,具体见下表格(骁龙845/2.7beta)。
  • 详见【GPU支持开源模型列表】:http://agroup.baidu.com/api/static/40/0243a9f31e7bc8dab29a523e69a6e0e50908a8?filename=OpenCL+%25E9%25AB%2598%25E4%25BC%2598+OP+.xlsx

性能

  1. 优化fc/elelmentwise_add/scale/activation/grid_sampler在CPU上的计算过程,支持变长输入,必要时做ReInitWhenNeeded:PaddlePaddle/Paddle-Lite#3302
  2. 针对tf模型v1/v2做优化,实现pass消除squeeze2和reshape2的冗余结构
  3. conv冗余计算优化,规范conv计算流程(param解包/gws计算/流程优化):https://github.com/PaddlePaddle/Paddle-Lite/pull/3924,提升范围:1%~53%,caffe_mobilenetv1v2
  4. 开启tune提升范围:4%~56%,caffe_mobilenetv1v2,990/980/970/855/845/835。QA反馈MNN/TNN 8月版本竞品测试中,标绿色的是该模型、该手机上表现最好的框架,Paddle-Lite在大约一半的 <模型 手机>组合情况中较竞品耗时更短;

bug修复

  1. 修复conv3x3 kernell bug:PaddlePaddle/Paddle-Lite#2853
  2. 修复fc buffer实现OOM bug:PaddlePaddle/Paddle-Lite#3062
  3. 修复reshape找不到layout挂掉的问题:PaddlePaddle/Paddle-Lite#3268
  4. 修复opencl的随机结果bug,原因是conv op的激活act_type没有初始化(和opencl端无关);
  5. 修复跑opencl,cxx_api会跑到arm cpu,原因:cxx_api在Build前传入inner_places,inner_places追加valid_places的精度和layout信息组成Place,追加到inner_places的,但kHost不支持opencl的layout和精度
  6. 修复部分机型crash , 经排查为手机上 libopencl 库版本较低导致,对不支持的符号做了兼容处理;
  7. mml库编译android armv8 .a集成到APP里编译出错:undef replace::stl pad。已修:PaddlePaddle/Paddle-Lite#3977
  8. 修复在不支持GPU的手机上,以cpu+gpu库的方式,加载cpu模型时segfault问题;
  9. 修改layout pass bug。判断是否为host(不仅有arm,还有x86和host)。而不是只是判断kARM,修改后可转换YOLOv3;
  10. 修复opencl多次Run在开启内存复用时计算结果第二次错误,原因是创建内存的条件判断的bug;
  11. ci在mali gpu上的leaky relul兼容性报错修复:PaddlePaddle/Paddle-Lite#4879

较大特性支持/改动

  1. OpenCL Image2D的FP32到FP16的类型支持方案agroup:http://agroup.baidu.com/paddle-infer/md/article/2562012PaddlePaddle/Paddle-Lite#2964
  2. 增加OpenCL精度Profiler,以及一个用于tensor序列建模的属性avg_grow_rate:PaddlePaddle/Paddle-Lite#3268
  3. 增加IsOpenclBackendValid API,让用户预先做判断:PaddlePaddle/Paddle-Lite#3951
  4. OpenCL AutoTune:PaddlePaddle/Paddle-Lite#4700
    1. 增加set_opencl_tune API,用户选择是否开启tune提升性能;
    2. 调研MNN/TFLite的auto
      1. tune策略,TFLiteTune调研与尝试:http://agroup.baidu.com/paddle-infer/md/article/3473411
      2. MNN策略调研:http://agroup.baidu.com/paddle-infer/md/article/3514138
    3. 优化现有Lite在OpenCL的Auto-Tune组织结构。Auto-Tune尽可能与kernel剥离(当前耦合程度较高,如Conv),后续易于扩展其它Kernel;
    4. 增加TUNE(RAPID),TUNE(NORMAL)方式,并优化现有tune API,让用户好用易用一目了然:PaddlePaddle/Paddle-Lite#4959
  5. MacOS / Linux X86 OpenCL支持: PaddlePaddle/Paddle-Lite#4757
    1. 支持模型转换的编译/使用/文档、lite库编译/文档、lite运行(所有kernel对FP32和FP16的兼容):PaddlePaddle/Paddle-Lite#4757
    2. 兼容性bug修复:运行时随机挂(内存复用)、精度存在问题(采样器bug): PaddlePaddle/Paddle-Lite#4877PaddlePaddle/Paddle-Lite#4829
    3. x86平台macos linux opencl 精度profiler支持:PaddlePaddle/Paddle-Lite#4829
    4. FP32 / FP16类型的兼容增强,提供用户侧API选择计算精度:PaddlePaddle/Paddle-Lite#4959PaddlePaddle/Paddle-Lite#4958

后端基础支持:文档、编译、CI、单元测试

  1. 模型转换支持opencl模型转换:PaddlePaddle/Paddle-Lite#2874
  2. 规范化layout_kernel的命名/CMake/单测精度阈值调整/mobilenetv1v2单测计时统计/conv内拼写错误等:PaddlePaddle/Paddle-Lite#3010
  3. 增强Activation枚举值的可视化打印:PaddlePaddle/Paddle-Lite#3085
  4. 增加kernel_func_name_便于debug排查问题(与后续Profiler):PaddlePaddle/Paddle-Lite#3085
  5. 修复编译opencl库不带cv库的问题:PaddlePaddle/Paddle-Lite#3089
  6. 支持clang编译opencl库:PaddlePaddle/Paddle-Lite#3153
  7. 增加test_mobilenetv1单测对OpenCL
    OPENCL的支持:PaddlePaddle/Paddle-Lite#2874
  8. 增加FreeImage对OpenCL Image2D类型,强化现有memory层对opencl buffer/image2d资源的管理:PaddlePaddle/Paddle-Lite#3290
  9. 增加对opencl的多线程测试
  10. 增加concat对多输入>4个input的情况支持
  11. 增加/优化如何使用Android OpenCL GPU文档:PaddlePaddle/Paddle-Lite#2897PaddlePaddle/Paddle-Lite#3091PaddlePaddle/Paddle-Lite#3951

竞品测试:N次N个框架

mace/mnn/tnn/ncnn/tflite/mindspore:http://agroup.baidu.com/paddle-infer/view/office/2539063

6个机型990/980/970/855/845/835。4个模型caffe/tf的mobilenetv1v2。

  • 10月mindspore:lite基本全面超越;
  • 8月mnn/tnn:QA反馈MNN/TNN 8月版本竞品测试中,Lite是表现现最好的框架,在上述大约一半的 <模型 手机>组合情况中较竞品耗时更短;

QA提测相关

  1. 针对超分模型测试流程的说明:http://wiki.baidu.com/pages/viewpage.action?pageId=1074890424

Paddle:调研/中英文文档修复/API修复

  1. Pytorch op调研8个,完成。2月
  2. 修复clip相关的paddle文档,级别高。6月
  3. 3个训练clip相关API的迁移/修复,9月
  4. clip_by_norm性能慢于1.8版本8倍:CMake对Eigen版本升级导致
  5. 中英文clip等API中英文文档修复:PaddlePaddle/docs#2922PaddlePaddle/Paddle#28994

Paddle-Lite

文档

  1. 文档:增加如何添加Layout、如何使用OPENCL预测:PaddlePaddle/Paddle-Lite#2897PaddlePaddle/Paddle-Lite#3091

bug修复

  1. 修复build.sh、ci_build.sh、build_bm.sh里多线程编译。拼写错误等:https://github.com/PaddlePaddle/Paddle-Lite/pull/3094/files
  2. 修复armv8 cpu编译demo/mobile_light.so出现undef CreatePaddlePredictor的问题:PaddlePaddle/Paddle-Lite#3123
  3. 增强现有单测,追加命令行补充input_shape/repeats/warmup/是否打印结果 ,便于benchmark:PaddlePaddle/Paddle-Lite#3153
  4. 解耦精度和性能Profiler:https://github.com/PaddlePaddle/Paddle-Lite/pull/3305/files
  5. 定位clang opencl编译失败,arm cpu编译奇慢无比的问题,二分commit定位发现是有改动kernel注册导致爆出大量return type&和override warn的警告log导致,修复为不报warn;
  6. 修复tf_vgg16在转换cpu模型时,移除tf冗余op的pass因空指针挂掉的问题;

特性支持

  1. 精度Profiler优化:修改开启精度Profiler时,内存复用pass关闭的情况。增加写入每层计算结果到手机,并增加一个环境变量用来决定是否写入文件到目录;
  2. 性能Profiler优化:记录每个kernel_func_name,不仅限于opencl,也有arm cpu。极大方便网络逐层conv profiler,且更重要的是具有计算量macs和ops,以及op属性,如input/output shape大小/stride/pad等等必要属性;
  3. 增加mobile_light demo对多input输入的命令行传参支持,方便QA和RD自测;
  4. paddle2.0对齐Op。完成grid_sampler op 3个attribute、lookup_table 3个attribute的支持,完善并补全对应单测:PaddlePaddle/Paddle-Lite#4908

mobile业务:全民小视频-人脸特效AR项目-人脸关键点模型

  • 背景:
    • 先前上线使用Ankain,目前计划迁移Paddle-Lite;
    • 目前plite性能比Anakin好:mv6s模型,shell环境plite 1.8ms,anakin 1.9ms。祥达app内lite 2.7ms,结果也已对齐;
      环境:mv3模型、cpu-armv7-st;
  • 目前问题:mv6因int8缘故,精度较v3低,故用v3。v3的int8和float模型性能接近。人脸关键点v3模型,int8和float性能接近,int8收益很小,原因仍需进一步分析。

测了
【kernel(profile的k-average)整体耗时】
v3-int8-model: 5.908ms
v3-float-model: 7.503ms
补充:repeats=10000,warmup=100
环境:v2.1.0, OMP_OFF,PROFILE,ADD_DETECT_KERNELS_OPS,test_mobilenetv1_int8
【模型整体耗时】
v3-int8-model: 10.969 ms
v3-float-model: 11.951 ms
补充:repeats=10000
环境:v2.1.0, OMP_OFF,ADD_DETECT_KERNELS_OPS,tiny_pulish的cxx-demo-mobile_light,libc++_shared
【框架整体耗时-kernel的Run方法直接return】
v3-int8-model: 0.3095 ms
v3-float-model: 0.3269 ms
环境:v2.1.0, OMP_OFF,SHUTDOWN_LOG_ON,ADD_DETECT_KERNELS_OPS,tiny_pulish的cxx-demo-mobile_light,libc++_shared
总体来看以上3部分:
kernel整体耗时,int8比float快 1.6 ms
模型整耗时,int8比float快 1.0 ms
框架整体耗时,int8比float快 0.02 ms
分析:
int8 kernel比float确实有性能优势。kernel总体耗时,int8(5.9ms)比float(7.5ms)快 1.6 ms;
模型整体耗时相近,可能被框架本身慢和模型差异带慢了。模型整体耗时,int8(10.9ms)比float(11.9ms)快 1.0 ms;
模型整体耗时排除kernel总体耗时,也就是带profile的框架耗时,int8(5.0ms)比float(4.4ms)慢了0.6 ms,这个 0.6, 似乎是int8和float模型差异,导致的慢0.6ms的原因。另外可能就是框架本身慢。
框架整体耗时,没法体现模型差异慢,似乎模型差异慢是开了profile的缘故,与前面模型差异慢的结论矛盾,int8(0.30ms)比float(0.32ms)快 0.02 ms;
仍需进一步长线分析


2月

【本周计划,周五已汇总更新(红字)】
【已完成,APP包内体积为260KB】模型批量裁剪vis的15个模型(11个vis的,4个手百的),看看包体积大小是多少;
【已完成,精度下降,下周再试新feature】int8量化精度有修复(陈姣),查看int8 mv6s模型的精度是否有提高。
【周一】
模型批量裁剪根据文档,发现目前脚本有问题,已经反馈志强,等待修复;
【周二】
1.模型批量裁剪问题已修复,根据对15个模型(11个vis+4个手百),armv7-cpu的库(tiny_publish,android_stl_shared),体积如下:
./libpaddle_light_api_shared.so:684K;
./libpaddle_light_api_shared.so.zip:260K(APP包内体积)。

2.int8量化精度修复看mv6s精度是否提高,进行中。将93张图片,lite的结果跑出来了,需要与hanqi联调比对fluid的结果。精度下降了,在93张的lite结果和fluid-gpu比,因为是关键点模型,lite和fluid-gpu的输出元素值逐个比对的,最大diff增大(最大diff先前是0.78,现在是1.68)。后续arm cpu在int8量化的lite层面还会做一些精度上的优化。


2月17日

2.17 本周进展:
模型批量裁剪,对15个模型(11个vis+4个手百),armv7-cpu的库(tiny_publish,android_stl_shared),APP包内体积 260K。
int8量化精度有修复,查看int8 mv6s模型的精度,在93张图片上比较lite和fluid-gpu结果发现精度误差增大,后续arm cpu在int8量化的lite层面还会做一些精度上的优化,等待后续优化。


3月

v2.3精度有修复,重测v4.5模型在93张图上的精度。目前我这里测精度与先前v2.1无提升(最大diff与先前一样,无变化),但@陈姣 那里用dev分支(int8修复部分与v2.3无变化)测有巨大与fluid一致

【周一】
提供用于QA测试 int8 v45人脸关键点模型的文档和脚本。
写了供QA参考的测试精度文档:人脸关键点v45 int8模型在PaddleLite release/v2.3的批量图片精度验证;
重写了批量生成93个bin的编译+运行+与fliuid批量比对的脚本;
自己复测后v2.3-armv7-cpu,lite与fluid-gpu在93张图片上的abs_diff与v2.1接近,0.78,相对误差0.06(因为是人脸关键点模型,所以看相对误差可能意义不大)。具体见表格的第一个子表sheet;
结果与陈姣确认,此外,和陈姣讨论,因为考虑到QA工作重复,先不找QA提测。
与张晰、晓刚一起看祥达上周反馈的paddle多线程在AR环境里计算结果错误的问题,编译ios找出当初有错的包等。
张晰 验证2.3分支的ios包,不存在该问题;
想确定问题版本commit id,但vis那边找不到了原压缩包。注:先前@袁帅 提供包,commit-id一并打包压缩。


【周二/周三】
mv3模型lite性能低于anakin。与陈姣、张晰测试mv3、mv45模型在高通625上的性能。
发现lite比anakin慢的原因:relu6+dwconv的融合的relu6判断影响性能,
除@陈姣 反馈的结论外,从详情见表格;可以看到:
开启OPENMP,降低单线程性能5%(来自lite基于mv45模型):
clang编译,性能相比gcc编译提升6%(来自anakin基于mv45模型)。


paddledetection【TODO】
背景:发现profiler里tf和lite卷积个数不一致,反馈给青青方面,提供新的ssd mobilenetv3模型,比较lite与tflite在armv8 cpu单线程上的性能;
状态:ssd-mobilenetv3青青方面@于广华 提供新模型,还在查模型paddle与tf的差异

【MEG-地图-RONIN模型】(已上线)

  • 背景:在客户端加载过程中遇到了crash的情况,arm-cpu部署;
  • 需求:解决部署问题;
  • 解决bug1:缺少arm cpu cast的一种情况,dev已merge,release2.6已merge;
  • 解决bug2:业务方反馈调用时,试用包armv8,在RuntimeProgram挂掉,但demo无法复现应该是版本与RD测试不一致;
  • 问题讨论1:加载非法文件卡主,如非模型文件,目前在armv8发生未解密模型文件,predictor加载卡死问题:1.加解密和mml高度耦合,2.本身校验有一定性能损失对已有框架优化所有业务带来加载性能增加,3.开发周期长,建议交给mml来做预先加密模型文件的判断;
  • 收益:gps信号弱场景下 地图定位精度上升5%
  • owner:panyu