Views
No views yet
larryvrh/MiniMax-H3-Turbo-Lora: a LoRA that lets MiniMax-H3 render joint video + synchronized stereo audio in about 4 sampling steps instead of the usual ~20.transformer.*.lora_A/B.weight)convert.py to turn the original ComfyUI / generate.py safetensors into that layout⚠️ Early prototype. Same caveat as the upstream release: under-trained preview weights, not production quality. They already beat the base model at 4 steps (sharper detail, cleaner / better-synced audio), but treat this as a work-in-progress taste, not a finished product. Prefer the non-EMAckpt500weights by default.
W_eff = W + lora_B @ lora_A, alpha = rank so scale is 1). QKV is split into to_q / to_k / to_v, and SwiGLU fc1 halves are swapped to match Diffusers' [value; gate] layout.| file | source (ComfyUI layout) | notes |
|---|---|---|
minimax_h3_turbo_4step_ckpt500_diffusers.safetensors | minimax_h3_turbo_4step_ckpt500.safetensors | recommended default — newest non-EMA @ ~500 steps, usually sharpest |
minimax_h3_turbo_4step_ema_ckpt500_diffusers.safetensors | minimax_h3_turbo_4step_ema_ckpt500.safetensors | EMA @ ~500 steps — smoother, but early EMA can show ghosting / motion smear |
transformer. for MiniMaxH3Transformer3DModel.load_lora_adapter.main, plus PEFT:1pip install torch torchvision --index-url https://download.pytorch.org/whl/cu126
2pip install -r requirements.txt
3pip install git+https://github.com/huggingface/diffusers.git1import torch
2from diffusers import ComponentsManager, ModularPipeline
3from diffusers.utils.export_utils import encode_video
4from huggingface_hub import hf_hub_download
5from safetensors.torch import load_file
6
7def network_alphas_alpha_eq_rank(state_dict):
8 # Turbo LoRA: alpha == rank. Required when ranks differ (attn/mlp=64, adaln=16).
9 alphas = {}
10 for key, tensor in state_dict.items():
11 if key.endswith(".lora_B.weight") and tensor.ndim > 1:
12 base = key[: -len(".lora_B.weight")]
13 alphas[f"{base}.alpha"] = float(tensor.shape[1])
14 return alphas
15
16lora_path = hf_hub_download(
17 "InstantX/MiniMax-H3-Turbo-Lora-Diffusers",
18 "minimax_h3_turbo_4step_ckpt500_diffusers.safetensors",
19)
20
21manager = ComponentsManager()
22pipe = ModularPipeline.from_pretrained("MiniMaxAI/MiniMax-H3", components_manager=manager)
23pipe.load_components(dtype=torch.bfloat16)
24
25lora_sd = load_file(lora_path, device="cpu")
26pipe.transformer.load_lora_adapter(
27 lora_sd,
28 prefix="transformer",
29 adapter_name="turbo_4step",
30 network_alphas=network_alphas_alpha_eq_rank(lora_sd),
31)
32
33# Load LoRA *before* enabling offload so PEFT injects into resident modules.
34manager.enable_auto_cpu_offload(device="cuda", memory_reserve_margin="12GB")
35
36# Optional: FlashAttention-3 on Hopper (kernels from the Hub).
37try:
38 pipe.transformer.set_attention_backend("_flash_3_hub")
39except Exception:
40 pipe.transformer.set_attention_backend("native")
41
42# MiniMaxH3Scheduler: num_inference_steps is the sigma grid length *including* terminal 0,
43# so it drives (num_inference_steps - 1) model evals.
44# 5 -> 4 evals (matches upstream generate.py --steps 4)
45# 7–9 -> 6–8 evals (upstream comfort zone for sharpness at this early checkpoint)
46results = pipe(
47 prompt="A corgi in a chef hat flipping a pancake, sizzling sounds and a cheerful bark.",
48 num_frames=124, # 17*k+5, ~5.17s @ 24fps
49 height=768,
50 width=1344,
51 num_inference_steps=5,
52 generator=torch.Generator().manual_seed(42),
53 output=["videos", "audio", "sampling_rate"],
54)
55
56encode_video(
57 results["videos"][0],
58 fps=24,
59 output_path="out.mp4",
60 audio=results["audio"][0],
61 audio_sample_rate=results["sampling_rate"],
62)scheduler shift 12, audio_scheduler shift 3). You do not need the ComfyUI Turbo custom sampler node; a wrong single-schedule sampler is what blows up audio at 4 steps in ComfyUI.larryvrh/MiniMax-H3-Turbo-Lora (ComfyUI module names, fused qkv_proj / mlp.fc1).1pip install safetensors torch
2
3python convert.py \
4 --input minimax_h3_turbo_4step_ckpt500.safetensors \
5 --output minimax_h3_turbo_4step_ckpt500_diffusers.safetensorsconvert.py does:MiniMaxH3Transformer3DModel (blocks.* → transformer_blocks.*, mlp.fc* → ff.net.*, final_layer.adaln_proj → norm_out.linear, …).attn.qkv_proj LoRA into to_q / to_k / to_v (shared A, row-split B in [q_all; k_all; v_all] layout).mlp.fc1 LoRA halves from [gate; value] to Diffusers SwiGLU [value; gate].transformer. prefix for load_lora_adapter.num_inference_steps=5) works; at this early checkpoint 6–8 evals (num_inference_steps=7…9) are usually sharper. Any count ≥ 4 evals is valid; more steps look better.height / width multiples of 32 (short edge typically 768). num_frames at 24 fps snaps up to the video VAE’s 17·k+5 grid (124 ≈ 5 s). Validated roughly 5–15 s.ComponentsManager.enable_auto_cpu_offload; smaller cards need quantization / group offload as in the MiniMax-H3 Diffusers docs.larryvrh/MiniMax-H3-Turbo-LoraMiniMaxAI/MiniMax-H3