用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/HorizonRobotics/OE-Skills --skill j6-plugin-export命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
基于 SOC 职业分类
正在显示 SKILL.md
| name | j6-plugin-export |
| description | 使用 horizon_plugin_pytorch 的 hbdk4.export 将 QAT 模型导出为 HBIR IR 模块。以独立导出脚本的形式执行,不在训练或评测脚本中添加导出逻辑。 |
在使用 horizon_plugin_pytorch 的 QAT 工具链完成校准/训练后,创建一个独立的导出脚本,将 QAT 模型导出为 HBIR IR 模块,用于后续编译部署。
本 Skill 只做一件事:创建独立导出脚本,脚本中包含
from horizon_plugin_pytorch.quantization import hbdk4 as hb4
from hbdk4.compiler import save
model.eval()
set_fake_quantize(model, FakeQuantState.VALIDATION)
hbir_model = hb4.export(model, example_inputs, ...)
save(hbir_model, "output_path")
不引入任何其他改动(不改模型结构、不改 qconfig、不改 prepare/convert、不改训练/数据逻辑、不在训练或评测脚本中添加导出逻辑)。
导出逻辑必须放在独立脚本中,禁止在训练脚本、评测脚本或其他已有脚本中添加导出逻辑。
原因:
独立导出脚本必须包含以下步骤,按固定顺序执行:
set_march — 设置目标平台model.eval() — 切换到推理模式set_fake_quantize(model, FakeQuantState.VALIDATION) — 切换到验证状态example_inputshb4.export(model, example_inputs, ...) — 执行导出save(hbir_model, output_path) — 保存 HBIR 模型到文件即使训练/评测脚本末尾是"导出的自然位置",也不应在其中插入导出代码。应创建独立脚本。
hb4.export 不区分 QAT 模型和 float 模型,如果误传 float 模型,导出会静默成功但结果无意义。因此:
Agent 侧约束:创建导出脚本前,必须确认用户提供的 checkpoint 是 QAT checkpoint(已完成 prepare + 校准/训练),而非 float checkpoint。如果用户未明确说明,应主动询问确认。
运行时检查:导出脚本中必须在 export 之前加入 QAT 模型验证,检查模型是否包含 fake-quant 模块:
# 验证模型是 QAT 模型(包含 fake-quant 模块)
_has_fq = any(
"FakeQuantize" in type(m).__name__
for m in model.modules()
)
assert _has_fq, (
"当前模型不包含 FakeQuantize 模块,不是 QAT 模型。"
"请确认使用的是 QAT checkpoint 而非 float checkpoint。"
)
import torch
import horizon_plugin_pytorch as horizon
from horizon_plugin_pytorch.quantization import hbdk4 as hb4
from horizon_plugin_pytorch.quantization import FakeQuantState, set_fake_quantize
from hbdk4.compiler import save
import torch
import horizon_plugin_pytorch as horizon
from horizon_plugin_pytorch.quantization import hbdk4 as hb4
from horizon_plugin_pytorch.quantization import FakeQuantState, set_fake_quantize
from hbdk4.compiler import save
# 1. 设置 march
horizon.march.set_march(horizon.march.March.NASH_E)
# 2. 构建/加载 QAT 模型
model = build_model()
model.load_state_dict(torch.load("qat_checkpoint.pth"))
# 3. eval
model.eval()
# 4. 切换到 VALIDATION
set_fake_quantize(model, FakeQuantState.VALIDATION)
# 5. 验证是 QAT 模型
_has_fq = any("FakeQuantize" in type(m).__name__ for m in model.modules())
assert _has_fq, (
"当前模型不包含 FakeQuantize 模块,不是 QAT 模型。"
"请确认使用的是 QAT checkpoint 而非 float checkpoint。"
)
# 6. 构造 example_inputs
example_input = torch.randn(1, 3, 224, 224)
# 7. 导出
hbir_model = hb4.export(model, (example_input,))
# 8. 保存
save(hbir_model, "output.bc")
import torch
import horizon_plugin_pytorch as horizon
from horizon_plugin_pytorch.quantization import hbdk4 as hb4
from horizon_plugin_pytorch.quantization import FakeQuantState, set_fake_quantize
from hbdk4.compiler import save
horizon.march.set_march(horizon.march.March.NASH_E)
model = build_model()
model.load_state_dict(torch.load("qat_checkpoint.pth"))
model.eval()
set_fake_quantize(model, FakeQuantState.VALIDATION)
# 验证是 QAT 模型
_has_fq = any("FakeQuantize" in type(m).__name__ for m in model.modules())
assert _has_fq, (
"当前模型不包含 FakeQuantize 模块,不是 QAT 模型。"
"请确认使用的是 QAT checkpoint 而非 float checkpoint。"
)
example_input = torch.randn(1, 3, 224, 224)
hbir_model = hb4.export(
model,
(example_input,),
input_names={"image": "input_image"},
output_names={"feature": "feat_map", "raw": "raw_map"},
input_descs={"image": "RGB input image"},
output_descs={"feature": "ReLU features", "raw": "raw conv output"},
)
save(hbir_model, "output.bc")
导出后的 hbir_model 可通过 functions 属性访问导出的函数:
# native_pytree=True(默认,推荐)
hbir_ret = hbir_model.functions[0](model_args)
| 参数 | 类型 | 默认值 | 是否必填 | 说明 |
|---|---|---|---|---|
model | nn.Module | — | 必填 | 待导出的 QAT 模型,必须处于 eval 模式且已切换到 VALIDATION |
example_inputs | Any | — | 必填 | tracing 示例输入,支持 Tensor、tuple、dict 或嵌套结构 |
name | str | "forward" | 可选 | 导出模块中的函数名 |
input_names | Optional[Any] | None | 可选 | HBIR 输入名称,结构须与 example_inputs 一致 |
output_names | Optional[Any] | None | 可选 | HBIR 输出名称,结构须与模型输出一致 |
input_descs | Optional[Any] | None | 可选 | HBIR 输入描述,结构须与 example_inputs 一致 |
output_descs | Optional[Any] | None | 可选 | HBIR 输出描述,结构须与模型输出一致 |
native_pytree | bool | True | 可选 | 是否使用 hbdk4 原生 pytree,推荐 True |
| 参数 | 类型 | 默认值 | 是否必填 | 说明 |
|---|---|---|---|---|
module | HBIR Module | — | 必填 | hb4.export 返回的 HBIR 模型 |
output_path | str | — | 必填 | 保存路径,如 "output.bc" |
导出前必须按固定顺序执行:
model.eval()
set_fake_quantize(model, FakeQuantState.VALIDATION)
model.eval() 确保模型处于推理模式(BN 等算子使用 running stats)set_fake_quantize(model, FakeQuantState.VALIDATION) 确保 observer 不再更新统计量,仅执行伪量化如果忘记切换状态,observer 可能仍在更新统计量,导致导出结果不可预期。
独立导出脚本中必须在最开始设置 march,确保后续所有平台相关逻辑都在正确的上下文中执行。
example_inputs 应当与模型 forward 的输入签名匹配,能跑通目标 forward 路径。如果模型 forward 有多个参数,example_inputs 应为对应的 tuple 或 dict。
input_names 的结构须与 example_inputs 一致output_names 的结构须与模型输出一致例如:如果 example_inputs 是 dict,input_names 也应是 dict 且 key 对应。
export 前不要修改模型结构(hook、子模块等),所有结构修改应在 prepare 之前完成。
导出时可能出现如下 warning:
Converting a tensor to a Python {} might cause the trace to be incorrect. We can't record the data flow of Python values, so this value will be treated as a constant. This means that the exported hbir might not generalize to other inputs!
这是 hb4.export tracing 过程中的已知行为,不要尝试分析、定位或修复该 warning。该 warning 不影响导出流程,不属于本 Skill 的处理范围。
本 Skill 适用于:
以下情况不属于本 Skill 的直接处理范围:
prepare(...) → 用 j6-plugin-preparej6-plugin-set-fake-quantizej6-plugin-set-marchj6-plugin-insert-quant-dequant如果用户同时提这些需求,应分步处理,export 仅负责其中一环。
在完整的 Horizon QAT 工作流中,export 是 最后一步:
因此:
model.eval() + set_fake_quantize(model, VALIDATION) 已调用horizon_plugin_pytorch 的 QAT 机制set_march。eval() 模式。set_fake_quantize(model, FakeQuantState.VALIDATION)。example_inputs 能跑通模型的 forward 路径,且与 forward 签名对齐。from horizon_plugin_pytorch.quantization import hbdk4 as hb4。from horizon_plugin_pytorch.quantization import FakeQuantState, set_fake_quantize。hbir_model = hb4.export(model, example_inputs, ...) 调用。from hbdk4.compiler import save。save(hbir_model, output_path) 调用。input_names/output_names,其结构与 example_inputs/模型输出一致。