资讯动态

AMCT 新模型族适配指南:注册模型、定义 PtqUnit、接入 quant block 与 wrapper 的完整实操

发布时间:2026/9/18 4:24:41 来源:尧图企业网站定制
AMCT 新模型族适配指南注册模型、定义 PtqUnit、接入 quant block 与 wrapper 的完整实操【免费下载链接】amctAMCT是CANN提供的昇腾AI处理器亲和的模型压缩工具仓。项目地址: https://gitcode.com/cann/amct导读本文面向需要在 CANN AMCT 中为 LLM 接入新模型族的开发者系统讲解模型适配Model Adapter的完整方法论如何注册模型适配类、定义PtqUnit、构建 quant block、补齐模型专属的 attention / MLP wrapper同时严格保持 workflow、quantizer、algorithm、solver 各层边界稳定。读完本文你将掌握一套最小改动范围、最大复用存量抽象的适配工作流——从结构判断、BF16 baseline 打通、浮点等价验证到最小 PTQ 集成 smoke 与文档写回判断并能据此完成 dense 与 MoE 两类新模型的接入。本文内容以仓库内 .agents/skills/quant-tools/model-adapter/SKILL.md 及其配套参考文档为主体并结合 .agents/docs/repo-map.md、.agents/docs/casebook/ 及各模型适配器源码进行深化。一、模型适配的定位与核心边界在 AMCT 的 PTQ 主流程中模型适配是一个职责非常收敛的动作只做适配不重写主 PTQ 流程。它对应的工作是注册新模型族到模型 registry定义该模型的PtqUnit拆分方式把模型的 block 接到 quant block 构建链路上为模型专属的 attention / MLP 结构补齐量化 wrapper。与之相对重写主 PTQ 流程、跑量化实验、推荐量化方案等都不属于模型适配的范畴分别归属 quant-run、scheme-recommendation 等其他 skill。仓库分层边界根据 .agents/docs/repo-map.md整个 LLM PTQ 链路按职责分为以下几层适配新模型时默认只允许触碰其中一层层主要位置职责默认规则CLIamct_pytorch/cli/llm/解析参数并启动 workflow不放模型逻辑Workflowamct_pytorch/workflows/编排 eval、PTQ 数据提取、PTQ 训练不放模型细节Model adapteramct_pytorch/common/models/llm/...构建 block、quant block、拆PtqUnit、加载 unit 输入和参数新模型适配主入口Quant modulesamct_pytorch/quantization/modules/提供通用量化 wrapperActivationQuantizer、WeightQuantizer、QuantLinear保持通用Algorithmsamct_pytorch/algorithms/实现 activation / weight / structure 算法通过targets注册Optimizationamct_pytorch/common/optimization/管 optimizer、epoch 循环、重建训练不混入模型分支Dataamct_pytorch/common/datasets/提供 PTQ 输入、GT 生成、dataloader优先复用现有 provider适配新模型时改动默认只落在amct_pytorch/common/models/llm/family/model/...。只有在有明确理由时才允许触碰其他层现有共享抽象确实不够时才改amct_pytorch/common/models/llm/common/...通用 wrapper 真的表达不了该模型路径时才改amct_pytorch/quantization/modules/...workflow 本身与该模型结构不兼容时才改amct_pytorch/workflows/...但边界规则要求尽量避免模型特有逻辑严禁塞进 workflow。从源码结构看目前已在 amct_pytorch/common/models/llm/init.py 中注册的 LLM 适配器包括deepseek_v3_2、deepseek_v4、longcat_lite、longcat_next、glm5、glm5_2、qwen3、qwen3_moe、qwen3_5、qwen3_5_moe、qwen3_6_moe、qwen3_next、hyv3可作为新模型接入时的直接参照。二、适配前的准备先读文件、先查结果2.1 必读文件清单动手写代码前先按顺序阅读以下文件.agents/docs/repo-map.md —— 稳定架构说明理解分层边界与当前接通状态.agents/skills/quant-tools/model-adapter/references/model-adapter.md —— 8 步适配工作流.agents/skills/quant-tools/model-adapter/references/validation-checklist.md —— 适配完成前必须逐项核对的最小验证清单。读完 repo-map 后还要抽查其中的锚点文件确认当前 map 仍然有效包括README.mdamct_pytorch/cli/llm/args.pyamct_pytorch/workflows/llm_ptq.pyamct_pytorch/common/models/llm/__init__.pyamct_pytorch/common/models/llm/common/base.pyamct_pytorch/common/models/llm/common/quant_apply.pyamct_pytorch/quantization/modules/quant_base.pyamct_pytorch/quantization/modules/quant_linear.pyamct_pytorch/common/optimization/blockwise_solver.py2.2 先查现有结果再决定是否重跑适配开始前必须先检查仓库里是否已有可复用结论是否已有同模型的适配结论见.agents/docs/casebook/....agents/docs/casebook/...是否已有可复用经验outputs/或日志里是否已有 BF16 baseline / wrapper 校验 / 最小 PTQ 集成 smoke 结果。原则已有结果足够回答当前问题时先复用并说明口径。只有在代码、模型版本、评测口径或目标范围变化时才重新执行实验——不要默认重复执行同口径实验。2.3 评测口径强约束seq_len4096当前模型适配阶段中凡是需要落Wikitext PPL的验证统一使用seq_len4096这是默认强约束不要沿用旧的2048口径用户没有显式指定seq_len时按4096执行 BF16 baseline 和后续等价性验证历史 baseline 若不是4096默认不能直接当作当前适配结论复用除非明确说明只是参考、不是同口径结果只有用户明确要求其他seq_len时才允许偏离默认口径并且必须在结论里写清楚。三、固定流程从结构判断到文档写回模型适配有一个固定的执行流程对应 SKILL.md 的固定流程小节共 12 步先读repo-map再抽查锚点文件确认当前 map 仍有效先查现有结果casebook、outputs、日志中的 baseline / wrapper 校验 / smoke已有结果足够则先复用并说明口径仅在代码、模型版本、评测口径或目标范围变化时重跑解析新模型结构至少明确block / attention / MLP class、dense 还是 MoE、experts 是显式模块还是 packed tensor、PtqUnit准备怎么拆先确定 attention 的最小实现目标默认目标是blockwise PPL / PTQ / deploy不要默认按上游源码完整保留 generate / decode / cache 分支先定改动范围默认只改amct_pytorch/common/models/llm/...先制定复用计划优先复用PtqUnit、QuantLinear、QuantGatedMLP和现有 quant-apply helper先打通 BF16 推理拿到 baseline再验证关闭量化后 wrapper 前向与原始浮点模块一致或足够接近适配正确性验证不属于量化效果判断再打通一个最小 PTQ 集成 smoke至少一个 quant block、至少一个可枚举的PtqUnit、至少一次 unit 输入 / GT 准备、至少一次参数导出与回载最后总结适配结果、剩余风险和未接通部分结束前判断是否需要同步repo-map、casebook和Agent Docs触发则更新不触发也要明确说明理由。四、Step 1先判断新模型结构写代码前先回答下面几个问题如果答不清就不要开改block class 是什么attention class 是什么MLP class 是什么模型是 dense 还是 MoE如果是 MoEexperts 是独立模块还是 packed tensor哪些子结构要变成PtqUnit结构判断的实战样例以 casebook 中 .agents/docs/casebook/hunyuan/hy3-preview.md 的 Hy3-preview 为例结构判断的产出是这样的架构80 层 decoderfirst_k_dense_replace1layer0 为 dense GatedMLPintermediate 13312layer1-79 为 MoEmoe_intermediate 1536192 routed experts top-8 1 shared expertsigmoid 路由 expert_bias route_norm router_scaling 2.826GQA 64/8、head_dim 128、qk_normhidden 4096、vocab 1208321 层 MTPenable_lm_head_fp32experts 形态packed expertsgate_up_proj[192,3072,4096] down_proj[192,4096,1536]。casebook 是仓库内沉淀的模型专属经验库适配同系列或同结构模型时应优先阅读对应条目qwen、deepseek、glm、hunyuan、longcat 等系列均有独立 casebook 目录。五、Step 2-3定写入范围、按顺序复用5.1 写入范围新模型默认只改amct_pytorch/common/models/llm/family/model/...。其他层的改动必须有明确理由详见第一节边界表格。5.2 复用优先顺序1. 复用 PtqUnit 2. 复用 QuantLinear 3. 复用 QuantGatedMLP 4. 复用 apply_quant_to_attn() / apply_quant_to_moe_mlp() 5. 只有真正不同的部分再写模型专属 wrapper除非同一种模式已经在至少两个模型族里重复出现否则不要急着抽新基类。5.3 现有可复用抽象源码依据BaseModel位于amct_pytorch/common/models/llm/common/base.py是目前最核心的复用抽象BaseModel.build_quant_block()—— 按layer_idx构建单层 quant block默认实现即block()BaseModel.iter_ptq_units()—— 按quant_target拆分 PTQ unitattn-linear/attn-cache走 attention 路径moe走 per-expert 枚举mlp直接产出单 unitBaseModel.ptq_param_handler/BaseModel.ptq_param_store—— PTQ 参数的导出与回载链路BaseModel.do_block_forward()—— blockwise 前向执行已支持 per-sample stateself.input_ids用于 v4 这类 MoE hash routing 需要 token-id 路由的场景BaseModel.load_layer_weight()/get_embed_load_specs()—— safetensors 按前缀加载与 embed 部分加载规格。QuantGatedMLP实际定义在amct_pytorch/common/models/llm/common/quant_apply.py是可复用的 gated-MLP 量化 wrapper通过group区分三种路径mlp—— dense MLP默认moe.routed—— routed MoE 中每个 expert 的 wrappermoe.shared—— shared-expert wrapper通过build_no_algo_args()清空 algos跳过 PTQ 专属算法。apply_quant_to_attn() / apply_quant_to_moe_mlp()提供递归的 wrapper 注入工具前者把self_attn/linear_attn替换为量化 wrapper后者自动处理 dense MLP、per-expert MoE 与 shared experts 三种形态的group分配。PtqUnit是一个 dataclass字段为kind、name、layer_idx、module、metadata配套make_ptq_unit()与iter_indexed_units()两个构造工具。底层量化 wrapper来自amct_pytorch/quantization/modules/ActivationQuantizer、WeightQuantizer、QuantLinear这些模块本来就是给模型专属 wrapper 复用的。5.4 最小路径推荐顺序不要一口气适配整个模型。推荐顺序先做一个 block loader再做一个 quant block builder再做一个 PTQ unit enumerator再打通一条 wrapper 路径最后补保存 / 加载路径。复杂模型的优先顺序为MLP first → attention → MoE / packed experts。六、Attention 适配原则优先于照搬源码attention wrapper 的适配有一条铁律先按当前框架真实目标做最小化实现不要为了贴源码而默认保留生成态分支。6.1 核心原则当前默认目标是blockwise路径上的 BF16 / PPL / PTQ / deploy不是完整生成态推理不要为了适配通路强行保留不参与当前路径的复杂步骤例如past_key_values、decode-only cache 分支、当前始终为None的附加参数forward里的参数如果在当前路径下确实恒为None要先判断它是否真的参与计算如果不参与就不要为了形式上对齐源码而保留额外分支attention wrapper 的实现目标是**足够正确且尽量简单**不是最大程度复刻上游源码的所有枝杈同系列模型如果 attention 结构和当前任务口径一致优先共用实现。6.2 参数收敛的实操规则repo-map 对参数收敛给出了更细的规则scaled_dot_product_attention的调用参数要按当前真实跑通路的传参来收敛不要默认照搬源码里的attention_mask、cache 或其它生成态参数参数是否保留要按 debug 时看到的真实运行时传参来判断而不是按源码形参表机械保留如果某个参数在当前 blockwise / PPL 路径下恒为None、恒为固定值或根本不参与实际计算就不要继续把它当成有效输入向下传递当前流程根本不用 cache 时就不要保留past_key_values.update(...)这类只服务生成态的步骤qwen3是明确例子当前 PPL/PTQ/deploy 路径应优先复用一份 attention 实现只保留当前真实执行所需的position_embeddings和scaled_dot_product_attention调用参数。6.3 案例佐证Hy3-preview 的适配结论明确提到attn wrapper 采用is_causalTrue, attn_maskNone的 sdpa 调用方式同时不建议attn sdpa 同时传attn_mask和is_causalTrue会撞 assert。这正是按真实运行传参收敛、去掉无效传参原则的落地实例。七、Wrapper 合并原则attention / MLP / MoE-MLP 通用除了 attentionMLP / MoE-MLP 也遵守同样的合并原则如果同系列两个 wrapper 的初始化、状态和forward一样就只保留一份实现不要为了兼容旧类名、少改 import长期保留行为完全重复的类只有以下情况才拆成两份 wrapper底层模块结构真的不同导出语义不同PTQ unit 边界不同量化路径不同一个是 dense 版本、一个是 moe 版本本身不构成拆分类的理由关键看实现是否真的不同适配时要主动判断能不能合并不要为了完全不动旧代码而保留重复实现。从 repo-map 记录的适配形态看qwen3系列 dense / MoE 适配器amct_pytorch/common/models/llm/qwen/qwen3/qwen3.py与qwen3_moe.py体现了dense 与 moe 尽量共用 attention 实现的合并思路而deepseek_v3_2amct_pytorch/common/models/llm/deepseek/deepseek_v3_2/deepseekv3_2.py则说明 attention 侧和 MoE 侧可以走不同的 target 路径但最终仍复用BaseModel、PtqUnit和通用 quant wrapper 主链。八、Step 4-7BF16 baseline → 浮点等价 → 最小 PTQ 闭环8.1 Step 5先拿到 BF16 baseline进入量化前先确保模型的 BF16 推理路径能跑通baseline 指标能被记录。如果当前因为环境或路径原因暂时拿不到 baseline也要明确记录阻塞点不能静默跳过。另外注意 Hy3-preview 案例中的关键陷阱eval_modebf16需带--bit_config全 ≥16bit 的 yaml如configs/bf16.yaml空配置全 16bit否则会报eval_modebf16 requires a bit_config with no 16-bit entries—— 即BF16 baseline 也必须显式给 bit_config。8.2 Step 6先过浮点等价检查在做 PTQ 前先验证原始 float block forward 正常quant block forward 正常关闭量化后quant block 与原始 float block 足够接近。如果关闭量化后仍和原始 float block 不一致先修 wrapper 等价性不要继续往 PTQ 走。这一步属于适配正确性验证不属于量化效果判断——不要在这一步下 PPL、delta 或量化方案优劣的结论。8.3 Step 7再接最小 PTQ 闭环float 等价过了之后再做抽一条 unit 输入路径为该 unit 生成 GT跑一次 unit 级 solver监控训练健康信号loss 是否下降正常应从初始值逐步收敛loss 是否为 0 或 NaN立即停止说明适配失败参数是否真正更新check parameter grad保存 PTQ 参数回载 PTQ 参数。关键检查点如果训练 epoch loss 恒为 0 或 NaN说明该 PTQ unit 未被正确优化可能是build_no_algo_args与iter_ptq_units不一致、输入为 None、梯度未传播等应立即停止并检查适配逻辑不要浪费计算资源。参考 casebook 中hunyuan/hy3-preview的 shared_experts PTQ 策略矛盾案例。做完这些再考虑更大范围的评测。8.4 案例shared_experts PTQ 策略矛盾hy3-preview该案例是loss 恒为 0 必须立即停止的典型复现现象PTQ 报PTQ input file not found: block_*_moe.shared_in.pkl训练 loss 恒为 0虽有参数保存但无实际优化根因quant_module 用build_no_algo_args(args)清空 algos但 adapteriter_ptq_units错误 yield shared_experts → 两层设计矛盾处理注释掉 adapter 中的 yield保持与 quant_module 一致shared_experts 使用直接量化密集激活效果已够好教训MoE adapter 必须检查build_no_algo_args与iter_ptq_units的一致性优先用通用函数apply_quant_to_moe_mlp自动处理 shared_experts训练 loss 恒为 0 时立即停止检查适配逻辑。九、验证清单与完成标准9.1 最低必做Validation Checklist对所有修改文件做语法检查BF16 baseline 路径至少验证一次或明确记录阻塞原因至少构建一层新模型的 quant block至少枚举出一个PtqUnit在适配路径上验证关闭量化后wrapper 前向与原始浮点模块一致或足够接近至少验证一个 unit 的 PTQ 参数可以导出。9.2 推荐再做跑一个 unit 级 PTQ smoke test回载保存的 PTQ 参数并跑一次 forward检查模型特有逻辑是否泄漏到了amct_pytorch/workflows/...检查是否无必要地改动了 solver。9.3 收尾自检结束前确认改动是否主要停留在amct_pytorch/common/models/llm/...是否先复用了现有 wrapper再新增抽象关闭量化时wrapper 是否保住了原始浮点行为是否避免了没有必要的框架级重构9.4 完成标准SKILL.md满足下面条件前不要认为适配完成至少一层的 quant wrapper 能正常构建BF16 baseline 已拿到或明确记录为什么当前拿不到已验证适配路径上关闭量化后wrapper 仍保持浮点等价至少一个 PTQ unit 能被枚举并完成最小 PTQ 集成 smoke已跑过验证清单已完成文档写回判断触发则已更新未触发则已说明理由。十、文档写回触发与输出要求10.1 文档写回触发适配完成后的文档写回repo-map / 系列 casebook README / 个案 / Agent Docs及默认不做统一见 .agents/docs/README.md 的「文档写回触发」。repo-map 的更新规则是只有在框架边界或核心流程变化时才更新例如llm_ptq.py改变了主流程编排语义amct_pytorch/common/models/llm/__init__.py改变了实际注册的模型集合BaseModel改变了 block / unit / 导出加载语义quant_base.py改变了算法分流方式blockwise_solver.py改变了优化职责边界。而新增一个尚未接入主注册链的模型目录新增一个算法文件修一个局部 wrapper bug改一个不影响复用边界的模型专属实现细节等不要重写 repo-map。Agent Docs只在文档层级或职责边界变化时更新不因普通模型适配而默认改动。10.2 结束时的输出要求适配结束时必须逐项说明新模型的结构判断结果实际改动范围是否越界复用了哪些现有抽象BF16 baseline 是否已跑通浮点等价检查是否通过最小 PTQ 集成 smoke 是否已打通还剩哪些风险或未完成项如果发生重跑为什么旧结果不能直接复用attention 是否按最小化实现原则收敛如果没有为什么是否更新了repo-map如果没有为什么是否更新了系列casebook README或个案如果没有为什么是否需要更新Agent Docs如果不需要为什么。十一、常见适配形态参考仓库已有先例repo-map 记录了五种典型适配形态可作为新模型接入时的对照样例Qwen3 dense 形态qwen3.py注册模型适配类、按layer_idx加载单层 block、实现build_quant_block(layer_idx)与iter_ptq_units(layer_idx, block)、模型专属 wrapper 放在模型目录下维护额外注意lm_head可能与embed_tokenstied 不一定单独落盘attn-linear 必须继续复用官方attention_interface不能因为只量化 q/k/v/o 就切到自定义 attention kernelDeepseekV3.2 形态deepseekv3_2.pyattention 侧和 MoE 侧走不同 target 路径但最终仍复用BaseModel、PtqUnit与通用 quant wrapper 主链LongcatLite 形态longcat_lite.py输入路径和 decoder block 拓扑可以很特殊但模型专属的输入重放、quant wrapper 注入和 PTQ unit 路由仍应放在amct_pytorch/common/models/llm/...Qwen3Next 形态qwen3_next.py同一家族内部混有linear_attention和full_attention需在 adapter 内分别维护两类 maskcheckpoint 展开的 per-expert 权重与运行时 packed experts 的重组优先留在 adapter 内LongcatNext 形态longcat_next.py顶层trust_remote_code模型可能因额外依赖无法直接空载可在 adapter 内直接实例化文本模型类checkpoint 的lm_head形状与默认 config 不一致时最小 shape patch 留在 adapter 内。此外MoE 类模型的常见起点是复用qwen3_moe的QuantGatedExperts自带 materialize PTQ 实体化路径与apply_quant_to_moe_mlp自动处理 shared_experts不建议自写 experts 量化类只做materializeFalse惰性视图PTQ 时 weight 留 CPU 会导致 device 不一致。十二、总结AMCT 的新模型适配是一条边界稳定、先复用后新增、最小闭环验证的工程链路先读 repo-map 与 casebook 判断结构与复用点再按block loader → quant block builder → PTQ unit enumerator → wrapper 路径 → 保存/加载的最小路径推进依次打通 BF16 baseline、浮点等价检查与最小 PTQ 集成 smoke最后按验证清单与输出要求收尾并判断是否触发文档写回。牢记两条最关键的纪律只做适配、不重写主 PTQ 流程训练 loss 恒为 0 或 NaN 时立即停止排查适配逻辑。遵循本文流程即可把新的 dense 或 MoE 模型族以最小代价、最大复用度接入 AMCT 的 PTQ 主流程。【免费下载链接】amctAMCT是CANN提供的昇腾AI处理器亲和的模型压缩工具仓。项目地址: https://gitcode.com/cann/amct创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价