SGLang Diffusion 模型量化实战:基于 NVIDIA ModelOpt 的 FP8 / NVFP4 检查点接入、验证与基准测试全流程

📅 发布时间:2026/9/10 9:39:20
SGLang Diffusion 模型量化实战:基于 NVIDIA ModelOpt 的 FP8 / NVFP4 检查点接入、验证与基准测试全流程
SGLang Diffusion 模型量化实战基于 NVIDIA ModelOpt 的 FP8 / NVFP4 检查点接入、验证与基准测试全流程【免费下载链接】sglangSGLang is a high-performance serving framework for large language models and multimodal models.项目地址: https://gitcode.com/GitHub_Trending/sg/sglang本篇技术指南聚焦 SGLang Diffusion 与 NVIDIA ModelOpt 之间的量化桥接如何把经过 ModelOpt 离线 PTQ训练后量化导出的扩散 TransformerDiT检查点转换为 SGLang 可加载、可验证、可基准测试的 FP8 或 NVFP4 检查点并落地到 FLUX、Wan2.2、HunyuanVideo、Qwen Image 等模型家族上。读完本文你将掌握从 BF16 基线验证、ModelOpt 量化导出、FP8 离线转换、SGLang 组件级加载到轨迹相似度精度验证与公平基准测试的完整可复现流程以及其中的精度保护回退BF16 fallback与 offload 约束等关键工程细节。本文内容以仓库内技能文档 SKILL.md 为主体骨架结合 quantization.mdx、三个转换/验证工具脚本及运行时量化实现源码展开。一、总体定位ModelOpt-to-SGLang 桥ModelOpt 是 NVIDIA 提供的模型优化工具链其 diffusers 示例中包含离线 PTQ 导出流程量化脚本与预设配置输出backbone.pt、hf/等格式的量化产物。SGLang Diffusion 需要把这些产物翻译成自己运行时的检查点布局并完成加载、质量验证与性能基准测试。这就是本工作流的核心职责使用 ModelOpt 官方quantize.py作为 PTQ 事实来源不自行发明量化算法保持工作流通用模型特异的回退逻辑收敛在独立的小分支中而不是散落在主转换路径里仅在 BF16 与量化命令除检查点覆盖项外完全一致时才进行基准测试对比扩散 FP8 场景强制dit_cpu_offloadfalse而dit_layerwise_offloadtrue在固定路径上是合法选项用于降低 DiT 常驻显存多 Transformer 管线使用按组件per-component覆盖为不同骨干模型指定不同检查点。二、仓库当前支持的能力边界2.1 已落地能力根据技能文档与 quantization.mdx 的说明当前仓库包含扁平quant_methodmodeloptquant_algoFP8/NVFP4的配置解析序列化配置键以quant_methodmodelopt为准FP8/NVFP4 仅是对外的文档标签扩散侧 ModelOpt FP8 线性层加载与 NVFP4 加载NVFP4 支持从 ModelOpt 导出物直接重建量化配置FLUX.2 打包 QKVpacked-QKV检测可区分打包 NVFP4 检查点与标准 diffusers 导出物对不兼容的 FP8 CPU offload 的自动防护同时保留 layerwise DiT offload三个配套工具FP8 Transformer 构建器、NVFP4 混合 Transformer 构建器、去噪轨迹相似度校验器详见下文各节。与 ModelOpt PTQ/导出工作流并列的还有一条在线运行时量化路径如--quantization fp8/mxfp4两者职责不同除非用户明确要求运行时量化否则不要把在线量化混入 ModelOpt PTQ/导出流程。2.2 已验证的模型家族支持矩阵技能文档与文档中的Validated ModelOpt Checkpoints一节共同确认了如下已验证范围FP8FLUX.1-dev、FLUX.2-dev、Wan2.2、HunyuanVideo、Qwen Image、Qwen Image EditNVFP4FLUX.1-dev、FLUX.2-dev、Wan2.2、Qwen Image、Qwen Image 2512、Qwen Image Edit、Qwen Image Edit 2511。主文档目前跟踪 13 个已发布的 ModelOpt 检查点其中 12 个位于lmsys/*命名空间FLUX.2 NVFP4 原始导出保留官方仓库black-forest-labs/FLUX.2-dev-NVFP4raw export走--transformer-weights-path流程。更早的BBuf/*示例仅用于历史分支测试不应在新工作中使用。较新的模型家族、新精度或新检查点布局在未写入文档矩阵并配套验证故事之前一律按不支持对待。B200 CImultimodal-gen-test-1-b200还包含 Ideogram4 NVFP4 原生加载用例ideogram4_nvfp4_t2i来自Comfy-Org/Ideogram-4这是既有 NVFP4 路径的佐证但除非 quantization.mdx 补充了精确检查点、加载路径、质量检查与基准范围否则不应据此把支持矩阵扩展到 Ideogram4。2.3 MiniMax-H3 边界MiniMax-H3 是独立在线 FP8 路径的现行证据不是经过验证的 ModelOpt PTQ/导出家族。其经过验证的 B200/B300 服务配方是加载未量化根检查点 --quantization fp8并将视频/音频 patch 投影、timestep MLP、最终视频/音频头保留在 FP32。因此不要为 H3 扩展 ModelOpt 支持矩阵不要对 H3 运行通用 ModelOpt 转换器除非其精确导出物、加载映射、精度检查与基准范围均已验证若用户需要 H3 在线量化命令与质量注意事项走sglang-diffusion-performance技能与 MiniMax-H3 cookbook在线 FP8 是近似方案必须与 eager BF16/FP32 在视频和音频上分别对比且与 Cache-DiT 叠加会复合两次近似。2.4 相关 PR 关注列表历史参考技能文档列出的相关 PR 仅作为 ModelOpt 扩散支持的历史脉络不应仅因 PR 存在就扩张已验证矩阵#23155Qwen Image ModelOpt FP8 支持#23199HunyuanVideo ModelOpt FP8 支持#23373新增运行时量化 flag在 CLI 行为合并前保持 PTQ/导出流程与运行时量化示例分离#24024Transformer FP8-cast 兼容模式#24186重新启用 B200 多模态 CI包含 FLUX.2 与 Wan2.2 的 NVFP4 修复。使用时务必复查 PR 状态与当前源码树并以文档/CI 矩阵作为支持边界新增矩阵行必须在当前分支完成精确检查点、加载路径、精度检查与基准范围的全部验证。三、FP8 与 NVFP4 在 SGLang 中的接入差异两者并非以完全相同的方式接入 SGLang理解差异是选择工作流的关键。FP8需要额外转换步骤经过验证的 ModelOpt diffusers FP8 导出物仍需一次 SGLang 侧离线转换SGLang 期待显式的weight_scale与input_scale张量验证路径还会从backbone.pt物化出 SGLang 原生的float8_e4m3fn权重。NVFP4通常无需离线转换官方 diffusers 导出物往往已包含打包 FP4 权重、缩放张量与足够的 safetensors 元数据SGLang 可以据此重建量化配置此时 SGLang 主要工作是检测检查点家族并把张量重排为运行时布局因此 NVFP4 通常省去 FP8 那道额外转换B200 上后端选择影响明显需要记录运行用的是默认 CUTLASS 路径还是 cuDNN 支撑的 FlashInfer FP4 GEMM 路径。重要提醒通常不等于总是。具体加载路径仍取决于检查点家族尤其是是否采用打包 QKV 布局。例如 FLUX.2 NVFP4 家族就需要专门的打包检测与运行时布局处理见 flux_2.py。四、端到端通用工作流七步第 1 步先验证 BF16 基线任何量化工作开始之前BF16 路径必须已经健康在 SGLang 中运行原始 BF16 模型固定 prompt、seed、尺寸、步数与 GPU 拓扑保存输出与perf.json。未通过基线不进入量化阶段。第 2 步使用 ModelOpt 官方脚本量化使用 ModelOpt 官方quantize.py其 diffusers 示例与量化预设见 ModelOpt 仓库的examples/diffusers/对应的通用模板如下python quantize.py \ --model model-name \ --override-model-path hf-repo-or-local-model \ --model-dtype Half|BFloat16 \ --format fp8|fp4 \ --batch-size 1 \ --calib-size calib-size \ --n-steps calib-steps \ --quantize-mha \ --prompts-file prompt-file \ --quantized-torch-ckpt-save-path out/ckpt \ --hf-ckpt-dir out/hf当前 ModelOpt 扩散示例中NVFP4 导出使用--format fp4不要假设当前签出的 ModelOpt 版本接受字面量nvfp4格式串除非已本地验证对多 Transformer 模型逐个骨干分别量化每个输出目录相互独立同时保存backbone.pt与对应的hf/component导出物。第 3 步将 FP8 导出物转换为 SGLang 格式FP8 需要额外转换使用仓库内工具 build_modelopt_fp8_transformer.pyPYTHONPATHpython python3 -m sglang.multimodal_gen.tools.build_modelopt_fp8_transformer \ --modelopt-hf-dir out/hf \ --modelopt-backbone-ckpt out/ckpt/backbone.pt \ --base-transformer-dir base-model-transformer-dir \ --output-dir out/sglang_transformer \ --overwrite转换器核心工作对应脚本 docstring 与实现从backbone.pt读取weight_quantizer._amax与input_quantizer._amax写出weight_scale与input_scale将符合条件的 FP8 权重物化为float8_e4m3fn保留 ModelOptignore层为 BF16剔除不应进入 SGLang 原生检查点的陈旧_quantizer.*张量与回退层缩放。BF16 回退集fallback preset是按模型家族隔离的、经过验证的精度保护。运行时 modelopt_fp8.py 中ignore列表按 glob 前缀匹配既匹配完整前缀也匹配首路径分量命中层走UnquantizedLinearMethod。FLUX.1-dev--model-type flux1强制或--model-type auto在导出配置识别出FluxTransformer2DModel时自动生效以下模块保持 BF16transformer_blocks.*.norm1.lineartransformer_blocks.*.norm1_context.lineartransformer_blocks.*.ff.net.0.projtransformer_blocks.*.ff.net.2transformer_blocks.*.ff_context.net.0.projtransformer_blocks.*.ff_context.net.2single_transformer_blocks.*.norm.linearsingle_transformer_blocks.*.proj_mlp脚本内对应正则可见 build_modelopt_fp8_transformer.pyDEFAULT_FLUX1_KEEP_BF16_PATTERNS。HunyuanVideo--model-type hunyuan-video或 auto 识别HunyuanVideoTransformer3DModel保持 BF16 的模块包括context_embedder.*x_embedder.projtime_text_embed.(timestep_embedder|guidance_embedder|text_embedder).linear_[12]norm_out.linearproj_outtransformer_blocks.*.norm1.lineartransformer_blocks.*.norm1_context.linearsingle_transformer_blocks.*.norm.linearHunyuanVideo 的 ModelOpt/diffusers 模块名与 SGLang 运行时名在 fused QKV、fused QKVMLP 层上不一致例如context_embedder.*到txt_in.*的映射转换器内维护了 diffusers→runtime 的替换映射见HUNYUANVIDEO_RUNTIME_NAME_REPLACEMENTS并需与 hunyuanvideo.py 保持同步后再信任转换出的缩放张量。Qwen Image / Qwen Image Edit共用QwenImageTransformer2DModel一套回退预设覆盖两者--model-type qwen-image强制或 auto 识别保持 BF16 的模块包括img_intxt_intime_text_embed.timestep_embedder.linear_1/linear_2norm_out.linearproj_outtransformer_blocks.*.img_mlp.net.2transformer_blocks.*.img_modtransformer_blocks.*.txt_mod注意 Qwen 调制权重在 safetensors 中可能写作.img_mod.1.weight与.txt_mod.1.weight回退匹配前需先把这些模块名规范化canonicalize为.img_mod与.txt_mod。关键顺序约束Qwen Image FP8 的显式 BF16 回退张量必须先写入、再处理ModelOpt ignore 权重否则转换器统计信息可能显示已回退而输出检查点仍保留源 FP8 张量导致严重的图像质量退化。NVFP4 混合检查点构建对于 FLUX.1-dev 这类需要混合 BF16NVFP4 检查点的家族使用 build_modelopt_nvfp4_transformer.py 显式构建PYTHONPATHpython python3 -m sglang.multimodal_gen.tools.build_modelopt_nvfp4_transformer \ --base-transformer-dir base-model-transformer-dir \ --modelopt-hf-dir out/hf/transformer \ --output-dir out/transformer-mixed \ --pattern-preset flux1-nvfp4该构建器保留大部分 ModelOpt 导出的 NVFP4 张量仅把经过验证的数值敏感模块替换为基础检查点的原始 BF16 张量。FLUX.1-dev 混合构建还必须保留config.json中的quant_type: NVFP4并为已验证的 diffusers 导出物设置swap_weight_nibbles: false串行 FP4 权重的字节序与运行时内核一致。第 4 步在 SGLang 中加载量化检查点单 Transformer 示例sglang generate \ --model-path base-model \ --transformer-path quantized-transformer \ --prompt prompt \ --seed seed \ --save-output多 Transformer 示例如 Wan2.2 仅主 transformer 量化sglang generate \ --model-path base-model \ --transformer-path quantized-transformer \ --transformer-2-path another-transformer-or-bf16-override \ --prompt prompt \ --seed seed \ --save-output完整 ModelOpt Diffusers 仓库示例当前 Qwen Image NVFP4 路径sglang generate \ --model-path lmsys/qwen-image-2512-modelopt-nvfp4-sglang \ --prompt prompt \ --seed seed \ --save-outputCLI 选择准则只有当模型实际上只有一个 transformer 覆盖项时才使用全局--transformer-path不同骨干需要不同检查点时使用按组件覆盖如--transformer-2-path对已发布的完整 ModelOpt Diffusers 仓库如 Qwen Image NVFP4 家族直接用--model-path这与 transformer-only 覆盖不同首选 CLI 形式是--component-path配置展开形式如--component_paths.transformer_2...同样解析到同一内部覆盖映射若覆盖仓库/目录本身携带config.jsonSGLang 会优先读取覆盖项自身的量化配置而不是基础模型的配置--transformer-path用于带config.json的组件覆盖目录--transformer-weights-path用于按原始权重探测的仓库或路径raw weights probing。第 5 步验证精度两级验证简化确定性验证reduced deterministic validation固定 prompt、seed、分辨率与步数对比 BF16 与量化运行捕获去噪轨迹denoising trajectories检查每步 latent 余弦相似度以及 MAE 或 RMSE用 PSNR 或 MAE 等图像指标对比最终帧。工具为 compare_diffusion_trajectory_similarity.py其实现会逐采样步对比 reference 与 candidate 的 latent并输出帧级compute_uint8_frame_metrics首帧/中间帧/全帧PYTHONPATHpython python3 -m sglang.multimodal_gen.tools.compare_diffusion_trajectory_similarity \ --model-path base-model \ --model-id optional-native-model-id \ --prompt prompt \ --width w \ --height h \ --num-inference-steps steps \ --guidance-scale cfg \ --seed seed \ --candidate-transformer-path quantized-transformer \ --output-json report.json当--model-path指向本地目录、但运行时仍需要原生 FLUX.1 模型注册时使用--model-id FLUX.1-dev。全输出验证full-output validation用相同的用户可见生成配置分别跑 BF16 与量化模式目视检查输出只对实际检查过的精确范围宣称质量保持。第 6 步正确进行基准测试仅在以下条件在 BF16 与量化命令间全部一致时才允许对比prompt、seed、width/height、帧数、推理步数GPU 数量与拓扑offload 标志compile 设置profiler 设置。唯一允许的差异是量化检查点路径本身。解释规则主要预期收益在去噪阶段文本编码与 VAE 的差异是次要的除非它们本身也被量化否则不应过度归因。B200 上的后端选择案例引自 quantization.mdx 已验证结论适用范围限定于该文档记录的检查点与形状扩散 ModelOpt NVFP4 路径在 Blackwell 上默认使用 FlashInfer TensorRT-LLM FP4 GEMMflashinfer_trtllm高分辨率 Qwen Image 生成可改用 CUTLASS 后端1024x1024 则可能仍是 BF16 更快。例如SGLANG_DIFFUSION_FLASHINFER_FP4_GEMM_BACKENDcutlass \ sglang generate \ --model-path lmsys/qwen-image-2512-modelopt-nvfp4-sglang \ --width 2048 --height 2048 \ --prompt A tiny astronaut reading a book under a glass greenhouse \ --save-output可用的SGLANG_DIFFUSION_FLASHINFER_FP4_GEMM_BACKEND取值包括flashinfer_cudnn、flashinfer_cutlass、flashinfer_trtllm。原则是对实际形状做基准测试而不是假定某个后端或量化检查点必然更快。第 7 步仅在必要时添加模型特定回退若通用 FP8 路径在新模型家族上失败排查哪些模块数值敏感或与加载器不兼容保持回退模式小而明确将其隔离在转换器中而不是散落临时特例每次回退改动后重跑确定性轨迹校验。不要把单一已验证模型的怪癖上升为通用规则除非另一家族也需要它。五、FP8 Offload 约束与运行时强制行为当前扩散 ModelOpt FP8 支持要求dit_cpu_offloadfalse需要降低 DiT 常驻显存时可启用dit_layerwise_offload。原因与运行时行为FP8 线性路径依赖加载后 CUTLASS 兼容的权重布局dit_cpu_offload目前仍被保守对待固定 layerwise offload 路径现在保留非连续张量 stride而不是把 FP8 权重展平重建成连续布局参考 transformer_load_utils.py 中_maybe_disable_incompatible_dit_offload_modes等适配逻辑其对modelopt_fp8配置强制关闭dit_cpu_offload因此SGLang 检测到modelopt_fp8时会强制禁用dit_cpu_offload基准命令仍应显式固定 offload 标志使命令行本身就能体现对比规则。六、运行时实现纵深从quant_methodmodelopt到内核6.1 扁平配置解析与注册runtime/layers/quantization/__init__.py注册扩散侧量化方法modelopt_fp8.py 实现扁平quant_methodmodelopt导出的静态 per-tensor FP8 路径。从源码看ModelOptFp8Config.get_name()返回modelopt要求quant_algo包含FP8并声明最低计算能力为 89get_min_capability()支持 BF16/FP16 激活。每个量化线性层在检查点中的预期布局为.weightfloat8_e4m3fn[out, in]FP8 量化权重.weight_scalefloat32标量per-tensor 权重缩放.input_scalefloat32标量per-tensor 静态激活缩放.biasbfloat16未量化._amax校准产物加载时忽略。命中ignore列表的层保持 bfloat16 并走标准未量化线性方法底层复用 SRT 的apply_fp8_linear/cutlass_fp8_supportedfp8_utils。6.2 NVFP4 配置重建quantization_utils.py 承担扁平 ModelOpt 配置的归一化与 NVFP4 配置重建通过normalize_flat_modelopt_quant_config处理扁平配置并在 NVFP4 场景下聚合多个 safetensors 文件的元数据quant_algo含NVFP4、quant_type含NVFP4、或format nvfp4的层标记来重建量化配置。它还能从权重/缩放张量形状推断 NVFP4group_size_infer_nvfp4_group_size_from_shapes并在与 config 冲突时报警/回退到 config 值识别打包 QKVpacked_qkv与 Comfy 层标记记录scale_layout、swap_nibbles、被排除模块等关键字段。这正是官方 diffusers 导出物自带元数据、SGLang 可自描述重建这一特性的底层实现也解释了为何 NVFP4 通常不需要像 FP8 那样的额外离线转换。6.3 核心代码文件速查文件角色runtime/layers/quantization/init.py注册扩散量化方法runtime/layers/quantization/modelopt_fp8.py扁平quant_methodmodelopt导出的静态 per-tensor ModelOpt FP8 路径runtime/layers/quantization/modelopt_quant.pyModelOpt FP8 与 NVFP4 运行时加载runtime/utils/quantization_utils.py解析扁平 ModelOpt 配置并从元数据重建 NVFP4 配置runtime/loader/transformer_load_utils.py防护不兼容的 FP8 offload 模式runtime/models/dits/flux_2.py打包 FLUX.2 NVFP4 家族的打包 QKV 处理tools/build_modelopt_fp8_transformer.py从 ModelOpt 导出物构建 SGLang 可加载的 FP8 Transformertools/build_modelopt_nvfp4_transformer.py为需要保留 BF16 层的家族构建混合 BF16NVFP4 Transformer 目录tools/compare_diffusion_trajectory_similarity.py简化确定性 BF16-vs-量化验证docs/docs/sglang-diffusion/quantization.mdx公开 ModelOpt 支持矩阵与 CLI 示例test/server/testcase_configs.py可复用的 ModelOpt 测试用例常量、阈值与辅助函数test/server/gpu_cases.py具体 GPU 与 B200 ModelOpt CI 用例清单七、文档维护与结果声明纪律已验证的 ModelOpt 支持矩阵统一维护在 docs/docs/sglang-diffusion/quantization.mdx每一行应记录已验证范围、量化 DiT 权重的 Hugging Face 仓库或路径、关键注意事项若量化权重尚未发布明确写unpublished不要留空验证完新的 ModelOpt 量化路径后先更新支持矩阵再关闭任务B200 CI 中宽松的 BF16-vs-量化质量检查旨在捕获空白、损坏或明显偏离的图像而非追求逐像素一致使用前先检查当前分支的run_suite.py主线与特性分支可能不同。结果声明纪律Claim Discipline只宣称端到端实际验证过的范围不要把单 Transformer FP8 覆盖说成全模型 FP8若 BF16 与量化命令的 offload 行为不同不要把一个实际部署对比称为基准测试。八、总结把 NVIDIA ModelOpt 的离线 PTQ 导出物接入 SGLang Diffusion是一条量化 → 转换 → 加载 → 验证 → 基准的五段链路。本文基于仓库技能文档与源码给出了完整实操路径FP8 依赖build_modelopt_fp8_transformer.py的显式转换含模型家族化的 BF16 回退集与 HunyuanVideo 命名映射NVFP4 则多借助导出物自带元数据在运行时重建配置含 FLUX.2 打包 QKV 检测加载阶段需区分--transformer-path、--transformer-weights-path与--model-path三种语义验证阶段用轨迹相似度工具量化对比基准阶段必须保证 BF16 与量化命令除检查点外完全同构。同时牢记两条硬约束——FP8 下dit_cpu_offloadfalse、以及任何新模型家族进入支持矩阵前都必须补齐文档行与完整验证故事。lmsys/*下已发布的 13 个 ModelOpt 检查点外加black-forest-labs/FLUX.2-dev-NVFP4即这条流水线的现成样例FP8 家族走--transformer-path组件覆盖Qwen Image NVFP4 全仓库可直接作为--model-path加载。以此为基础任何新的扩散骨干都能沿着同样的模板完成量化接入。【免费下载链接】sglangSGLang is a high-performance serving framework for large language models and multimodal models.项目地址: https://gitcode.com/GitHub_Trending/sg/sglang创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考