性能与方法论 134GB 跑在 128GB 上的六期复盘
T AGENT 开发纪实 · EP35 · MiniMax-H3 六期原理课 ⑥(收尾)
六期讲完:原理、量化、硬件、补丁、部署。这一期把数字收拢成账本,把踩坑收拢成方法论,把单机折腾收拢成开源协作的模式。128 装下 134,不是运气,是闭环。
加载
532s
每步去噪
7.75s
5s 视频
1235s
期系列
6
💡 本节要点:EP35:性能与方法论——六期系列收尾:532s 加载 / 7.75s 每步 / 2s→298s / 5s→1235s / 超线性缩放 O(T²) / 三步组合拳 / fail-closed 方法论 / 开源协作模式
起点问题
四个问题:六期讲完,还剩什么?
- 📊 · 性能账本 · 加载多久?每步多慢?内存怎么花的?——全部实测数字
- 📈 · 超线性 · 视频越长,单位成本越高——O(T²) 架构成本长什么样?
- 🧭 · 方法论 · 六连坑能沉淀成什么?——fail-closed 与三步组合拳
- 🤝 · 开源协作 · 上游镜像、社区补丁、贡献路径——怎么参与?
所有问题的答案,指向同一条主线: 失败链推着走,组合拳兜着底,验证链守着门
💡 本节要点:起点问题:性能数字到底是多少?为什么视频越长单位成本越高?失败链能沉淀成什么方法论?开源项目怎么协作?——四个问题对应:账本、超线性、fail-closed、协作模式
实测账本
性能全景:一次请求的全部数字
- ⏱️ · 532.3 s · 全模型加载(13/13 分片 · 154.75s 分片读取)
- ⚙️ · 7.75 s · 2s 请求平均每去噪步(20 步 · flow_shift 12)
- 🚀 · 154.9 s · 2s 视频端到端(HTTP 200 · 产物 698,852 B)
- 🧠 · 89.17 GB · 加载后模型内存(FP8 在线量化)
- 92,957 MiB · 请求后 GPU 分配 · 低于 102GB 常驻红线
- 21 GB · 宿主可用内存 · 余量管理留出的呼吸空间
- 2.8 / 15 GB · swap 用量 · 少量换页,无掉电、无温度告警
注:数据来源:docs/RESULTS.md(一次 FL2VA 文生视频请求,单机 DGX Spark)
💡 本节要点:性能全景(RESULTS.md 实测):分片 13/13 · 154.75s;全模型加载 532.257s;模型内存 89.1659 GiB;2s 请求端到端 154.956s;平均每去噪步 7.748s
关键规律
视频越长,单位成本越高:超线性缩放
| 指标 | 2s(56 帧) | 5s(124 帧) | 增长 |
|---|---|---|---|
| 引擎耗时 | 298.2 s | 1,179.9 s | 3.96× ← 帧只涨 2.21× |
| 每步去噪 | 14.9 s | 59.0 s | 3.96× |
| 每帧每步成本 | 0.266 s | 0.476 s | 1.79× |
| 音频帧(32kHz) | 74,400 | 165,600 | 2.23× 线性 |
| MP4 编码 | 2.6 s | 55.3 s | 21× |
| 根因 视频扩散注意力随帧数 O(T²) 增长,GB10 统一内存带宽进一步放大 —— 架构性成本,与电压/温度无关(直插墙插后满载两次通过)。 | |||
| > 注:两次 5s 生成差异 ~15%(1024.7 vs 1179.9s)属正常波动 | |||
| > 💡 本节要点:超线性缩放(generation-benchmark.md):帧数 2.21× → 引擎耗时 3.96×;每帧每步 1.79×;音频线性 2.23×;MP4 编码 21×——视频扩散注意力 O(T²) 架构性成本 × 统一内存带宽 |
坑点复盘
隐藏瓶颈:MP4 编码不是免费的
- 无 NVENC · 容器内没有硬件编码器 · H.264 全靠 CPU 软编 —— GB10 的算力不在编码上
▌ 2s · 56 帧 · 2.6s
▌ 5s · 124 帧 · 55.3s(21×)
占比 5s 时编码 55.3s,占端到端 4.5%,且增长 21× 远超引擎的 4× - 🔮 · 外推 10s ≈ 55–70 min · 未实测;内存余量仅 ~19 GiB,长视频有压力
教训 1 5s 请求客户端超时必须 ≥ 1800s,否则响应写回断开的 socket,视频丢失
教训 2 服务端孤儿请求跑完自动恢复空闲,无需重启容器💡 本节要点:隐藏瓶颈:容器内无 NVENC 硬件编码 → 纯 CPU 软编;56 帧 2.6s → 124 帧 55.3s(21×);5s 时编码占端到端 4.5%;外推 10s ≈ 55–70 min(未实测);客户端超时必须 ≥1800s
组合拳复盘
128 装下 134:三步组合拳的账本
134 GB 磁盘 BF16 原样 一个字节没动 → 67 GB FP8 在线量化 加载时现转 · 免校准 → ~102 GB 统一内存 demand paging 用到多少换入多少 → 18–19 GB 余量管理 留给宿主的呼吸空间
| 实测节点 | 数字 | 说明 |
|---|---|---|
| 加载后模型内存 | 89.1659 GiB | FP8 权重 + 激活 + KV |
| 请求后 GPU 分配 | 92,957 MiB | 低于 102GB 红线 |
| 宿主可用内存 | 21 GiB | 余量管理生效 |
| swap | 2.8 / 15 GiB | 少量换页,无掉电 |
注:量化只是第一步,真正装下靠的是整套协同(EP31/EP32 详述)
💡 本节要点:内存账本复盘:三步组合拳——FP8 在线量化 134→67GB + 统一内存 demand paging 常驻 ~102GB + 余量管理留 18-19GB;实测 89.17GB 加载 / 92,957 MiB 请求后 / 21GB 宿主可用
方法论 ①
失败链:一次失败,换一条路
—— 内存 118–119GB,超限 → 换 FP8
BF16 硬扛
—— SM121 无 INT8 指令 → 换 FP8(唯一原生选择)
INT8
—— codegen 失败 → 换 Cutlass 原生内核
Triton 编 FP8
—— 变长内核编不出 → 换 PyTorch SDPA
FA4 CuTe
- 🧭 · fail-closed · 行不通就明确失败,不静默降级、不硬扛
- 🧩 · 窄补丁 · 只动必要的行,守 loader 契约(2→3 参数)
- 🔁 · 坑→资产 · 每个坑变成一个启动参数、一个补丁、一个测试
注:详细六连坑拆解见 EP33
💡 本节要点:失败链方法论:BF16 超限 → INT8 无指令 → loader 契约 → Triton 编不出 → AdaLN 精度 → FA4 编译——一次失败换一条路(fail-closed),不硬扛;每个坑都变成:一个启动参数 / 一个补丁 / 一个测试
方法论 ②
验证链:三层守门,逐级转正
单元层 5 个 patch tests 镜像内跑:QKV 布局 / loader 契约 / fc1 布局 / FP8 量化器 / AdaLN BF16 → 请求层 smoke-t2va .part 落盘 → HTTP 2xx → ffprobe 确认容器 → 转正 → 产物层 verify-output.sh 流式解析 / 全解码 / 音频在 / 校验和对
- ✅ · 5 测试全过 · 补丁层正确性
- 📡 · HTTP 200 · 请求层可达性
- 🎬 · 全解码通过 · 产物层可播放
注:fail-closed:一步不过,整个冒烟就算失败(EP34 详述)
💡 本节要点:验证方法论三层:单元层 5 个 patch tests 镜像内跑;请求层 smoke-t2va fail-closed(.part→2xx→ffprobe→转正);产物层 verify-output.sh(流/全解码/音频/校验和)
协作模式
单机折腾 → 开源协作:谁贡献了什么
vLLM / vLLM-Omni 上游框架 minimax-h3 镜像 · OpenAI 兼容 API → NVIDIA Cutlass FP8 缩放矩阵乘 SM121 原生内核 → PyTorch SDPA 注意力后端 绕开 FA4 编译 → 本项目兼容层 1 补丁 + 启动脚本 + 量化配置 + 安全策略 + 5 测试
贡献路径 读 README(诚实声明 + 复现路径)→ 跑 make 链 → 在固定 digest 上改补丁 → 全链路重验后再提
注:镜像内 vLLM 与 vLLM-Omni 版本不一致警告未压制——该固定组合实测通过(EP34)
💡 本节要点:开源协作模式:上游 vLLM / vLLM-Omni(minimax-h3 镜像)+ NVIDIA Cutlass(FP8 内核)+ PyTorch SDPA;本项目 = 1 个补丁文件 + 启动脚本 + 量化配置 + 安全策略 + 5 测试;贡献路径:读 README → 跑 make 链 → 固定 digest 上改补丁 → 全链路重验
可复现性
别人照着跑,能跑出同样的片
—— 镜像不变,跑法不变,复现的第一前提
固定 digest
—— preflight → build → up → status → smoke + verify,六条命令从零到片
make 链
—— 105 GiB 内存检查、license 承认、aarch64 校验,起不来先报错
前置门槛
—— 在线 FP8 非 BF16 基线;版本警告不压制;license 地域限制;仓库不含权重
诚实声明
- 🔒 · 锁镜像 · digest 级可复现
- 🔄 · 改动重验 · 改任何一环都从冷启动重跑
- 🪪 · 守 license · 社区许可,先授权再跑
💡 本节要点:可复现性:固定 digest 锁镜像;make 链 6 命令(clone → preflight → build → up → status → smoke+verify);诚实声明:在线 FP8 非 BF16 基线、版本警告不压制、license 地域限制、仓库无权重分发
系列回顾
六期一条线:从架构到方法论
| EP | 主题 | 一句话 | 关键交付 |
|---|---|---|---|
| 30 | 模型原理 | FL2VA:63GiB 文本编码器 + 33.1B DiT + 双 VAE | 134GB 权重画像 |
| 31 | 量化原理 | 在线动态 FP8:免校准、加载时现转 | 内存减半 |
| 32 | 硬件适配 | GB10 SM121:统一内存 + 四个不支持 | N/A 与 nvidia-smi |
| 33 | 失败链与补丁 | 六连坑 → 窄补丁、守契约、重验证 | 5 patch tests |
| 34 | 部署实战 | 固定 digest + 文件级补丁 + fail-closed 链 | make 6 命令 |
| 35 | 性能与方法论 | 超线性缩放 + 组合拳 + 协作模式 | 本期收尾 |
| > 主线只有一条: 硬件划边界,失败链探路,组合拳兜底,验证链守门 | |||
| > 💡 本节要点:六期系列总结:EP30 模型原理(FL2VA 134GB)→ EP31 量化原理(在线动态 FP8)→ EP32 硬件适配(GB10 统一内存 + 四不支持)→ EP33 失败链与补丁(六连坑)→ EP34 部署实战(固定 digest + fail-closed)→ EP35 性能与方法论(本期) |
收尾
六期讲完,接下来轮到你
- 🚀 · 想复现 · git clone MiniMax-H3-DGX-Spark → 读 README → make preflight → 一步步到出片
- 📖 · 想深入 · 读 PATCH.md(六连坑拆解)+ RESULTS.md(实测账本),改补丁必须全链路重验
- 🧠 · 对硬件好奇 · GB10 统一内存的边界在哪、还能塞多大模型——是下一轮折腾的起点
134GB 跑在 128GB 上,不是魔术—— 是失败链、组合拳和验证链,把不可能变成了可复现
六期证据来源:README · Dockerfile · compose.yaml · start-fp8.sh · docs/PATCH.md · docs/RESULTS.md · output/generation-benchmark.md · 实测 nvidia-smi / /proc/meminfo
TomABC · MiniMax-H3 六期原理课 · 完结 🎉
💡 本节要点:结尾与行动号召:想复现 → git clone MiniMax-H3-DGX-Spark 读 README 跑 make 链;想深入 → 读 PATCH.md(六连坑)+ RESULTS.md(账本);对硬件好奇 → GB10 统一内存边界是下一轮折腾的起点;谢谢观看,六期系列完结