Mac Studio M5 Ultra에서 MiniMax H3, 768p 5초 영상 97초까지

M5 Ultra 256GB에서 MiniMax H3를 Mac용 엔진 VPIPE와 h3.c로 돌렸습니다. 1344×768·124프레임 텍스트→영상이 Turbo 4스텝과 int8 token 단계로 97초였고, 이미지·첫끝 프레임·참조 입력도 재 봤습니다.

MiniMax H3는 지금까지 Ryzen AI Max+ 395와 RTX Pro 6000 Blackwell에서 재 왔습니다. 이번에는 Mac Studio M5 Ultra(GPU 80코어, 통합 메모리 256GB, macOS 27.0.1)입니다. Mac에서 H3를 돌리는 엔진을 먼저 조사해 두 개를 골랐고, 두 엔진을 같은 작업으로 비교한 뒤 빠른 쪽의 가속 옵션을 하나씩 켜 가며 이 기계에서 가장 빠른 구성을 찾았습니다.

97.0초1344×768·124프레임 T2V (4회 평균)
32.8GB그때 최대 메모리
약 41초그중 고정 비용 (인코더·VAE·저장)
102초이미지 1장 참조 Ref2V (1회)

엔진 고르기

10월 26일에 Mac에서 H3를 돌릴 수 있는 엔진을 조사했습니다. 아래 수치는 모두 각 작성자가 보고한 값이고 우리가 잰 것이 아닙니다.

엔진 형태 판단
h3.c C + Metal CLI, MIT. 공식 bf16 가중치를 그대로 읽음 실측
VPIPE C++ 파이프라인 엔진 + 웹 UI·앱, Apache-2.0. int8 행렬곱, Sol-Attn, Sage, Turbo LoRA 런타임 적용 실측
mlx-serve Zig 서버 + Swift 앱, 자체 MLX 변환본 제외. 자체 문서에 1344×768·124프레임이 M4 Max에서 약 50분
FastVideo FastH3 MLX INT6 MLX 제외. M4 Max 36GB에서 832×480·5초·8스텝 925초
Python MLX 포트 여럿 MLX 제외. 8월 초 이후 정체, M5 Max에서 짧은 클립 약 45분이라는 보고
ComfyUI (MPS) Python 제외. M5 Pro에서 480×864·약 9초·20스텝이 1시간 넘게 걸렸다는 보고

VPIPE 문서에는 두 엔진을 직접 비교한 값도 있습니다. 960×544·124프레임·6스텝, LoRA 없이 M5 Pro 24GB에서 VPIPE 5분 29초, h3.c 7분 11초였고, M4 Pro 64GB에서는 17분 43초와 23분 9초였습니다. M5 Pro의 h3.c는 메모리가 부족해 SSD 스트리밍과 bf16으로 돈 값입니다.

시험 환경과 작업

  • 엔진: VPIPE main 11b8e4d, h3.c main 8974cc0. VPIPE 웹 UI는 OpenSSL 4 환경에서 빌드되지 않아 CLI로만 썼습니다.
  • 가중치: Hugging Face 공식 MiniMaxAI/MiniMax-H3(rev 42ed227ee) bf16과 LightX2V Turbo LoRA(rev 30f485ed8). 파일마다 SHA256을 대조했습니다. 비교용으로 ComfyUI INT8 ConvRot DiT(Ryzen AI Max+ 395가 쓴 것과 같은 종류)도 받았습니다.
  • 재는 법: 실행부터 MP4 기록까지를 E2E로 쟀고, 최대 메모리는 프로세스의 peak footprint입니다. 모든 측정에서 swap 증가는 없었습니다.
  • 같은 기계에서 상시 돌리는 LLM 서버가 GPU 메모리를 약 249GB 잡고 있어 H3와 동시에 돌릴 수 없습니다. 측정 동안 내렸다가 다시 올렸습니다.
작업 해상도 · 길이 스텝 · LoRA 프롬프트 · 시드
W1 960×544 · 124프레임 6스텝, LoRA 없음 피아노 치는 연주자 · 6
W2 864×480 · 56프레임 8스텝 회전하는 종이 조형 · 17
W3a 1344×768 · 124프레임(5.17초) · 24fps Turbo 4스텝, shift 영상 6 / 오디오 3 실험실을 걷는 작은 빨간 로봇(발소리 포함) · 20260831
W3b W3a와 같음 8스텝, LoRA 없음 W3a와 같음

W3a의 프롬프트와 시드는 Ryzen AI Max+ 395 측정과 같습니다.

1차: 두 엔진 비교

먼저 같은 작업으로 두 엔진을 비교했습니다. 워밍업 1회 뒤 매번 새 프로세스로 3회 쟀고, 평균 ± 표본 표준편차입니다.

작업 엔진 E2E (초) denoise (초) 영상 VAE (초)
W3b 8스텝 h3.c 350.3 ± 6.1 269.2 (스텝당 33.6) 70.2
W3b 8스텝 VPIPE bf16 362.3 ± 3.5 324.3 (스텝당 40.5) 27.0
W1 6스텝 h3.c 102.7 ± 1.2 58.8 33.2
W1 6스텝 VPIPE bf16 107.0 ± 1.0 81.7 14.3
W2 8스텝 h3.c 38.0 ± 0.0 16.9 11.1

LoRA 없이 8스텝을 돌리면 두 엔진의 전체 시간은 비슷했습니다. h3.c는 denoise가 17% 빠르고 영상 VAE가 2.6배 느려서 서로 상쇄됩니다.

W1은 위 VPIPE 문서의 비교와 같은 작업입니다. 다만 VPIPE는 int8 행렬곱(i8_gemm)을 켠 상태로 쟀습니다.

W1 (초) M5 Pro 24GB (작성자 보고) M4 Pro 64GB (작성자 보고) M5 Ultra
VPIPE 329 1063 107
h3.c 431 1389 103

h3.c의 int8 행 단위 FC2 옵션(--use-int8-row-fc2)은 347초로 기본(350초)과 표준편차 안에서 같았고 출력만 바뀌었습니다. W2에 대해서는 h3.c PR #75 작성자가 M5 Ultra에서 49~57초를 보고했지만, 측정 하네스가 달라 직접 비교하지 않습니다.

h3.c는 LoRA를 읽지 못합니다. 그래서 4스텝 Turbo를 쓰는 W3a는 VPIPE로만 쟀습니다.

VPIPE 구성 (W3a, Turbo v1.2) E2E (초) denoise (초) 최대 메모리
공식 bf16, int8 행렬곱 끔 214.7 ± 4.0 174.0 49.7GB
공식 bf16, int8 행렬곱(i8_gemm) 199.3 ± 6.5 160.7 50.4GB
공식 bf16, i8_gemm + Sol + Sage + PV8 110.3 ± 0.6 72.0 51.0GB
ComfyUI INT8 DiT, 기본 199.3 ± 1.5 160.7 30.9GB
ComfyUI INT8 DiT, Sol + Sage + PV8 * 112.3 ± 0.6 73.7 31.4GB

* 다른 파일 다운로드(약 13MB/s)와 시간이 겹친 측정입니다. 겹친 셀이 느려지지는 않았고, 같은 INT8 기본 구성을 다운로드와 겹쳐 쟀을 때가 187.3초로 오히려 빨랐습니다. VPIPE가 실행 중에 행렬곱 경로를 자동으로 고르면서 생기는 회차 간 변동으로 봅니다.

i8_gemm만으로는 7% 빨라졌고, Sol-Attn과 SageAttention, PV 8bit를 함께 켜자 199.3초가 110.3초가 됐습니다. Turbo LoRA v1.1과 v1.2는 속도가 같았습니다(197.0초와 199.3초, INT8 기본).

2차: 가속 옵션을 하나씩

1차에서 가장 빨랐던 bf16 + i8_gemm + Sol + Sage + PV8을 기준으로 옵션을 더 켜 봤습니다. W3a, 로봇 프롬프트이고, 따로 적지 않은 값은 워밍업 1회 뒤 1회만 잰 것이라 몇 초 차이는 의미를 두기 어렵습니다.

구성 E2E (초) denoise (초) 메모
기준 (i8_gemm_tier 기본 accurate) 109 67
i8_gemm_tier: fast 107 66 메모리 51→33GB
i8_gemm_tier: token 93 52 4회 평균 97.0 ± 1.0
Sol τ 1.5 104 63 정확히 계산하는 키 블록 21.9%→13.2%
token + τ 1.5 89.7 ± 0.6 (4회) 48.7 구도는 기준과 같음
token + τ 2.0 85 45 로봇이 둘로 늘어나 쓰지 않음
VAE를 ANE로 117 72 느려짐
DiT 일부를 ANE로 117 75 느려짐. M5에서는 쓰지 말라는 문서와 같음
VDN 선형 어텐션 (Sol 대신) 163 121 5초 클립에서는 느림
TaoMate-H3 3스텝 스트리밍 176 129 느리고 프롬프트에 없는 사람이 나옴
Turbo FL2V v1.3 (v1.2 대신) 116 74 구도가 다르고 속도 이득 없음

가장 큰 이득은 int8 행렬곱 단계를 token으로 올린 것이었습니다. 1회 측정끼리 109초에서 93초로 15% 줄었고, 가중치를 int8로 들고 있어 메모리도 51GB에서 33GB로 줄었습니다. VAE에 i8_gemm을 켜는 옵션은 H3의 VAE가 무시해서 출력이 그대로였습니다.

ComfyUI INT8 DiT를 쓰는 것은 이득이 없었습니다. int8 행렬곱 단계가 이미 INT8인 가중치에는 적용되지 않아서, 공식 bf16에 token 단계를 켠 쪽이 더 빨랐습니다.

Sol τ를 1.5로 올리면 T2V가 97초에서 89.7초로 더 빨라지지만 기본값으로 쓰지 않습니다. 이미지 참조 Ref2V에서 마지막 1초에 고양이가 둘로 늘었고, 정확 경로에서도 τ1.5면 같은 현상이 났습니다. τ1.0에서는 한 마리였습니다. τ2.0은 T2V에서도 로봇이 둘이 됐습니다.

입력 종류별 결과

같은 공통 설정(공식 bf16, i8_gemm + token 단계, Sol, Sage, PV8, Turbo 4스텝, 1344×768·124프레임)으로 입력 종류를 바꿔 쟀습니다. 표의 τ는 실제로 잰 값 그대로입니다. I2V와 FL2V, 영상 참조는 τ1.5로 쟀고 τ1.0으로는 재지 않았습니다. τ1.5를 기본값으로 쓰지 않는 이유는 위 콜아웃에 적었습니다.

작업 입력 Sol τ E2E (초) denoise (초) 최대 메모리
T2V 텍스트 1.0 97.0 ± 1.0 55.7 32.8GB
T2V 텍스트 1.5 89.7 ± 0.6 48.7 32.8GB
I2V 첫 프레임 1.5 93.7 ± 0.6 52.0 32.7GB
FL2V 첫·끝 프레임 1.5 96.7 ± 0.6 55.0 32.9GB
Ref2V 1024² 이미지 1장 1.0 102 (1회) 57 92.4GB
Ref2V 이미지 + 5.17초 영상(소리 포함) 1.5 426.3 ± 5.9 350.7 102.9GB
Ref2VA 흉내 (FL2VA 가중치) 1024² 이미지 1.5 128 (1회) 77 94.9GB

Ref2V는 공식 Ref2VA 파티션과 LightX2V Turbo Ref2V 4스텝 v1.0 768p LoRA를 썼고, 나머지는 Turbo FL2V v1.2입니다. 마지막 행은 Ref2V 가중치 없이 FL2VA 가중치로 참조 이미지를 넣어 본 것입니다.

어느 작업이든 고정 비용이 약 41초 있습니다. 텍스트 인코더 약 12초, 영상 VAE 약 26초, 오디오와 저장 약 3초입니다. Ref2V는 여기에 참조를 읽는 준비가 15초(이미지)에서 44초(영상) 더 듭니다.

영상 참조가 이미지 참조보다 훨씬 오래 걸리는 것은 시퀀스 길이 때문입니다. 960×544 참조 영상이 출력 크기인 1344×768로 올려져 3.8만 행이 더해지고, 전체 시퀀스가 8.4만 행이 됩니다. 참조 영상을 원래 크기로 두면(reference_video_short_edge: 0) INT8 기준 482초가 274초로 줄었지만, 고양이가 참조 영상 속 연주자의 옷을 입고 사람도 함께 나와 참조가 섞였습니다. 그래서 기본값(짧은 변 768)을 유지했습니다. 결과 영상은 참조 영상의 나무 톤 방과 고정 카메라를 따르고, 고양이 생김새는 참조 이미지를 따랐습니다.

참조 이미지는 짧은 변 1024로 넣었습니다. LightX2V Turbo가 학습할 때 쓴 정책(참조 면적을 출력 크기에 맞춤)과 이 이미지에서는 같은 크기입니다. VPIPE의 Ref2VA 기본값 2048은 행이 4배로 늘어납니다.

같은 시드면 같은 영상이 나오나

  • h3.c는 모든 작업에서 4회 출력이 영상·오디오 모두 비트 단위로 같았습니다.
  • VPIPE 기본(accurate) 단계는 같은 시드라도 프로세스마다 출력이 달랐습니다. 행렬곱 경로와 어텐션 타일 크기를 실행 중에 시간을 재서 고르기 때문입니다. 같은 설정을 두 번 돌린 결과끼리 PSNR·SSIM은 4스텝 Turbo가 18.5~19.6dB·0.67~0.71, 8스텝이 27.4dB·0.93이었고, 구도는 같고 세부가 달랐습니다. VPIPE_H3_NO_QMM_AUTOTUNE=1 VPIPE_H3_ATTN_BQ=64를 주면 고정되는 것을 480p INT8 Turbo에서 3회 확인했고, 768p·bf16에서는 확인하지 않았습니다.
  • token 단계는 프로세스를 새로 띄워도 T2V·I2V·FL2V·이미지 Ref2V 출력이 비트 단위로 같았습니다. 다만 8.4만 행인 이미지 + 영상 Ref2V는 회차마다 달랐습니다.

화질

4스텝 T2V는 같은 설정을 다시 돌려도 PSNR이 약 19dB라서 PSNR로 경로 간 우열을 가리기 어렵습니다. 아래는 출력을 고정하는 환경 변수를 주고 768p Turbo v1.2를 1회씩 돌려, bf16·i8_gemm 끔을 기준으로 비교한 값입니다.

경로 PSNR (dB) SSIM
bf16 + i8_gemm 18.3 0.676
ComfyUI INT8 17.3 0.625
bf16 고속 (Sol + Sage + PV8) 14.4 0.551
INT8 고속 14.2 0.555

앞의 두 줄은 회차 간 차이 범위 안이라 우열을 가릴 수 없습니다. 고속 경로는 같은 시드에서 다른 표본을 만들었습니다. 배경이 모니터 벽 대신 유리 실린더가 되는데, 회차가 바뀌어도 그 구도를 유지하고 프레임 손상은 없어서 품질 저하가 아니라 다른 결과로 봅니다. 4스텝 T2V에서 token 단계와 기본 경로도 18.0dB·0.63으로 회차 간 차이 범위 안이었고, 눈으로 보면 구도가 같았습니다.

첫·끝 프레임이 고정되는 FL2V는 비교가 더 의미 있습니다. token + τ1.5와 accurate + τ1.0의 차이가 35.7dB·0.978로 작았습니다. 768p 출력은 모두 눈으로 봤을 때 정적 노이즈나 깨짐이 없었습니다.

다른 기계와 (참고)

같은 구성끼리 맞춘 비교입니다. 이 글의 대표값은 위의 M5 Ultra 최고 구성이고, 아래는 그와 다른 구성에서 잰 값입니다.

비교 그쪽 M5 Ultra 배율
Ryzen AI Max+ 395, W3a, 같은 INT8 DiT·Turbo v1.1 Dense 617초 VPIPE INT8 v1.1 197.0초 3.1배 빠름
Ryzen AI Max+ 395, W3a, Sol 431초 (Turbo v1.1) VPIPE INT8 Sol 119.3초 (Turbo v1.2) 3.6배 빠름
RTX Pro 6000 Blackwell, W3b 8스텝의 스텝당 7.0~7.8초 h3.c 33.6초 / VPIPE 40.5초 4.3~4.8배 / 5.2~5.8배 느림

두 번째 줄은 LoRA 판이 달라서 첫 줄보다 거칠게 맞춘 비교입니다. Ryzen AI Max+ 395의 측정 과정은 HIP Sol 글에, Blackwell은 가속 경로 글에 있습니다.

하지 않은 것

  • h3.c의 열린 PR(#75 지연 컴파일, #80·#73 VAE 정밀도, #14 Turbo LoRA를 가중치에 접기)은 재지 않았습니다. h3.c로 FL2V와 Ref2V도 재지 않았습니다.
  • VPIPE의 텍스트 인코더 8bit 양자화, HyperFlow 8스텝, Ref2V 8스텝 LoRA의 화질, 10초 이상 긴 클립은 아직입니다. VDN 선형 어텐션은 길수록 유리하다고 문서에 적혀 있어 긴 클립에서는 다를 수 있습니다.
  • GPU 클럭·온도·전력은 재지 않았습니다. 화질은 PSNR·SSIM과 눈으로 본 것뿐이고, 사람 평가나 지표 모델로 재지 않았습니다.
  • 메모리는 VPIPE 값만 적었습니다. h3.c는 파일 매핑이 footprint에 잡히지 않는 것으로 보여 엔진 간 메모리 비교에 쓰지 않았습니다.