--- base_model: - MiniMax/MiniMax-H3 frameworks: - "" license: Apache License 2.0 base_model_relation: quantized --- # MiniMax-H3-NF4 本模型是视频生成模型 [MiniMax-H3](https://modelscope.cn/models/MiniMax/MiniMax-H3) 的 **NF4 量化版本**,采用 `bitsandbytes` 4-bit 量化方案,配合 [DiffSynth-Studio](https://github.com/modelscope/DiffSynth-Studio) 使用,可以在显存和内存有限的设备上运行模型推理。 ## 环境安装 ```shell git clone https://github.com/modelscope/DiffSynth-Studio.git cd DiffSynth-Studio pip install -e ".[all]" ``` ## 推理代码 ### 启用显存管理 运行以下代码,使用 DiffSynth-Studio 进行推理,显存管理将会自动启用,实际的显存占用量取决于 GPU 上的可用显存,最低 8G 显存即可运行。 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:
展开代码 ```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 = "一个网站页面,网站页面UI设计,网站动效,视频展示了流畅的网页向下滚动效果。一个极具爆发力与动感的产品官网风格产品落地页 UI/UX 演示视频,核心展示主体是该产品图片1。页面采用粗犷有力、倾斜的超大号无衬线字体进行张扬的排版。背景有极具速度感的动态光影、暗色碳纤维或运动透气网眼纹理在交织变换。视频展示了节奏紧凑、充满力量感的网页向下滚动效果,以及鼠标悬停时强烈的视觉放大与颜色反转等 UI 交互动作。" 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) 提供了 MiniMax-H3 的 pruned 变体,它把 DiT 的时间步嵌入 MLP 替换为一张查找表,使 `adaln_proj.linear` 的输入维度从 2688 降到 8,模型参数量降至约 20B。我们对其同样提供了 NF4 量化权重,单个 DiT 文件约 9.8 GB。 用法与上文完全一致,只需把 DiT 的 `origin_file_pattern` 换成 pruned 版本,文本编码器与两个 VAE 仍然复用同一套权重。 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-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:
展开代码 ```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 = "一个网站页面,网站页面UI设计,网站动效,视频展示了流畅的网页向下滚动效果。一个极具爆发力与动感的产品官网风格产品落地页 UI/UX 演示视频,核心展示主体是该产品图片1。页面采用粗犷有力、倾斜的超大号无衬线字体进行张扬的排版。背景有极具速度感的动态光影、暗色碳纤维或运动透气网眼纹理在交织变换。视频展示了节奏紧凑、充满力量感的网页向下滚动效果,以及鼠标悬停时强烈的视觉放大与颜色反转等 UI 交互动作。" 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
### 极端硬件优化 如果你的计算设备性能极为有限,我们支持开启硬盘到显存的直连,在这样的配置下,模型中的张量将会按照计算顺序逐个从硬盘加载到显存,只需 8G 内存即可运行: ```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, ) ``` 如果你希望在 Mac M 系列芯片上运行模型推理,我们也是支持的,尽管这并不推荐: ```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, ) ``` ## 训练代码 本量化模型支持 LoRA 训练,请按照以下步骤启动训练程序。 下载样例数据集: ```shell modelscope download --dataset DiffSynth-Studio/diffsynth_example_dataset --include "minimax_h3/MiniMax-H3-FL2VA/*" --local_dir ./data/diffsynth_example_dataset ``` 适合数据中心 GPU(例如 Nvidia H20)的训练配置:运行以下脚本,启动 LoRA 训练程序,需要 48G 显存。 ```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 ``` 适合消费级 GPU(例如 Nvidia RTX 4090)的训练配置:运行以下脚本,启动两阶段拆分训练与 gradient checkpointing offload,需要 24G 显存。 ```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" ``` ## 参考资料 * DiffSynth-Studio 文档:[Minimax-H3](https://diffsynth-studio-doc.readthedocs.io/en/latest/Model_Details/MiniMax-H3.html) * DiffSynth-Studio 文档:[显存管理](https://diffsynth-studio-doc.readthedocs.io/en/latest/Pipeline_Usage/VRAM_management.html) * DiffSynth-Studio 文档:[两阶段拆分训练](https://diffsynth-studio-doc.readthedocs.io/en/latest/Training/Split_Training.html) * DiffSynth-Studio 文档:[低显存训练](https://diffsynth-studio-doc.readthedocs.io/en/latest/Pipeline_Usage/Model_Training.html#low-vram-training)