Paddle 仓库调试
调试流程
1. 描述问题并构造最小复现
- 用简洁的自然语言说明:
- 触发步骤(命令、脚本、关键配置)。
- 期望行为 vs 实际行为。
- 是否只在特定环境 / 机器 / 设备 / 数据子集上出现。
- 任何调试开始前,先确认 bug 能被稳定复现。若按照给定命令或脚本无法复现:
- 检查命令是否抄错、参数是否缺失;
- 比对并对齐环境(Paddle / Python / CUDA / CUDNN / 驱动 / 显卡型号等);
- 确认与最初出问题的环境一致后再继续。
- 尽量抽取一个独立的 Python 脚本(或单测)承载问题:
- 固定随机种子(
numpy/random/paddle.seed等); - 使用固定、可序列化的小数据(固定随机数或离线样本);
- 去掉与问题无关的逻辑(复杂数据增强、冗余日志、训练循环中的花活等)。
- 固定随机种子(
- 目标是做到:
- 一条命令即可复现:
python reproduce_xxx.py; - 输入、输出和错误信息尽量稳定可重复。
- 一条命令即可复现:
2. 代码定位与多假设验证
2.1 使用工具定位代码
- ast-grep:用于结构化代码搜索,快速定位特定代码模式,推荐 ast-grep/agent-skill 中的 ast-grep 技能。
2.2 带观测点的复现
- 阅读报错栈和相关代码时,先列出多个可能原因假设(数据异常、shape 错误、数值不稳定、环境不一致、算子实现问题等),不要立刻改代码。
- 围绕这些假设,在关键路径上加入观测点,用合适的方式采集运行时信息(print、logger、profiling、断点、额外统计等)。
- 常用观测方式:
- 打印与断言:
- 在关键算子调用前后,打印 Tensor 的 shape、dtype、device、数值范围(min/max/mean)。
- 使用断言检查 shape、数值范围、NaN/Inf,在异常刚出现时 fail fast。
- 对比法:
- 对同一逻辑分别在 CPU / GPU 上运行,比较中间结果差异。
- 通过简化模型或更小 batch 验证问题是否依赖规模。
- 版本与环境信息:
- 记录
paddle.__version__、CUDA/CUDNN 版本、驱动信息等,保证之后能在相同环境下复现。
- 记录
- 打印与断言:
- 每完成一次带观测点的复现:
- 基于运行时数据排除不成立的假设,收敛到少数更可疑的根因;
- 在更窄的范围内继续加观测点,逐步缩小问题所在的模块 / 算子 / 配置。
- 将本轮调试产生的原始日志和关键观测结果统一保存到
.paddle-agent/debug-logs/目录,便于后续对比与归档。
3. 先写问题分析报告,再做最小修复
- 基于已有观测和对比结果,先完成问题分析报告,重点回答:
- 如何复现:命令、环境、最小脚本路径;
- 现象是什么:错误信息或异常行为;
- 根因是什么:配置 / 数据 / 框架 / 算子 / 环境中的哪一处有问题;
- 有哪些关键证据:日志片段、对比结果、重要观测点输出。
- 报告以独立文件形式存放在
.paddle-agent/debug-analysis/目录,按问题编号或日期命名,便于团队检索。 - 归因时可结合以下典型维度进行简要说明:
- 接口 / 形状 / dtype:
- 指出出错的 Paddle API 或算子,以及哪个输入 Tensor 的 shape / dtype 与预期不符。
- NaN / Inf / 数值发散:
- 说明哪一层或哪段前向 / 反向首次出现异常数值,以及关闭某些损失项或调整学习率后的对比结果。
- 性能与显存:
- 指明瓶颈主要在 CPU、IO 还是 GPU kernel,以及简化数据增强或调整 batch size / num_workers 后的变化。
- 接口 / 形状 / dtype:
- 只有在分析结论较为充分且需要推进修复时,才进入「最小修复」阶段:
- 设计改动面尽量小的一组修改来验证根因,而不是大范围重写或连带修改无关模块。
- 先用最小复现脚本验证问题已被修复且未引入新异常;
- 再用完整训练 / 推理脚本验证关键业务路径;
- 若问题仍存在或出现新异常,则基于新现象补充观测点,继续新的「假设 → 埋点观察 → 验证 / 否定 → 小步修复」循环。
4. 利用 Git / CI 收束和巩固结论
- 当判断问题可能由近期提交引入时:
- 使用
git bisect对可疑提交范围做二分定位,将排查范围压缩到少量变更。
- 使用
- 对已经定位并(准备)修复的问题:
- 补充一条覆盖「最小复现脚本」逻辑的单测,防止后续回归;
- 留意 CI 中与该模块相关用例是否出现新增失败或波动,并在调试报告中记录;
- 将最终结论与关键证据沉淀到
.paddle-agent/debug-analysis/中对应的问题文档,保证与代码和用例信息一致。
注意事项
- 调试的第一目标是稳定复现并缩小范围,不要一开始就尝试大规模重构或到处改逻辑。
- 任何「只在某些机器上出现」的问题,优先从环境差异入手,而不是猜测代码随机出错。
- 对于已经完成一次完整调试闭环的问题,建议整理:
- 问题现象与复现步骤;
- 归因(配置 / 数据 / 框架 / 算子 / 环境);
- 关键证据(日志、对比实验、最小复现脚本);
- 最终修复方案及其对行为、性能的影响。
- 在 Paddle 仓库或相关项目中遇到 bug 时,优先按本 skill 的流程执行,再考虑具体修复实现细节。