导出失败别慌:coreai-models 调试工具箱完整指南——include-debug-info、剥离调试信息与 PSNR 数值校验
【免费下载链接】coreai-modelsModel export recipes, Python primitives, and Swift runtime utilities for on-device AI项目地址: https://gitcode.com/gh_mirrors/co/coreai-models
coreai-models 是一套面向 Apple 平台端侧 AI 的模型导出工具集,提供导出配方(export recipes)、Python 原语和 Swift 运行时工具,把 PyTorch 模型转换为 Core AI.aimodel格式。当导出失败、数值对不上或产物体积异常时,include-debug-info开关、调试信息剥离和 PSNR 数值校验就是三件最实用的调试利器。本文将从零讲清它们的用法,帮你在 10 分钟内定位并解决导出问题。
1️⃣ 准备工作:获取 coreai-models 仓库
如需本地运行导出命令,先克隆仓库:
git clone https://gitcode.com/gh_mirrors/co/coreai-models导出前建议先确认支持哪些模型:
uv run coreai.model.registry --list-models --type llm整体目录结构可以参考仓库主文档 models/README.md,各模型家族的导出配方位于models/<名称>/export.py。
2️⃣ 理解导出默认行为:为什么你的 .aimodel 信息很少
coreai-models 所有导出路径默认使用转换器的RELEASE模式,只嵌入最少量调试信息,让产出的.aimodel体积最小——这正是发布时想要的状态。这一默认值由全仓库共享的常量锁定:
- 常量定义:python/src/coreai_models/_constants.py 中的
DEFAULT_INCLUDE_DEBUG_INFO = False - 配置落点:python/src/coreai_models/export/pipeline.py 中
ExportConfig的include_debug_info字段
也就是说:默认导出 = RELEASE 模式 = 最小调试信息。理解了这一点,才能判断"调试信息缺失"到底是异常还是预期。
3️⃣ 一键开启:使用 include-debug-info 定位导出失败
什么时候该加 --include-debug-info?
遇到以下三类问题时,值得重新导出一份带完整调试信息的资产:
| 症状 | 说明 |
|---|---|
| ❓ 数值不对 | 输出与 PyTorch 参考结果偏差大,但说不清哪层出的错 |
| 🧱 算子降级失败 | 某个 op 无法被 Core AI 降低(lowering) |
| 🗺️ 需要回溯源码 | 要把计算图节点映射回 Python 源码 |
--include-debug-info会让转换器切换到DEBUG模式,把完整调试信息嵌入.aimodel:
uv run coreai.llm.export Qwen/Qwen3-0.6B --include-debug-info全平台统一:所有导出入口都支持该开关
这个标志不是某个脚本的私货,而是贯穿整个工具箱的统一契约:
coreai.llm.export(语言模型)coreai.vlm.export(视觉-语言模型)coreai.diffusion.export(扩散模型)coreai.segmentation.export(图像/视频分割)- 以及每个独立的 models/<名称>/export.py 配方,例如:
uv run models/whisper/export.py --include-debug-info独立配方(如 models/whisper/export.py)通过uv run直接执行,无需额外安装依赖(PEP 723 内联依赖)。
一个容易踩的坑:--verbose 不是调试信息
⚠️--include-debug-info与--verbose/-v完全独立。-v只提高控制台日志级别,不会改变.aimodel资产里嵌入的任何内容。想看控制台细节用-v,想给资产加调试信息必须用--include-debug-info。
仓库如何保证"每个入口行为一致"
测试文件 python/tests/test_model_units/test_export/test_include_debug_info.py 对每一条导出路径做了契约检查:
- 锁定全仓库默认值必须为
False(RELEASE 模式) - 参数化检查
ExportConfig与DiffusionExportConfig是否继承共享常量 - 扫描全部独立
models/*/export.py配方,确保它们都声明了--include-debug-info且默认 RELEASE 模式,并禁止裸构造TorchConverter()(那会静默继承库的 DEBUG 默认值)
4️⃣ 调试完别忘瘦身:不重新导出,原地剥离调试信息
诊断完成后,你通常不想带着完整的 DEBUG 信息把资产发出去。好消息是:不需要重新导出。models/README.md给出了原地剥离的标准流程(models/README.md):
from coreai.authoring import AIModelAsset from coreai_torch.debugging.debug_info import strip_debug_info source = AIModelAsset.load("inputModel.aimodel") metadata = source.metadata author, license_, description = ( metadata.author, metadata.license, metadata.model_description ) program = source.program strip_debug_info(program) # 原地修改 program program.save_asset(Path("outputModel.aimodel"))📌最容易翻车的细节:save_asset()只会持久化creationDate、assetVersion和producer三项元数据。如果不把author、license、description重新挂回去,发布出去的资产会静默丢失署名和许可证信息:
AIModelAsset.load("outputModel.aimodel").update_metadata( lambda m: ( setattr(m, "author", author), setattr(m, "license", license_), setattr(m, "model_description", description), ) )剥离后的outputModel.aimodel携带的调试信息量,与默认RELEASE导出的产物一致。
5️⃣ 数值对不上?用 PSNR 定位精度问题
PSNR 是什么、仓库怎么算
PSNR(峰值信噪比,单位 dB)是 coreai-models 校验模型转换数值正确性的核心指标:值越高,压缩/转换后的输出与 fp16 参考输出越接近。仓库内置了可直接复用的度量脚本 skills/skills/model-compression-exploration/scripts/quality_metrics.py,除了psnr还提供:
| 指标 | 适用场景 |
|---|---|
psnr/snr | 连续输出(logits、特征图) |
iou | 二值/阈值化输出(分割掩码、检测热力图) |
判定基准:什么 PSNR 算"过"
skills/skills/model-authoring/SKILL.md 给出了清晰的验证门槛,建议对照着判断自己的导出结果:
| 对比场景 | 门槛 | 含义 |
|---|---|---|
| 重写模型 vs 源模型(PyTorch) | > 70 dB | 实现正确 |
| Neural Engine 布局 vs GPU 布局 | > 70 dB | 布局转换正确 |
| 编译后 vs PyTorch | ≥ 40 dB | 编译精度(fp16 + 优化) |
| 4-bit 调色板压缩后 | ≥ 35 dB | 压缩可接受 |
压缩位数与 PSNR 的对应关系:8-bit 通常 > 55 dB(低于 50 dB 要警惕),4-bit 约 40 dB(低于 35 dB 要排查),2-bit 仅 25–35 dB,一般不建议发布。
常见 PSNR 异常速查表
这些"症状→原因→修复"来自仓库沉淀的排障手册 skills/skills/model-authoring/references/common_issues.md:
| PSNR 症状 | 常见原因 | 修复方向 |
|---|---|---|
| SDPA 只有 ~15–30 dB | 因果掩码方向反了((1, query, 1, key)) | 转置掩码或改用create_ane_causal_mask() |
| M-RoPE 只有 ~18 dB | GPU 的 M-RoPE 模式未精确复刻 | 对齐torch.cat([cos, cos])后按::2索引 |
| 20–30 dB | 激活函数选错(SiLU/QuickGELU/GELU 混用) | 先打印源模型激活函数的type() |
| 数值整体错乱 | 张量不连续,Neural Engine 按连续内存读取 | 所有张量在包装NDArray前调用.contiguous() |
💡 特别注意:跨布局直接比较裸张量得到的 PSNR 没有意义,先做对应的布局变换再比较。
Swift 端也有对应校验
导出后的 Swift 运行时同样内置了数值校验工具,例如语音识别的对照测试 swift/Sources/Tools/speech-recognizer/SpeechParity.swift 和图像分割的image-segmenterCLI(内含 PSNR 比较参数)swift/Sources/Tools/image-segmenter/ImageSegmentationRunnerMain.swift。在设备上验证与 Python 侧参考输出的偏差时可以直接使用。
6️⃣ 实战排查流程:四步走
把三件工具串起来,形成标准排查链路:
- 🔍 复现:默认导出失败或输出异常,先用
-v观察控制台日志(记住:它不改资产内容) - 🐞 取证:加
--include-debug-info重新导出,用调试信息定位到具体算子/图层 - 📊 定量:用 PSNR/SNR/IoU 对照上面两张表,判断是编译精度问题、布局问题还是压缩过头
- ✂️ 收尾:问题解决后,用
strip_debug_info原地剥离调试信息,并重新挂回元数据,产出最小体积的发布版.aimodel
总结
coreai-models 的调试工具箱围绕一个朴素原则设计:默认产物面向发布(RELEASE + 最小调试信息),诊断时随时可切换,诊断后随时可剥离。记住三个要点即可应付绝大多数导出问题:
--include-debug-info全平台通用,且与-v互不干扰- 剥离调试信息无需重新导出,但务必回挂 author/license/description 元数据
- 拿不准数值对不对时,用 PSNR 门槛表对照:> 70 dB 看实现,≥ 40 dB 看编译,≥ 35 dB 看 4-bit 压缩
更多模型细节可继续查看对应模型卡片,例如 models/qwen3/README.md 与 models/whisper/README.md;压缩探索的完整方法论见 skills/skills/model-compression-exploration/SKILL.md。
【免费下载链接】coreai-modelsModel export recipes, Python primitives, and Swift runtime utilities for on-device AI项目地址: https://gitcode.com/gh_mirrors/co/coreai-models
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考