Logsumexp OP 性能优化设计文档
基本信息 | 内容 |
---|---|
提交作者 | Asthestarsfalll |
提交时间 | 2023-03-05 |
版本号 | V 1.0 |
依赖飞桨版本 | develop |
文件名 | 20220305_logsumexp_op_optimization. Md |
1 背景与意义
1.1 飞桨现状
目前 Paddle 内 logsumexp OP 的 GPU 计算调用了 eigen,性能较差,有较大的提升空间。
1.2 业内方案调研
1.2.1 PyTorch
PyTorch 中使用了 cutlass 实现,代码见 此
1.2.2 OneFlow
OneFlow 中使用了 ReduceKernel+ElementwiseKernel 组合的方式,代码见 此
1.3 对比分析
二者与 paddle 中实现思路基本一致,值得一提的是 OneFlow 的实现方式中有对输入数据含 Inf 的处理。
2 设计方案与性能预期
2.1 算子分析
Logsumexp 计算公式如下:
为了解决输入数据中某些数据过大或过小计算指数造成的上溢和下溢的问题,可以将上述公式 (1) 等价转换为:
其中 m 一般取输入数据中最大的数。
由于 logsumexp 与 softmax 类似,可以参考 softmax,转换其输入为 (num_rows, num_cols).
2.1 关键模块与性能提升点
具体实现方式上,可以借助 shared memory 合并带有 Reduce 计算的 Kernel,以减少访问 global memory 的次数。Fusion 后的 logsumexp Kernel 会在一开始把输入加载到 shared memory 中,每个 block 的 shared memory 加载一个 instance 的 feature,shape 为 (1, c)
。后续的所有中间计算结果都保存到 shared memory 中,只将最后的输出 out 写到 global memory 里。
需要注意的是,这种 fusion 仅在 c 在一个适当的范围里才能使用,过小会浪费 block 的 thread 资源,过大会由于 shared memory 资源不够,导致 Kernel 启动失败。
性能预期提升为原算子的 10 倍以上。
2.2 Host 端计算流程
将输入按照 softmax 的方式转换为二维 (num_rows, num_cols).