agent-l / docs /experiments /exp_b_performance_tuning.md
zhou777's picture
Add files using upload-large-folder tool
0525670 verified
|
Raw
History Blame Contribute Delete
8.26 kB

Experiment B Performance Tuning

背景

本文档基于 2026-03-31 对实验 B 当前正式训练的实时观测整理,目标是回答:

  1. 当前系统资源到底卡在哪里
  2. 哪些参数最值得优先调整
  3. 怎样在不破坏现有可跑性的前提下,尽量提升训练速度

当前训练实例:

  • 训练日志:runs/logs/tomato-exp-b-attr_20260331-192847.log
  • 输出目录:runs/mid/qwen3_5_35b_a3b_exp_b_attr/v1-20260331-192847
  • 当前启动时的关键降载参数:
    • DATASET_NUM_PROC=1
    • DATALOADER_NUM_WORKERS=2

说明:

  • 这两个参数不是为了提速,而是为了绕过上一轮实验 B 在数据映射阶段被 SIGKILL 的问题。
  • 当前这轮已经成功越过上一轮失败位置,并进入正式 Train 阶段。

实时观测

1. GPU

观测时刻的 nvidia-smi

  • GPU 显存占用约 33.9 GiB ~ 35.1 GiB / 49.1 GiB
  • GPU 利用率约 19% ~ 27%
  • 功耗约 95W ~ 115W

补充观测:

  • nvidia-smi dmon 连续采样期间,显存保持高占用,但 sm 利用率瞬时值很低。
  • 这说明模型已经装载完成,但算力并没有持续吃满。

结论:

  • 当前不是“显存不够”,而是“显存还有余量,但计算吞吐没有被充分压满”。
  • 对 RTX 6000 Ada 来说,当前功耗和利用率都偏保守,明显还有提速空间。

2. CPU

观测时刻的系统级 CPU:

  • 112 核机器整体 idle 大约 90%
  • iowait1%

训练相关进程:

  • 4 个主要训练 worker 的单进程 CPU 大约都在 96% 左右

结论:

  • 机器总 CPU 资源非常充足。
  • 当前不是整机 CPU 不够,而是训练进程只吃到了少量核,整体 CPU 远未成为上限。

3. 内存与 Swap

观测时刻:

  • 物理内存总量约 1.0 TiB
  • available867 GiB
  • swap 15 GiB 已满

结论:

  • 内存容量本身完全不是问题。
  • 但 swap 已满说明机器历史上发生过明显的内存换出,这对训练稳定性是个风险信号。
  • 上一轮实验 B 在数据映射阶段被 SIGKILL,与预处理阶段资源压力过高是吻合的。

4. 磁盘 I/O

iostat 观测结果:

  • CPU iowait 很低
  • NVMe 利用率很低,吞吐量也不高

结论:

  • 当前不是磁盘带宽瓶颈。
  • 训练速度慢,主要不是因为数据文件读不动。

5. 训练阶段特征

从日志看,实验 B 的时间主要消耗在两段:

  1. 数据映射 / tokenization 阶段很长
  2. 进入训练后,GPU 利用率仍偏低

同时,日志里还能看到两个重要事实:

  • 当前使用的是 --attention_backend unfused
  • 参数对象里实际 sequence_parallel=False

这意味着:

  • 训练吞吐已经天然比更激进的 fused/flash 路线慢
  • 不能把当前性能预期建立在“高级并行优化已生效”的假设上

主要瓶颈判断

基于当前观测,实验 B 的性能问题优先级大致如下:

  1. 预处理阶段过慢,且并发一高就有稳定性风险
  2. 训练阶段 GPU 显存占用中等,但算力利用率偏低
  3. 当前批大小和重计算策略偏保守,更像“先保跑通”,不是“先榨吞吐”
  4. 现有 unfused attention backend 本身限制了吞吐上限

不是主要瓶颈的项:

  • 机器总内存容量
  • 磁盘 I/O
  • 整机 CPU 总量

提速建议

以下建议按优先级排序。

P0:先把“稳定跑通”和“性能调优”分成两套参数

当前这轮参数适合保命,不适合作为长期最快配置。

建议保留两套启动配置:

  • safe 配置
    • DATASET_NUM_PROC=1
    • DATALOADER_NUM_WORKERS=2
  • fast 配置
    • DATASET_NUM_PROC=2
    • DATALOADER_NUM_WORKERS=4
    • 开始逐步压测

理由:

  • 现在最清楚的事实是:预处理并发拉高后,实验 B 曾经直接被系统杀掉。
  • 但一味维持 1/2 组合,会显著拖慢数据准备。

推荐做法:

  1. 先用 safe 配置跑通一次完整训练
  2. 再单独开小样本性能压测,把 dataset_num_procdataloader_num_workers 逐步抬高
  3. 只要出现明显 swap 抖动或再次 SIGKILL,立即回退

P1:把数据缓存预构建为独立步骤

当前训练把“数据准备”和“正式训练”绑在同一次进程里,这会让每次重试都重复走长时间 Map

建议:

  • 增加一个独立的“数据缓存预构建”步骤
  • 在正式训练前先把 train/val 数据的 tokenization 和缓存文件准备好
  • 正式训练只消费缓存

价值:

  • 可以把最不稳定、最容易触发 SIGKILL 的阶段前置
  • 训练重试时不必重复长时间 Map
  • 这通常是当前最容易拿到的真实提速项

P2:优先尝试增大 MICRO_BATCH_SIZE

当前 GPU 显存大约只占到了 34~35 GiB / 49 GiB,每卡仍有十几 GiB 余量。

建议从小步试探:

  • 先试 MICRO_BATCH_SIZE=5
  • 再试 MICRO_BATCH_SIZE=6
  • 同步调整 GLOBAL_BATCH_SIZE

推荐原则:

  • 维持梯度累积逻辑清晰
  • 每次只改一个量
  • 观察显存、step time、是否出现 OOM

理由:

  • 当前显存没打满
  • 但 GPU 算力利用率偏低
  • 典型原因之一就是每步喂给 GPU 的活太小

这是最可能直接提升训练吞吐的参数。

P3:减少重计算强度

当前配置:

  • --recompute_granularity full
  • --recompute_method uniform
  • --recompute_num_layers 1

在显存还有余量的前提下,建议做对照试验:

  • 降低 recompute 范围
  • 或直接尝试关闭部分重计算

理由:

  • 重计算本质上是“用时间换显存”
  • 现在更像是时间更紧,而不是显存更紧

建议:

  • 先保留当前配置跑通一版
  • 之后做一组短跑 benchmark,比对 step time 和显存峰值

P4:检查 attention backend

当前是:

  • --attention_backend unfused

这通常意味着:

  • 兼容性更稳
  • 吞吐更差

建议:

  • 在不影响稳定性的前提下,继续修复 / 验证更快的 attention backend
  • 如果后续能恢复到更高效的 fused/flash 路线,训练速度会有明显提升

这项的潜在收益很大,但风险也高,所以优先级放在批大小和重计算之后。

P5:重新评估 expert_model_parallel_size

当前配置:

  • expert_model_parallel_size=4
  • tensor_model_parallel_size=1
  • pipeline_model_parallel_size=1

这说明当前主要是 EP 路线。

建议:

  • expert_model_parallel_size=4 和更保守配置做小样本性能对照
  • 重点观察 step time、GPU util 和通信开销

原因:

  • 当前 GPU 利用率不高,可能有一部分时间耗在 MoE 路由和通信上
  • 这类瓶颈通常不能只靠加 dataloader 解决

这项不建议直接在正式训练上改,先做 benchmark。

P6:处理 swap 已满的问题

虽然当前物理内存还很多,但 swap 已满不是健康信号。

建议:

  • 正式训练前确认没有残留的大进程长期占内存
  • 定期清理历史残留的训练/推理进程
  • 把“预处理高并发压测”与“正式训练”分开,避免训练时叠加系统脏状态

如果后续还出现:

  • 数据映射阶段突然变慢
  • 训练被 SIGKILL

应优先排查内存换出和宿主机资源保护,而不是先怀疑模型参数。

推荐调优顺序

建议按下面顺序做,不要一次改太多:

  1. 先用当前 safe 配置完整跑通实验 B
  2. 抽离数据缓存预构建步骤
  3. 压测 MICRO_BATCH_SIZE=5/6
  4. 压测较轻的 recompute 配置
  5. 压测更激进的 dataloader / dataset 并发
  6. 再评估 attention backendexpert_model_parallel_size

最值得先做的三件事

如果只做最有收益的三项,优先建议:

  1. 把数据缓存预构建独立出来,避免每次重试都重复长时间 Map
  2. 增大 MICRO_BATCH_SIZE,把剩余显存换成吞吐
  3. 在稳定跑通后,降低重计算强度,减少“用时间换显存”

一句话结论

当前实验 B 的主要问题不是机器不够强,而是训练配置仍偏“保守保命型”。

这台机器的瓶颈不在磁盘和总内存,当前最值得利用的性能空间主要在:

  • 更合理的数据缓存策略
  • 更大的 batch
  • 更少的重计算
  • 更高效的 attention backend