Paddle 【PFCC-Roadmap】算子性能优化

oxalkeyp  于 4个月前  发布在  其他
关注(0)|答案(1)|浏览(54)

Roadmap

OP性能是飞桨框架重要功能之一,通过 OP benchmark,我们发现有些OP性能不够好,没有充分利用硬件算力。 石墨表格《PFCC-Roadmap》之【飞桨 OP 性能优化】 为当前在Paddle中部分性能需要优化的案例,我们内部在不断地进行优化。你如果对这方面有兴趣,欢迎参加此项活动。

目前主要以CUDA编程为主,若对手写Kernel的概念了解不多,请详细阅读 CUDA 编程模型概述 。我们通常使用以下方法对GPU算子进行性能优化:

  1. 数据向量化读写:GPU kernel 的性能瓶颈常被划分为计算瓶颈compute-bound和访存瓶颈memory-bound,当前硬件架构不断更新,算力不断提高,算力与带宽的差距越来越大,导致越来越多的 kernel 性能受制于访存瓶颈。用户可采用常见的 int4,float4 等向量化类型实现数据的向量化读写操作,详见 CUDA相关文档 。当然,鼓励采用通用化的数据类型表示方法 AlignedVector ,以适应不同的向量化读写规则,具体使用案例见 gelu_funcs.h .
  • 快速计算方法:针对前面提到的计算瓶颈问题,我们提供一些基础的优化策略供参考:

  • 快速整型除法:GPU kernel中难免需要计算线程的索引 (index) 进而完成计算,部分索引计算时可能涉及除法,若出现连续除法或取模计算,如 int index = a/b/c ,计算性能难免受到影响。出现此类时,推荐采用 FastDivmod 方法完成计算索引计算,使用方法详见 pooling.cu .

  • warp计算加速工具 :CUDA内置了一套warp级别的shuffle操作指令,能够提升计算效率。Paddle基于此提供了一套可加速Warp级和block级运算的指令库 math_cuda_utils.h ,可加速warp内或block内的最大值、最小值、求和等操作.

  • 内置intrinsic:CUDA内部提供了多种intrinsic计算方法,如针对 float16类型 的向量级计算 __hadd2 (详见 CUDA相关文档 ),灵活运用这类计算可以解决这类case的性能不足问题。除此之外,建议谨慎使用 _expf,_fdivideintrinsic ,这类计算通过牺牲精度以提升性能,但是Paddle作为核心训练框架,OP精度对最终的模型收敛性会有影响.

  • 循环展开:采用 #pragma unroll 指令,编译器会展开具有已知循环次数的小循环加速循环的执行效率.

  • 合理的线程配置策略:GPU Kernel通常需要设置线程配置参数,以确定执行kernel时可分配的计算资源,选择合理的配置参数,能够优化计算Kernel的性能,影响线程配置的因素主要有以下几个方面:

  • 为了将bank冲突将到最低,应尽量使每个block含有的线程数是64的倍数;

  • block的数量是应当是流处理器(SM) 的2倍以上,避免当某个block中线程被同步时,对应的硬件SM闲置;

  • block中的线程数应该设置成Warp尺寸的整数倍,且不超过最大线程数的规定。 一个block中设置的线程过多会导致每个线程可利用的寄存器变少,单寄存器变少时因访问溢出寄存器数据(溢出的数据在设备存储器中)致计算变慢,甚至调用失败。

推荐采用 gpu_launch_config.h 中的线程配置方法选择较为合理的配置参数,若有更好的线程设置策略,欢迎补充。

  • 高性能计算库:飞桨内置了一套模块化的高性能计算组件库 kps ,可以模块化、高性能地完成GPU Kernel实现及优化。此外,若采用如 cublas 等高性能计算库能获得显著的性能收益,也欢迎使用, cublas 库使用示例见 matmul_kernel_impl.h , cudnn 库的使用示例见conv_kernel.cu, thrust 库使用示例见coalesced_kernel.cu.
eyh26e7m

eyh26e7m1#

附录

【方向说明】

  • 技术标签:深度学习框架,C++,Python,CUDA
  • 详细描述:飞桨支持CPU/GPU算子计算,但是部分算子的计算性能仍存在持续优化的空间。请在不影响计算正确性和精度的情况下对算子进行性能优化,并结合 PaddlePaddle/Benchmark 验证算子性能优化效果。

【参与指南】:

  • 飞桨成立了 PFCC(Paddle Framework Contributor Club) ,是一个有兴趣、正在、或者已经为飞桨开源框架做开源贡献的贡献者而成立的虚拟组织,在这里,飞桨开源框架的贡献者进行讨论、交流和分享,并为飞桨框架做出持续的贡献。欢迎你持续关注并加入(我们会定向邀请 Paddle repo 提交PR的开发者加入)。
  • 如果你对算子性能优化方向感兴趣,可以在 石墨表格《PFCC-Roadmap》之【报名页】 (可复制链接后用石墨文档 App 或小程序打开,持续更新)填入你的 GitHub ID,之后一起讨论后续规划和分工。

【提交流程】

【提交内容】

  1. 算子优化的设计文档,并提 PR 至 PaddlePaddle/community 的 rfcs/Ops 目录
  2. 算子优化代码,在Paddle repo的 paddle/phi/kernels 目录
  3. 性能验证代码,在 Benchmark repo/api/dynamic_tests_v2 目录
  4. 算子优化之后,在PR描述中(可参考 PR40941PR30380 )提交优化前后算子在Benchmark平台上的性能数据

【合入标准】

  1. 按 算子性能优化设计规范_TBD 完成设计文档,针对每个OP优化描述性能优化的逻辑和原理
  2. 按 算子性能优化验收标准_TBD 完成性能优化,并在PR描述中贴入性能优化前后PaddlePaddle/Benchmark中效果对比

【技术要求】

  1. 熟悉Paddle框架的算子开发和测试
  2. 熟练掌握 C++, Python,以及CPU/GPU端性能优化技巧

【参考内容】

  1. 文档:算子性能优化贡献文档_TBD

相关问题