在 AWS g6e 上自建 MiniMax H3:部署实录、十个坑,以及自建 vs 官方 API 的账
• 日期:2026-09-07
• 机型:EC2 g6e.4xlarge(16 vCPU / 128GB RAM / 1× NVIDIA L40S 48GB / 940GB 本地 NVMe)
• 系统:Deep Learning OSS Nvidia Driver AMI GPU PyTorch 2.13 (Amazon Linux 2023) 20260905
• 模型:MiniMax H3(H3-Base 开源权重,ComfyUI 重打包 INT8 版)+ H3 Fun ControlNet
• 结论预告:GPU 利用率超过约 1/3,自建就比官方 API 便宜;但你会失掉 2K、Context-IR 和 BF16 精度
1. 一句话总结
| 自建 g6e | 官方 API | |
|---|---|---|
| 5.17s 768p 片段成本 | $0.13 | $0.41 |
| 需要原片作控制输入的重绘任务(83s) | $4.00 | $13.31 |
| 2K 输出 | 做不到 | $0.13/秒 |
| 提示词优化(Context-IR) | 自己写 | 托管 |
| 权重精度 | INT8 剪枝 | BF16 |
| 冷启动 | 13 分钟下 90GB | 无 |
2. 选机型:先被容量教育一顿
原计划是 g7e.4xlarge(1× RTX PRO 6000 Blackwell 96GB),因为 H3 的 BF16 主干是 66GB,96GB 能原生装下。结果 9 个 region 的所有 AZ 全部 InsufficientInstanceCapacity。这个报错既可能是配额也可能是真没货,两步就能定性:查配额(L-DB2E81BA 充足),再在同一 AZ 起一台 t3.micro 对照成功——账号/子网/权限都没问题,剩下就是 AWS 侧真实容量短缺。
降级到 g6e.4xlarge(L40S 48GB)。用 describe-instance-type-offerings 一查,东京只有 1a/1c 有供应、1d 没有。别假设 GPU 机型在 region 内所有 AZ 都能开,启动脚本要按 AZ 顺序重试,一个没货就换下一个。
3. 坑 1:权重有两套,选错白下 400GB
H3 在 HuggingFace 上有两个来源,选错就白下几百 GB:
| 仓库 | 大小 | 格式 | 给谁用 |
|---|---|---|---|
| MiniMaxAI/MiniMax-H3 | 498GB | diffusers 目录结构 | diffusers / SGLang / vLLM |
| Comfy-Org/MiniMax-H3 | ~90GB | 单文件 safetensors | ComfyUI |
我们前一台机器就是照着官方仓库下了 255GB 才发现 ComfyUI 加载不了——ComfyUI 的 UNETLoader / CLIPLoader 要的是重打包的单文件格式。
用 ComfyUI 的话,只需要下这些(约 90GB):
diffusion_models/minimax_h3_ref2va_pruned_int8_convrot.safetensors 19.5GB
text_encoders/qwen3vl_32b_minimax_h3_int8_convrot.safetensors 25.3GB
text_encoders/qwen3vl_32b_minimax_h3_nvfp4_awq.safetensors 14.6GB
vae/minimax_h3_video_vae_fp16.safetensors
vae/minimax_h3_audio_vae_fp32.safetensors ← H3 音视频联合生成,音频有独立 VAE
loras/minimax_h3_fl2v_turbo_{4,8}step_*.safetensors
embeddings/minimaxh3_*.safetensors ← 10 个风格 embedding
model_patches/minimax_h3_fun_controlnet_union_pruned_int8_convrot.safetensors 2.2GB
用 hf_transfer(HF_HUB_ENABLE_HF_TRANSFER=1)下载,90GB 实测 13 分钟(19/19 文件)。
最后那个 model_patches/ 很多教程里说"没有公开权重",实际是有的——查 Comfy-Org/MiniMax-H3 的文件列表就能看到。
4. 坑 2:48GB 装不下 BF16,必须走 INT8 剪枝版
显存账本(L40S 实际可用 46068 MiB):
| 组件 | BF16 | INT8 剪枝 |
|---|---|---|
| 主干 transformer | 66GB ✗ | 19.5GB ✓ |
| Qwen3-VL-32B 文本编码器 | ~64GB ✗ | 25.3GB(或 NVFP4 14.6GB) |
| Video VAE | ~5GB | 5GB |
| ControlNet patch | — | 2.2GB |
所以 48GB 卡上只能跑 *_pruned_int8_convrot 版本。这是自建和官方 API 的第一个实质差异:官方跑 BF16 全量,你跑的是剪枝量化版。
图 1:H3-Base 用同一个 33B Omni Transformer 联合去噪视频与音频,再分别解码为同步画面和立体声。
Ada 架构要选 INT8,不要 NVFP4
ComfyUI 官方模板默认用 NVFP4 文本编码器(14.6GB,更省显存)。但 ComfyUI 启动日志里 nvfp4 落在 Emulated ops,而 int8_tensorwise、convrot_w4a4 等在 Native ops。
NVFP4 在 Ada(L40S / L4 / RTX 4090)上是软件模拟的,更慢。 NVFP4 是 Blackwell 的原生格式。在 L40S 上要选 int8_convrot(25.3GB),虽然多占 11GB 显存,但走原生算子。
5. 坑 3:aimdo memory compile error
加上 ControlNet 后直接崩:
File ".../comfy_aimdo/malloc_graph.py", line 16, in _call
raise RuntimeError("aimdo memory compile error")
现场:生成前 GPU 已占 41.7GB(文本编码器 25.9 + 主干 20),再加 2.2GB 的 controlnet patch 就爆了——新的 comfy_aimdo 显存规划器在编译内存图时失败。
排查发现,--disable-smart-memory --reserve-vram 1.0 能把生成后显存压到 645MB,但 aimdo 照样报错(只是失败得更快,40s vs 270s)——它不是纯 OOM。真正的开关在 comfy/cli_args.py 里:加上 --disable-comfy-compiler 就成功了,峰值显存 28GB。
经验:aimdo memory compile error 是新显存编译器不支持某些算子组合,不是显存不够。遇到先关掉编译器,别一头钻进"怎么省显存"。
6. 坑 4:ModelPatchLoader 下拉列表是空的
extra_model_paths.yaml 默认不声明 model_patches,于是 ControlNet 权重下载好了也看不见:
base_path: /mnt/models/comfyui
diffusion_models: diffusion_models
text_encoders: text_encoders
vae: vae
loras: loras
embeddings: embeddings
model_patches: model_patches # ← 这行要自己加
改完要重启 ComfyUI,ModelPatchLoader 的下拉列表才会出现权重。
7. 坑 5:存储放哪——NVMe 快但停机清空
g6e.4xlarge 自带 940GB 本地 NVMe,读写极快,但停机即清空。前一台机器就是这个配置,每次开机重下 90GB。
这次把 /mnt/models 放在 1000GB gp3 根盘上,NVMe 只当临时盘。但必须把 EBS 提到 16000 IOPS / 1000 MB/s(配置见部署清单),因为 gp3 默认只有 125 MB/s,而 H3 每次生成要从盘上读 20GB 主干 + 25GB 文本编码器:
| 吞吐 | 45GB 加载耗时 |
|---|---|
| gp3 默认 125 MB/s | ~6 分钟 |
| 提到 1000 MB/s | ~45 秒 |
代价(东京 gp3 实价):
| 项 | 单价 | 1TB / 16000 IOPS / 1000 MB/s |
|---|---|---|
| 容量 | $0.096 / GB-月 | $96 / 月 |
| 预置 IOPS(3000 以上) | $0.006 / IOPS-月 | $78 / 月 |
| 预置吞吐(125 MB/s 以上) | $49.152 / GiBps-月 | $42 / 月 |
| 合计 | 约 $216 / 月 ≈ $0.30 / 小时 |
这笔钱停机也照收。 所以存储策略是个真实权衡:
• 常跑(每天 >4 小时)→ 用 EBS 持久化,省掉每次 13 分钟的重下
• 偶尔跑 → 用 NVMe,接受冷启动,停机后只留一个小根盘
8. 坑 6:ComfyUI 没有任何认证
ComfyUI 默认无登录、无 token,却能读机器上的文件、跑任意 Python(自定义节点)、用你的 GPU。绝对不要为了方便开公网端口。
我们的做法:
• 安全组 零入站规则(脚本里断言 length(IpPermissions) == 0,不为 0 直接 abort)
• 不配 SSH key
• ComfyUI 只绑 127.0.0.1:8188
• 访问走 SSM 端口转发:
--document-name AWS-StartPortForwardingSession \
--parameters '{"portNumber":["8188"],"localPortNumber":["8188"]}'
批量操作也走 SSM send-command,不开 22 端口。IAM 直接复用现成的 SSM 实例角色。
9. 坑 7:帧数必须落在 17k+5 网格上
H3 的采样是 17 帧一块,合法帧数只能是 17k+5:5, 22, 39, ..., 124, 141, ..., 362。官方标称 4–15 秒,实际训练范围是 124–362 帧(24fps 下 5.17–15.08s)。
这对做短剧翻拍很要命:短剧镜头中位数只有 1.88s,没有一个镜头能单独生成。要么生成 5.17s 再裁(浪费 60%+ 算力),要么把连续镜头凑成一组。代码里必须把目标帧数向上取整到最近的 17k+5(ceil((n-5)/17) 再 ×17+5)。
10. 坑 8:Context-IR 不开源,提示词得自己写
这是自建和 API 最大的功能差异。完整的 H3 系统是三段:
图 2:完整 H3 系统包含三个阶段;开源自建能直接拿到的是中间的 H3-Base,Context-IR 与 2K 重生成仍由官方托管。
官方 README 原话:*"H3-Context-IR is critical to the quality of the final output"*,但它依赖多阶段流水线和多个托管模型,不在开源范围内。
所以自建的时候,你拿到的是一个"只吃结构化输入"的裸模型。得照 docs/VIDEO_PROMPT_WRITING_GUIDE_base_en.md 自己写 IR:
The young woman with a bright voice (S1) says: <d>[Chinese] 台词原文</d>
[Shot 2] At 00:04.042, the camera cuts to ...
overall_soundscape: ...
non_diegetic_music: ...
几个语法要点:
• [Shot N] At 00:SS.mmm, the camera cuts to ... —— 显式剪辑点,第一个镜头不写时间戳
• <d>[Chinese] ...</d> —— 台词。说话人身份和语气写在标签外面,标签内只放语言标记 + 原文,一字不改
• (S1)–(S5) —— 说话人 ID,跨镜头保持一致,声音才不会串
• 画外音写 says in an off-screen voiceover,后面补一句嘴唇保持闭合
• 画面上真实可见的文字用英文双引号包起来
写对了模型会真的把台词念出来(32kHz 立体声,音视频联合生成,不是后期配的)。验证别靠听感,用 ASR 转写回来对——转写里的同音错字是 whisper 自己的问题,正说明台词确实发声了。
一句话:省下的 API 费,一部分要用写提示词工程的人力补回来。
11. 坑 9:DLAMI 里没有 ffprobe
DLAMI 自带的 ffmpeg 来自 imageio_ffmpeg,只有 ffmpeg 二进制、没有 ffprobe。要读时长/流信息,就用 imageio_ffmpeg.get_ffmpeg_exe() 拿到 ffmpeg 路径、以 ffmpeg -i 代替。要烧中文字幕还得自己装字体:dnf install -y google-noto-sans-cjk-sc-fonts。
12. 坑 10:脚本层面的低级坑(但最耗时间)
按浪费时间排序:
1. ffmpeg 吃 stdin。while read ... done < list.tsv 循环里调 ffmpeg 会吃掉剩余行,循环只跑一次半——加 -nostdin。
2. 嵌套 heredoc 引号地狱。SSM 下发脚本时 <<EOF 里套 <<'RUN' 会被展开得面目全非;正确做法是本地写文件 → base64 -w0 → 远端 base64 -d。
3. 多行提示词塞 TSV。IR 三段用空行分隔,塞进 TSV 后 awk 只取到第一行——改成一个任务一个 .txt。
4. 实例时钟差。实例和跳板机差 8 分钟,一度以为卡死;判断进度用实例自己的 date -Is。
5. ffmpeg glob 自我污染。-pattern_type glob -i "dir/*.jpg" 输出写进同一目录时,下次会把上次输出当输入。
13. 实测性能数据
g6e.4xlarge / L40S 48GB / 768×1344 / 8 步 / INT8 权重:
| 任务 | 帧数(输出时长) | 耗时 | 单帧 |
|---|---|---|---|
| T2V(无 ControlNet) | 124f (5.17s) | 160s | 1.29 s/帧 |
| T2V + ControlNet | 124f (5.17s) | 200s | 1.61 s/帧 |
| T2V + ControlNet | 243f (10.12s) | 496–522s | 2.09 s/帧 |
| T2V + ControlNet | 277f (11.54s) | 626s | 2.26 s/帧 |
| T2V + ControlNet | 328f (13.67s) | 832s | 2.54 s/帧 |
| T2V + ControlNet | 345f (14.38s) | 931s | 2.70 s/帧 |
| 同上 + CFG 2.5 | 243f | 924s | 1.8 倍 |
两个观察:
• 单帧成本随序列变长而上升(1.6 → 2.7 s/帧,注意力超线性):要吞吐用短片段,要连贯性用长片段。
• 峰值显存 28–34GB / 46GB 仍有余量,但再长的序列会先撞显存墙。
14. 价格对比:自建 vs 官方 API
官方 API 价目(platform.minimax.io,2026-09-07 查)
| 项目 | 价格 |
|---|---|
| MiniMax-H3 768P 输出 | $0.08 / 秒 |
| MiniMax-H3 2K 输出 | $0.13 / 秒 |
| MiniMax-H3-Max 480P / 768P | $0.05 / $0.08 每秒 |
| 768P → 2K 重生成 | $0.05 / 秒 |
| 输入图片 | 前 5 张免费,之后 $0.04 / 张 |
| 输入音频 | 免费 |
| 输入视频 | 按输入时长 × 输出分辨率单价计费(768P $0.08/秒) |
| H3-Context-IR | $0.90 / M 输入 token,$3.60 / M 输出 token |
自建成本(按 g6e.4xlarge = $3.0042/小时 计算)
$3.0042/h = $0.000834 / 秒机时。
| 场景 | 自建耗时 | 自建成本 | API 成本 | 倍数 |
|---|---|---|---|---|
| 5.17s 纯文生视频 | 160s | $0.133 | $0.414 | 省 3.1× |
| 10.12s + ControlNet | 500s | $0.417 | $0.810 | 省 1.9× |
| 14.38s + ControlNet | 931s | $0.777 | $1.150 | 省 1.5× |
关键:带视频输入的任务差距被拉大
API 按输入视频时长也收一次钱。我们那个"现代剧改宋朝古装"的任务要拿原片当控制视频:
| 自建 | API(v2v,输入+输出都按 768P 计) | |
|---|---|---|
| 83.17s 成片(实际完成部分) | 1.33h GPU = $4.00 | 83.17×$0.08×2 = $13.31 |
| 154.71s 全片(估算) | 2.2h GPU = $6.61 | 154.71×$0.08×2 = $24.75 |
省 3.3–3.7 倍。 视频到视频的重绘/换风格类任务,自建的经济优势最明显。
盈亏平衡点:GPU 要多忙才划算
自建按小时烧钱、闲着也烧,单纯比单价没意义。
$3.0042/h ÷ $0.08/秒 = 每小时要产出 37.6 秒成片才追平 API。
| 模式 | 满负荷产出 | 盈亏平衡利用率 |
|---|---|---|
| T2V(5.17s / 160s) | 116 秒/小时 | 32% |
| ControlNet(10.12s / 500s) | 73 秒/小时 | 52% |
把 EBS 那 $0.30/h 算进去($3.30/h ÷ $0.08 = 41.3 秒/小时):T2V 要 36%,ControlNet 要 57%。
结论:GPU 利用率能稳定超过 1/3 到 1/2,自建划算;低于这个数,直接调 API。
Spot 可以把这条线压得很低
g6e.4xlarge 当前实价:
| region | 按需 | Spot |
|---|---|---|
| ap-northeast-1 | $4.357 | ~$2.11 |
| us-west-2 | $3.004 | $1.29(2d)~$3.00(2a/2b,按 AZ 差异大) |
Spot 打对折的话平衡点降到 15–25%。批量离线出片(可中断、可重试)非常适合 Spot;交互式调参不适合。
还有个易忽略的点:同一机型跨 region 差 45%(东京 $4.357 vs 俄勒冈 $3.004)——没有数据驻留要求就跑 us-west-2。
15. 功能差异:自建能做什么,不能做什么
| 能力 | 自建(H3-Base 开源权重) | 官方 API |
|---|---|---|
| 分辨率 | 短边 768(我们跑 768×1344) | 768P + 2K |
| 2K | ✗ H3-Regenerate-2K 权重不开源 | ✓ $0.13/秒 或 $0.05/秒重生成 |
| 时长 | 17k+5 网格,训练范围 124–362 帧 | 4–15 秒 |
| 音频 | ✓ 32kHz 立体声,联合生成 | ✓ 同 |
| 台词发声 | ✓ 但要自己写 <d> 标签和说话人 ID | ✓ Context-IR 自动处理 |
| 提示词理解 | ✗ Context-IR 不开源,要自己实现等价物 | ✓ 托管(按 token 计费) |
| T2V / 首尾帧 FL2VA | ✓ | ✓ |
| Ref2VA(≤9 图 / ≤3 视频 / ≤3 音频) | ✓ 权重开放 | ✓ |
| Fun ControlNet(结构控制 / 局部重绘) | ✓ ComfyUI 重打包提供 model_patch | API 侧以 v2v 形式暴露,不给你 strength/end_percent 旋钮 |
| 采样参数微调 | ✓ strength、end_percent、CFG、sigma shift、step 数 | ✗ |
| 权重精度 | INT8 剪枝(48GB 卡的硬约束) | BF16 全量 |
| 内容审核 | 无 | 有自动审核,可能误杀 |
| 数据不出域 | ✓ | ✗ |
| 冷启动 | 13 分钟下 90GB + 每次生成加载 ~45s | 无 |
| 许可 | MiniMax H3 Community License | 商业 API 条款 |
自建独有的价值:旋钮
这次任务里,"把现代西装换成宋制圆领袍"靠提示词怎么写都解决不了,真正起作用的是只有自建才能碰的参数。机制是:turbo LoRA 按 CFG=1 蒸馏,文本条件推力弱;而 ControlNet 的结构 hint 每一步都注入,深色西装+领带是极强的结构信号。扩散前 20–35% 步骤决定构图,把 end_percent 降到 0.35 = 构图定下就撒手,后 65% 步骤按提示词渲染布料。
调 API 摸不到这个旋钮。这是自建除省钱之外最实在的理由。
许可证:一个容易漏掉的硬约束
• 许可是 MiniMax H3 Community License,不是 Apache/MIT
• HF README 里给了一个申请表链接,标注 "only for USA/EU/UK/South Korea" —— 这几个地区用开源权重需要单独申请
• 仓库里另有 docs/QA-about-License.md
商用前一定要读原文(huggingface.co/MiniMaxAI/MiniMax-H3/blob/main/LICENSE)并按自己的主体和地区确认,别只看"开源"两个字。
16. 部署清单(可直接照做)
INSTANCE_TYPE=g6e.4xlarge
AMI_ID=ami-07ec5aef5cf34abfb # DLAMI PyTorch 2.13 AL2023 20260905
# 只有 1a / 1c 有供应,按顺序重试
# 2. 1TB gp3,务必提 IOPS 和吞吐
--block-device-mappings '[{"DeviceName":"/dev/xvda","Ebs":{
"VolumeSize":1000,"VolumeType":"gp3","Iops":16000,"Throughput":1000,
"DeleteOnTermination":true,"Encrypted":true}}]'
# 3. 零入站安全组 + SSM 实例角色,不配 SSH key
--metadata-options "HttpTokens=required,HttpEndpoint=enabled"
# 4. 权重:Comfy-Org 重打包(不是官方 498GB 仓库)
HF_HUB_ENABLE_HF_TRANSFER=1 # 90GB / 13 分钟
# 5. ComfyUI 启动参数(缺一个就崩)
--listen 127.0.0.1 --port 8188 \
--disable-smart-memory --reserve-vram 1.0 --disable-comfy-compiler
# 6. extra_model_paths.yaml 记得加 model_patches
# 7. 成本兜底:48 小时自动关机
cat > /etc/cron.hourly/h3-uptime-guard <<'EOF'
#!/bin/bash
UP=$(awk '{print int($1)}' /proc/uptime)
[ "$UP" -gt 172800 ] && /sbin/shutdown -h now
EOF
最后一条别省。$3/小时的机器忘关一周就是 $500。
17. 什么时候该自建,什么时候该用 API
用官方 API:
• 需要 2K 输出(自建做不到)
• 提示词是自然语言、想让 Context-IR 帮你优化
• 量小或者波峰波谷明显,GPU 利用率上不去 1/3
• 团队没人愿意维护 ComfyUI + 权重 + 显存调参
• 需要 BF16 的画质上限
自建:
• 量大且稳定(GPU 利用率 >50%)
• 视频到视频的重绘/换风格类任务(API 连输入视频都收费,自建省 3 倍以上)
• 需要动 strength / end_percent / CFG / sigma shift 这些旋钮
• 素材不能出域
• 能接受 768p 和 INT8 精度
• 主体和地区符合 Community License(美/欧/英/韩需申请)
我们的场景"批量短剧翻拍"落在自建这边:量大、要控制旋钮、要拿原片作控制输入。但2K 只能回头找 API——768p 竖屏投放够用,要交付高清就用官方 768P → 2K 重生成($0.05/秒):自建出 768p,挑中的片段送 API 升 2K。
18附:数据来源与实测环境
| 项 | 值 / 来源 |
|---|---|
| g6e.4xlarge 按需价 | $3.00424/h(us-west-2)、$4.35703/h(ap-northeast-1),AWS Pricing API |
| g6e.4xlarge Spot | ~$2.11(东京)、$1.29–3.00(俄勒冈,按 AZ) |
| gp3 单价(东京) | $0.096/GB-月、$0.006/IOPS-月、$49.152/GiBps-月 |
| H3 API 价目 | platform.minimax.io/docs/guides/pricing-paygo(2026-09-07) |
| 模型规格 | HF MiniMaxAI/MiniMax-H3 README |
| 性能数据 | 本次实测,g6e.4xlarge / 768×1344 / 8 步 / INT8 / ComfyUI |
管线脚本(供参考):launch-tokyo.sh(起机)、bootstrap-tokyo.sh(幂等自举,开机自动补齐)、h3_cn.py(ControlNet 生成器)、rexec.sh(SSM 执行,无 SSH)、status.sh(健康报告)。
微信扫码
用微信扫一扫,把文章带到聊天或朋友圈。
讨论
用 GitHub 账号评论 —— 评论存放在本仓库的 Discussions 里。
继续阅读
- AI 与 Agent
我不再蹲模型发布了:换了半年最强模型,我的幻觉一点没少
半年里 Opus 主力型号发了四代、价格没动,我天天拿最新模型干活,热情却没了、幻觉也没少。这篇把六条困惑一条条摊开:榜单、幻觉、真实提效、harness、对 Agent 的过度依赖,以及自己被提速多少的错觉。
- AI 与 Agent
提示缓存(一):到底缓存了什么
prompt caching 省下的不是网络往返,而是 prefill 阶段的算力。本文讲清 KV cache 从哪来、前缀哈希为什么要求逐 token 一致、TTL 为什么必须存在,以及缓存写入为什么会比不缓存更贵。
- AI 与 Agent
提示缓存(二):五家厂商三家云的账单差异
AWS 文档说 Claude Sonnet 4.5 在 Bedrock 上要 4096 token 才能缓存,我实测是 1024——和一方 API 一样。本文对照五家模型厂商与三家云的当期倍率、TTL 档位、跨区域行为,并区分哪些数字是实测的、哪些只是文档值。
- AI 与 Agent
提示缓存(三):开了却没命中,怎么查
提示缓存失效几乎不报错——推理成功、日志干净、只有账单变贵。本文按出现频率拆四类元凶:前缀混进易变内容、序列化顺序抖动、工具顺序不稳、中间层静默吞掉缓存标记,并给出一个跨厂商的命中率自检脚本。