DeepSpeed Mixture-of-Quantization(MoQ)量化训练完全指南:从 QAT 渐进式降精度到 GLUE 任务实战 DeepSpeed Mixture-of-QuantizationMoQ量化训练完全指南从 QAT 渐进式降精度到 GLUE 任务实战【免费下载链接】DeepSpeedDeepSpeed is a deep learning optimization library that makes distributed training and inference easy, efficient, and effective.项目地址: https://gitcode.com/GitHub_Trending/de/DeepSpeedMixture-of-QuantizationMoQ是 DeepSpeed 在 QATQuantization-Aware Training量化感知训练之上提出的一套模型压缩方案它不再让模型全程使用单一精度做量化微调而是在训练过程中按照预定义调度将数据精度从高位宽逐步降低到目标位宽并借助模型参数的二阶信息为不同网络层分别动态调整量化节奏。读完本文你将掌握 MoQ 的全部配置项语义与默认值、如何用一份 DeepSpeed JSON 配置 一段启动脚本对 GLUE 任务如 MRPC开展 8-bit 量化微调、如何用 eigenvalue 做逐层敏感性分析以及这些机制在当前仓库源码中的落点与注意事项。本文以官方教程 MoQ-tutorial.md 为核心骨架并结合deepspeed/compression、deepspeed/runtime下的实现代码交叉印证。MoQ 是什么用“渐进式降精度”替代“一步到位”的量化传统 QAT 在整个训练过程中把模型权重固定在目标位宽例如直接跳到 8-bit被量化层从第一轮起就在低精度下“挣扎”。MoQ 的核心不同在于以 QAT 为底座量化在训练中发生而非训练后 PTQ梯度仍然流过伪量化算子让模型适应量化误差精度随训练步进递减训练从高精度FP16 或 16-bit 量化起步经过一段稳定期后按预设周期逐步降低位宽直到触达target_bits如 8-bit逐层差异化调度利用模型参数的二阶信息eigenvalue特征值评估各层的敏感度为网络的不同层单独调节量化调度让更“敏感”的层在低精度前停留更久、获得更多适应迭代。实验表明加入这种调度并在训练过程中混合多种数据精度后量化模型的质量与最终精度保持能力优于一步到位的基本 QAT见下文“微调结果”表。MoQ 方法的深入原理可参见官方发布的 MoQ 深度解读博客。使用 MoQ 的前提条件要在自己的训练脚本里启用 MoQ 量化训练需要满足两条硬性要求将 DeepSpeed 集成进训练脚本参见 Getting Started 快速上手在训练脚本中通过--deepspeed与--deepspeed_config参数或deepspeed.initialize()初始化引擎。在 DeepSpeed 配置 JSON 中补充模型量化相关参数也就是下文逐一说明的 MoQ 参数。额外说明MoQ 需要与 FP16 混合精度训练配合使用。在 deepspeed/runtime/engine.py 中可以看到明确约束MoQ (quantize in optimization step) weight quantization is only supported for FP16——量化发生在优化器步骤中的 MoQ 路径目前仅支持 FP16 训练模式因此教程中的配置文件都开启了fp16。MoQ 参数全解从开关到算法逐项释义MoQ 的量化调度由一组配置参数定义用户可以通过不同组合探索多样的量化策略。教程中记录的参数清单与默认值整理如下。MoQ 核心参数配置项含义默认值enabled是否启用量化训练Falsequantize_verbose是否打印量化的详细信息Falsequantizer_kernel是否启用专门的量化算子内核Falsequantize_type量化类型symmetric或asymmetricsymmetricquantize_groups量化分组数表示量化一个模型张量时使用的 scale 个数1quantize_bits位宽转换区间控制数据精度从起始位宽向最终目标位宽的过渡过程例如从 16-bit 一路降到 8-bitstart_bits量化训练中的起始位宽默认16target_bits量化训练的目标位宽默认16。quantize_schedule每个精度档位的训练步数调度决定在每个精度级别上如何安排训练步数quantize_period精度位宽数降低一次的周期。默认每100个训练步降一次精度且每降低 1 bit周期会翻倍即第二次降精度发生在 200 步后、第三次在 400 步后依此类推schedule_offset量化开始生效的时间点。在该 offset 之前模型保持普通训练精度FP32/FP16。默认100步。quantize_algo量化算法q_type目前支持对称量化与非对称量化分别产生有符号与无符号整数默认symmetricrounding量化值取整策略可选择就近取整nearest或随机取整stochastic默认nearest。补充说明教程早期版本将上述参数统一书写在顶层quantize_training段下。从当前仓库的 deepspeed/compression/constants.py 看同一套语义在新的weight_quantization框架中以enabled / quantizer_kernel / schedule_offset / quantize_groups / quantize_verbose / quantization_type / rounding共享参数加different_groups分组模块作用域的形式组织位宽切换所需的start_bits / target_bits / quantization_period被放入每个分组group的params中且schedule_offset的默认值为0。若你的安装版本以compression_training为解析入口见 deepspeed/runtime/engine.py 的quantize_training()建议参考 docs/_pages/config-json.md 中compression_training一节的最新字段布局。Eigenvalue特征值参数用于基于二阶信息的动态逐层量化调度全部收在eigenvalue子段中配置项含义默认值enabled是否启用带 eigenvalue 调度的量化训练Falseverbose是否打印 eigenvalue 计算的详细信息Falsemax_iter计算特征值的最大迭代次数幂迭代上限100tol计算特征值的收敛容忍误差1e-2stability方差稳定因子用于归一化时防止除零1e-6gas_boundary_resolution每经过 N 个 gradient accumulation stepgas边界计算一次特征值1layer_name指向需要计算特征值的所有层的模型作用域名bert.encoder.layerlayer_num需要计算特征值的层数无默认须显式指定这些键名与默认值与 deepspeed/runtime/constants.py 中的定义一一对应解析逻辑位于 deepspeed/runtime/config.py 的get_eigenvalue_config()。实战对 GLUE 任务做 MoQ 量化微调教程以 GLUE 任务微调作为 MoQ 的完整示范。动手前你需要安装 DeepSpeedcheckout Hugging Facetransformers分支并安装其全部依赖GLUE 示例使用其text-classification/run_glue.py。第一步准备 DeepSpeed 量化配置文件以test.json为例以下是对量化训练至关重要的参数布局{ optimizer: { type: AdamW, params: { lr: 2e-5, weight_decay: 0.0, bias_correction: true } }, gradient_clipping: 1.0, fp16: { initial_scale_power: 16, enabled: true }, quantize_training: { enabled: true, quantize_verbose: true, quantizer_kernel: true, quantize-algo: { q_type: symmetric }, quantize_bits: { start_bits: 16, target_bits: 8 }, quantize_schedule: { quantize_period: 400, schedule_offset: 0 }, quantize_groups: 8, } }要点解读fp16必须开启如前面所述量化在优化步骤中进行的 MoQ 仅支持 FP16 引擎quantize_bits的 16→8 表示从 16-bit 出发逐步向 8-bit 收敛quantize_period: 400配合教程“每降 1 bit 周期翻倍”的规则总训练步数需要覆盖全部降级阶段否则无法在训练结束前达到target_bitsquantize_groups: 8表示对每个被量化张量使用 8 个 scale 的分组对称量化。第二步编写启动脚本以 MRPC 为例将脚本放到 Hugging Face 示例目录如transformers/examples下通过--deepspeed test.json让 DeepSpeed 读取上述 JSON。以 MRPC 任务为例TSKmrpc TEST_JSONtest.json python text-classification/run_glue.py \ --model_name_or_path bert-base-cased \ --task_name $TSK \ --do_train \ --do_eval \ --max_seq_length 128 \ --per_device_train_batch_size 32 \ --learning_rate 2e-5 \ --num_train_epochs 3 \ --output_dir /tmp/$TSK/ \ --fp16 \ --warmup_steps 2 \ --deepspeed test.json运行该脚本即会得到带 MoQ 量化的 MRPC 精度accuracy与 F1 指标。可调项均可替换将TSK换成cola/sst2/rte/qnli/qqp/mnli/wnli/stsb即可在其余 GLUE 任务上复现。基于二阶信息的动态调度Eigenvalue 机制Eigenvalue 在训练中扮演“层敏感度代理”的角色开启后DeepSpeed 会在每个gas_boundary_resolution边界为每个指定层计算特征值并根据层敏感度将quantize_period提升最多 5 倍该倍数来自启发式选择让敏感层在下一轮降精度之前有足够的迭代步数来适应。其计算原理在 deepspeed/runtime/eigenvalue.py 的Eigenvalue.compute_eigenvalue()中可见对每个 block 使用幂迭代power iteration逼近海森-向量积对应的最大特征值——先随机初始化向量v并归一化然后循环执行Hv torch.autograd.grad(grads, params, grad_outputsv, ...)、用内积inner_product(Hv, v)更新特征值估计直到满足max_iter上限或相邻两次估计的相对误差低于tol。post_process()会把各层特征值映射到[0, 1.0]区间用于调度比较。使用 eigenvalue 的注意事项沿用教程要点训练会明显变慢每个指定层都要迭代计算特征值开销显著FP16 下的 NaN/Inf 处理受限于 FP16 表示范围部分层的特征值可能变成 NaN/Inf。对这些层DeepSpeed 会返回所有非 NaN/Inf 层特征值中的最大值若所有层都是 NaN则统一返回1.0。这一回退逻辑与 deepspeed/runtime/eigenvalue.py 的post_process()行为一致quantize_period可能被显著放大特征值最多把周期提升 5 倍叠加“每降 1 bit 周期翻倍”若初始quantize_period已很大最终周期可能超出训练总步数。因此使用 eigenvalue 时应从相对较小的quantize_period起步保证训练能在结束前走完所有精度过渡阶段不保证精度更好开启 eigenvalue 通常需要与start_bits、quantize_period、quantize_groups等设置联合调优。带有 eigenvalue 的完整配置示例12→8-bitBERT 12 层逐层调度{ ...... quantize_training: { enabled: true, quantize_verbose: true, quantizer_kernel: true, quantize_type: symmetric, quantize_bits: { start_bits: 12, target_bits: 8 }, quantize_schedule: { quantize_period: 10, schedule_offset: 0 }, quantize_groups: 8, fp16_mixed_quantize: { enabled: false, quantize_change_ratio: 0.001 }, eigenvalue: { enabled: true, verbose: true, max_iter: 50, tol: 1e-2, stability: 0, gas_boundary_resolution: 1, layer_name: bert.encoder.layer, layer_num: 12 } } }当前仓库实现现状务必以实际版本为准教程所描述的 eigenvalue 动态调度在早期版本为可用特性但当前 deepspeed/runtime/config.py 的get_eigenvalue_config()中带有一条assert not get_eigenvalue_enabled(...), Eigenvalue based MoQ is temporarily disabled断言——即在当前代码路径下开启 eigenvalue 会直接触发“暂时停用”的断言失败。同时本仓库的量化主入口已迁移至compression_training/weight_quantization框架教程中的顶层quantize_training段属于历史配置路径。因此在较新版本中运行 eigenvalue 示例前请先核对所安装 DeepSpeed 的版本与配置解析行为若不支持应使用纯quantize_schedule的固定周期调度或按 deepspeed/compression/constants.py 中的新框架字段重组配置。GLUE 微调结果与调度策略对照教程在下表中给出每个 GLUE 任务达到报告精度所用的调度参数所有实验统一采用 8 组的分组对称量化symmetric grouped quantization with 8 groups。任务STSBMRPCCOLAWNLISST2RTEQNLIQQPMNLIstart-bits121212121212121214period1010884008641812启用 EigenvalueFalseTrueTrueTrueFalseTrueFalseTrueTrue可以看到不同任务对起始位宽12 或 14、周期长短8400以及是否启用 eigenvalue 的选择差异很大——这正体现了 MoQ 参数空间的自由度SST2/QNLI 使用大周期且关闭/开启 eigenvalue 的不同组合而绝大多数任务采用了较小周期并开启 eigenvalue。各方案在 GLUE SQuAD 上的精度保持结果任务STSBMRPCCOLAWNLISST2RTEQNLIQQPMNLISQuADACCw/o QAT(FP16)88.7188.1256.7856.3491.7465.390.9690.6784.0490.560Basic QAT88.988.3552.7855.391.564.290.9290.5984.0190.39-0.87MoQ88.938959.3356.3492.0967.1590.6390.9484.5590.710.75解读要点以最后一列ACC相对未量化 FP16 基线的平均精度增量衡量Basic QAT 平均下降约 0.87 个百分点而 MoQ 在绝大多数任务上不仅没有掉点平均还高出约 0.75 个百分点MoQ 在 COLA、SST2、RTE、QQP、MNLI 上均超越了 FP16 基线说明渐进式降精度能有效弥补量化误差带来的精度损失。工程细节量化在训练管线中的实际执行路径把教程放到仓库源码中“对号入座”可以帮助你理解 MoQ 的工程实现调度器配置解析后deepspeed/compression/scheduler.py 中的compression_scheduler负责在引擎每次step()时推进training_steps并轮询各压缩方法在训练步数越过schedule_offset后把目标模块的weight_quantization_enabled置为True量化层载体deepspeed/compression/basic_layer.py 提供可替换的量化基础模块如Linear_Compress、Embedding_Compress等它们接收start_bits / target_bits / quantization_period并依据目标位宽选择对称/非对称、三元、二值等不同量化器引擎侧开关deepspeed/runtime/engine.py 的quantize_training()将配置汇总为quantize_enabled / quantize_groups / quantization_type / rounding / verbose / quantizer_kernel等运行时标志当启用且未采用quantize_weight_in_forward时引擎会从 deepspeed/runtime/quantize.py 构造Quantizer在FP16 优化器步骤内完成权重位宽随训练步的切换——这正是 MoQ “量化发生在训练过程”的底层实现。调参 Tips 与总结围绕 MoQ 的使用教程给出了两条关键建议这里结合参数语义做进一步展开调度必须匹配总迭代数设置quantize_period与schedule_offset前先估算任务的总样本数与训练迭代数确保模型在训练结束前确实降到了目标精度。由于周期会随每次降 1 bit 而翻倍可粗略估算“所有精度阶段累计所需步数 ≈ offset period × (2^降级次数 − 1)”级别的量级再反推period的取值上限。若启用了 eigenvalue还需考虑其最多 5 倍的周期放大效应。Eigenvalue 是“自动寻优器”而非“精度保险丝”它对网络不同部分动态调整量化周期带来两个正面效果其一相比所有层共用同一quantize_period逐层差异化调度有望获得更高精度其二它基于敏感度自动为每层找到一个合适的量化节奏省去人工为每层手调周期的工作。但它并不保证结果更好实际使用时应与其他设置start_bits、quantize_period、quantize_groups一起纳入搜索空间并结合上表任务级的参数先例快速定位可行区间。综上MoQ 提供了一条“从 FP16 出发、逐步量化到目标位宽、可选 eigenvalue 逐层加速”的完整训练路径。在 DeepSpeed 中落地时建议以 MoQ-tutorial.md 中的 GLUE 配置为模板先复现 MRPC 基线再按任务特性调整start_bits、quantize_period、quantize_groups与 eigenvalue 开关同时注意你安装的 DeepSpeed 版本对quantize_training历史与compression_training现行框架两组配置字段的兼容情况。更进一步可将该量化能力与其他压缩技术如 模型压缩教程 中讲解的剪枝、层裁剪等组合构建完整的端到端模型瘦身方案。【免费下载链接】DeepSpeedDeepSpeed is a deep learning optimization library that makes distributed training and inference easy, efficient, and effective.项目地址: https://gitcode.com/GitHub_Trending/de/DeepSpeed创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考