news 2026/9/10 11:03:10

多 GPU JAX 训练如何开启 PGLE,让集合通信与计算重叠

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
多 GPU JAX 训练如何开启 PGLE,让集合通信与计算重叠

多 GPU JAX 训练如何开启 PGLE,让集合通信与计算重叠

【免费下载链接】jaxComposable transformations of Python+NumPy programs: differentiate, vectorize, JIT to GPU/TPU, and more项目地址: https://gitcode.com/GitHub_Trending/ja/jax

在多 GPU 上跑 JAX 训练时,AllReduce、AllGather、ReduceScatter 这类集合通信操作如果与计算串行执行,GPU 时间就会被白白消耗在等待通信上。JAX 的 GPU performance tips 给出了一个官方方案:Profile Guided Latency Estimator(PGLE)。它先实测各计算指令和集合通信的真实运行时间,再把这份 profile 信息喂回 XLA 编译器,用于生成更好的调度决策——由--xla_gpu_enable_latency_hiding_scheduler延迟隐藏调度器把异步通信与计算重叠起来。该文档明确说明:与 GPU 间通信相关的优化只有在多设备运行时才有意义。

PGLE 支持 GPU 平台,有两种用法:

  • Auto PGLE:一次运行内自动完成「采集 profile → 重新编译」,对训练脚本最省事;
  • Manual PGLE:跑两次任务,第一次采集并保存 profile,第二次把 profile 文件喂给编译器。

一个必须先知道的前提:JAX profiler(两种 PGLE 工作流都依赖它)不能与 NVIDIA Nsight Systems 共存,这一点本文后文会给出规避方式。

开启 Auto PGLE(推荐主路径)

方式一:设置环境变量

在训练入口的 shell 环境或启动脚本中设置。必选:

export JAX_ENABLE_PGLE=true # For JAX version <= 0.5.0 make sure to include: export XLA_FLAGS="--xla_gpu_enable_latency_hiding_scheduler=true"

注意第二条 XLA flag:文档标注它针对 JAX <= 0.5.0,如果你的 JAX 版本更新,是否仍需要以当前版本的默认行为为准,可参考 xla_flags 核对。

可选参数:

export JAX_PGLE_PROFILING_RUNS=3 export JAX_PGLE_AGGREGATION_PERCENTILE=85
  • JAX_PGLE_PROFILING_RUNS:控制用多少次重跑来采集 profile 数据。次数越多 profile 信息越好,但会多出等量的非优化训练步骤。默认值是 3(见 config.py 中pgle_profiling_runs的定义)。
  • JAX_PGLE_AGGREGATION_PERCENTILE:聚合各设备性能数据所用的百分位。当各 step 间性能抖动太大、噪声难以过滤时,可以降低该值。默认值是 90。

另外文档提示:目前 Auto PGLE 的 profile 采集与 command buffer 不兼容。若启用了 command buffer,Auto PGLE 会在采集期间临时禁用它、重编译后再恢复;如果你希望开启/关闭 PGLE 时 command buffer 行为一致,可以手动禁用:

export XLA_FLAGS="${XLA_FLAGS} --xla_gpu_enable_command_buffer=''"

方式二:在 Python 代码中用 config 上下文设置

如果不想改 shell 环境,也可以在代码里用 JAX 的 config 上下文管理器(见 gpu_performance_tips.md):

import jax from jax._src import config with config.enable_pgle(True), config.pgle_profiling_runs(1): # Run with the profiler collecting performance information. train_step() # Automatically re-compile with PGLE profile results train_step() ...

这里train_step()是你的训练步骤函数,需要替换为自己的实现。文档描述的行为是:在pgle_profiling_runs指定的次数内运行并采集性能信息,之后 JAX 自动用采集到的 profile 结果重新编译模块,后续调用直接走重编译后的可执行体。

限制:Auto PGLE 不适用于预编译模块

Auto PGLE 需要在运行时重新编译模块,因此对以下写法不生效

  • AOT(提前编译)的模块;
  • lower().compile()再调用的模式:
import jax from jax._src import config train_step_compiled = train_step().lower().compile() with config.enable_pgle(True), config.pgle_profiling_runs(1): train_step_compiled() # No effect since module was pre-compiled. train_step_compiled()

如果你使用持久编译缓存 + AOT 的流程,Auto PGLE 的开法不成立,应转看下文「配合持久编译缓存采集 Nsight 分析」的两步法。

验证与排查

判断 Auto PGLE 是否在正常工作:文档描述的预期行为是模块在采集够 profile 运行次数后于同一次运行内自动重编译,你不需要手动干预。tests/pgle_test.py 中的testAutoPgle展示了官方验证思路:开启xla_dump_toxla_gpu_experimental_dump_fdo_profiles编译选项后,第 1 次运行生成的.fdo_profile文件应为空;第 3 次运行(触发重编译)之后会多出非空的 FDO profile 文件,说明 profile 被实际喂入了重编译。

PGLE 采到空 trace 时:当检测到 trace 为空,JAX 会发出RuntimeWarning,提示可能是与 Nsight Systems 等同样订阅 CUPTI 的工具产生了竞争(对应 XLA 侧的CUPTI_ERROR_MULTIPLE_SUBSCRIBERS_NOT_SUPPORTED),并建议改为「先用 PGLE 填充持久编译缓存,再用JAX_COMPILATION_CACHE_EXPECT_PGLE跑第二次」的方式(见 profiler.py 中的告警文案)。

需要 Nsight Systems 分析时:由于 JAX profiler 与 Nsight 不能共存,文档给出两步流程(JAX_COMPILATION_CACHE_EXPECT_PGLE配置项自 JAX v0.5.1 引入):

第一步,启用 PGLE 把优化后的函数写进持久编译缓存:

export JAX_ENABLE_COMPILATION_CACHE=yes # not strictly needed, on by default export JAX_COMPILATION_CACHE_DIR=/root/jax_cache JAX_ENABLE_PGLE=yes python my-model.py

第二步,用 Nsight 跑第二次,并从缓存加载 PGLE 优化后的函数:

JAX_COMPILATION_CACHE_EXPECT_PGLE=yes nsys profile python my-model.py

my-model.py替换为你的训练入口;JAX_COMPILATION_CACHE_DIR示例值/root/jax_cache来自文档,可替换为你有写权限的目录。JAX_COMPILATION_CACHE_EXPECT_PGLE的语义是:编译缓存中若存在用 profile 数据编译过的条目,即使当前未启用 PGLE 也会优先加载;找不到优先条目时会打印告警。

Manual PGLE(可选替代路径)

如果 Auto PGLE 不适合你的流程(例如想在采集与优化之间做其他处理),文档给出了手动三步流程。

第 1 步:开延迟隐藏调度器跑一次负载:

export XLA_FLAGS="--xla_gpu_enable_latency_hiding_scheduler=true"

第 2 步:用 JAX profiler 采集并后处理 profile,把提取出的指令延迟保存为二进制 protobuf 文件:

import os from etils import epath import jax from jax.experimental import profiler as exp_profiler # Define your profile directory profile_dir = 'gs://my_bucket/profile' jax.profiler.start_trace(profile_dir) # run your workflow # for i in range(10): # train_step() # Stop trace jax.profiler.stop_trace() profile_dir = epath.Path(profile_dir) directories = profile_dir.glob('plugins/profile/*/') directories = [d for d in directories if d.is_dir()] rundir = directories[-1] logging.info('rundir: %s', rundir) # Post process the profile fdo_profile = exp_profiler.get_profiled_instructions_proto(os.fspath(rundir)) # Save the profile proto to a file. dump_dir = rundir / 'profile.pb' dump_dir.parent.mkdir(parents=True, exist_ok=True) dump_dir.write_bytes(fdo_profile)

示例中的profile_dir = 'gs://my_bucket/profile'是文档给出的 GCS 路径,替换为你可写的 profile 目录。运行你的工作负载的那几行(示例中被注释的train_step()循环)需要自己打开。完成后,rundir(代码里会打印出来)下会生成profile.pb

第 3 步:把 profile 文件通过--xla_gpu_pgle_profile_file_or_directory_path传给第二次编译:

export XLA_FLAGS="--xla_gpu_enable_latency_hiding_scheduler=true --xla_gpu_pgle_profile_file_or_directory_path=/path/to/profile/profile.pb"

/path/to/profile/profile.pb替换为第 2 步实际生成的文件路径。

验证方式:把日志级别调到包含INFO,跑真实工作负载:

export TF_CPP_MIN_LOG_LEVEL=0

如果运行日志里出现下面这两条(文档示例日志):

2023-07-21 16:09:43.551600: I external/xla/xla/service/gpu/gpu_hlo_schedule.cc:478] Using PGLE profile from /tmp/profile/plugins/profile/2023_07_20_18_29_30/profile.pb 2023-07-21 16:09:43.551741: I external/xla/xla/service/gpu/gpu_hlo_schedule.cc:573] Found profile, using profile guided latency estimator

说明 profile 已被延迟隐藏调度器使用。

相关 XLA 调优参数

PGLE 之外,同一文档列出了几个与通信重叠直接相关的 XLA flag(均通过XLA_FLAGS设置):

  • --xla_gpu_enable_latency_hiding_scheduler:启用延迟隐藏调度器,让异步通信与计算高效重叠。默认值为False,是 PGLE 生效的前提。
  • --xla_gpu_memory_limit_slop_factor:作为总可用内存的乘数生成阈值,指导调度器在「降低内存」与「延迟隐藏」之间取舍;低于阈值时允许更激进的优化(可能临时增加内存占用)。默认值为 95。
  • --xla_gpu_all_gather_combine_threshold_bytes/--xla_gpu_reduce_scatter_combine_threshold_bytes/--xla_gpu_all_reduce_combine_threshold_bytes:调优何时把多个小的AllGather/ReduceScatter/AllReduce合并成一次大通信,减少跨设备通信开销。combine_threshold_bytes默认 256;文档建议对 Transformer 类负载,可以把 AllGather/ReduceScatter 的阈值调得足够高,至少能合并一个 Transformer Layer 权重对应的通信。

参考

  • 主文档:docs/gpu_performance_tips.md(PGLE 自动/手动工作流、flag 说明、Nsight 两步法)
  • 配置项定义与默认值:jax/_src/config.py(enable_pglepgle_profiling_runs默认 3、pgle_aggregation_percentile默认 90、compilation_cache_expect_pgle
  • Auto PGLE 行为验证:tests/pgle_test.py、多机测试 tests/multiprocess/pgle_test.py

【免费下载链接】jaxComposable transformations of Python+NumPy programs: differentiate, vectorize, JIT to GPU/TPU, and more项目地址: https://gitcode.com/GitHub_Trending/ja/jax

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/10 11:01:02

CANN/GE内核工具使用说明

一、工具用途 【免费下载链接】ge GE&#xff08;Graph Engine&#xff09;是面向昇腾的图编译器和执行器&#xff0c;提供了计算图优化、多流并行、内存复用和模型下沉等技术手段&#xff0c;加速模型执行效率&#xff0c;减少模型内存占用。 GE 提供对 PyTorch、TensorFlow 前…

作者头像 李华
网站建设 2026/9/10 10:59:38

嵌入式QT车载影音系统C++源码:从工程结构到真机部署

简介&#xff1a;这是一套面向嵌入式与Qt开发学习者的车载影音系统完整工程&#xff0c;基于C在Qt/Embedded环境下实现&#xff0c;涵盖天气、视频、音乐、地图四大功能模块。天气模块通过HTTP请求并解析JSON数据展示未来5天预报&#xff1b;视频与音乐模块调用mplayer进程并支…

作者头像 李华
网站建设 2026/9/10 10:56:07

WeChatMsg 微信聊天记录备份完整指南:3 个任务导出成 Word 和 PDF

WeChatMsg 微信聊天记录备份完整指南&#xff1a;3 个任务导出成 Word 和 PDF 【免费下载链接】WeChatMsg 提取微信聊天记录&#xff0c;将其导出成HTML、Word、CSV文档永久保存&#xff0c;对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/GitHub_Trendi…

作者头像 李华