h3.c: MiniMax H3 영상 생성 모델을 애플 실리콘에서 돌리는 C 언어 구현체 (feat. antirez)

h3.c 소개

영상 생성 모델을 로컬에서 돌려 보려면 대개 대용량 GPU가 있는 장비부터 찾게 됩니다. 가중치가 BF16으로 수십 기가바이트에 이르고, 디노이징 패스를 수십 번 반복해야 짧은 클립 하나가 나오기 때문입니다. 맥에서 시도하더라도 통합 메모리에 모델이 통째로 올라가야 한다는 조건이 먼저 걸립니다.

h3.c는 MiniMax의 영상·음향 생성 모델인 H3를 애플 실리콘에서 직접 실행하도록 C와 Metal로 다시 구현한 추론기입니다. 저장소 이름은 h3.c이고 README에서는 h3-metal로 부르며, Redis 개발자로 알려진 antirez(Salvatore Sanfilippo)가 공개했습니다. 프로젝트는 동작하는 수직 슬라이스를 차례로 쌓는 방식으로 만들어지고 있어서, 호스트와 모델 메타데이터 확인, Metal 블록 패리티, 프롬프트 인코딩, 프롬프트에서 영상·음향 생성, 첫 프레임과 끝 프레임 조건화, 순서가 있는 참조 입력이 차례로 완성되었습니다.

현재는 프롬프트에서 영상과 음향을 만드는 경로, 첫·끝 프레임 조건화, 이미지와 영상과 음향을 순서대로 넣는 Ref2VA 참조가 모두 끝에서 끝까지 동작합니다. 진행 중인 작업은 M3 Max와 M5 Max에서의 H3 전용 Metal 성능과 메모리 최적화입니다.

h3.c를 쓰기 전에 확인할 모델 가중치 사용 제한

h3.c 자체는 자유롭게 쓸 수 있는 코드지만, 이 도구가 실행하는 MiniMax H3 가중치에는 지역 제한이 걸려 있습니다. MiniMax H3 Community License Agreement는 적용 지역을 "worldwide, excluding the Excluded Territories" 로 정의하고, 제외 지역(Excluded Territories)에 유럽연합과 영국, 대한민국, 미국을 명시합니다. 같은 문서는 제외 지역 안에서 이 저작물과 그 출력물을 사용·복제·수정·배포·전시하는 것이 이 계약으로 허가되지 않는다고 못 박습니다.

배포처인 Hugging Face 모델 카드는 제외 지역 사용자를 위한 별도 라이선스 신청 양식을 함께 안내하고 있습니다. 국내에서 이 모델을 실제 업무나 서비스에 쓰려면 이 경로로 별도 허가를 받아야 하므로, h3.c의 코드 라이선스와는 별개로 확인하고 넘어가야 하는 부분입니다.

h3.c가 기존 실행 경로와 다른 점

같은 모델을 맥에서 돌리는 기존 방법은 MLX 기반 구현을 쓰는 것입니다. h3.c는 그 위에 얹는 래퍼가 아니라 Metal 커널까지 직접 작성한 별도 구현이며, 그래서 정확성을 스스로 증명해야 하는 부담을 함께 집니다. 저장소는 이 부담을 테스트로 처리합니다. make test는 결정적 호스트 테스트를 돌리고, MLX 고정 자료가 설치되어 있으면 Metal 소스를 런타임에 컴파일해 완전한 토이 H3 블록의 결과를 MLX 출력과 대조합니다. make parity는 그 대조만 따로 실행합니다.

런타임 컴파일을 택한 것도 의도된 선택이어서, Xcode의 선택 사항인 오프라인 Metal 툴체인을 요구하지 않습니다. 다만 저장소는 MLX와 픽셀 단위로 동일한 결과는 기대하지 않는다고 밝히고 있습니다. 난수 스트림이 다르기 때문입니다.

직접 구현이 만들어 낸 실질적 차이는 실행 옵션의 폭입니다. 디노이징 패스 수, 디노이저 재사용, 활성 트랜스포머 블록 수, 코어 잔차 재사용, 토큰 축소, 내부 렌더 해상도가 각각 별도 손잡이로 노출되어 있어서 품질과 속도 사이의 지점을 직접 고를 수 있습니다.

h3.c의 속도와 메모리 조절

기본값은 --steps 20 --layers 50 --reuse 1이고, 여기서 각 손잡이를 하나씩 돌려 가며 비교하는 것이 저장소가 권하는 방식입니다.

가장 큰 폭으로 시간을 줄이는 것은 디노이징 패스 수입니다. --steps N은 언제나 정확히 N번의 패스를 뜻하며, 네 번에서 일곱 번 구간은 저예산 비교에서 선택된 동일한 스케줄을 사용하고 숫자를 올릴수록 디테일과 움직임이 점진적으로 좋아집니다. 512 정사각 22프레임 여우 테스트에서 선택된 4패스 결과는 29패스 기준 대비 영상 전체 SSIM 0.556을 기록했고, 별도의 서퍼 테스트에서는 0.547이었습니다. 시간으로는 M5 Max에서 4패스 디노이즈가 약 3.5초, 기준이 26.4초였습니다.

--reuse는 모든 패스에서 디노이저를 새로 계산하는 대신 일부만 계산하고 건너뛴 구간의 속도를 외삽합니다. 20스텝 기준으로 --reuse 2는 11번, --reuse 3은 8번만 새로 평가합니다. 다만 패스 수 자체가 아주 적을 때는 --reuse 1을 유지해 요청한 모든 패스가 실제로 돌아가게 하라고 안내합니다. --layers는 50개 블록 중 일부만 실행해 시간과 상주 메모리를 함께 줄이고, --token-reduction은 중간 블록에서 가로 방향 영상 토큰을 짝지어 계산량을 낮춥니다. 512 정사각에서 45 레이어 + reuse 2 조합의 디노이즈 구간은 토큰 축소를 켜면 16.69초에서 12.60초로 줄었지만, 구성이 기준 경로에서 더 벌어질 수 있습니다.

조합에는 지켜야 할 선도 있습니다. --reuse--core-reuse는 함께 쓸 수 없고, --layers 40--reuse 3에 토큰 축소까지 얹은 조합은 검증에서 색 링잉과 윤곽선, 잔상이 생긴 사례로 기록되어 있습니다.

h3.c의 SSD 스트리밍

메모리가 부족한 장비를 위한 경로는 --ssd-streaming입니다. 이 옵션은 원본 BF16 체크포인트를 변환이나 양자화 없이 그대로 쓰면서, DiT 블록을 두 개만 메모리에 두고 GPU가 현재 블록을 계산하는 동안 다음 블록을 SSD에서 읽어 옵니다. M5 Max에서 추적된 DiT 텐서 저장량은 512 정사각에서 약 36.5GiB에서 2.0GiB로, 864x480에서 2.1GiB로 떨어졌습니다.

대가는 시간입니다. 예열된 50블록 순전파는 512 정사각에서 1.35초 대신 2.49초가 걸려 84% 느려졌고, 864x480에서는 2.14초 대신 2.68초로 26% 느려졌습니다. 두 검사 모두 결과는 바이트 단위로 동일했습니다. 저장소는 이 2.0~2.1GiB가 전체 시스템 메모리가 아니라 DiT의 추적된 텐서 저장량이라는 점을 따로 짚습니다. 프롬프트 인코딩과 두 개의 VAE는 별도 단계에서 돌아 각자의 최대치를 여기에 더하지 않지만, 운영체제와 미디어 버퍼와 출력 해상도를 위한 여유는 여전히 필요합니다. 미리보기를 켜는 --show는 프리뷰 VAE를 상주시켜 약 10GiB를 더 쓰므로 메모리를 최대한 아끼려면 빼야 합니다.

이 옵션은 명시적인 메모리와 속도의 맞바꿈이고 기본값이 아니며, --use-int8-row-fc2와 함께 쓸 수 없습니다.

h3.c의 해상도와 길이 제약

가로와 세로는 각각 32의 배수여야 하고 최소 32 이상이며, 두 값의 곱이 768 * 1344 픽셀을 넘을 수 없습니다. H3-Base가 768p급 모델이라 이 범위 안에서도 크기마다 안내가 다릅니다. 512 정사각이 여러 프롬프트로 반복 검증된 가장 안전한 개발 크기이고, 768 정사각은 검증된 고품질 정사각 출력이지만 훨씬 비쌉니다. 1344x768과 768x1344가 공개된 768p급 가로·세로 한계입니다.

256 정사각은 네이티브 빠른 미리보기 크기인데, 이 크기에서 H3는 8x8 유효 공간 토큰 격자만 갖기 때문에 세밀한 디테일과 복잡한 구성을 담을 자리가 부족합니다. h3.c는 정확히 256 정사각에서 공간 RoPE 좌표를 자동으로 절반으로 줄이며, 이 처리가 긴 렌더에서 반복되던 격자 무늬를 없앴다고 기록되어 있습니다. 128 정사각은 4x4 토큰 격자로는 알아볼 수 있는 피사체가 나오지 않아 지원하지 않습니다.

길이는 24fps 기준이고 프레임 요청은 5 + 17*n 형태로 올림 처리됩니다. 22프레임이 약 0.917초, 107프레임이 4.458초, 243프레임이 10.125초입니다. --seconds로 시간을 요청하면 24fps로 환산한 뒤 가장 가까운 상위 형태로 올림되므로 --seconds 10은 243프레임, 즉 10.125초가 됩니다. 공개된 작업 흐름이 상정하는 길이는 대략 4초에서 15초 사이입니다.

h3.c는 누구에게 유용한가

M3 Max나 M5 Max급 애플 실리콘 맥을 가지고 있고 영상 생성 모델의 내부 동작을 직접 만져 보려는 쪽에 맞습니다. 손잡이마다 무엇을 얼마나 바꾸는지가 측정값과 함께 문서화되어 있어서, 확산 모델의 속도와 품질 사이 절충을 실제 수치로 관찰하기에 좋은 교재이기도 합니다. C와 Metal로 쓰인 단일 구현이라 코드를 읽어 내려가며 파이프라인 전체를 따라가기도 수월합니다.

반대로 결과물의 품질만 필요하다면 적합하지 않습니다. 짧은 클립 하나에도 수십 초가 들고, 검증된 크기가 512에서 768 정사각 중심이며, FFmpeg와 FFprobe가 PATH에 있어야 하고 Hugging Face 스냅샷을 미리 받아 두어야 합니다. 무엇보다 국내에서는 앞서 짚은 모델 가중치의 지역 제한을 먼저 해결해야 합니다.

h3.c 설치 및 사용법

빌드한 다음 모델 구성을 먼저 확인합니다. 예시는 Hugging Face 스냅샷이 ./MiniMax-H3에 있고 FFmpeg와 FFprobe가 PATH에 있다고 가정합니다.

make -j8
mkdir -p outputs
./h3 --info -d ./MiniMax-H3

--info는 모든 가중치를 매핑하거나 미디어를 생성하지 않고 모델 배치와 선택된 Metal 장치만 확인합니다. 검증된 균형 프리셋으로 첫 영상을 만들면 다음과 같습니다.

./h3 --profile \
  -d ./MiniMax-H3 \
  -p "A red fox walks through fresh snow in a pine forest. Medium tracking shot, natural winter light, realistic fur, soft footsteps and wind." \
  --width 512 --height 512 \
  --frames 22 --steps 20 \
  --layers 45 --reuse 2 \
  --show \
  -o outputs/fox-fast.mp4

-p 없이 실행하면 같은 바이너리가 대화형 세션으로 들어갑니다. 이 세션은 BF16 프롬프트 조건화와 준비된 DiT, 영상 디코더를 메모리에 유지하므로 같은 프롬프트를 다른 시드로 다시 돌릴 때 불러오기와 인코딩을 반복하지 않습니다. !status, !seed random, !seconds 2, !show, !save output.mp4, !cache 같은 명령을 쓸 수 있고 전체 목록은 !help로 확인합니다.

./h3 -d ./MiniMax-H3 --width 512 --height 512 --steps 6

첫 프레임과 끝 프레임을 고정하려면 세션에서 !first!last를 쓰고, 일반적인 참조 이미지는 !ref-image를 씁니다. 참조는 넣은 순서대로 <Picture 1>, <Picture 2> 형태로 모델에 전달되며 파일 이름 자체는 의미를 갖지 않습니다. 순서가 있는 참조는 첫·끝 프레임 고정과 섞어 쓸 수 없습니다.

h3> !ref-image person.png
h3> Make the person shown in Picture 1 wave to the camera.

명령줄에서는 참조 종류에 따라 플래그가 나뉩니다. 이미지 한 장은 --ref-image, 사운드트랙을 무시하고 움직임만 이어 갈 때는 --ref-silent-video, 영상에 담긴 소리까지 살릴 때는 --ref-video를 씁니다. 독립적인 음향 참조는 이미지나 영상 참조와 함께여야 하고, 길이는 2초에서 15초 사이여야 하며, 최대 세 개까지 그리고 디코딩된 총 길이 15초까지만 받습니다.

프롬프트는 짧아도 동작하지만 공개된 구성은 Context-IR에 가까운 서술을 기대합니다. 피사체와 동작, 배경, 카메라, 조명과 스타일, 원하는 소리를 나눠 적는 형태입니다.

Scene: a single red fox in a snow-covered pine forest at dawn.
Action: the fox walks steadily left to right and looks toward the camera once.
Camera: medium-height lateral tracking shot, 50 mm lens, stable framing.
Look: photorealistic fur, cold blue ambient light, warm sunrise rim light.
Audio: soft footsteps in snow, light wind through pine branches, no music.

옵션을 비교할 때는 프롬프트와 시드, 해상도, 프레임 수, 스텝 수를 모두 같게 두고 한 번에 하나만 바꿉니다. --seed의 기본값은 42입니다. 전체 CLI 설명은 ./h3 --help에 있습니다.

h3.c의 라이선스

h3.c는 MIT 라이선스로 공개되어 있어 개인 및 상업적 목적으로 자유롭게 사용할 수 있습니다. 함께 포함된 제3자 구성 요소의 조건은 THIRD_PARTY_NOTICES.md에 정리되어 있습니다. 이 조건은 h3.c의 코드에만 해당하며, 이 도구가 실행하는 모델 가중치에는 앞서 다룬 별도의 사용 제한이 적용됩니다.

:github: h3.c 프로젝트 GitHub 저장소

:hugs: h3.c가 사용하는 MiniMax H3 모델

더 읽어보기




이 글은 GPT 모델로 정리한 초안을 바탕으로 한 것으로, 원문의 내용 또는 의도와 다르게 정리된 내용이 있을 수 있습니다. 관심있는 내용이시라면 원문도 함께 참고해주세요! 읽으시면서 어색하거나 잘못된 내용을 발견하시면 댓글로 알려주시기를 부탁드립니다. :hugs:

이 도구를 직접 설치해 사용해보셨다면, :pytorch:파이토치 한국 사용자 모임:south_korea: 회원들을 위해 경험이나 팁을 댓글로 남겨주세요! :folded_hands: