Instructions to use tiny-random/minimax-h3 with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Diffusers
How to use tiny-random/minimax-h3 with Diffusers:
pip install -U diffusers transformers accelerate
import torch from diffusers import DiffusionPipeline # switch to "mps" for apple devices pipe = DiffusionPipeline.from_pretrained("tiny-random/minimax-h3", dtype=torch.bfloat16, device_map="cuda") prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k" image = pipe(prompt).images[0] - Notebooks
- Google Colab
- Kaggle
This tiny model is for debugging. It is randomly initialized with the config adapted from MiniMaxAI/MiniMax-H3.
File size:
- ~12MB text_encoder/model.safetensors
- ~0.5MB transformer/diffusion_pytorch_model.safetensors
- ~0.5MB transformer_ref/diffusion_pytorch_model.safetensors
- ~4MB vae/diffusion_pytorch_model.safetensors
- ~64MB audio_vae/diffusion_pytorch_model.safetensors
Requires diffusers from source (main) with MiniMax-H3 modular blocks, and a recent transformers that ships Qwen3VLForConditionalGeneration.
Notes:
- The conditioner must have
num_hidden_layers > 50because MiniMax-H3 readshidden_states[50]. - Transformer RoPE needs
attention_head_dim >= 6 * rope_freq_dim. - Audio VAE decoder needs
decoder_dim >= 128for the released 7-stage upsample stack.
| File path | Size |
|---|---|
| audio_vae/diffusion_pytorch_model.safetensors | 66.7MB |
| text_encoder/model.safetensors | 12.1MB |
| transformer/diffusion_pytorch_model.safetensors | 0.5MB |
| transformer_ref/diffusion_pytorch_model.safetensors | 0.5MB |
| vae/diffusion_pytorch_model.safetensors | 4.5MB |
Example usage:
import torch
from diffusers import ModularPipeline
model_id = "tiny-random/minimax-h3"
device = 'cuda' if torch.cuda.is_available() else 'cpu'
pipe = ModularPipeline.from_pretrained(model_id, workflow='t2va')
pipe.load_components(dtype=torch.bfloat16)
if device == 'cuda':
pipe.to(device)
outputs = pipe(
prompt='A red fox trotting through a snowy pine forest',
num_frames=124,
height=64,
width=64,
num_inference_steps=2,
generator=torch.Generator(device=device).manual_seed(42),
output=['videos', 'audio', 'sampling_rate'],
)
print(type(outputs['videos'][0]), getattr(outputs['videos'][0], 'shape', None))
print(type(outputs['audio'][0]), getattr(outputs['audio'][0], 'shape', None), outputs['sampling_rate'])
Codes to create this repo:
import json
from pathlib import Path
import torch
from diffusers import (
AutoencoderKLMiniMaxH3,
AutoencoderKLMiniMaxH3Audio,
MiniMaxH3Blocks,
MiniMaxH3Scheduler,
MiniMaxH3Transformer3DModel,
)
from huggingface_hub import hf_hub_download
from transformers import AutoConfig, AutoProcessor, AutoTokenizer, Qwen3VLForConditionalGeneration
source_model_id = "MiniMaxAI/MiniMax-H3"
save_folder = "/tmp/tiny-random/minimax-h3"
def save_json(path, obj):
Path(path).parent.mkdir(parents=True, exist_ok=True)
with open(path, 'w', encoding='utf-8') as f:
json.dump(obj, f, indent=2, ensure_ascii=False)
def init_weights(model):
torch.manual_seed(42)
model = model.cpu()
with torch.no_grad():
for name, p in sorted(model.named_parameters()):
torch.nn.init.normal_(p, 0, 0.1)
print(name, p.shape, p.dtype, p.device)
torch.set_default_dtype(torch.bfloat16)
text_dim = 32
Path(save_folder).mkdir(parents=True, exist_ok=True)
AutoTokenizer.from_pretrained(source_model_id, subfolder='tokenizer').save_pretrained(
f'{save_folder}/tokenizer'
)
AutoProcessor.from_pretrained(source_model_id, subfolder='processor').save_pretrained(
f'{save_folder}/processor'
)
with open(hf_hub_download(source_model_id, filename='text_encoder/config.json', repo_type='model'), 'r', encoding='utf-8') as f:
config = json.load(f)
# MiniMax-H3 conditions on hidden_states[50], so keep >50 layers with a tiny width.
config['text_config'].update({
'head_dim': 8,
'hidden_size': text_dim,
'intermediate_size': 64,
'num_attention_heads': 4,
'num_key_value_heads': 2,
'num_hidden_layers': 51,
'tie_word_embeddings': True,
})
config['text_config']['rope_scaling']['mrope_section'] = [2, 1, 1]
config['vision_config'].update({
'depth': 4,
'hidden_size': 64,
'intermediate_size': 128,
'num_heads': 4,
'out_hidden_size': text_dim,
'deepstack_visual_indexes': [1, 2, 3],
})
config['tie_word_embeddings'] = True
save_json(f'{save_folder}/text_encoder/config.json', config)
text_encoder = Qwen3VLForConditionalGeneration(
AutoConfig.from_pretrained(f'{save_folder}/text_encoder')
).to(torch.bfloat16)
init_weights(text_encoder)
text_encoder.save_pretrained(f'{save_folder}/text_encoder')
# attention_head_dim must cover 2 * 3 * rope_freq_dim rotary channels.
transformer_kwargs = dict(
num_attention_heads=2,
attention_head_dim=32,
hidden_size=64,
num_layers=2,
num_refiner_layers=1,
ffn_dim=128,
in_channels=8,
audio_in_channels=8,
patch_size=(1, 2, 2),
text_dim=text_dim,
freq_dim=64,
time_embed_hidden_dim=64,
time_embed_dim=32,
rope_freq_dim=4,
)
for subfolder in ('transformer', 'transformer_ref'):
transformer = MiniMaxH3Transformer3DModel(**transformer_kwargs)
init_weights(transformer)
transformer.save_pretrained(f'{save_folder}/{subfolder}')
with open(hf_hub_download(source_model_id, filename='vae/config.json', repo_type='model'), 'r', encoding='utf-8') as f:
vae_config = json.load(f)
vae_config.update({
'latent_channels': 8,
'block_out_channels': [32, 32, 32, 64, 64, 64],
'layers_per_block': 1,
'spatial_downsample_factors': [2, 2, 2, 2, 1, 1],
'temporal_downsample_factors': [1, 2, 2, 1, 1, 1],
'norm_num_groups': 8,
'decoder_num_layers': 2,
'decoder_num_attention_heads': 2,
'decoder_attention_head_dim': 16,
'decoder_num_register_tokens': 2,
'decoder_ffn_mult': 2,
'latents_mean': [0.0] * 8,
'latents_std': [1.0] * 8,
})
save_json(f'{save_folder}/vae/config.json', vae_config)
vae = AutoencoderKLMiniMaxH3.from_config(
AutoencoderKLMiniMaxH3.load_config(f'{save_folder}/vae')
)
init_weights(vae)
vae.save_pretrained(f'{save_folder}/vae')
# Keep hop length 800 (=32000/40Hz). decoder_dim must stay >= 128 for 7 upsample stages.
with open(hf_hub_download(source_model_id, filename='audio_vae/config.json', repo_type='model'), 'r', encoding='utf-8') as f:
audio_config = json.load(f)
audio_config.update({
'encoder_dim': 32,
'latent_dim': 128,
'latent_channels': 8,
'num_attention_heads': 4,
'decoder_dim': 128,
'latents_mean': [0.0] * 8,
'latents_std': [1.0] * 8,
})
save_json(f'{save_folder}/audio_vae/config.json', audio_config)
audio_vae = AutoencoderKLMiniMaxH3Audio.from_config(
AutoencoderKLMiniMaxH3Audio.load_config(f'{save_folder}/audio_vae')
)
init_weights(audio_vae)
audio_vae.save_pretrained(f'{save_folder}/audio_vae')
MiniMaxH3Scheduler.from_pretrained(source_model_id, subfolder='scheduler').save_pretrained(
f'{save_folder}/scheduler'
)
MiniMaxH3Scheduler.from_pretrained(source_model_id, subfolder='audio_scheduler').save_pretrained(
f'{save_folder}/audio_scheduler'
)
for index_name in ('model_index.json', 'modular_model_index.json'):
index = json.load(open(hf_hub_download(source_model_id, filename=index_name, repo_type='model'), encoding='utf-8'))
for value in index.values():
if isinstance(value, list) and len(value) >= 3 and isinstance(value[2], dict):
value[2]['pretrained_model_name_or_path'] = save_folder
save_json(f'{save_folder}/{index_name}', index)
pipe = MiniMaxH3Blocks().init_pipeline(save_folder)
pipe.load_components(dtype=torch.bfloat16)
pipe.save_pretrained(save_folder, safe_serialization=True, overwrite_modular_index=True)
torch.set_default_dtype(torch.float32)
print(pipe)
Printing the model:
MiniMaxH3ModularPipeline {
"_blocks_class_name": "MiniMaxH3Blocks",
"_class_name": "MiniMaxH3ModularPipeline",
"_diffusers_version": "0.40.0.dev0",
"audio_scheduler": [
"diffusers",
"MiniMaxH3Scheduler",
{
"pretrained_model_name_or_path": "./tmp/tiny-random/minimax-h3",
"revision": null,
"subfolder": "audio_scheduler",
"type_hint": [
"diffusers",
"MiniMaxH3Scheduler"
],
"variant": null
}
],
"audio_vae": [
"diffusers",
"AutoencoderKLMiniMaxH3Audio",
{
"pretrained_model_name_or_path": "./tmp/tiny-random/minimax-h3",
"revision": null,
"subfolder": "audio_vae",
"type_hint": [
"diffusers",
"AutoencoderKLMiniMaxH3Audio"
],
"variant": null
}
],
"canvas_max_pixels": 1032192,
"canvas_short_edge": 768,
"processor": [
"transformers",
"Qwen3VLProcessor",
{
"pretrained_model_name_or_path": "./tmp/tiny-random/minimax-h3",
"revision": null,
"subfolder": "processor",
"type_hint": [
"transformers",
"Qwen3VLProcessor"
],
"variant": null
}
],
"reference_image_short_edge": 2048,
"scheduler": [
"diffusers",
"MiniMaxH3Scheduler",
{
"pretrained_model_name_or_path": "./tmp/tiny-random/minimax-h3",
"revision": null,
"subfolder": "scheduler",
"type_hint": [
"diffusers",
"MiniMaxH3Scheduler"
],
"variant": null
}
],
"text_encoder": [
"transformers",
"Qwen3VLForConditionalGeneration",
{
"pretrained_model_name_or_path": "./tmp/tiny-random/minimax-h3",
"revision": null,
"subfolder": "text_encoder",
"type_hint": [
"transformers",
"Qwen3VLForConditionalGeneration"
],
"variant": null
}
],
"tokenizer": [
"transformers",
"Qwen2Tokenizer",
{
"pretrained_model_name_or_path": "./tmp/tiny-random/minimax-h3",
"revision": null,
"subfolder": "tokenizer",
"type_hint": [
"transformers",
"Qwen2Tokenizer"
],
"variant": null
}
],
"transformer": [
"diffusers",
"MiniMaxH3Transformer3DModel",
{
"pretrained_model_name_or_path": "./tmp/tiny-random/minimax-h3",
"revision": null,
"subfolder": "transformer",
"type_hint": [
"diffusers",
"MiniMaxH3Transformer3DModel"
],
"variant": null
}
],
"transformer_ref": [
"diffusers",
"MiniMaxH3Transformer3DModel",
{
"pretrained_model_name_or_path": "./tmp/tiny-random/minimax-h3",
"revision": null,
"subfolder": "transformer_ref",
"type_hint": [
"diffusers",
"MiniMaxH3Transformer3DModel"
],
"variant": null
}
],
"vae": [
"diffusers",
"AutoencoderKLMiniMaxH3",
{
"pretrained_model_name_or_path": "./tmp/tiny-random/minimax-h3",
"revision": null,
"subfolder": "vae",
"type_hint": [
"diffusers",
"AutoencoderKLMiniMaxH3"
],
"variant": null
}
]
}
- Downloads last month
- 17
Model tree for tiny-random/minimax-h3
Base model
MiniMaxAI/MiniMax-H3