원클릭으로
paddle-debug
// 在 Paddle 代码库中定位问题并输出高质量调试报告的专用技能。当遇到以下场景时优先使用:(1) Paddle 框架 bug 调试,(2) 算子实现问题排查,(3) 训练脚本异常诊断,(4) 分布式训练故障定位,(5) CUDA/GPU 相关错误处理,(6) 需要生成结构化调试报告。
// 在 Paddle 代码库中定位问题并输出高质量调试报告的专用技能。当遇到以下场景时优先使用:(1) Paddle 框架 bug 调试,(2) 算子实现问题排查,(3) 训练脚本异常诊断,(4) 分布式训练故障定位,(5) CUDA/GPU 相关错误处理,(6) 需要生成结构化调试报告。
将原生 PyTorch 自定义算子库、Torch extension、生态库(TorchCodec/FlashInfer/DeepEP 等)以及 Kernel DSL 生态(Triton/TileLang/TVM FFI 等)以最小修改方式接入 PaddlePaddle。遇到以下场景务必使用:迁移外部算子库到 Paddle;分析 PFCCLab fork 与上游的兼容差异;处理 paddle.enable_compat、paddle.utils.cpp_extension、TORCH_LIBRARY、torch.ops、at::Tensor/c10 compat 问题;为 compat gap 设计最小 workaround 并准备 Paddle issue 最小复现。
PaddlePaddle (飞桨) C++ 算子开发指南。提供从 YAML 配置、InferMeta 函数、Kernel 实现、Python API 封装、单元测试到编译验证的完整算子开发流程指导。在以下场景使用此 skill:(1) 为 Paddle 框架新增 C++ 算子 (2) 修改或调试已有 Paddle 算子 (3) 编写算子的 YAML 配置、InferMeta、Kernel、Python API 或单元测试 (4) 理解 Paddle 算子开发架构和流程 (5) 编译 Paddle 并验证算子正确性
Use when needing to compile, rebuild, or install Paddle from source after code changes. Covers cmake configuration, ninja incremental build, wheel packaging, and common build failure diagnosis.
Use when working with Paddle 3.0 compiler full pipeline: SOT (Symbolic Opcode Translator) for bytecode-level dy2st graph capture, PIR (Paddle IR) for SSA-based intermediate representation, CINN for fused CUDA kernel generation, operator decomposition (Prim), or the end-to-end flow from Python eager code to optimized GPU execution.
Use when working with Paddle's distributed training system: understanding parallelism strategies (DP, ZeRO, TP, PP, SP), semi-automatic parallel with ProcessMesh + shard_tensor, SPMD inference rules, pipeline scheduling, or auto_parallel Engine.
Use when navigating Paddle eager-mode (dynamic graph) source code, tracing forward/backward execution, debugging autograd issues, understanding PyLayer, or investigating complex-valued gradient computation. Covers Python API to C++ kernel call chain, backward graph topology sort, and inplace version tracking.
| name | paddle-debug |
| description | 在 Paddle 代码库中定位问题并输出高质量调试报告的专用技能。当遇到以下场景时优先使用:(1) Paddle 框架 bug 调试,(2) 算子实现问题排查,(3) 训练脚本异常诊断,(4) 分布式训练故障定位,(5) CUDA/GPU 相关错误处理,(6) 需要生成结构化调试报告。 |
调试遵循以下步骤:
用简洁的自然语言说明:
先确认 bug 能被稳定复现。若无法复现:
抽取独立的 Python 脚本承载问题:
numpy / random / paddle.seed 等)目标:一条命令即可复现 python reproduce_xxx.py。
阅读报错栈和相关代码时,先列出多个可能原因假设(数据异常、shape 错误、数值不稳定、环境不一致、算子实现问题等),不要立刻改代码。
围绕假设在关键路径上加入观测点:
| 观测方式 | 用途 |
|---|---|
| 打印与断言 | 在关键算子调用前后,打印 Tensor 的 shape、dtype、device、数值范围(min/max/mean) |
| 对比法 | 对同一逻辑分别在 CPU / GPU 上运行,比较中间结果差异 |
| 版本与环境信息 | 记录 paddle.__version__、CUDA/CUDNN 版本、驱动信息等 |
每完成一次带观测点的复现:
将调试日志保存到 .paddle-agent/debug-logs/ 目录。
基于已有观测和对比结果,先完成问题分析报告:
# [问题标题]
## 复现方式
- 命令:
- 环境:
- 最小脚本路径:
## 现象描述
[错误信息或异常行为]
## 根因分析
[配置 / 数据 / 框架 / 算子 / 环境中的哪一处有问题]
## 关键证据
[日志片段、对比结果、重要观测点输出]
报告存放在 .paddle-agent/debug-analysis/ 目录,没有该目录请创建。
归因时考虑以下维度:
只有在分析结论较为充分时,才进入最小修复阶段:
当判断问题可能由近期提交引入时:
git bisect 对可疑提交范围做二分定位对已定位的问题:
.paddle-agent/debug-analysis/详细的 CUDA 调试技巧:见 references/cuda-debug.md
快速参考:
# 启用错误检查环境变量复现问题
export PYTHONPATH=$(pwd)/Paddle/build/python
FLAGS_check_cuda_error=1 FLAGS_use_system_allocator=1 python reproduce.py
关键点:
FLAGS_check_cuda_error=1 让错误立即暴露PADDLE_ENFORCE_GPU_SUCCESS 不会调用 cudaGetLastError(),在错误路径上需手动清除cudaErrorInitializationError(3)——详见 references/cuda-debug.md 中的 CUDA Fork Safety 章节.h 后需重新编译所有引用它的 .cu,并重新链接 .socudaEventSynchronize、cudaStreamSynchronize 等,忽略返回值不仅丢失错误信息,还会导致 CUDA runtime 中残留 sticky errorPADDLE_ENFORCE_GPU_SUCCESS 抛出异常之前,手动调用 cudaGetLastError() 清除残留错误,否则 Python try/except 捕获异常后 CUDA 状态仍被污染cudaErrorInitializationError(3)num_workers > 0 fork 子进程;子进程继承了父进程中 GPU tensor 的引用,GC 回收时触发 cudaFreecudaGetDevice() 返回 cudaErrorInitializationError(3)、cudaErrorNoDevice(100)、cudaErrorInsufficientDriver(35) 均表示 CUDA 不可用cudaFree 是安全的,因为 fork 后子进程中的 GPU 内存不属于该进程,进程退出时由 OS/driver 回收修改 kernel 头文件后的增量编译:
cd build
# 编译修改的 kernel
ninja paddle/phi/CMakeFiles/phi_gpu.dir/kernels/gpu/<kernel_name>.cu.o -j512
# 重新链接 phi_gpu
ninja phi_gpu -j512
# 重新链接 libpaddle.so
ninja paddle/fluid/pybind/libpaddle.so -j512
# 如果 Python 库未自动更新,手动复制
cp paddle/fluid/pybind/libpaddle.so python/paddle/base/libpaddle.so
Paddle 构建产物存在两套路径,增量编译后 Python 加载的可能仍是旧版本:
| 构建产物路径 | Python 加载路径 | 说明 |
|---|---|---|
build/paddle/phi/libphi_core.so | build/python/paddle/libs/libphi_core.so | phi core 库 |
build/paddle/phi/libphi_gpu.so | build/python/paddle/libs/libphi_gpu.so | phi GPU 库 |
build/paddle/fluid/pybind/libpaddle.so | build/python/paddle/base/libpaddle.so | 主绑定库 |
增量编译后务必检查:
# 确认 Python 实际加载了哪个 .so
python -c "import paddle; import os; print(os.path.realpath(paddle.__file__))"
# 比较构建时间戳
stat build/paddle/phi/libphi_core.so
stat build/python/paddle/libs/libphi_core.so
# 如果时间戳不一致,手动同步
cp build/paddle/phi/libphi_core.so build/python/paddle/libs/libphi_core.so
cp build/paddle/phi/libphi_gpu.so build/python/paddle/libs/libphi_gpu.so
典型症状:修改了源码并重新编译,但运行时错误信息中的行号不变——这说明 Python 加载的仍是旧 .so。
当崩溃发生在公共底层函数(如 GetCurrentDeviceId、cudaFree)时,需穷举所有调用路径来定位真正的入口:
FLAGS_use_system_allocator)确定实际使用的分配器链路DenseTensor::~DenseTensor -> shared_ptr<Allocation> -> AllocationDeleter -> 具体分配器的 FreeImplbacktrace_symbols_fd 打印调用栈,确认实际触发路径PADDLE_ENFORCE_GPU_SUCCESS 是宏,行号由 __LINE__ 决定;FreeImpl 是虚函数,实际调用取决于运行时类型见 references/case-studies.md 了解实际调试案例。