mcpField
D
debug

debug

github.com/fcakyon开发45263 次安装3 天前更新
代码仓库

关于 debug

面向 Claude Code 的机器学习故障排查技能,要求先收集证据再提出修复方案。它引导研究者依次进行探测、标记假设、冒烟测试和对照实验,得出有依据的诊断或明确说明尚不确定。

主要功能

  1. 01五步调试流程
  2. 02探测进程、系统、GPU 和磁盘
  3. 03检查日志与检查点
  4. 04基于假设的冒烟测试
  5. 05每次只改一个变量的对照
  6. 06提供证据支持的诊断报告

适用场景

  1. 01调查崩溃或卡住的问题
  2. 02追查损失为 NaN 或训练发散
  3. 03诊断 GPU 利用率低
  4. 04重启前验证疑似原因

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/fcakyon/labrat --skill debug

安装后在 Claude Code 中输入/debug确认已加载。

详细介绍

调试:先取证,再行动

在 ML 调试中,代价最高的一类错误是仅凭看似合理的推测就断言原因,然后尝试用“修复”掩盖真正的问题。这项技能要求严格遵循以下顺序:探查 → 假设 → 冒烟测试 → 对照 → 断言。

当助手在没有工具输出佐证的情况下声称找到了原因时,Agentic Stop hook 会从 reason 路由到此处。

何时运行

用户刚刚说了以下任意内容:

  • “为什么 X 失败了/发散了/出现 NaN/OOM/卡住了/变慢了/崩溃了”
  • “loss 在上升”“指标看起来很奇怪”“GPU 利用率是 0”
  • “调试这个”“诊断”“排查故障”“调查这次运行”
  • 粘贴日志片段并询问哪里出了问题

五步协议

第 1 步:低成本探查

形成任何假设之前,先收集低成本证据。以下操作都不会耗费超过几秒:

进程状态:

ps aux | grep -E '(python|train|torchrun|accelerate)' | grep -v grep

进程还在运行吗?是僵尸进程还是已终止进程?是否有多个实例?

内核/系统事件:

dmesg | tail -100 # OOM kills, hardware errors, NFS errors
journalctl -xe --since "1 hour ago" | tail -50

GPU 状态:

nvidia-smi
nvidia-smi --query-gpu=utilization.gpu,memory.used,temperature.gpu --format=csv

GPU 到底在使用吗?“训练”期间 GPU 处于空闲状态,说明进程卡在数据加载上,或者已经退出。

磁盘/文件系统:

df -h /path/to/run-dir
du -sh /path/to/run-dir/*

磁盘空间耗尽了吗?检查点没有写入吗?

日志回溯: 读取训练日志最后几百行。不要只相信用户的总结,他们可能只是粗略浏览过。查找:

  • 异常回溯
  • 重复出现的“loss=NaN”或“grad_norm=Inf”
  • 提前停止的提示(运行可能已正常完成)
  • _最后_一次成功的 epoch/step(进度停在了哪里)

检查点状态:

ls -la /path/to/run-dir/checkpoints/

最近一次检查点是什么时候写入的?从它的大小能看出什么?空的 .pt 文件与一个写到一半的 2GB 文件情况不同。

第 2 步:提出假设(明确标注为假设)

探查之后,说明_可能_发生了什么,并明确表述为假设:

“假设:此次运行因 OOM 而失败,因为 dmesg 显示 3 分钟前发生了 oom-kill,且进程已消失。尚未排除的其他假设:(a) NFS 写入超时;(b) 被同级进程显式终止。”

绝不要直接跳到“原因是 X”。假设标签明确指出了你尚不确定的内容。

第 3 步:冒烟测试

确认或否定假设,成本最低的方法是在受控条件下复现故障特征:

  • OOM 假设:使用 batch_size=1 重跑 1 步。如果成功运行,则确认是 OOM;如果以相同方式失败,则说明并非 OOM。
  • 数据假设:使用内存中的合成数据集重跑。如果运行正常,则问题可能与数据路径有关。
  • 模型假设:仅对单个 batch 执行前向传播,并使用 eval() 模式。Loss 是有限值吗?输出正常吗?
  • 优化器假设:使用 lr=0 重跑。如果 loss 仍然爆炸,说明损失函数本身有问题(而不是优化器)。
  • 分布式假设:在 1 张 GPU 上重跑。如果运行正常,则问题可能与 DDP/NCCL 有关。

30 秒的冒烟测试胜过 30 分钟的重启祈祷。

第 4 步:对照

如果冒烟测试的结果不明确,就运行对照测试:只更改失败配置中的一个变量,然后重跑冒烟测试。差异有助于缩小可能的原因机制。

常见的对照维度(每次只更改一个):

  • 单源数据与多源数据
  • 默认 workers 与调整后的 workers
  • 开启与关闭混合精度
  • 开启与关闭梯度检查点
  • 开启与关闭 torch.compile
第 5 步:断言原因

只有在证据经过探查、冒烟测试和对照逐步累积之后,才能断言原因。断言应引用能够证明原因的具体工具输出:

“根因:NFS 写入超时。证据:dmesg 显示 14:23 出现 nfs server X not responding(与最后一次写入检查点的时间是同一分钟),且使用 batch=1 进行的冒烟测试重现了超时。建议的修复方法:为检查点绑定挂载本地临时目录,并在 epoch 结束时 rsync 到 NFS。”

如果证据没有逐步累积,就不要将假设升级为原因。应说明“我目前还不知道”,并提出下一步探查。

应避免的做法

  • “可能是 X,我试试 Y” → 不要这样做。先探查。
  • 通过做出小改动来重新运行,以此诊断问题。先进行冒烟测试,再有意重新运行。
  • 只引用用户的描述作为证据:重新阅读实际日志。
  • 当产物与之矛盾时,仍停留在第一个看似合理的原因上。

输出

一份简洁的诊断报告,包含:(1) 探查结果;(2) 假设;(3) 冒烟测试结果;(4) 原因或尚不确定的结论;(5) 建议的后续操作。每项判断都要引用支持它的工具输出。

评论

支持 Markdown