返回文章列表
2026年8月13日 15 分鐘閱讀

MiniMax H3 在 M5 Pro 實測:ComfyUI 安裝、M5 Kernel 與 64GB 記憶體調校

在 M5 Pro 64GB 上用 ComfyUI 跑通 MiniMax H3,整理模型下載、PyTorch nightly、M5 Metal Kernel、啟動參數與記憶體調校實測。

MiniMax H3 的 ComfyUI 節點從多方向匯入 M5 Pro 的極簡俯視實物攝影封面

我在一台 64GB 統一記憶體的 M5 Pro MacBook Pro 上,用 ComfyUI 跑通了 MiniMax H3 的首末幀圖生影片,包含模型原生音軌。

我另外安裝 ComfyUI-AppleSilicon-FP8 自訂節點,目的是讓 int8 線性層走針對 M5 寫的 Metal TensorOps kernel,盡量用到 M5 GPU 每個 shader core 裡的 Neural Accelerator。這是 M5 新增、專門加速矩陣乘法的硬體單元,相關設計可參考 Apple 的 M5 GPU 技術說明

最後的正式測試是 352×608、124 幀、10 步:產生 5.167 秒影片共花 8 分 22 秒。整個跑通過程最折騰的是原生 int8 kernel 建置失敗,以及 40GB 級權重帶來的記憶體壓力。

這篇先給可以直接採用的設定,再保留我一路判斷、測錯與修正的過程。

先看結論

實測時間

測試輸出條件產生時間
正式測試352×608、124 幀、5.167 秒、10 步501.6 秒(8 分 22 秒)
9:16 較高負載測試約 0.4M 解析度、5 秒約 25 分鐘

兩組測試的輸出條件不同,不能直接拿時間推算效能倍率。解析度、幀數與步數都會影響實際耗時。

環境與建議

項目本次結果
硬體MacBook Pro、M5 Pro、64GB 統一記憶體
測試環境macOS 26.5(25F71)、ComfyUI v0.31.0、Python 3.13.13
模型下載量約 40GB
建議啟動參數--disable-smart-memory --cache-none
最重要的檢查不要只看啟動 log,要確認 kernel loader 或比較穩態每步時間
輸入圖限制first_frame 會直接拉伸到畫布,最好先裁成目標長寬比

這些數字只適用於本文列出的硬體、版本、模型與參數,無法代表所有 M5 Pro 的效能。

兩套 ComfyUI 的隔離架構

圖 1 既有 ComfyUI Desktop 與 MiniMax H3 獨立環境。兩邊只透過 extra_model_paths.yaml 唯讀共用模型目錄。

只想照著做,可以先看這裡

1. 另建環境,不動原本的 ComfyUI Desktop

我原本的 ComfyUI Desktop 已經放了 373GB 模型和 11 個 custom node。MiniMax H3 當時需要 PyTorch nightly,直接升級既有環境的風險太高,所以我另外建立一套 ComfyUI,使用 8189 port。

mkdir -p ~/src/minimaxh3
cd ~/src/minimaxh3
git clone --filter=blob:none https://github.com/Comfy-Org/ComfyUI.git
cd ComfyUI
git checkout v0.31.0

uv venv --python 3.13 ../.venv
uv pip install --python ../.venv/bin/python -r requirements.txt

MiniMax H3 的核心支援在 2026 年 8 月 3 日合併,並收進 ComfyUI v0.30.0。我選 v0.31.0,是為了取得後續的 H3 VAE、音訊與取樣修正。

2. 下載需要的 4 個檔案

目錄檔案
models/diffusion_models/minimax_h3_fl2va_pruned_int8_convrot.safetensors
models/text_encoders/qwen3vl_32b_minimax_h3_nvfp4_awq.safetensors
models/vae/minimax_h3_video_vae_fp16.safetensors
models/vae/minimax_h3_audio_vae_fp32.safetensors

合計約 40GB。不要直接下載完整的 Comfy-Org/MiniMax-H3 儲存庫;本文測試時,完整儲存庫約 465GB。

我這次使用 Hugging Face Xet 傳輸時,在下載約 12GB 後停止前進。改走傳統 HTTP CDN 才完成下載:

export HF_HUB_DISABLE_XET=1

這是我在當時環境遇到的故障,不代表所有連線都需要停用 Xet。若曾強制中止下載,而且下一次執行沒有輸出、CPU 使用率接近零,可以再檢查快取中的 .lock 檔。

3. 確認 nightly 套件真的對齊

只下 --upgrade 時,pip 可能保留 stable 版 torchaudio,因為正式版的 PEP 440 排序高於同版號的 .dev 套件。我最後明確指定當天的 nightly:

./.venv/bin/python -m pip install --pre --upgrade --force-reinstall --no-deps \
  torchaudio==2.11.0.dev20260810 \
  --index-url https://download.pytorch.org/whl/nightly/cpu

最後使用的版本是:

torch       2.14.0.dev20260810
torchvision 0.29.0.dev20260810
torchaudio  2.11.0.dev20260810
mps         True

macOS 的 wheel 位於 PyTorch 的 cpu index,但安裝後仍可使用 MPS。

4. 不要把 capability summary 當成 kernel 已啟用

本次環境要讓 ComfyUI-AppleSilicon-FP8 的 M5 int8 kernel 建起來,需要處理兩個相容性問題:

  • custom node 傳入的 -std=c++17 蓋過 PyTorch nightly 要求的 C++20;
  • node 指定 MTLLanguageVersion4_1,但 macOS 26.5 的 SDK 與 runtime 最高接受 Metal 4.0。

我把相關 loader 的 C++ 標準改為 C++20,並讓缺少 MTLLanguageVersion4_1 的環境退回 MTLLanguageVersion4_0

#ifndef MTLLanguageVersion4_1
#define MTLLanguageVersion4_1 MTLLanguageVersion4_0
#endif

這是針對本文版本組合的本機修改,不應直接套用到其他版本。修改後我跑了 custom node 自帶的測試,結果是 50 passed;仍要搭配 loader 的 available() 或實際每步時間確認路徑真的生效。

5. 啟動設定

#!/bin/zsh
export PYTORCH_ENABLE_MPS_FALLBACK=1
exec .venv/bin/python main.py --listen 127.0.0.1 --port 8189 \
  --disable-smart-memory --cache-none

是否使用 --cache-none 要看工作內容。正式跑長片時,它能降低保留快取造成的記憶體壓力;反覆用相同提示詞測短片時,保留 conditioning 快取可能更省時間。

如果只想知道怎麼跑,到這裡已經足夠。下面是這套設定怎麼找出來的。

為什麼我沒有直接升級 ComfyUI Desktop

我原本以為 ~/Documents/ComfyUI 就是整套 ComfyUI,實際上 Desktop 版把程式與使用者資料分開:

項目位置或版本
Desktop app/Applications/Comfy Desktop.app v1.0.28
使用者資料~/Documents/ComfyUI
核心程式碼~/ComfyUI-Installs/ComfyUI/ComfyUI
原有版本v0.27.0-29-g091b70ed
原有 torch2.10.0 stable

原有版本還沒有 H3 支援,而且 Desktop app 會管理自己的核心儲存庫。就地切換版本或安裝 nightly 可能影響現有 custom node,之後也可能被 Desktop 更新覆蓋。

因此我把新環境放在 ~/src/minimaxh3,既有模型則透過 extra_model_paths.yaml 唯讀共用。H3 自己的模型放在新環境,需要時可以整包移除。

第一個誤判:GitHub Release 不等於 git tag

參考資料建議 v0.30.1。我先查 GitHub Releases API,沒有看到它,就判定這個版本不存在。

clone 後執行 git tag -l 才發現:

v0.30.0
v0.30.1
v0.30.2
v0.31.0
v0.31.1

v0.30.1 有 tag,只是沒有獨立 GitHub Release。這次經驗讓我之後查版本時會同時看 release、tag 與實際 commit,不再只依賴其中一種介面。

第二個誤判:log 全通過,不代表 kernel 已經建好

裝好 ComfyUI-AppleSilicon-FP8 後,啟動訊息看起來很完整:

[AppleSilicon-FP8] capabilities: macOS=26.5, torch=2.14.0.dev20260810, mps=yes,
compile_shader=yes, tensor_ops(M5/Metal4)=yes, ninja=yes
[AppleSilicon-FP8/int8_kernel] INT8 convrot Linear routed through bit-exact Metal kernel on MPS

我看到 tensor_ops=yesninja=yes 就以為成功了。第一次跑到 int8 層時,才出現:

[int8_ext] build failed; int8-native disabled
error: C++20 or later compatible compiler is required to use PyTorch.

capability summary 檢查的是硬體與工具是否存在,不會替第一次實際編譯背書。

M5 int8 kernel 的逐層驗證流程

圖 2 M5 int8 kernel 的驗證鏈。啟動檢查只確認必要條件;實際編譯、測試、loader 狀態與穩態每步時間都通過後,才能確認加速路徑生效。

C++17 蓋掉 C++20

編譯指令同時帶了兩個標準:

c++ ... -fPIC -std=c++20 -std=c++17 -ObjC++ -c int8_gemm.mm

後面的 -std=c++17 生效,因此 PyTorch 2.14 header 拒絕編譯。我原本以為是 PyTorch 注入 C++17,後來才從 cpp_extension.py 和 custom node loader 的參數順序確認,C++17 是 node 自己加的。

Metal 4.1 改成 4.0 後才編譯過

C++20 修好後,主機端又卡在:

error: use of undeclared identifier 'MTLLanguageVersion4_1'

我一度認為只能等 macOS 27 或 Xcode beta。接著我試過自行補出 4.1 enum;ObjC++ 雖然能編譯,runtime 仍拒絕 metal4.1。最後直接退回 Metal 4.0,runtime shader 才順利編譯完成。

能編譯過的關鍵在於,這版 kernel 使用的 matmul2dcooperative_tensor 在我的 macOS 26.5 runtime 上以 Metal 4.0 就已經可用。這是特定版本的實測結果,不宜外推到所有 node 或系統版本。

用每步時間確認 kernel 是否生效

同一組 608×352、5 幀、4 步測試:

狀態穩態每步sampling總時間
修改前11.02 s/it55 秒212.5 秒
只修 C++2011.08 s/it55 秒192.1 秒
再修 Metal 4.06.29 s/it35 秒169.0 秒

只修 C++20 時,總時間少了約 20 秒,但每步時間完全沒改善。可能是檔案快取造成了這段差異,loader 仍顯示 kernel 未啟用。

Metal 4.0 路徑生效後,穩態每步快 1.75 倍;整段 sampling 從 55 秒降到 35 秒,約快 1.57 倍。

跑通之後,下一個瓶頸是記憶體周轉

kernel 生效後,速度仍不穩定。我先看程序 RSS,峰值只有 13.4GB,和實際壓力明顯對不上;MPS 與檔案映射的記憶體不能只靠 RSS 理解。

接著我改為逐秒記錄 vm_stat,並用 ComfyUI log 對齊 text encoder、DiT、sampling 與 VAE 階段。這些是全系統計數器,因此以下歸因成立的前提是測試期間沒有其他明顯的記憶體重負載。

一次約 3.5 分鐘的測試期間,我觀察到:

指標變化量
壓縮119.6GB
解壓縮82.5GB
swap 寫出46.9GB
swap 讀回29.6GB
pagein40.8GB
可用記憶體谷底0.0GB
壓縮記憶體峰值34.0GB

這些數字顯示系統在測試期間大量搬移記憶體,但不能單靠 vm_stat 證明所有 pagein 都是 H3 權重。

--disable-smart-memory 把壓力移出 sampling

text encoder 約 14.6GiB,只在開頭編碼提示詞時使用。--disable-smart-memory 讓 ComfyUI 更積極卸載不用的模型後,sampling 階段的可用記憶體明顯回升。

設定總時間穩態每步解壓縮swap 讀回
預設149.6 秒5.51 s/it82.5GB29.6GB
--disable-smart-memory104.4 秒3.36 s/it55.7GB12.9GB
再加 --cache-none72.2 秒3.38 s/it48.4GB3.3GB

這組對照是在 kernel 修復後進行。不同批次的總時間仍會受 seed、檔案快取與模型載入狀態影響,所以我把穩態每步和總時間分開看。

分階段量測顯示,記憶體壓力集中在模型載入階段;sampling 階段相對寬鬆:

階段可用記憶體谷底壓縮記憶體峰值
text encoder 載入0.1GB21.2GB
DiT 載入0.0GB32.5GB
sampling16.8GB12.2GB
VAE 解碼16.9GB6.9GB

這不表示解析度與片長可以無限制提高;activation、attention 與 VAE 成本仍會隨畫面和幀數增加。它只說明在這組短片測試裡,最明顯的記憶體爭用發生在模型切換階段。

--cache-none 要看用途

短片連續跑第 2 次時,保留 conditioning 快取可以省掉 text encoder 載入:

設定第 1 次第 2 次
--cache-none66.8 秒66.8 秒
--cache-none97.7 秒33.5 秒

因此我的使用方式是:

  • 正式跑長片:保留 --cache-none,降低記憶體壓力。
  • 相同提示詞反覆測短片:可拿掉 --cache-none,利用 conditioning 快取。

若把省下的 64 秒直接套到 501.6 秒正式測試,總時間約縮短 13%;實際收益還要扣除保留快取可能造成的額外記憶體壓力。

最後跑出的結果

最終配置:

元件版本或模型
ComfyUIv0.31.0(43cb4ff
Python3.13.13
torch2.14.0.dev20260810
ComfyUI-AppleSilicon-FP8v1.3.0(3cc65dd),含本機相容性修改
DiTminimax_h3_fl2va_pruned_int8_convrot,約 19.5GiB
Text encoderqwen3vl_32b_minimax_h3_nvfp4_awq,約 14.6GiB

正式參數為 352×608、124 幀、24fps、10 步、res_multistep

項目結果
總時間501.6 秒
sampling416 秒,約 42.3 s/it
其他載入與解碼約 86 秒
輸出H.264 + AAC 32kHz 立體聲

我當時參考的測試紀錄寫 M4 Pro 64GB 約需 18 分鐘;若只用這個數字粗略換算,本次測試約快 2.15 倍。這項跨機器、跨環境比較僅供參考,沒有控制完整的 benchmark 條件。

音訊量測先排除近乎靜音

在沒有直接試聽的自動化檢查中,我先用以下方式排除近乎靜音:

正式影片量到 RMS −14.1dBFS、peak −4.2dBFS,至少可排除近乎無聲。zero-crossing rate 為 0.103,但 RMS 和 ZCR 都不足以單獨證明沒有噪音或內容失真;判斷音質仍需要實際試聽或頻譜分析。

0.2 秒煙霧測試的 RMS 只有 −72dBFS,幾乎無聲,因此太短的片段不適合拿來判斷 H3 音訊是否正常。

首幀會被直接拉伸

ComfyUI v0.31.0 的 nodes_minimax_h3.py 對首末幀採用不同策略:

if first_frame is not None:
    img = _resize(first_frame[:1], width, height, "disabled")
if last_frame is not None:
    img = _resize(last_frame[:1], width, height, "center")

first_frame 直接拉到目標畫布,last_frame 則保留比例後置中裁切。首幀又是整段影片的幾何基準,因此輸入圖最好先裁成和輸出相同的長寬比。

這次留下的檢查順序

回頭看,最浪費時間的是太早把「看起來成功」當成「真的成功」。下次我會照這個順序檢查:

  1. 先隔離環境,再安裝 nightly 與 custom node。
  2. 同時查 release、tag 和 commit,避免只依賴 GitHub Releases API。
  3. 檢查第一次實際 kernel 編譯;啟動 capability summary 只能當成初步資訊。
  4. 用 loader 狀態和穩態每步時間確認加速是否生效。
  5. 記憶體問題分階段量測,並把全系統計數器當成線索,不當成單一程序的直接證明。
  6. 比較效能時記錄 seed、冷/熱快取、模型載入狀態與是否重啟伺服器。

如果你更在意可預測的記憶體占用,也願意下載約 134 GiB 權重,可以接著看 h3.c 在同一台 M5 Pro 上的實測

常見問題

M5 Pro 64GB 能在本機跑 MiniMax H3 嗎?

可以。本文在 M5 Pro 64GB 上透過 ComfyUI 產生 352×608、124 幀、24fps 的 5.167 秒影片,10 步總時間為 501.6 秒。這是特定版本與設定下的單機實測,不代表所有 M5 Pro 都會得到相同結果。

用 ComfyUI 跑 MiniMax H3 要下載多少模型?

本文使用的 DiT、文字編碼器、video VAE 與 audio VAE 合計約 40GB;不必下載當時約 465GB 的完整模型儲存庫。

啟動訊息顯示 M5 TensorOps 可用,是否代表 Kernel 已啟用?

不代表。啟動訊息只能確認硬體與工具等必要條件;仍要檢查第一次實際編譯、loader 的可用狀態,並比較穩態每步時間,才能判斷 int8 Kernel 是否真的生效。

參考來源

相關文章