YAML Metadata Warning:empty or missing yaml metadata in repo card

Check out the documentation for more information.

About this repository

Just to be clear, this VAE currently has a lower result than the original VAE; you can read more details on HF. Also, this conversion was experimental and may not be working as it should.

This is a copy of iamkaikai/MiniMax-H3-Single-Frame-VAE-500K. All model weights, the training work and the results are by the original author; nothing here was retrained or improved. This mirror exists only to add two things:

  1. Loader nodes that read the author's original file, unmodified, inside ComfyUI.
  2. ComfyUI-ready .safetensors β€” the same decoder, converted to the key layout ComfyUI expects, for anyone who prefers a single file over two inputs.

You do not need the converted files. With the MiniMax-H3 Single-Frame VAE Loader node you can point straight at minimax_h3_single_frame_decoder_500k.safetensors downloaded from the original repository β€” the node pairs it with the official H3 VAE and does the key translation in memory. The converted files are a convenience, not a requirement.

If you use diffusers, ignore this repo and use the original β€” the author's load_decoder.py is all you need.


Why a conversion is needed at all

The published checkpoint is decoder-only (585 tensors: decoder.* + post_quant_conv.*) and uses diffusers naming. That is correct for the author's intended flow, which loads a complete H3 VAE and replaces two submodules:

vae.decoder.load_state_dict(decoder, strict=True)
vae.post_quant_conv.load_state_dict(post_quant_conv, strict=True)

ComfyUI has no equivalent "replace one submodule" step β€” its VAELoader builds a VAE from the file. Worse, detection in comfy/sd.py requires an encoder key:

elif "decoder.transformer_blocks.0.scale1" in sd and "encoder.down.5.block.0.conv1.weight" in sd:

A decoder-only file fails that test, so ComfyUI logs No VAE weights detected, VAE not initalized, leaves first_stage_model = None and falls back to Stable Diffusion geometry β€” 4 latent channels and 8x upscale, against H3's 24 channels and 32x. The result is blocky garbage. It is not a bug in ComfyUI and not a defect in the checkpoint; the two simply have different contracts.

What the conversion does

Renames diffusers β†’ ComfyUI, and fills in what a decoder-only file cannot carry (encoder.*, quant_conv, latents_mean/std, mask_token) from the official H3 VAE. That graft is exactly what the author's own script does, and it is sound because the author froze the encoder during training β€” the official encoder is the one this decoder was trained against.

Two of the transforms are not derivable from the names, and getting either wrong produces wrong output with no loading error. Both were settled by measuring correlation against the official VAE:

transform evidence
to_qkv is interleaved per head (32 heads, 3, 64 dim_head), not stacked [q;k;v] matches qkv.view(B, S, -1, 3*dim_head) in comfy/ldm/minimax/vae.py; correlation 0.998
ff.w1 halves are swapped relative to diffusers (ComfyUI reads gate first) correlation: straight βˆ’0.013, swapped +2.00

Validation. Same latent, raw decoder call on both sides β€” the author's diffusers path with the original file, against the converted file in ComfyUI: 72.92 dB PSNR, i.e. fp16 noise. Key check: 0 missing, 0 unexpected.

The tile size matters more than anything else

ComfyUI's MiniMaxH3VideoVAE tiles internally with a constructor default of tile_size=256, and the stock VAELoader does not expose that field. 256 is the worst value. Measured on a 1056x640 image, where "seam" is edge energy at tile boundaries relative to the image average (1.0 = invisible):

tile_size PSNR seam
256 (ComfyUI default) 22.17 dB 1.49 β€” visible
512 26.00 dB 0.91 β€” invisible
768 23.27 dB 1.71
1024 21.35 dB 2.42

512 is not arbitrary: the author trained 475k of the 500k images at ≀512px (250k@256 + 150k@384 + 75k@512), so 512-wide tiles keep every piece inside the regime that has training mass. Larger tiles push the decoder past what it saw; smaller ones multiply seams.

Turning tiling off is also wrong above ~768px β€” the patches stop agreeing and a 32px grid appears (block ratio 2.94 at 1024, 3.45 at 1536, against ~1.5 with tiling).

So: tiling on, tile_size 512.

Using it in ComfyUI

The nodes are part of ComfyUI-BFSNodes (v1.24.0+):

Option A β€” the author's original file, nothing converted (recommended if you want to stay on the upstream weights):

MiniMax-H3 Single-Frame VAE Loader

  • base_vae β†’ the official MiniMax-H3 VAE (the complete one, with encoder)
  • single_frame_decoder β†’ minimax_h3_single_frame_decoder_500k.safetensors, straight from the original repository
  • tiling: True, tile_size: 512

The node detects the diffusers naming, converts it in memory and grafts the missing encoder from base_vae. Nothing is written to disk and the original file is untouched β€” its SHA-256 still matches, so the author's load_decoder.py keeps working with it.

Option B β€” a converted file from this repo (one input instead of two):

MiniMax-H3 VAE Loader / tile control

  • vae_name β†’ minimax_h3_single_frame_500k_comfy.safetensors
  • tiling: True, tile_size: 512

Both paths produce bit-identical output (120 dB).

Then plain VAEEncode / VAEDecode in both cases.

fp16 and fp32 also decode bit-identically here β€” ComfyUI runs this VAE in fp16 either way, so the fp16 file is the sensible one and the fp32 is provided only to remove the doubt.

Limitations (unchanged from the original)

Everything the original card says still applies β€” this is the same decoder. In particular it is single-frame only: decoding a clip slice by slice, frame-to-frame flicker measured 2.6x the original, and each latent slice decodes 4 frames of which only the last is valid (hence decoded[:, :, -1] in the author's example). Fine texture is smoothed, and dense thin lines can moirΓ©.

Credit and license

All credit to iamkaikai. Same license as the original repository.

Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support