--- license: apache-2.0 --- # MiniMax-H3-NF4 This model is the **NF4 quantized version** of the video generation model [MiniMax-H3](https://modelscope.cn/models/MiniMax/MiniMax-H3), using the `bitsandbytes` 4-bit quantization method. When used with [DiffSynth-Studio](https://github.com/modelscope/DiffSynth-Studio), it enables model inference on devices with limited GPU memory and system RAM. ## Environment Setup ```shell git clone https://github.com/modelscope/DiffSynth-Studio.git cd DiffSynth-Studio pip install -e ".[all]" ``` ## Inference Code ### Enable Memory Management Run the following code to perform inference using DiffSynth-Studio. Memory management will be automatically enabled. The actual GPU memory usage depends on available GPU memory, and the model can run with as little as 8GB of GPU memory. FL2VA: ```python import torch from diffsynth.pipelines.minimax_h3_audio_video import MiniMaxH3Pipeline, ModelConfig from diffsynth.utils.data.audio_video import write_video_audio from modelscope import dataset_snapshot_download from PIL import Image vram_config = { "offload_dtype": "disk", "offload_device": "disk", "onload_dtype": torch.bfloat16, "onload_device": "cpu", "preparing_dtype": torch.bfloat16, "preparing_device": "cuda", "computation_dtype": torch.bfloat16, "computation_device": "cuda", } pipe = MiniMaxH3Pipeline.from_pretrained( torch_dtype=torch.bfloat16, device="cuda", model_configs=[ ModelConfig(model_id="DiffSynth-Studio/MiniMax-H3-NF4", origin_file_pattern="minimax-h3-fl2va-nf4.safetensors", **vram_config), ModelConfig(model_id="DiffSynth-Studio/MiniMax-H3-NF4", origin_file_pattern="minimax-h3-text-encoder-nf4.safetensors", **vram_config), ModelConfig(model_id="DiffSynth-Studio/MiniMax-H3-NF4", origin_file_pattern="video_vae_nf4.safetensors", **vram_config), ModelConfig(model_id="DiffSynth-Studio/MiniMax-H3-NF4", origin_file_pattern="audio_vae_nf4.safetensors", **vram_config), ], processor_config=ModelConfig(model_id="MiniMax/MiniMax-H3", origin_file_pattern="FL2VA/processor/"), vram_limit=torch.cuda.mem_get_info("cuda")[1] / (1024 ** 3) - 4, ) prompt = "A girl is very happy, she is speaking in english: “I enjoy working with Diffsynth-Studio, it's a perfect framework.”" video, audio = pipe( prompt=prompt, height=480, width=832, num_frames=124, num_inference_steps=50, seed=0, ) write_video_audio( video=video, audio=audio, output_path="t2va.mp4", fps=24, audio_sample_rate=32000, ) ``` Ref2VA:
Expand code ```python import torch from PIL import Image from diffsynth.pipelines.minimax_h3_audio_video import MiniMaxH3Pipeline, ModelConfig from diffsynth.utils.data.audio_video import write_video_audio from diffsynth.utils.data.audio import read_audio from diffsynth.utils.data import VideoData from modelscope import dataset_snapshot_download def align_frame_count(frame_count): current = max(int(frame_count), 1) while current % 17 != 5: current += 1 return current def read_video_with_fps(path, num_out_frames, height, width, fps=24): video = VideoData(path, height=height, width=width) frames = video.raw_data() src_fps = float(video.data.reader.get_meta_data()["fps"]) out = [] for k in range(num_out_frames): idx = int(round(k * src_fps / fps)) if idx >= len(frames): break out.append(frames[idx]) return out vram_config = { "offload_dtype": "disk", "offload_device": "disk", "onload_dtype": torch.bfloat16, "onload_device": "cpu", "preparing_dtype": torch.bfloat16, "preparing_device": "cuda", "computation_dtype": torch.bfloat16, "computation_device": "cuda", } pipe = MiniMaxH3Pipeline.from_pretrained( torch_dtype=torch.bfloat16, device="cuda", model_configs=[ ModelConfig(model_id="DiffSynth-Studio/MiniMax-H3-NF4", origin_file_pattern="minimax-h3-ref2va-nf4.safetensors", **vram_config), ModelConfig(model_id="DiffSynth-Studio/MiniMax-H3-NF4", origin_file_pattern="minimax-h3-text-encoder-nf4.safetensors", **vram_config), ModelConfig(model_id="DiffSynth-Studio/MiniMax-H3-NF4", origin_file_pattern="video_vae_nf4.safetensors", **vram_config), ModelConfig(model_id="DiffSynth-Studio/MiniMax-H3-NF4", origin_file_pattern="audio_vae_nf4.safetensors", **vram_config), ], processor_config=ModelConfig(model_id="MiniMax/MiniMax-H3", origin_file_pattern="Ref2VA/processor/"), vram_limit=torch.cuda.mem_get_info("cuda")[1] / (1024 ** 3) - 5, ) # Text + Reference Image -> Video + Audio dataset_snapshot_download(dataset_id="DiffSynth-Studio/diffsynth_example_dataset", local_dir="data/diffsynth_example_dataset", allow_file_pattern="minimax_h3/MiniMax-H3-Ref2VA/*") ref_image = Image.open("data/diffsynth_example_dataset/minimax_h3/MiniMax-H3-Ref2VA/0.png").convert("RGB") prompt = "A webpage, website UI design, web animation. The video demonstrates a smooth scrolling-down effect. A highly dynamic and energetic product homepage-style landing page UI/UX demo video, with the main focus being product image 1. The page features bold, slanted, oversized sans-serif typography for striking layout. The background contains fast-moving light effects combined with dynamically shifting dark carbon fiber or sport breathable mesh textures. The video shows a tightly paced, powerful scrolling-down animation, along with strong UI interactions such as visual zoom-in and color inversion on mouse hover." video, audio = pipe( prompt=prompt, height=480, width=832, num_frames=124, num_inference_steps=50, seed=42, references=[{"type": "image", "image": Image.open("data/diffsynth_example_dataset/minimax_h3/MiniMax-H3-Ref2VA/0.png").convert("RGB")}] ) write_video_audio( video=video, audio=audio, output_path="ti2va.mp4", fps=24, audio_sample_rate=32000, ) # Text + Reference Audio + Reference Video -> Video + Audio ref_video = read_video_with_fps("data/diffsynth_example_dataset/minimax_h3/MiniMax-H3-Ref2VA/video.mp4", 124, 480, 832) ref_audio, sample_rate = read_audio("data/diffsynth_example_dataset/minimax_h3/MiniMax-H3-Ref2VA/voice.mp3", duration=len(ref_video) / 24, resample=True, resample_rate=pipe.audio_vae.sample_rate) prompt = "subject_definitions:\n is the young man with short wavy blonde hair, wearing a bright pink suit jacket, matching pink trousers, an unbuttoned white shirt, and silver rings, holding a small black lamb in his arms in
[Comfy-Org/MiniMax-H3](https://www.modelscope.cn/models/Comfy-Org/MiniMax-H3) provides a pruned variant of MiniMax-H3, which replaces the DiT's timestep embedding MLP with a lookup table, reducing the input dimension of `adaln_proj.linear` from 2688 to 8 and bringing the total number of model parameters down to approximately 20B. We also provide NF4 quantized weights for this version, with each DiT file being around 9.8 GB. Usage is identical to the above; simply replace the DiT's `origin_file_pattern` with the pruned version. The text encoder and both VAEs still reuse the same set of weights. FL2VA:
Expand code ```python import torch from diffsynth.pipelines.minimax_h3_audio_video import MiniMaxH3Pipeline, ModelConfig from diffsynth.utils.data.audio_video import write_video_audio from modelscope import dataset_snapshot_download from PIL import Image vram_config = { "offload_dtype": "disk", "offload_device": "disk", "onload_dtype": torch.bfloat16, "onload_device": "cpu", "preparing_dtype": torch.bfloat16, "preparing_device": "cuda", "computation_dtype": torch.bfloat16, "computation_device": "cuda", } pipe = MiniMaxH3Pipeline.from_pretrained( torch_dtype=torch.bfloat16, device="cuda", model_configs=[ ModelConfig(model_id="DiffSynth-Studio/MiniMax-H3-NF4", origin_file_pattern="minimax-h3-fl2va-pruned-nf4.safetensors", **vram_config), ModelConfig(model_id="DiffSynth-Studio/MiniMax-H3-NF4", origin_file_pattern="minimax-h3-text-encoder-nf4.safetensors", **vram_config), ModelConfig(model_id="DiffSynth-Studio/MiniMax-H3-NF4", origin_file_pattern="video_vae_nf4.safetensors", **vram_config), ModelConfig(model_id="DiffSynth-Studio/MiniMax-H3-NF4", origin_file_pattern="audio_vae_nf4.safetensors", **vram_config), ], processor_config=ModelConfig(model_id="MiniMax/MiniMax-H3", origin_file_pattern="FL2VA/processor/"), vram_limit=torch.cuda.mem_get_info("cuda")[1] / (1024 ** 3) - 4, ) ``` prompt = "A girl is very happy, she is speaking in english: “I enjoy working with Diffsynth-Studio, it's a perfect framework.”" video, audio = pipe( prompt=prompt, height=480, width=832, num_frames=124, num_inference_steps=50, seed=0, ) write_video_audio( video=video, audio=audio, output_path="t2va.mp4", fps=24, audio_sample_rate=32000, ) ```
Ref2VA:
Expand code ```python import torch from PIL import Image from diffsynth.pipelines.minimax_h3_audio_video import MiniMaxH3Pipeline, ModelConfig from diffsynth.utils.data.audio_video import write_video_audio from diffsynth.utils.data.audio import read_audio from diffsynth.utils.data import VideoData from modelscope import dataset_snapshot_download def align_frame_count(frame_count): current = max(int(frame_count), 1) while current % 17 != 5: current += 1 return current def read_video_with_fps(path, num_out_frames, height, width, fps=24): video = VideoData(path, height=height, width=width) frames = video.raw_data() src_fps = float(video.data.reader.get_meta_data()["fps"]) out = [] for k in range(num_out_frames): idx = int(round(k * src_fps / fps)) if idx >= len(frames): break out.append(frames[idx]) return out vram_config = { "offload_dtype": "disk", "offload_device": "disk", "onload_dtype": torch.bfloat16, "onload_device": "cpu", "preparing_dtype": torch.bfloat16, "preparing_device": "cuda", "computation_dtype": torch.bfloat16, "computation_device": "cuda", } pipe = MiniMaxH3Pipeline.from_pretrained( torch_dtype=torch.bfloat16, device="cuda", model_configs=[ ModelConfig(model_id="DiffSynth-Studio/MiniMax-H3-NF4", origin_file_pattern="minimax-h3-ref2va-pruned-nf4.safetensors", **vram_config), ModelConfig(model_id="DiffSynth-Studio/MiniMax-H3-NF4", origin_file_pattern="minimax-h3-text-encoder-nf4.safetensors", **vram_config), ModelConfig(model_id="DiffSynth-Studio/MiniMax-H3-NF4", origin_file_pattern="video_vae_nf4.safetensors", **vram_config), ModelConfig(model_id="DiffSynth-Studio/MiniMax-H3-NF4", origin_file_pattern="audio_vae_nf4.safetensors", **vram_config), ], processor_config=ModelConfig(model_id="MiniMax/MiniMax-H3", origin_file_pattern="Ref2VA/processor/"), vram_limit=torch.cuda.mem_get_info("cuda")[1] / (1024 ** 3) - 5, ) # Text + Reference Image -> Video + Audio dataset_snapshot_download(dataset_id="DiffSynth-Studio/diffsynth_example_dataset", local_dir="data/diffsynth_example_dataset", allow_file_pattern="minimax_h3/MiniMax-H3-Ref2VA/*") ref_image = Image.open("data/diffsynth_example_dataset/minimax_h3/MiniMax-H3-Ref2VA/0.png").convert("RGB") prompt = "A website page, web UI design, website motion effects. The video demonstrates a smooth scrolling-down effect on a webpage. An intense, dynamic product landing page UI/UX demonstration video with strong visual impact, centered around Product Image 1. The layout features bold, slanted, oversized sans-serif typography. The background includes dynamic lighting effects conveying speed, along with evolving dark carbon fiber or athletic mesh textures. The video showcases a fast-paced, powerful scrolling animation, as well as strong UI interactions such as dramatic visual zooming and color inversion on mouse hover." video, audio = pipe( prompt=prompt, height=480, width=832, num_frames=124, num_inference_steps=50, seed=42, references=[{"type": "image", "image": Image.open("data/diffsynth_example_dataset/minimax_h3/MiniMax-H3-Ref2VA/0.png").convert("RGB")}] ) write_video_audio( video=video, audio=audio, output_path="ti2va.mp4", fps=24, audio_sample_rate=32000, ) # Text + Reference Audio + Reference Video -> Video + Audio ref_video = read_video_with_fps("data/diffsynth_example_dataset/minimax_h3/MiniMax-H3-Ref2VA/video.mp4", 124, 480, 832) ref_audio, sample_rate = read_audio("data/diffsynth_example_dataset/minimax_h3/MiniMax-H3-Ref2VA/voice.mp3", duration=len(ref_video) / 24, resample=True, resample_rate=pipe.audio_vae.sample_rate) prompt = "subject_definitions:\n is the young man with short wavy blonde hair, wearing a bright pink suit jacket, matching pink trousers, an unbuttoned white shirt, and silver rings, holding a small black lamb in his arms in
### Extreme Hardware Optimization If your computing hardware has extremely limited performance, we support enabling direct disk-to-GPU-memory access. With this configuration, tensors in the model will be loaded sequentially from disk into GPU memory as needed for computation, allowing the model to run with only 8GB of RAM: ```diff vram_config = { + "offload_dtype": "disk", + "offload_device": "disk", + "onload_dtype": "disk", + "onload_device": "disk", + "preparing_dtype": "disk", + "preparing_device": "disk", + "computation_dtype": torch.bfloat16, + "computation_device": "cuda", } pipe = MiniMaxH3Pipeline.from_pretrained( torch_dtype=torch.bfloat16, device="cuda", model_configs=..., processor_config=..., + vram_limit=0, ) ``` If you wish to run model inference on Mac M-series chips, we also provide support—although this is not recommended: ```diff vram_config = { + "offload_dtype": "disk", + "offload_device": "disk", + "onload_dtype": "disk", + "onload_device": "disk", + "preparing_dtype": "disk", + "preparing_device": "disk", + "computation_dtype": torch.bfloat16, + "computation_device": "mps", } pipe = MiniMaxH3Pipeline.from_pretrained( torch_dtype=torch.bfloat16, + device="mps", model_configs=..., processor_config=..., + vram_limit=0, ) ``` ## Training Code This quantized model supports LoRA training. Follow the steps below to launch the training job. Download the example dataset: ```shell modelscope download --dataset DiffSynth-Studio/diffsynth_example_dataset --include "minimax_h3/MiniMax-H3-FL2VA/*" --local_dir ./data/diffsynth_example_dataset ``` Training configuration suitable for data center GPUs (e.g., Nvidia H20): Run the following script to start LoRA training, which requires 48GB of GPU memory. ```shell accelerate launch examples/minimax_h3/model_training/train.py \ --dataset_base_path data/diffsynth_example_dataset/minimax_h3/MiniMax-H3-FL2VA \ --dataset_metadata_path data/diffsynth_example_dataset/minimax_h3/MiniMax-H3-FL2VA/metadata.csv \ --data_file_keys "video,input_audio" \ --extra_inputs "input_audio" \ --height 480 \ --width 832 \ --num_frames 124 \ --dataset_repeat 100 \ --model_id_with_origin_paths "DiffSynth-Studio/MiniMax-H3-NF4:minimax-h3-text-encoder-nf4.safetensors,DiffSynth-Studio/MiniMax-H3-NF4:minimax-h3-fl2va-nf4.safetensors,DiffSynth-Studio/MiniMax-H3-NF4:video_vae_nf4.safetensors,DiffSynth-Studio/MiniMax-H3-NF4:audio_vae_nf4.safetensors" \ --learning_rate 1e-4 \ --num_epochs 5 \ --remove_prefix_in_ckpt "pipe.dit." \ --output_path "./models/train/MiniMax-H3-T2VA-nf4" \ --lora_base_model "dit" \ --lora_target_modules "qkv_proj,out_proj" \ --lora_rank 32 \ --use_gradient_checkpointing \ --find_unused_parameters ``` Training configuration suitable for consumer-grade GPUs (e.g., Nvidia RTX 4090): Run the above script to start a two-stage split training with gradient checkpointing and offload enabled, requiring 24GB of VRAM. ```shell accelerate launch examples/minimax_h3/model_training/train.py \ --dataset_base_path data/diffsynth_example_dataset/minimax_h3/MiniMax-H3-FL2VA \ --dataset_metadata_path data/diffsynth_example_dataset/minimax_h3/MiniMax-H3-FL2VA/metadata.csv \ --data_file_keys "video,input_audio" \ --extra_inputs "input_audio" \ --height 480 \ --width 832 \ --num_frames 124 \ --dataset_repeat 1 \ --model_id_with_origin_paths "DiffSynth-Studio/MiniMax-H3-NF4:minimax-h3-text-encoder-nf4.safetensors,DiffSynth-Studio/MiniMax-H3-NF4:video_vae_nf4.safetensors,DiffSynth-Studio/MiniMax-H3-NF4:audio_vae_nf4.safetensors" \ --learning_rate 1e-4 \ --num_epochs 1 \ --remove_prefix_in_ckpt "pipe.dit." \ --output_path "./models/train/MiniMax-H3-T2VA-nf4-split-cache" \ --lora_base_model "dit" \ --lora_target_modules "qkv_proj,out_proj" \ --lora_rank 32 \ --use_gradient_checkpointing \ --use_gradient_checkpointing_offload \ --task "sft:data_process" accelerate launch examples/minimax_h3/model_training/train.py \ --dataset_base_path "./models/train/MiniMax-H3-T2VA-nf4-split-cache" \ --data_file_keys "video,input_audio" \ --extra_inputs "input_audio" \ --height 480 \ --width 832 \ --num_frames 124 \ --dataset_repeat 100 \ --model_id_with_origin_paths "DiffSynth-Studio/MiniMax-H3-NF4:minimax-h3-fl2va-nf4.safetensors" \ --learning_rate 1e-4 \ --num_epochs 5 \ --remove_prefix_in_ckpt "pipe.dit." \ --output_path "./models/train/MiniMax-H3-T2VA-nf4" \ --lora_base_model "dit" \ --lora_target_modules "qkv_proj,out_proj" \ --lora_rank 32 \ --use_gradient_checkpointing \ --use_gradient_checkpointing_offload \ --find_unused_parameters \ --task "sft:train" ``` ## References * DiffSynth-Studio Documentation: [Minimax-H3](https://diffsynth-studio-doc.readthedocs.io/en/latest/Model_Details/MiniMax-H3.html) * DiffSynth-Studio Documentation: [VRAM Management](https://diffsynth-studio-doc.readthedocs.io/en/latest/Pipeline_Usage/VRAM_management.html) * DiffSynth-Studio Documentation: [Two-Stage Split Training](https://diffsynth-studio-doc.readthedocs.io/en/latest/Training/Split_Training.html) * DiffSynth-Studio Documentation: [Low VRAM Training](https://diffsynth-studio-doc.readthedocs.io/en/latest/Pipeline_Usage/Model_Training.html#low-vram-training)