msmodelslim-model-dequant

star 29

为 msModelSlim 适配流程注入反量化能力。先识别模型权重是否可反量化,再实现反量化脚本并接入 model_adapter。当前仅覆盖 FP8 的 per-block 与 per-channel 两类;若格式不确定或无公开反量化规则,要求用户提供反量化脚本或浮点权重。

kali20gakki By kali20gakki schedule Updated 6/10/2026

name: msmodelslim-model-dequant description: 为 msModelSlim 适配流程注入反量化能力。先识别模型权重是否可反量化,再实现反量化脚本并接入 model_adapter。当前仅覆盖 FP8 的 per-block 与 per-channel 两类;若格式不确定或无公开反量化规则,要求用户提供反量化脚本或浮点权重。

msModelSlim 反量化接入 Skill

本 Skill 用于在模型适配前处理 FP8 量化权重,将可识别权重恢复为 bf16/fp16 再进入后续适配与量化流程。

适用范围

  • 支持:
    • FP8 per-block(块级 scale)
    • FP8 per-channel(通道级 scale)
  • 不支持(默认阻塞):
    • 无法确认反量化规则的自定义量化格式
    • 缺少必要 scale/shape 元数据的量化权重
    • 仅有推理框架专用格式且无训练侧可逆映射说明
    • 非 FP8(例如 INT4/INT8/FP4)在本 Skill 中默认不处理

必需输入

  • 模型目录(至少含 config.jsonmodel.safetensors.index.json
  • 目标模型的 model_adapter.py

硬门禁:先识别“可接受反量化权重”

在编写任何脚本前,必须先判定是否属于可接受类型:

  1. 读取 config.json,提取可用量化配置字段(如量化类型、group/block 相关参数)
  2. 读取 model.safetensors.index.jsonweight_map
  3. 按键名模式识别:
    • FP8 per-block 可接受:存在与权重匹配的块级 scale(常见键后缀如 xxx.weight_scale_inv / xxx.scale),且可推导块大小 block_size
    • FP8 per-channel 可接受:存在与权重某一维匹配的通道级 scale(常见形态如 [out_features][in_features] 或可广播到对应通道维)
  4. 用 scale 形状对权重形状做一致性检查:
    • per-block:MN 可按 block_size 分块并与 scale 网格对应
    • per-channel:scale 的长度或广播维度与指定 channel axis 一致
  5. 若未命中上述模式,标记为 未知/不接受格式 并停止实现

必须输出判定依据(命中的键模式、样例键名、对应文件)。

工作流

1) 识别与分流

  • 未量化:直接跳过反量化步骤,进入后续适配
  • 可接受量化(FP8 per-block/per-channel):进入脚本实现与适配器接入
  • 未知/不接受量化:阻塞并向用户提出材料请求(见“阻塞话术”)

2) 实现反量化脚本(convert_*_to_bf16.py

按 FP8 模式创建脚本,最小要求:

  • 提供 convert_* 主转换函数(必须带可见进度条与异常提示)
  • 脚本只需覆盖当前模型确认的量化模式(可仅实现 per-block)
  • 将结果统一转换到 torch.bfloat16(或项目默认浮点 dtype)
  • 参数回写必须 dtype-safe(强约束):
    • 若原始权重存储 dtype 为 FP8,禁止直接将反量化得到的 BF16/F16 张量回写到该 FP8 存储;否则会发生静默类型回退
    • 必须先将“原参数存储”提升到目标浮点 dtype(如 BF16),再执行赋值/拷贝
    • 允许不同代码风格实现(原地改写或整体替换),但必须保证 dtype 与 device 一致
    • 回写后必须有显式校验(断言或日志)确认最终参数 dtype 已是目标浮点类型,而非 FP8
  • 对 index 与 safetensors 不匹配场景给出 warning 并安全跳过
  • 进度条要求:
    • 必须使用 tqdm(或等价方案)显示转换进度,禁止仅打印日志让用户等待
    • total 必须可追踪(例如按待转换参数个数/层数),并实时更新 desc(如当前层名)
    • 长耗时阶段(扫描权重、逐层反量化、保存结果)至少覆盖主耗时环节中的一个;优先覆盖逐层反量化主循环
  • 导出件要求: -如果反量化脚本可以离线运行,即可以先运行反量化导出浮点权重,则导出件中必须包含原生权重中的所有文件,特别chat_template.jinja 文件,该文件缺失会导致服务化异常。

建议函数骨架:

@lru_cache(maxsize=1)
def get_weight_map(model_path: str) -> Dict[str, str]:
    ...

@torch.no_grad()
def convert_module_xxx_to_bf16(name: str, module: nn.Module, model_path: str, weight_map: Dict[str, str]):
    ...

per-block 示例:

def decode_fp8_per_block(weight: torch.Tensor, scale: torch.Tensor, block_size: int = 128) -> torch.Tensor:
    m, n = weight.shape
    scale_expanded = scale.repeat_interleave(block_size, dim=0).repeat_interleave(block_size, dim=1)[:m, :n]
    return (weight.float() * scale_expanded.float()).to(torch.bfloat16)

参数回写(通用伪代码):

dequant_weight = dequantize(fp8_weight, scale_info)   # dequant_weight: BF16/F16
if original_param_storage_is_fp8:
    promote_original_param_storage_to_target_float_dtype()
assign_or_copy_with_device_dtype_alignment(dequant_weight)
verify_param_dtype_is_target_float_dtype_not_fp8()

可选工具脚本(用于判定权重/scale 形状):

  • scripts/inspect_safetensors.py
  • 用法:
    • python scripts/inspect_safetensors.py -m /path/to/model
    • python scripts/inspect_safetensors.py -m /path/to/model -p "model.layers.*.mlp*.weight*"

3) 接入 model_adapter.py

在适配器中注入反量化调用,要求:

  • 在调用 transformers 加载模型前,先检查模型目录 config.json 是否包含量化字段(如 quantization_configquant_methodfmtweight_block_sizemodules_to_not_convert 等)
  • 若检测到量化字段,必须主动删除这些字段后再进行加载,避免 transformers 按量化方式装载权重
  • 删除原因必须在日志中说明:昇腾当前不支持 FP8 量化权重直载,若不清理配置会导致错误加载路径
  • 可接受实现方式:
    • 直接修改模型目录下 config.json 后加载;或
    • 生成去量化字段的临时 config 并确保后续加载明确使用该配置
  • 无论采用哪种方式,都必须保证“最终传给 transformers 的 config 不包含量化相关字段”
  • 在模型权重可用后、量化流程前调用 convert_*_to_bf16
  • 仅对命中的量化子模块执行,避免全模型无谓遍历
  • 转换失败不应静默吞掉;至少记录 warning 与原因

接入示例:

from .convert_fp8_to_bf16 import convert_module_fp8_to_bf16

def init_model(...):
    model = ...
    convert_module_fp8_to_bf16(name="", module=model, model_path=model_path, weight_map=...)
    return model

4) 最小验证

  • 校验可读性:脚本能读取 index 与目标 safetensors
  • 校验转换:目标层权重 dtype 由 FP8 变为 bf16/fp16
  • 校验接入:adapter 初始化路径已触发自动转换函数
  • 校验回退:非量化权重或不匹配键时不报致命错误
  • 校验模式:输出明确 per-blockper-channel 判定结果
  • 校验赋值安全:确认未出现“BF16 copy_ 到 FP8 存储后仍为 FP8”的回退问题

阻塞话术(必须原样遵循语义)

当量化格式不确定或缺反量化规则时,必须明确告知:

  • 当前权重格式无法确认可逆反量化规则,不能安全实现通用反量化。
  • 请用户二选一提供:
    1. 官方/已验证的反量化脚本(含权重键映射与scale定义)
    2. 对应浮点权重(bf16/fp16/fp32)
  • 在补齐材料前,不进入模型适配代码改写阶段。

输出模板

Agent 每次执行本 Skill 后,输出以下结构:

## 反量化判定结果
- 量化状态:未量化 | FP8 per-block(可接受) | FP8 per-channel(可接受) | 未知(阻塞)
- 判定依据:{keys/file evidence}

## 反量化实现动作
- 新增/复用脚本:{path}
- 核心函数:{functions}
- 适配器接入点:{adapter_path + function}

## 验证结果
- 读取校验:通过/失败
- dtype 校验:通过/失败
- 适配器触发校验:通过/失败

## 后续动作
- 若阻塞:请求用户提供反量化脚本或浮点权重
- 若通过:进入模型适配主流程
Install via CLI
npx skills add https://github.com/kali20gakki/msAgent --skill msmodelslim-model-dequant
Repository Details
star Stars 29
call_split Forks 7
navigation Branch main
article Path SKILL.md
More from Creator