Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

编译时间优化 #49148

Closed
zlsh80826 opened this issue Dec 18, 2022 · 3 comments
Closed

编译时间优化 #49148

zlsh80826 opened this issue Dec 18, 2022 · 3 comments
Assignees
Labels
status/close 已关闭 type/enhancement 优化性建议

Comments

@zlsh80826
Copy link
Collaborator

zlsh80826 commented Dec 18, 2022

问题描述 Please describe your issue

背景

Paddle 在近期的更新支援了 Ninja 在 Linux 环境中编译 ( #44210, #48435, #48932, #42283 ),在我们的硬体环境下表现十分出色(256核心,HDD 硬盘),不管是 cmake configure 还是编译的时间都远优于 Makefile. 如下表

cmake 时间 编译时间 编辑 dense_tensor.h 后重编 paddle_python 时间
Ninja (无 ccache) 105 1794 x
Ninja (有 ccache) 103 924 1290
Makefile (无 ccache) 226 2475 x
Makefile (有 ccache) 223 1020 1839

在实验可以看出 Ninja 得益于更好的依赖判断来提高编译时的处理器利用率,并且 Ninja 不是透过 -M 生成的大量依赖档案,能减少 I/O 开销。在没有 ccache 或是更改头文件的时候能大幅的提高编译效率

分析与优化建议

Ninja 编译完成后会产生 .ninja_log 的文件,可以透过 ninjatracing 转换成 chrome's about:tracing 的格式并且用 https://ui.perfetto.dev 视觉化。下图是在有 ccache 的情况下编译 GPU + 推理的时间分布图,对应的 cmake 参数见附录

paddle-ninja-build

从视觉化的图表可以看出有几处瓶颈值得优化

  1. 第三方库 protobuf
  2. 第三方库 warpctc
  3. libphi_cpu, libphi_gpu 的依赖导致顺序的执行 (此处应该可以平行化)
  4. libphi_static_1.a
  5. libpaddle_inference_c.so
  6. .timestep (setup.py)

我简单看了一下这几处的瓶颈也提供一些建议可以改善编译所需的时间

1. protobuf

Paddle 在 protobuf 的 ExternalProject_Add 覆写CONFIGURE_COMMAND,导致 protobuf 没有启用 Ninja generator,因此变成串行编译,造成很严重的编译性能瓶颈。此处预期可以带来 2~3 分钟的编译时间减少。

2. warpctc

warpctc 的 CMakeLists.txt 用了已经被废弃的 CUDA_ADD_LIBRARY,不仅不能被 ccache 支援,也不能用上 cuda 11.2 的多架构平行编译功能,相关的改动我已经提了一个 PRbaidu-research/warp-ctc 底下。此处预期可以带来 1~2 分钟的编译时间减少。

3. libphi_gpu.a 和 libphi_cpu.a 相互依赖

图中标注 3 的区块中,棕色的是 libphi_gpu.a,深绿色的是 libphi_cpu.a。可以看到 libphi_cpu.a 没有跟 libphi_gpu.a 并行执行,反而是等 libphi_gpu.a 执行完后再执行,造成了约 30 秒的瓶颈。透过在 paddle/phi/CMakeLists.txt 添加以下指令后会看到 libphi_cpu.alibphi_gpu.a 互相依赖,导致 Ninja 不能并行生成这两个静态函式库。我理解这两个函式库应该不需要互相依赖,若能解决这个问题就能带来 30 秒的编译时间减少

get_target_property(OUT phi_gpu LINK_LIBRARIES)
message(STATUS phi_gpu_dependency=${OUT})

4. libphi_static_1.a

这部分看代码应该是要把所有的 phi 的依赖打包成一个静态函式库供给后续需要 phi 的档案使用,因为 libphi_static_1.a 似乎没有要对外使用,只有编译时期要做 linking 而已,使用 create_dummy_static_lib(phi LIBS ${PHI_DEPS} LIMIT 100) 从分析图上来看带来了将近一分半的性能瓶颈。我想这边若只是要制作一个 target 来给后面需要 phi 的依赖使用的话,使用

       add_library(phi INTERFACE)
       target_link_libraries(phi INTERFACE ${PHI_DEPS})

也可以达到相同的功能,并且能省下 build 资料夹 6G 的空间,加上带来一分半的编译时间缩短。

5. libpaddle_inference_c.so

看代码这似乎是给 c 提供的 inference 动态函式库,这边因为依赖 libpaddle_inference.a 导致有约一分半的性能瓶颈,我想这边应该能够修改 cmake 让 libpaddle_inference_c.so 依赖 libpaddle_inference.a 的依赖,这样这两个函式库就能并行执行了。或是 libpaddle_inference.a 没有要暴露出去,本来就只是为了 libpaddle_inference_c.so 而生成的话,可以用跟第四点一样的方法,将 https://github.com/PaddlePaddle/Paddle/blob/develop/paddle/fluid/inference/CMakeLists.txt#L79-L80 替换成

  add_library(paddle_inference INTERFACE)
  target_link_libraries(paddle_inference INTERFACE ${fluid_moduels} ${phi_modules}
                      ${phi_kernels} ${STATIC_INFERENCE_API} ${utils_modules})

就能带来一分半的编译时间缩短

6. .timestamp

这部分看代码应该是最后用 setup.py 制作 paddle 的 whl 用的,这部分我还没有详细看,似乎有一个 PR 是在做这个优化的。这部分带来了约 45 秒的性能瓶颈

以上六个性能瓶颈若能全部解决预期能带来 6-10 分钟的编译时间缩短,这在 CI 工作上能带来十分明显的收益,除了减少 Paddle 开发者的开发周期,远期而言也能因为开发效率的提升而有助于 Paddle 生态的使用者。

附录

cmake 参数

cmake -Bbuild -S. \
    -GNinja \
    -DINFERENCE_DEMO_INSTALL_DIR=/workspace/paddle/data \
    -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
    -DCMAKE_BUILD_TYPE=Release \
    -DCMAKE_CUDA_FLAGS='-t0' \
    -DCUDA_ARCH_NAME=Manual \
    -DCUDA_ARCH_BIN="70 75 80 86 90" \
    -DWITH_INCREMENTAL_COVERAGE=OFF \
    -DWITH_INFERENCE_API_TEST=ON \
    -DWITH_DISTRIBUTE=ON \
    -DWITH_COVERAGE=OFF \
    -DWITH_TENSORRT=ON \
    -DWITH_TESTING=ON \
    -DWITH_CONTRIB=ON \
    -DWITH_ROCM=OFF \
    -DWITH_RCCL=OFF \
    -DWITH_STRIP=ON \
    -DWITH_MKL=OFF \
    -DWITH_AVX=OFF \
    -DWITH_GPU=ON \
    -DWITH_PYTHON=ON \
    -DPY_VERSION=3.8 \
    -Wno-dev
@zlsh80826 zlsh80826 changed the title 編譯時間優化 编译时间优化 Dec 18, 2022
@zhiqiu
Copy link
Contributor

zhiqiu commented Dec 19, 2022

非常感谢,我们近期也在优化paddle对ninja的支持,并且期望后续可以将ninja作为paddle编译的默认选项。上述建议我们会逐一尝试下。

@zhiqiu zhiqiu self-assigned this Dec 20, 2022
@paddle-bot paddle-bot bot added status/following-up 跟进中 type/enhancement 优化性建议 status/close 已关闭 and removed status/new-issue 新建 type/others 其他问题 labels Dec 20, 2022
@paddle-bot paddle-bot bot closed this as completed Dec 20, 2022
@paddle-bot paddle-bot bot removed the status/following-up 跟进中 label Dec 20, 2022
@phlrain
Copy link
Collaborator

phlrain commented Dec 20, 2022

非常感谢,我们近期也在优化paddle的编译效率, 包含ninjia和clang的多种尝试,代码退场的多种尝试

@zlsh80826
Copy link
Collaborator Author

Hi @zhiqiu @phlrain,
baidu-research/warp-ctc#179 這個 PR 能大幅改進 warp-ctc 的編譯效率,能幫忙請 warp-ctc 的同事看一下嗎?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status/close 已关闭 type/enhancement 优化性建议
Projects
None yet
Development

No branches or pull requests

3 participants