- 人工智能
- 大模型
- 预训练
- 微调
- LoRA
- RLHF
- 强化学习
- 分布式训练
【免费下载链接】PaddleNLP
Easy-to-use and powerful LLM and SLM library with awesome model zoo.
导读
在 PaddleNLP 的 GPT-3 模型库(ppfleetx 框架)中,当训练任务从单卡扩展到 DP/MP/PP 混合并行(hybrid parallel)甚至流水线并行时,性能瓶颈往往隐藏在数据加载、通信、kernel 执行与显存分配等环节。本篇文章以 hybrid_profiler.md 为核心,完整讲解如何在 GPT 混合并行训练任务中开启 Paddle Profiler、定制统计视图、通过 Chrome Tracing 与 VisualDL 查看结果,并结合仓库源码深入解析每个配置项在引擎中的实际作用。读完本文,你将掌握一套可复现的 GPT 训练性能剖析流程,并能读懂 Overview、Model、Operator、Kernel 等 summary 报表,定位训练热点。
一、Profiler 在 GPT 训练中的定位与适用场景
GPT-3 这类大规模稠密 Transformer 模型的训练通常采用数据并行(DP)、张量并行(MP)、流水线并行(PP)等混合并行策略。在 ppfleetx 框架 中,训练引擎在每轮训练循环中同时承担 forward、backward、optimization、dataloader 与通信调度等职责,任何一环出现耗时异常都会直接反映在吞吐上。
Profiler 的作用正是在训练过程中按 step 粒度采集 CPU 侧算子调用、GPU 侧 kernel 执行、内存申请释放以及分布式通信事件的时间数据,最终输出两类产物:
- 训练结束时在控制台打印的 summary 统计表格;
- 保存在配置目录下的profiler JSON 文件(Chrome Tracing 格式),可供浏览器或 VisualDL 可视化分析。
该功能由 eager_engine.py 中的EagerEngine统一接入:只要任务配置中存在Profiler段且enable: True,引擎便会创建paddle.profiler.Profiler实例并在训练循环中自动上报数据。从源码看,Profiler 的开启逻辑位于EagerEngine.__init__(第 241-257 行),每步调用self.profiler.step()(第 399 行),训练结束时在_profiler_done中执行stop与汇总打印(第 859-872 行)。因此在 ppfleetx 体系内,Profiler 的使用方式是"零侵入"的,只需修改 YAML 配置即可。
二、参数配置:完整 Profiler 配置项详解
开启 Profiler 需要在任务的 YAML 配置文件中加入Profiler段,并将enable置为True。仓库基础配置 pretrain_gpt_base.yaml 中已预置了该段落的骨架:
Profiler: enable: False scheduler: [1, 5] profiler_log: profiler_log detailed: False完整的可配置参数如下,可直接整体粘贴到任务配置中按需调整:
Profiler: enable: True scheduler: [1, 5] profiler_log: log_path detailed: True record_shapes: True profile_memory: True summary: overview: True device: True model: True dist: True kernel: True op: True mem: True memcpy: True各核心参数的含义与默认值如下表:
| 参数名 | 参数释义 | 默认值 |
|---|---|---|
| enable | 是否开启 Profiler | False |
| scheduler | 定义分析区间,如[1, 5]记录 step 1 到 step 4 的分析数据 | None |
| profiler_log | 日志(JSON)文件目录 | profiler_log |
| detailed | 是否显示详细信息(是否打印全部 summary 表格) | False |
| record_shapes | 是否记录 tensor shape 相关信息 | True |
| profile_memory | 是否统计 memory 相关信息 | True |
其中scheduler采用"左闭右开"区间语义:配置[1, 5]表示记录 step 1 到 step 4 共 4 个 step 的数据。由于 profiling 本身会引入采样开销,建议只对少数几个 step 进行采样,而非全程开启。
2.1 定制 summary 输出视图
当detailed=True时,引擎会在训练结束时打印所有summary 表格;当detailed=False时,用户可以按需定制需要展示的表格。从 eager_engine.py 的源码看,引擎维护了一张SummaryView到配置键名的映射表(views_dict),并将 Overview、Model、Kernel、Operator 四类设为默认视图(default_views)。也就是说,即使你不写summary段,这四张表也会默认打印;写入的键值为True时会被加入待打印列表,值为False时则跳过。
各 summary 子参数说明:
| 参数名 | 参数释义 | 默认值 |
|---|---|---|
| summary.overview | 显示每种类型的 Event 时间消耗 | True |
| summary.device | 显示 CPU 和 GPU 的平均利用率信息 | False |
| summary.model | 显示模型 dataloader、forward、backward、optimization 时间消耗 | True |
| summary.dist | 显示计算、通信以及重叠时间 | False |
| summary.kernel | 显示 GPU 执行的 kernel 信息 | True |
| summary.op | 显示框架中算子(op)的执行信息 | True |
| summary.mem | 显示内存/显存占用统计信息 | False |
| summary.memcpy | 显示框架中调用内存操作所花费的时间 | False |
2.2 源码层面的配置读取逻辑
以下代码片段位于 eager_engine.py,展示了 Profiler 配置从 YAML 到paddle.profiler.Profiler实例的完整映射关系:
self.profiler = None if "Profiler" in configs and configs.get("Profiler", {}).get("enable", False): self.profiler_config = configs["Profiler"] scheduler = self.profiler_config.get("scheduler", None) profiler_log = self.profiler_config.get("profiler_log", "./profiler_log") record_shapes = self.profiler_config.get("record_shapes", True) profile_memory = self.profiler_config.get("profile_memory", True) self.profiler = paddle.profiler.Profiler( targets=[paddle.profiler.ProfilerTarget.CPU, paddle.profiler.ProfilerTarget.GPU], scheduler=scheduler, on_trace_ready=paddle.profiler.export_chrome_tracing(profiler_log), record_shapes=record_shapes, profile_memory=profile_memory, ) self.profiler.start() logger.warning("Profiler is enabled, do not enable it in production.")可以确认以下几点实现事实:
- 目标同时覆盖 CPU 与 GPU:
targets同时传入ProfilerTarget.CPU与ProfilerTarget.GPU,因此 CPU 侧的算子调度开销与 GPU 侧的 kernel 执行都会被记录; - 默认值由引擎兜底:
profiler_log在配置缺省时使用./profiler_log,record_shapes与profile_memory缺省为True,与文档表格一致; - 输出格式为 Chrome Tracing:
on_trace_ready绑定export_chrome_tracing(profiler_log),即 JSON 产物可直接在chrome://tracing/中加载; - 引擎会在每步结束时上报:训练循环内(第 399 行附近)调用
self.profiler.step(),与scheduler的区间语义配合完成采样; - 训练收尾自动输出:
_profiler_done(第 859-872 行)负责stop()、打印 summary 与提示 VisualDL 启动命令,同时引擎会打印一行日志:"For more information please install visualdl and run it with following command"。
引擎打印 summary 时以sorted_by=paddle.profiler.SortedKeys.GPUTotal排序(第 857 行),这意味着 Kernel/Operator 表格中的热点项会按GPU 总耗时从高到低排列,方便直接定位最耗时的 kernel。
提示:源码中
EagerEngine对应动态图(dygraph)训练路径,而 auto_engine.py 中同样从paddle.profiler引入SummaryView与job_schedule_profiler_range,说明自动并行(auto parallel)路径同样具备 Profiler 能力,但本文以混合并行动态图路径的文档说明为准。
三、运行分析:在 GPT 混合并行任务中开启 Profiler
本节以GPT 混合并行(hybrid parallel)训练为例,演示完整的启用流程。
3.1 进入模型目录
cd slm/model_zoo/gpt-33.2 修改配置文件或使用命令行覆盖
打开 pretrain_gpt_base.yaml,将Profiler.enable改为True,并按上一节说明调整scheduler、detailed、summary等参数;也可以不修改文件,直接使用命令行参数覆盖。例如:
python -m paddle.distributed.launch \ ./tools/train.py -c \ ./ppfleetx/configs/nlp/gpt/pretrain_gpt_1.3B_dp8.yaml -o Profiler.enable=True该命令从slm/model_zoo/gpt-3目录执行,-c指定 1.3B 规模、DP8 的预训练配置(pretrain_gpt_1.3B_dp8.yaml),-o Profiler.enable=True以键值覆盖方式动态开启分析器,无需改动任何文件。
3.3 实操建议
在使用 Profiler 工具进行性能分析时,建议减少 train 的步数,获得分析数据即可停止训练。
原因有两方面:一是 Profiler 的采样区间(如[1, 5])本身只需要几个 step 就能覆盖;二是开启 profiler 与内存统计会引入额外开销,长时间开启既不必要也会污染性能数据。仓库 pretrain_gpt_base.yaml 中Engine.max_steps默认高达 500000,因此做剖析时务必把步数临时调小,例如通过-o Engine.max_steps=5一并覆盖。
四、结果分析:两种查看方式
训练结束后,会得到两类数据:
- 根据配置信息在控制台打印的 summary 表格;
- 在配置的
profiler_log目录中保存的profiler JSON 文件。
JSON 文件可以通过以下两种方式查看:
- Chrome Tracing:在 chrome 浏览器中打开
chrome://tracing/,然后打开 JSON 文件查看时间线; - VisualDL:根据控制台提示信息(引擎会打印一行
visualdl --host 0.0.0.0 --logdir <profiler_log>命令),安装并启动 VisualDL:
visualdl --logdir log_path然后根据提示在浏览器中打开性能分析模块查看。
在使用 visualdl 时,如果 log 文件数据较大,启动会比较耗时,请耐心等待。
关于具体的信息含义解释以及分析方法,可参考 PaddlePaddle 官方提供的 Profiler 教程文档与paddle.profiler.ProfilerAPI 文档(在模型开发中通用)。官方文档同时适用于本仓库场景,本文第五、六节给出的报表解读即为官方语义在本仓库混合并行任务中的具体体现。
五、附录:控制台 summary 报表示例与解读
以下示例来源于仓库文档 hybrid_profiler.md,对应一次 4-step 采样的 GPT 混合并行训练。
5.1 Overview Summary:各类事件的总体时间构成
---------------------------------------------Overview Summary--------------------------------------------- Time unit: ms ------------------------- ------------------------- ------------------------- ------------------------- Event Type Calls CPU Time Ratio (%) ------------------------- ------------------------- ------------------------- ------------------------- ProfileStep 4 18591.04 100.00 CudaRuntime 87527 8555.11 46.02 Operator 21912 1883.11 10.13 UserDefined 13116 1841.33 9.90 OperatorInner 33668 1018.39 5.48 Forward 8 731.46 3.93 Backward 4 671.82 3.61 Optimization 4 315.91 1.70 Dataloader 4 1.37 0.01 ------------------------- ------------------------- ------------------------- ------------------------- Calls GPU Time Ratio (%) ------------------------- ------------------------- ------------------------- ------------------------- Kernel 16092 4924.90 26.49 Memcpy 4278 3617.26 19.46 Memset 780 2.31 0.01 Communication 192 2363.13 12.71 ------------------------- ------------------------- ------------------------- -------------------------解读要点:CPU 侧CudaRuntime占比高达 46.02%,说明大量 CPU 时间消耗在 CUDA 运行时 API 调用(如 launch、同步)上;GPU 侧Kernel占 26.49%、Memcpy占 19.46%、Communication占 12.71%。在混合并行场景中,通信(Communication)占比与 DP/MP/PP 的切分策略强相关,若该比例过高,应优先检查通信算子与重叠调度。
5.2 Model Summary:模型各阶段时间分解
-----------------------------------------------------Model Summary----------------------------------------------------- Time unit: ms --------------- ------ ----------------------------------------------- --------------------------------------------- Name Calls CPU Total / Avg / Max / Min / Ratio(%) GPU Total / Avg / Max / Min / Ratio(%) --------------- ------ ----------------------------------------------- --------------------------------------------- ProfileStep 4 18591.04 / 4647.76 / 14114.47 / 757.27 / 100.00 4924.90 / 1231.22 / 2853.61 / 682.04 / 100.00 Dataloader 4 1.37 / 0.34 / 0.85 / 0.16 / 0.01 0.00 / 0.00 / 0.00 / 0.00 / 0.00 Forward 8 731.46 / 91.43 / 133.28 / 49.03 / 3.93 714.83 / 89.35 / 174.91 / 4.72 / 14.51 Backward 4 671.82 / 167.96 / 168.29 / 167.52 / 3.61 1701.53 / 425.38 / 426.97 / 424.10 / 34.55 Optimization 4 315.91 / 78.98 / 89.07 / 73.78 / 1.70 108.27 / 27.07 / 27.09 / 27.06 / 2.20 Others - 16870.48 / - / - / - / 90.75 2400.27 / - / - / - / 48.74 --------------- ------ ----------------------------------------------- ---------------------------------------------解读要点:Forward调用 8 次(4 个 step × 2,符合 GPT 前向中 q/k/v 融合或 micro-batch 展开的结构),Backward4 次;GPU 侧Backward耗时(1701.53 ms,34.55%)显著高于Forward(714.83 ms,14.51%),且Others在 CPU 侧占比高达 90.75%,提示大量时间消耗在未归类事件(如同步等待)上,需要结合 Operator/Kernel 明细进一步定位。
5.3 Operator Summary:算子级热点
----------------------------------------------------------------Operator Summary----------------------------------------------------------------- Time unit: ms ---------------------------------------------------- ------ ----------------------------------------- ---------------------------------------- Name Calls CPU Total / Avg / Max / Min / Ratio(%) GPU Total / Avg / Max / Min / Ratio(%) ---------------------------------------------------- ------ ----------------------------------------- ---------------------------------------- -----------------------------------------------------------Thread: All threads merged------------------------------------------------------------ GradNodePyLayer_RecomputeFunction_backward 96 663.37 / 6.91 / 17.17 / 4.01 / 18.56 1629.87 / 16.98 / 17.41 / 16.69 / 26.98 TransformerDecoderLayer 96 262.68 / 2.74 / 5.91 / 1.90 / 39.60 661.18 / 6.89 / 7.11 / 6.73 / 40.57 backward 96 318.62 / 3.32 / 10.57 / 1.31 / 48.03 968.69 / 10.09 / 10.31 / 9.91 / 59.43 matmul dygraph 2312 200.13 / 0.09 / 1.61 / 0.04 / 5.60 1487.76 / 0.64 / 9.81 / 0.22 / 24.63 matmul infer_meta 964 1.42 / 0.00 / 0.01 / 0.00 / 0.71 0.00 / 0.00 / 0.00 / 0.00 / 0.00 matmul compute 964 71.38 / 0.07 / 1.59 / 0.03 / 35.67 644.02 / 0.67 / 9.81 / 0.22 / 43.29 MEMSET 192 - / - / - / - / - 0.42 / 0.00 / 0.00 / 0.00 / 0.07 volta_fp16_s884gemm_fp16_128x128_ldg8_f2f_nn 384 - / - / - / - / - 199.35 / 0.52 / 0.83 / 0.22 / 30.95 volta_fp16_s884gemm_fp16_256x128_ldg8_f2f_nn 384 - / - / - / - / - 263.96 / 0.69 / 0.79 / 0.59 / 40.99 volta_h884gemm_64x128_ldg8_nn 192 - / - / - / - / - 141.13 / 0.74 / 0.92 / 0.61 / 21.91 void cutlass::Kernel<cutlass_70_tensorop_f16_... 4 - / - / - / - / - 39.15 / 9.79 / 9.81 / 9.78 / 6.08 matmul node_creation 676 2.05 / 0.00 / 0.03 / 0.00 / 1.02 0.00 / 0.00 / 0.00 / 0.00 / 0.00 ...解读要点:GradNodePyLayer_RecomputeFunction_backward(重计算反传)是 CPU/GPU 双侧的绝对热点,GPU 占比 26.98%;其下的TransformerDecoderLayer与backward是嵌套子项,说明重计算的反向链路是主要开销来源。matmul dygraphGPU 耗时 1487.76 ms(24.63%),其 compute 内核为多个volta_fp16_*gemm系列 kernel,在 V100(sm_70)环境上分别贡献 20.97%~40.99% 的子项占比。这类明细可以指导是否启用fused_linear、fuse_attn_qkv等算子融合开关(参考 pretrain_gpt_base.yaml 中 Model 段的fused_linear: False、fuse_attn_qkv: True等配置)。
5.4 Kernel Summary:GPU kernel 热点排行
---------------------------------------------------------------Kernel Summary--------------------------------------------------------------- Time unit: ms ------------------------------------------------------------------------------------------ ------ ---------------------------------------- Name Calls GPU Total / Avg / Max / Min / Ratio(%) ------------------------------------------------------------------------------------------ ------ ---------------------------------------- ncclKernel_AllReduce_RING_LL_Sum_half(ncclWorkElem) 96 2360.57 / 24.59 / 2202.54 / 0.46 / 47.93 volta_fp16_s884gemm_fp16_256x128_ldg8_f2f_nn 384 263.96 / 0.69 / 0.79 / 0.59 / 5.36 volta_fp16_s884gemm_fp16_128x128_ldg8_f2f_stages_32x1_tn 384 241.74 / 0.63 / 0.84 / 0.22 / 4.91 void paddle::operators::VectorizedRandomGenerator<phi::dtype::float16, unsigned char> 580 209.08 / 0.36 / 0.97 / 0.06 / 4.25 volta_h884gemm_64x128_ldg8_nn 288 203.89 / 0.71 / 0.92 / 0.57 / 4.14 volta_fp16_s884gemm_fp16_128x128_ldg8_f2f_nn 384 199.35 / 0.52 / 0.83 / 0.22 / 4.05 volta_h884gemm_256x64_ldg8_tn 288 149.52 / 0.52 / 0.54 / 0.45 / 3.04 void phi::funcs::VectorizedBroadcastKernel<phi::dtype::float16, phi::dtype::float16, ph... 1352 123.12 / 0.09 / 0.40 / 0.05 / 2.50 void paddle::operators::SoftmaxMaskFuseUpperTriangleGPUKernel<phi::dtype::float16, 10> 192 122.37 / 0.64 / 0.66 / 0.60 / 2.48 void cutlass::Kernel<cutlass_70_tensorop_f16_s884gemm_f16_256x128_nt_align8> 100 103.07 / 1.03 / 8.08 / 0.73 / 2.09 void phi::funcs::VectorizedElementwiseKernel<phi::dtype::float16, paddle::operators::Cu... 292 90.80 / 0.31 / 0.83 / 0.06 / 1.84 volta_h884gemm_64x128_ldg8_nt 192 79.76 / 0.42 / 0.43 / 0.40 / 1.62 void Eigen::internal::EigenMetaKernel<Eigen::TensorEvaluator<Eigen::TensorAssignOp<Eige... 576 75.36 / 0.13 / 0.20 / 0.07 / 1.53 ...解读要点:ncclKernel_AllReduce_RING_LL_Sum_half以 2360.57 ms、47.93% 的占比高居榜首(96 次调用),这是混合并行中梯度 AllReduce 通信的典型特征——在 DP=8 的场景下,每个 step 的梯度规约都会触发 NCCL AllReduce。紧随其后的是各类volta_fp16_s884gemm/volta_h884gemmGEMM kernel,它们是 Transformer 中线性层与注意力矩阵乘的主体。整体呈现出"通信 kernel 与 GEMM kernel 分庭抗礼"的形态,若期望降低 AllReduce 占比,可考虑梯度累积、张量融合(Optimizer.tensor_fusion)或通信与计算重叠等策略。
六、从报表到调优:一套可落地的分析路径
综合以上四类报表,推荐的分析顺序为:
- 先看 Overview:确认 CPU/GPU 侧各类事件占比,若
Communication或Memcpy占比异常,优先排查通信与数据搬运; - 再看 Model:对比 Forward / Backward / Optimization / Dataloader 的时间占比,识别阶段级瓶颈(Backward 过重通常指向重计算或梯度同步);
- 深入 Operator:定位是哪些算子占据 GPU 时间,评估算子融合(如
fuse_attn_qkv、fused_linear)与 kernel 选择是否合理; - 最后落 Kernel:确认底层 kernel 名称与占比,验证是否命中了预期的 GEMM 模板(如
volta_fp16_*、cutlass系列),并检查ncclKernel_AllReduce_*这类通信 kernel 的调用次数是否与并行策略一致。
值得注意的是,Profiler 输出的是事实数据而非结论,相同占比在不同并行策略下的含义不同:例如在 PP 场景中Others类目占比高,往往意味着流水线气泡(bubble)导致的等待时间,需要结合 hybrid_parallel.md 中的并行策略文档综合分析。
结语
通过本文你可以完成从"配置开启"到"报表解读"的完整 Profiler 使用闭环:在 pretrain_gpt_base.yaml 中设置Profiler.enable: True(或通过-o Profiler.enable=True覆盖),借助scheduler限定采样区间、summary定制输出视图,训练完成后用 Chrome Tracing 或 VisualDL 分析 JSON 产物。底层引擎 eager_engine.py 的源码证实:配置会直接映射为paddle.profiler.Profiler实例,CPU/GPU 双目标采样、Chrome Tracing 导出与按 GPU 总耗时排序的 summary 打印均由引擎自动完成。掌握这套流程后,面对 GPT 混合并行训练的吞吐瓶颈,你就能用数据说话,快速定位通信、算子与内存层面的优化空间。
- 人工智能
- 大模型
- 预训练
- 微调
- LoRA
- RLHF
- 强化学习
- 分布式训练
【免费下载链接】PaddleNLP
Easy-to-use and powerful LLM and SLM library with awesome model zoo.
相关推荐
PaddleNLP GPT 混合并行训练与 Zero-shot 文本生成实战指南
PaddleNLP GPT 混合并行训练与 Zero shot 文本生成实战指南 本指南以 PaddleNLP 仓库 slm/model_zoo/gpt 3/p
人工智能大模型预训练微调LoRARLHF强化学习分布式训练模型推理服务推理引擎模型量化模型压缩本地部署NLPPaddleNLP Trainer API 全解:从单卡微调到混合并行训练实战指南
PaddleNLP Trainer API 全解:从单卡微调到混合并行训练实战指南 PaddleNLP 的 Trainer 训练 API 将模型训练过程中的通用
人工智能大模型预训练微调LoRARLHF强化学习分布式训练模型推理服务推理引擎模型量化模型压缩本地部署NLPverl 分布式训练性能剖析:PyTorch Profiler 配置与实战指南
verl 分布式训练性能剖析:PyTorch Profiler 配置与实战指南 本文系统讲解 verl(HybridFlow)中如何使用原生 PyTorch P
人工智能大模型强化学习RLHF分布式训练微调
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考