mcpField
D
debug-model

debug-model

github.com/modular测试与质量2071.3k 次安装3 天前更新
代码仓库

关于 debug-model

面向可运行 PyTorch 参考模型的 MAX 移植调试技能,适用于输出不一致的情况。它通过张量转储比较,区分模型、解码状态与服务流水线故障。

主要功能

  1. 01逐层生成 HF 和 MAX 张量转储
  2. 02数值比较并定位差异
  3. 03并行调查工作流
  4. 04检查强制解码与增量解码

适用场景

  1. 01排查自定义 MAX 移植的对齐失败
  2. 02检查量化或多 GPU 移植改动
  3. 03调查 MAX 升级后的回归

安装

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

$npx skills add https://github.com/modular/skills --skill debug-model

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

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
agent-workflow.md
comparator-build.md
comparator-output-patterns.md
stacked-failures.md

详细介绍

奇偶一致性/连贯性故障排查协议

模型运行时没有报错,但输出不正确。标量 F.print 插桩会掩盖方向性错误,而且每增加一处插桩都要完整重新编译。请先构建逐层张量转储比较器。之后的每项检查都只需从磁盘读取 numpy 数据。

适用场景: MAX 输出与可运行并可插桩的 PyTorch 参考模型不一致。主要场景是自定义架构移植版虽能提供服务,却无法通过奇偶性或连贯性检查。同一协议也适用于已正常工作的移植版的量化变体、已正常工作的单 GPU 移植版的多 GPU 转换,以及 MAX 升级后的回归问题。只要存在可信的参考模型,均可使用此协议。

不适用场景:

  • 服务加载时崩溃 → 修复配置、权重或模块(import-model)
  • 模块尚未实现完成 → import-model 第 2 阶段
  • 已验证的模型需要调整 logit 比较容差 → 这是阈值校准,本协议不涵盖

参考资料

文件阅读时机
comparator-build.md构建 HF/MAX 转储器和比较器
comparator-output-patterns.md解读比较器输出、误报断崖、token-0 不变量
agent-workflow.md调度并行调查 Agent
stacked-failures.md修复有所帮助,但验证仍未通过

如需了解 MAX 内置的运行时调试选项(NaN 检查、源代码回溯、算子日志),请参阅 MAX 调试工具。 max.nn.hooks.PrintHook(在 comparator-build.md 中介绍)会打印层的 输入和输出,便于快速排查。

协议

步骤 0:检查 HF 是否正常

在相同的 HF 仓库、提示词和检查点上运行 model.generate(...)。如果 HF 输出不连贯,请先修复分词器或聊天模板。问题不在 MAX 模型。

pixi run python -c "
import torch
from transformers import AutoTokenizer, AutoModelForCausalLM
tok = AutoTokenizer.from_pretrained('<repo>')
model = AutoModelForCausalLM.from_pretrained('<repo>', dtype=torch.float32, device_map='auto')
text = tok.apply_chat_template([{'role':'user','content':'Hello!'}], tokenize=False, add_generation_prompt=True)
out = model.generate(**tok(text, return_tensors='pt').to(model.device), max_new_tokens=32, do_sample=False)
print(tok.decode(out[0]))
"
步骤 1:构建比较器

按照 comparator-build.md 操作。你需要三个 产物:HF 转储器、MAX 转储器(forward() 插桩 + 独立运行器)和比较器脚本。请在 MAX 的 forward() 内将转储张量转换为 FP32。

注意:请先验证转储器,再信任其结果。 在一个 MAX 已能正常提供服务的 ModuleV3 模型上运行两个转储器,并在其 forward() 中添加插桩。使用 olmo3,或通过 --prefer-module-v3 提供服务的 llama3_modulev3。预期每一层的 cos ≈ 0.999,两边的 prompt_tokens.npy 完全相同,且 post_embed cos = 1.0。达不到这些结果 就说明转储器有问题。在将任何内容用于比较移植版之前,请先修复转储器。

步骤 2:读取比较器输出,然后分支处理

按照 comparator-output-patterns.md 操作。在对模型进行二分排查之前,先检查误报断崖(hidden_states 索引错误、解码前缀转储缺少 attention_mask)。

根据首次通过检查的比较器运行结果,选择下一步:

  • 某一层存在偏差 → 排查层级。继续步骤 3 至 5。
  • 每一层都匹配(cos ≥ 0.99),但生成结果仍有偏差 → 模型的数学计算很可能正确。跳到步骤 6。不要对层进行二分排查。
  • 模式符合误报断崖特征 → 修复转储器,重新转储,再次读取。不要使用有问题的比较器来调试模型。

当全局 cos 不明确时,计算逐 token 和逐维度的余弦切片:

cos_per_token = [cos(h[t], m[t]) for t in range(h.shape[0])]
cos_per_dim = [cos(h[:, d], m[:, d]) for d in range(h.shape[1])]

如果 HF 出现尖峰而 MAX 保持平坦,但 max_diff 较高,通常意味着 HF 构建了移植版中没有的注意力锚点。

步骤 3:调度调查 Agent

遵循 agent-workflow.md。一名主 Agent 分析转储并依据张量证据对假设进行排序。辅助 Agent 并行开展工作(权重统计、代码差异、内核检查、子 tap 准备)。主 Agent 完成定位前,不要调度尝试修复的 Agent。

步骤 4:重新编译前进行数值验证

针对每个假设:读取转储张量,计算修复后的结果,并与 HF 比较。匹配 → 重新编译。不匹配 → 尝试下一个假设。

步骤 5:应用修复,重新转储并再次比较

一次编译,一次冒烟测试,通过完整比较器(所有层的 cos > 0.99)。如果验证仍然失败,请参阅 stacked-failures.md。

步骤 6:Serve 与 pipeline

如果解码步骤 K 的 teacher-forced 转储与 HF 匹配,但生成文本仍然不同, 则模型计算很可能正确。先进行二分排查,再重新对层进行二分排查:

检查通过失败 →
Teacher-forced 转储 @ Kcos ≥ 0.99,argmax 匹配步骤 1 到 5(模型错误)
增量 pipeline 解码 @ Ktoken K 与 HF 匹配解码状态错误(KV、卷积缓存)
Serve 与 pipeline @ K匹配测试框架错误(分词器、聊天模板、token 恢复)

如果缺少以下脚本,请创建:pipeline 解码比较、增量层转储、serve 比较脚本。如果 teacher-forced 和 pipeline 都通过,但 serve 失败,请勿修改模型。

评论

支持 Markdown