Prhub

#35816 [diffusion] docs: add tuning guide for h3 on consumer-level gpu

原始 PR 作者 mickqian 合并时间 2026-08-22 23:48 文件变更 4 提交数 16 评论 0 代码增减 +389 / -27

执行摘要

为 MiniMax-H3 新增消费级 GPU 调优指南与预算感知部署配置

PR body 明确说明:H3 权重约 108 GB(DiT 61.73 GB + text encoder 46.18 GB),现有 recipe(24 GB 单卡、双 32 GB 卡)都假设主机能容纳全部权重,而消费级配置做不到——「No consumer configuration can, and where the shortfall lands decides the throughput」。文档缺失的核心信息是「On consumer hardware the host is the binding constraint, not the card. The H3 page did not say so」:短fall 落点(主机 vs 显存)直接决定吞吐,但原页面只字未提。

值得精读。虽然是文档 PR,但其价值超出普通文档:一是「宿主才是约束」的分析框架可直接迁移到任何大权重 diffusion 模型的部署文档;二是 fair-cap 对比设计(同权重、同 allocator cap、诚实标注 ComfyUI 软限制差异)是跑分型文档的范本;三是 16 个 commit 展示了用实测修正错误结论的完整过程——先承认 ComfyUI 更快,再随运行时优化反超,最终全面改写;四是 unverified recipe 契约与校验脚本是文档工程化的好实践。阅读时注意区分 verified(实测)与 derived(推导)数字。

讨论亮点

该 PR 无 GitHub review 评论(comments_count = 0,review_comments_count = 0),实质讨论发生在 16 个 commit 的演进中,且多次是作者对自身错误结论的公开修正:

  1. Recipe B 的 VRAM 门槛修正(ed40a20):最初建议 12 GB 可用,实测 4 个驻留 DiT 层在 12 GiB cap 下 OOM,必须 16 GB;
  2. ComfyUI 对比结论反转(3f4bfe14):早期声称 ComfyUI 在 12+32 下不能跑 bf16,实测发现是测量错误——ComfyUI 内存管理器读取系统 RAM 自适应,用 psutil patch 模拟 32 GiB 世界后它反而以 13.0 s/it 领先当时的 Recipe A(17-18 s/it);
  3. 全请求胜出依赖 decode 优化(187c54c7):denoise 领先但流式 decode 需 209 s,「三分之二解码器为 decode-only 驻留、结束后释放」才在 12 GiB cap 内把整请求压到 279-283 s;
  4. 页面空白事故(34ba7446):配置常量放模块顶层导致 snippet 渲染整页空白,改 IIFE 修复——docs 站点构建系统的真实陷阱;
  5. 数字边界诚实声明:正文写明 12% 的请求时间波动跟踪 host load、更小差异不作数;32 GB 图形是在 2 TB 主机上取到的乐观值,真实 32 GB 机器会因 re-read 更慢,NVMe 是 requirement 而非 recommendation。

实现拆解

1. cookbook 新增「Consumer GPU tuning」章节(docs/cookbook/diffusion/MiniMax/MiniMax-H3.mdx,+181 行)

  • 核心论断:消费级硬件上 host RAM 决定可用路径;32 GB 主机内权重无法 pin,每一步需从 checkpoint mapping 同步复制约 60 GiB(映射源走驱动同步缓冲,不重叠计算),因此 NVMe 是硬性要求而非建议。
  • 给出 Recipe A(12 GB VRAM + 32 GB 主机)与 Recipe B(主机内存充裕的快速路径)两条命令;Recipe B 以 4 个驻留 DiT 层换取 6.01 s/step,但需要 16 GB VRAM 与约 112 GB pinned 主机内存。
  • 测量方法学两则:主机内存按 RssAnon(匿名页)计数而非 VmRSS(page cache 可被内核回收);VRAM 用 torch.cuda.set_per_process_memory_fraction 硬性 cap 而非 nvidia-smi(caching allocator reserved pool 会高估需求)。
  • 新增启动日志三行自查(Layerwise offload: host memory available、leaving N GiB of weights on the checkpoint mapping、video_vae 的 host mmap vs host pageable),把「机器是否匹配预算」的确认提前到第一分钟。
  • ComfyUI 对比升级为 fair-cap:两边同权重、同硬 cap 12 GiB,Recipe A 在 32/48/64 GB 主机全请求胜出(235/218/180 s vs 276-302/246-267/194-195 s),并明确标注 ComfyUI 的 --reserve-vram 是软限制(实测峰值 13.5 GiB,真实 12 GB 卡给不出)。

2. builder 配置重构为预算感知工厂(docs/src/snippets/configs/MiniMaxAI/minimax-h3.jsx,+185/-23)

  • 关键修复:原静态对象引用的顶层常量(CONSUMER_SINGLE 等)不被 snippet 系统跨文件携带,曾导致整个 H3 页面空白;改为 IIFE 闭包后常量与 config 同作用域。
  • 新增 host_ram overlay 维度(32/48-64/96 GB+),仅对消费级单卡显示;新增 12 款消费级与 2 款工作站显卡(RTX 4090/3090/4080/5080/5070 Ti/4060 Ti/5070/4070/3060、RTX 6000 Ada、RTX PRO 6000),按 12/16/24/48/96 GB VRAM 分层共享测得数据。
  • consumerFlags(s) 按「卡档位 × 主机预算」组合生成 flags:12 GB 基础为 video_vae=36 解码期驻留 + 组件 offload;24 GB + 32 GB 主机追加 10 个 DiT 驻留层(实测 10.4 vs 11.6 s/step);96 GB+ 主机追加 4 个;48 GB 工作站追加 40 个;96 GB 工作站整套 DiT 驻留、仅 offload 编码器与 VAE。
  • consumerHints(s) 为每个组合输出实测预期(步进/解码/整请求时间、ComfyUI 对比、扩页段内存环境变量等),并把「启动日志应输出 leaving ... GiB of weights on the checkpoint mapping,否则主机不是你以为的约束」写进提示。
  • 同步清理了 datacenter recipe 中不再适用于消费级的 --dit-offload-prefetch-size 1 与 --enable-torch-compile false。

3. 渲染器适配(docs/src/snippets/_deployment.jsx,+13/-3)

  • handleSelect 的 hw 切换分支在继承 nodes/gpus_per_node/tp_size 等资源形状之外,追加继承新卡的 placement 与 encoder——否则从 RTX 5090 切到 RTX 4090 会保留 resident 选择,生成单张 24 GB 卡无法运行的命令并被标为 unverified。
  • recipe 徽标与按钮区分 Verified/Derived 两态(renderStatus、Use verified/derived recipe 文案),与 unverified 标志联动。

4. 文档契约校验(docs/scripts/check_cookbook_configs.mjs,+10/-1)

  • 双向断言:普通 verifiedRecipes 条目必须解析为 verified;声明 unverified 的条目若解析为 verified 则直接 fail,防止「声明未验证但实际按已验证展示」的静默漂移。

5. 测试与依赖配套

  • 纯文档/站点配置 PR,无运行时代码与测试文件;数据全部来自单张 RTX 4090 的实测(864×480 / 124 帧 / 20 NFE / bf16 / seed 1101 / cfg 1.0 / euler_ancestral / sigma shift 12.0/3.0)。
  • 落地依赖 PR#35967(fp16-held VAE decoder)合并;PR body 注明「#35967 (fp16-held VAE decoder) is merged; this is now free to land」,最终修订记录了 video_vae=36 在 12 GB 上的可行性。
文件 模块 状态 重要度
docs/src/snippets/configs/MiniMaxAI/minimax-h3.jsx 文档配置 modified 8.62
docs/cookbook/diffusion/MiniMax/MiniMax-H3.mdx 部署指南 modified 5.28
docs/src/snippets/_deployment.jsx 部署渲染器 modified 5.09
docs/scripts/check_cookbook_configs.mjs 校验脚本 modified 3.19

关键符号

consumerFlags workstation96Flags consumerHints config handleSelect

关键源码片段

docs/src/snippets/_deployment.jsx core-logic

部署渲染器适配:硬件切换时继承新卡的 placement 与 encoder,避免生成单卡无法运行的 resident 命令;新增 Derived/Verified recipe 双态徽标与按钮文案,支撑 unverified 契约。

// 硬件切换时,builder 不仅需要跟随新卡调整资源形状(节点数、TP 等),
// 还必须重置 placement 与 encoder:它们是按硬件验证的 recipe 事实。
// 若沿用上一张卡的选项,可能生成新卡跑不了的命令——例如在单张
// 消费级卡上 resident 61.7 GB DiT——并错误显示为 unverified。
if (dim === "hw") {
  const currentRecipe = recommendedBuilderRecipe(prev.hw);
  const nextRecipe = recommendedBuilderRecipe(value);
  const resourcesFollowPlatformDefault = !!currentRecipe
    && Number(prev.nodes) === Number(currentRecipe.nodes)
    && Number(prev.gpus_per_node) === Number(currentRecipe.gpus_per_node);
  next = {
    ...next,
    nodes: resourcesFollowPlatformDefault
      ? (nextRecipe?.nodes ?? next.nodes)
      : next.nodes,
    gpus_per_node: resourcesFollowPlatformDefault
      ? (nextRecipe?.gpus_per_node ?? next.gpus_per_node)
      : next.gpus_per_node,
    topology_mode: "auto",
    tp_size: resourcesFollowPlatformDefault
      ? (nextRecipe?.tp_size ?? 1)
      : next.tp_size,
    placement: resourcesFollowPlatformDefault
      ? (nextRecipe?.placement || "auto")
      : next.placement,
    encoder: resourcesFollowPlatformDefault
      ? (nextRecipe?.encoder || "auto")
      : next.encoder,
  };
}
docs/scripts/check_cookbook_configs.mjs test-coverage

为 derived/unverified recipe 建立双向校验契约:普通条目必须解析为 verified,unverified 条目不得解析为 verified,防止文档契约静默漂移,是本次文档工程化的关键配套。

// recipe 可以携带 unverified: true:它只提供该卡的默认资源形态,
// 不声称做过验证运行,且必须按此解析。这里做双向断言:
// 普通条目必须解析为 verified;声明 unverified 的条目一旦解析为
// verified 就立即 fail,防止文档契约静默漂移。
if (recipe.unverified) {
  const resolved = validateResolved(selection, `verifiedRecipes[${index}]`);
  if (resolved && resolved.builder.verification?.serve === "verified") {
    fail(where, `verifiedRecipes[${index}] is declared unverified but resolves as verified`);
  }
} else {
  validateResolved(selection, `verifiedRecipes[${index}]`, true);
}

评论区精华

没有提炼出高价值讨论线程

当前评论区没有形成足够清晰的争议点或结论,后续有更多讨论时会体现在这里。

风险与影响

数字时效性:所有性能数字是特定硬件组合(RTX 4090 + 2 TB 主机)的实测,随 layerwise offload 与解码器相关运行时优化(#35967、#35734 等)持续演进可能过时,需要专人维护同步。

builder 配置回归风险:minimax-h3.jsx 是 docs 站点运行时渲染的代码,曾发生整页空白事故;本次重构未增加自动化测试,仅靠 check_cookbook_configs.mjs 兜底,而该脚本只校验 topology 与 verified 状态,不校验 flags 的合法性与页面是否可渲染。

unverified 契约误报风险:check_cookbook_configs.mjs 新增双向断言,未来新增硬件若声明与解析结果不一致会直接 CI fail;这是有意的护栏,但也要求作者正确理解 verify 解析语义。

用户误导风险:12 款新硬件条目共享档位数据,30 系卡步进时间高于 40 系实测、48/96 GB 工作站卡为 derived 未验证(hints 已声明),用户若不细读可能误判自身硬件表现。

用户面:消费级 H3 用户(RTX 3060 到 RTX PRO 6000)获得首份可决策的部署指南——预算匹配的 flags、实测预期、与 ComfyUI 的公平对比以及启动日志自查方法。

站点面:deployment builder 新增 Host RAM 选择维度与 12 款显卡,H3 页面的交互能力显著扩展;曾出现的整页空白 bug 也在重构中修复。

团队/流程:建立 verified/derived recipe 文档契约与双向校验脚本,为后续新增硬件(如 RTX 50 系后续型号)提供可扩展模板。

运行时影响:为零,不涉及 python/sglang 任何代码。

性能数字依赖单一测量环境 builder 配置无自动化测试 曾发生整页空白回归事故 依赖 #35967 合并时序

关联 Issue

未识别关联 Issue

当前没有检测到明确关联的 Issue 链接,后续同步到相关引用后会出现在这里。

完整报告

参与讨论