self-hosted/ai
§01·recipe · video

MiniMax H3 on RTX 5070: 12 GB, where nvfp4 is native and unused

videoadvanced12GB+ VRAMAug 8, 2026

This advanced recipe sets up MiniMax H3 (Hailuo 3) on the RTX 5070, needing about 12 GB of VRAM.

models
tools
prerequisites
  • You are outside the licence's Excluded Territories — the European Union, the United Kingdom, the Republic of Korea and the United States of America — and note the restriction reaches the video you generate, not only the weights
  • NVIDIA RTX 5070 (12GB VRAM), Blackwell sm_120
  • 32GB system RAM **and** `--disable-pinned-memory` on the launch line; 64GB to keep the 42.47 GB weight set in page cache instead of re-reading it from disk
  • 45GB free space on an NVMe SSD — the four weight files are 42.47 GB and a 12 GB card re-reads most of them every step
  • ComfyUI 0.30.0 or newer, on a CUDA 13 (cu130) build of PyTorch

What You'll Build

A locally generated clip with native stereo audio from MiniMax H3, on a 12 GB RTX 5070, using ComfyUI's dynamic VRAM offloading.

You have probably arrived here with a specific and reasonable idea: the RTX 5070 is Blackwell, the text encoder ComfyUI's template loads is an NVFP4 file, and 4-bit weights on FP4 tensor cores is exactly the kind of thing that ought to rescue a small card. This page exists mostly to take that idea apart, because it is the strongest wrong intuition available about this hardware.

The first half of the answer is that the hardware claim is true. supports_nvfp4_compute() returns True for any NVIDIA device of compute-capability major version 10 or above, and consumer Blackwell reports 12.x — so nvfp4 prints under Native ops in your startup log, where every other 12 GB card in this family prints it under emulated ops. The second half is that it buys you nothing, because the shipped encoder declines its own quantised path in 350 of its 351 layers — a fact you can read out of the file yourself, and one that has nothing to do with which GPU you own. Hardware support is a property of the format. Use is a property of the file.

What actually decides this page is capacity: 39.554 GiB of weights against 12 GiB of VRAM, with a transformer that on its own is larger than the card. Everything below follows from that.

⚠️ Read the licence before you download 42 GB. MiniMax H3 is not open-source. The MiniMax H3 Community License Agreement grants rights only inside its Applicable Territory, and Section I.5 defines the Excluded Territories as "means the European Union, the United Kingdom, the Republic of Korea and the United States of America." Section V.4 reaches past the weights to what you make with them: "You may not use, reproduce, modify, distribute, or display the MiniMax H3 Works or any of their Outputs or results outside the Applicable Territory." — the output video is covered.

The machine-readable license: facet on the model card is the uninformative other, so a catalogue filter or licence scanner keyed on that field sails straight past the territorial clause; it lives only inside the LICENSE file. The Comfy-Org repack this page installs relicenses nothing, and neither does a community re-quantisation, a GGUF or a Turbo LoRA built on these weights — each is a Model Derivative and inherits the terms. MiniMax publishes a licence Q&A and an application route for per-deployment licensing at platform.minimax.io/h3-license. This is a summary written by a reader of the text, not legal advice.

Hardware data: RTX 5070 (12GB VRAM, sm_120) · 39.554 GiB of weights streamed against a 12 GiB card · See benchmark data

ℹ️ 768p is the local ceiling, whatever your card. H3 reaches 2K through a separate H3-Regenerate-2K stage, and the model card says of it: "this module is not yet open-sourced. We will release it once it is ready." — the official route to 2K is an API call back to MiniMax, under their platform terms on top of the weights licence. What runs on your card is H3-Base, which the same card describes as "H3-Base: Generates audio and video based on the H3-Context-IR output, producing results at 768p resolution."

Requirements

ComponentMinimumThis recipe
GPU12GB VRAMRTX 5070 (12GB, sm_120) — no published measurement exists on this card; every timing below names the card it was actually taken on (/contribute)
RAM32GB with --disable-pinned-memory; 64GB to keep the weights in page cache— this is the prerequisite most likely to waste your download; see Running
Storage39.554 GiB of weights (42.47 GB as HuggingFace reports it), NVMe strongly preferred
SoftwareComfyUI 0.30.0+, torchaudio, CUDA 13 build of PyTorch

The four files the official ComfyUI text-to-video template loads, byte-exact from the Comfy-Org repack's tree API:

FileBytesGiBDestination
minimax_h3_fl2va_pruned_int8_convrot.safetensors20,970,379,61619.530models/diffusion_models/
qwen3vl_32b_minimax_h3_nvfp4_awq.safetensors15,687,142,55114.610models/text_encoders/
minimax_h3_video_vae_fp16.safetensors5,207,808,4964.850models/vae/
minimax_h3_audio_vae_fp32.safetensors605,254,8080.564models/vae/

That sums to 39.554 GiB against a 12 GiB card — a 27.554 GiB shortfall. The decimal restatement is 42.47 GB, which is the figure HuggingFace prints and the one to size your disk against.

A word on this page's min_vram_gb: 12, because on this card it reads like a coincidence and is one. That field is a filter floor — the smallest capacity on which the install documented below actually runs — and it is 12 on every NVIDIA page in this family, including the 32 GB one. It happens to equal your card's capacity. Read it as "this is the bottom of the range", not as "this card has what it needs".

What actually gates this card

Not the shader count, and not, in the way you would expect, the 12 GB either. Here is the arithmetic, all of it from comfy/model_management.py at tag v0.30.2 and the byte counts above.

minimum_inference_memory() returns 0.8 GiB plus EXTRA_RESERVED_VRAM, which is 400 MiB on Linux — 1.191 GiB. On Windows the base is 600 MiB, and a further 100 MiB is added under the comment "more extra reserved vram on 16GB+ cards" — but check the indentation before you inherit that number, because it is nested inside the if WINDOWS: block and gated on total_vram exceeding 15 GiB. A 12 GB card is under that threshold, so the Windows floor here is 1.386 GiB, not the 1.484 GiB you will see quoted in write-ups about larger cards — that figure is correct for them and wrong for you. It does not change any verdict in the table below, because both large stages were already short; it is simply the number to use if you re-run the arithmetic yourself.

StageResident weightsComfyUI's reserve (Linux)Stage totalAgainst 12 GiB
Text encode (Qwen3-VL-32B, NVFP4-AWQ)14.610 GiB1.191 GiB15.800 GiBshort by 3.800 GiB
Denoise (the H3 DiT, pruned int8+convrot)19.530 GiB1.191 GiB20.721 GiBshort by 8.721 GiB
Decode (video VAE fp16, 124 frames at 864×480)4.850 GiB1.455 GiB6.305 GiBclears by 5.695 GiB

Only the decode row fits, and its reserve is not a guess — comfy/sd.py ships a first-party estimator for this VAE, (9.5 × frames × height × width + 270,000,000) × dtype_size × 1.03 above 22 frames, which at 124 frames of 864×480 in fp16 gives 1.455 GiB.

The middle row is the page. load_models_gpu sizes the resident weight budget as max(0, free_mem − minimum_memory_required, min(free_mem × MIN_WEIGHT_MEMORY_RATIO, …)), and MIN_WEIGHT_MEMORY_RATIO is set to 0.0 under if is_nvidia() — so the third term vanishes and the budget is free VRAM minus the reserve: at most 10.809 GiB, less once a desktop session has taken its cut, since the comparison is against torch.cuda.mem_get_info and not against the sticker capacity. The transformer is 19.530 GiB and the model card calls it "H3-Omni-Transformer is a 33B-parameter dense, single-stream Transformer" — dense, so every sampling step touches every weight. At least 8.721 GiB of it therefore crosses PCIe on every step, for every step you ask for. The text encoder is short by 3.800 GiB and streams too, which is the one thing a 16 GB card is spared.

Losing more margin is not a cliff, though. With MIN_WEIGHT_MEMORY_RATIO at zero the loader keeps proportionally fewer weights resident and streams the rest; you lose minutes, not the render. That is why the resources that decide whether your run finishes are system RAM, the host link and the SSD — and why every prerequisite on this page after the first one is about the machine around the card rather than the card.

What nvfp4 does not do here — and what int8 does

This is the section that is different on your card, so it is worth doing properly rather than inheriting an answer written for a 3060.

The hardware gate passes. supports_nvfp4_compute() in comfy/model_management.py returns True for any NVIDIA device whose compute-capability major version is 10 or above, and the consumer 50-series reports 12.x — a 5070 Ti in KJNodes issue #723 and a 5060 Ti in #721 are both logged as sm_120. So nvfp4 appears under Native ops in your startup log, which is also how you confirm the card is being detected as Blackwell at all. On a 3060 or a 4070 — the other 12 GB cards in this family — it appears under emulated ops instead. Genuinely different, and genuinely irrelevant, for the following reason.

The shipped file opts out. qwen3vl_32b_minimax_h3_nvfp4_awq.safetensors carries 351 small comfy_quant descriptor tensors, one per quantised layer, each holding a JSON string. You do not have to download 14.6 GB to read them: safetensors puts a JSON header at the front of the file, every tensor's data_offsets are in it, and a descriptor's payload length is just the difference between its two offsets. One range request over the header closes the census completely — no sampling, no inference:

351 descriptors, payload lengths: 350 × 55 bytes, 1 × 29 bytes
  55 → {"format": "nvfp4", "full_precision_matrix_mult": true}
  29 → {"format": "int8_tensorwise"}          (on model.embed_tokens)
input_scale tensors in the whole file: 0

comfy/ops.py reads that full_precision_matrix_mult key straight into module._full_precision_mm, and builds its dispatch predicate as _use_quantized = (… and not self._full_precision_mm and …). With the flag set, the quantised matmul is skipped and the weight is expanded into the compute dtype first — on your Blackwell card exactly as on an Ampere one. The zero input_scale count corroborates it from the other side: activation scales are precisely what an FP4 tensor-core matmul consumes, and the file ships none. Asked in discussion #16 whether nvfp4 was Blackwell-only, Kijai — a Comfy-Org member — said it is not, because "it's just used as storage format here, there's nothing hardware specific about that". The file agrees with him byte for byte.

So take the nvfp4 encoder, and take it for its size. The alternative in the repack, qwen3vl_32b_minimax_h3_int8_convrot.safetensors, is 27,141,342,152 B = 25.277 GiB — 10.668 GiB more to stream on every generation, and 10.668 GiB more staged in host RAM, on a card that already streams both of its large modules. That is the whole argument on this tier, and it does not route through your tensor cores at any point.

The positive half, which is real. Run the same census over the transformer this page installs and it comes back completely different: minimax_h3_fl2va_pruned_int8_convrot.safetensors carries 200 descriptors, all 200 of them 72 bytes of {"format": "int8_tensorwise", "convrot": true, "convrot_groupsize": 256}, with no opt-out on any layer. That file really does take its accelerated path. It is gated not on the file and not on your compute capability but on two things you control at install time: a cu130 PyTorch build, and a comfy-kitchen backend that imports successfully. Get either wrong and the page's whole performance story quietly changes. Installation step 1 is about exactly that.

Installation

1. Update ComfyUI onto a CUDA 13 PyTorch

H3's nodes ship in ComfyUI core (comfy_extras/nodes_minimax_h3.py), not as a custom node, from v0.30.0 onward. That module imports torchaudio at load time, so a hand-built environment carrying only torch and torchvision fails at startup even though requirements.txt covers it.

The CUDA floor is a gate in ComfyUI's own source rather than folklore. comfy/quant_ops.py parses torch.version.cuda, and below 13 it calls ck.registry.disable("cuda") after logging "WARNING: You need pytorch with cu130 or higher to use optimized CUDA operations." That single call removes the comfy-kitchen CUDA backend, which is what supplies the convrot kernels for the int8 weights you are about to download. Nothing errors; everything is simply slower.

Order matters: requirements.txt lists torch unpinned, so running it after a cu130 install resolves a default-index wheel over the top and silently undoes the fast path. Install the CUDA 13 stack last, from its own index.

cd ComfyUI
git fetch --tags && git checkout v0.30.2
pip install -r requirements.txt
pip install --force-reinstall --index-url https://download.pytorch.org/whl/cu130 \
  torch torchvision torchaudio

Before going further, confirm three lines in the startup log: the torch version must contain +cu130; comfy-kitchen's CUDA backend must report 'available': True rather than a failed import; and nvfp4 should be listed under Native ops rather than emulated ones. That third line is how you know the driver and card are being detected as sm_120 — it is a useful sanity check even though, per the section above, nothing in this workflow will use it.

2. Download the weights

pip install -U "huggingface_hub[cli]"

hf download Comfy-Org/MiniMax-H3 \
  diffusion_models/minimax_h3_fl2va_pruned_int8_convrot.safetensors \
  text_encoders/qwen3vl_32b_minimax_h3_nvfp4_awq.safetensors \
  vae/minimax_h3_video_vae_fp16.safetensors \
  vae/minimax_h3_audio_vae_fp32.safetensors \
  --local-dir models

The repo's own paths are already diffusion_models/, text_encoders/ and vae/, so --local-dir models lands all four files where the loaders look. Run it from the ComfyUI directory step 1 left you in. Pointing --local-dir at models/diffusion_models instead gives you models/diffusion_models/diffusion_models/… and a node that cannot see its own weights.

Pass the filenames as positional arguments, as shown. Handing several of them to --include makes everything after the first one positional anyway and drops the flag, with only a UserWarning to say so.

3. SageAttention — there is a live sm_120 bug, and your capacity is what keeps you out of it

Sage attention is the largest speed lever available on this model, and sm_120 is the one architecture with an open, named defect against it. That sounds like a reason to skip it. Worked through properly it is not, and the reason is specific enough to be worth the six paragraphs.

First, two different things share the name. ComfyUI's own --use-sage-attention flag imports exactly one symbol — from sageattention import sageattn, in comfy/ldm/modules/attention.py — and binds optimized_attention = attention_sage. PyPI's newest release is 1.0.6, a py3-none-any wheel: pure Python over Triton, no compiled CUDA kernels, no architecture check anywhere in it. Its sageattn accepts head dimensions of 64, 96 or 128, and H3's is 128 — the transformer's blocks.N.attn.qkv_proj.weight is [21504, 5376], three projections of 7168 = 56 heads × 128 — and the DiT calls optimized_attention(q, k, v, self.heads, mask=None, …). No mask, supported head dimension: the flag reaches H3's self-attention on the stock wheel. KJNodes' MiniMaxH3MemoryEfficientSageAttentionPatch is the other thing. It replaces diffusion_model.blocks.{i}.attn.forward wholesale and cannot run on 1.0.6 at all: nodes/ltxv_nodes.py imports get_cuda_arch_versions and per_warp_int8_cuda from sageattention.core, 1.0.6 defines neither, and the node raises "sageattention is not new enough version or could not determine CUDA architecture, cannot apply MiniMax H3 Memory Efficient Sage Attention Patch." — which is KJNodes issue #721, filed from an RTX 5060 Ti, the same compute capability 12.x as this card.

Second, on sm_120 those two routes converge on the same arithmetic once you install 2.x, and it is the arithmetic with the bug. SageAttention's own dispatcher sends this architecture to sageattn_qk_int8_pv_fp8_cuda(…, qk_quant_gran="per_warp", pv_accum_dtype="fp32+fp16"), with the reason in a comment on the same line: "sm120 has accurate fp32 accumulator for fp8 mma and triton kernel is currently not usable on sm120." KJNodes' H3 patch arrives at the same family by its own route — its sm120/sm121 branch quantises V through per_channel_fp8 and calls into the _qattn_sm89 FP8 kernels. Both are FP8 PV on this card. There is no version of "use the node instead of the flag" that changes that.

Third, the defect. ComfyUI issue #15263 was filed as a missing low_precision_attention=False on H3's attention call — an omission that is genuinely there in comfy/ldm/minimax/model.py, and genuinely not the fault. Its author retracted both the root cause and his own proposed one-line fix on 8 August, having converged with another investigator on the real one: "This lines up with what I've been seeing, and I think you've got it right that FP8 PV is the cause." The issue has been retitled accordingly, for SageAttention's FP8 PV kernels producing noise above roughly 160k tokens on sm_120. If you have read the older framing anywhere — including in the first half of that issue's own body — it is superseded. It is length-gated, and it is a cliff, not a gradient — on a 96 GB RTX PRO 6000 Blackwell running the bf16 checkpoint at 1920×1088, the reporter's own bracket is "And it's a cliff, not a slope. 151k is clean, 167k is garbage, nothing soft in between." Below that line the same install produces clean video and a real speedup; above it, a completed render of pure noise with no warning and no error.

Fourth — and this is why the section ends in a recommendation rather than a warning — a 12 GB card cannot get there. Count tokens the way that thread does, ceil(frames/4) × (W/32) × (H/32):

configurationtokensvs the 151k clean row
the template default, 864×480 / 124 frames12,5558 %
1344×768 (H3's area cap) / 124 frames31,24821 %
1344×768 × 362 frames — H3's area cap at the top of its trained frame range91,72861 %
the reporter's last clean run, 1920×1088 / 294 frames150,960
the reporter's first noise run, 1920×1088 / 328 frames167,280111 %

MAX_PIXELS is 768 * 1344 in comfy_extras/nodes_minimax_h3.py and the trained frame range tops out at 362, so the largest job inside H3's own envelope is 61 % of the lowest number anyone has run clean, and the canvas this page recommends is around 8 %. The failing runs are at 1920×1088, which is 2.02× the model's area cap. One honest caveat on the metric, raised in the thread by the person who built the table: video_latent_t() in that same file returns 107 temporal positions for 362 frames rather than the 91 this formula assumes, so "so it's a consistent metric for comparing runs, but I don't think it's the model's literal sequence length". Recount every row that way and each grows by the same factor — the 61 % is unchanged. The ratio is what survives, and the ratio is the part this page needs.

Fifth, do not try to route around it by pinning an FP16 PV kernel. That workaround is still written at the top of the issue and its own thread has already overtaken it. On 8 August the reporter ran every KJNodes mode at ~186k tokens on sm_120 and none of them survived: sageattn_qk_int8_pv_fp16_cuda gave Fatal Python error: Aborted on the first attention call, sageattn_qk_int8_pv_fp16_triton reached step 2 and died with cudaErrorIllegalAddress, and the FP8 modes crashed or produced noise. His conclusion matches the upstream comment quoted above — "Which is why I don't think pinning an FP16 PV kernel for H3 can work. On sm120 there isn't one to pin." — and the person who had proposed the FP16 route withdrew it the same day: "That kernel table settles the part I had wrong, so let me withdraw the FP16-PV suggestion up front rather than defend it." Pinning a kernel converts a bug you cannot reach into a crash you can.

What about staying on 1.0.6? Arithmetically it is on the clean side of this, and that is a fact about the wheel rather than an opinion: unpack the sdist and there are zero occurrences of fp8, float8, e4m3 or e5m2 across all eleven of its modules. It has one Triton path — INT8 QK, tl.dot(p, v, out_dtype=tl.float16) accumulated into acc = tl.zeros([BLOCK_M, HEAD_DIM], dtype=tl.float32) — which is the same arithmetic class as every clean high-token report in that thread. But the person who verified it clean did so on an RTX 3090, sm_86, and nobody in the thread has run 1.0.6 on sm_120, while upstream's own comment calls Triton unusable on this architecture. So: promising, unverified here, and not something to plan around.

The speed it is worth, measured on this page's exact configuration. In that same issue, a commenter on an RTX 3090 (sm_86), ComfyUI 0.30.1, torch 2.11.0+cu130, sageattention 1.0.6, running minimax_h3_fl2va_pruned_int8_convrot.safetensors at 864×480 / 124 frames / 20 steps on res_multistep+simple with a fixed seed, measured 9.00 s/it without sage against 6.57 s/it through the KJNodes node and 6.50 s/it through the core flag — about 1.37× on sampling either way — and checked the result rather than assuming it: "Output is clean — a normal, coherent video with the audio track intact, visually equivalent to the non-sage run." That is the template configuration this page installs, on the same checkpoint, which makes the ratio about as transferable as a cross-card number gets. It is not a timing for your card: a 3090 is 24 GB and Ampere, and on sm_86 sage 1.0.6 runs the Triton FP16 PV path while your card on 2.x gets FP8 PV.

So, the order to work in. Take a baseline render with no attention patch at all, so you know what correct output looks like on your prompt. Then add sage — the flag is one pip install and needs no build, the KJNodes node needs a from-source 2.x build and buys you nothing on the arithmetic — and look at the frames. Stay inside H3's trained range and its area cap, which is where this page's canvas advice already puts you and which is also where the bug is unreachable. The length widget will take 3600 frames if you insist, so the envelope is a convention rather than a wall; leave it and you are in genuinely untested territory in more ways than one.

If you do build 2.x for the KJNodes node, there is a separate unresolved report on your architecture worth knowing about first. KJNodes issue #723, from an RTX 5070 Ti on sm_120 with cu130 and sageattention 2.2.0, has the patch applying cleanly and then failing on repetition — "Runs 1-3 complete clean (~140s each), run 4 aborts mid-sampling", escalating to a driver-level timeout that takes the GPU out until reboot. Open, no maintainer reply, one machine. If you want the build anyway, note that on Linux it is the only route: PyPI's release index stops at 1.0.6 and that artifact is a py3-none-any wheel with no compiled kernels in it at all, while the fork that does ship binaries — woct0rdho/SageAttention — calls itself in its own title a "fork for Windows wheels and easy installation", builds against MSVC and the Windows SDK, and explains that "We cannot publish the wheels to PyPI, because PyPI does not support multiple PyTorch/CUDA variants for the same version of SageAttention." So, from source:

pip install ninja packaging
CUDA_HOME=/usr/local/cuda-13.2 PATH=/usr/local/cuda-13.2/bin:$PATH \
TORCH_CUDA_ARCH_LIST=12.0 MAX_JOBS=8 \
pip install --no-build-isolation "git+https://github.com/thu-ml/SageAttention.git"

--no-build-isolation is mandatory — without it pip pulls a second torch into the build and wrecks the environment. Once built, a direct from sageattention.core import _qattn_sm89 can still fail while the node itself works, and that is the design rather than a broken build: _resolve_qattn() in nodes/ltxv_nodes.py probes three locations in turn — sageattention.core._qattn_sm89, sageattention.core.sm89_compile, then the sageattention.sm89_compile module — and takes the first one that exposes qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf. Do not chase that import error; check whether the patch applied.

One thing not to expect from any of it: a lower VRAM ceiling — and the honest form of that sentence is now weaker than it used to read. The KJNodes node advertises reduced peak VRAM. The only node-by-node VRAM comparison ever published on this model was withdrawn by its own author on 8 August (see the note under VRAM usage), so nothing surviving confirms or refutes the claim on any card, and nothing has ever measured it on 12 GB. Treat the node as a speed lever rather than a capacity one, and if you do measure it, /contribute is where it would go.

4. Load the official template

Open ComfyUI, go to Template Library, and pick MiniMax H3 Text to Video, or drag in video_minimax_h3_t2v.json. It wires exactly the four files above, at 20 steps with sampler res_multistep and scheduler simple. The ComfyUI tutorial documents this template plus the image-to-video and reference-to-video variants.

Running

Start ComfyUI with two flags, not zero. On a 32 GB machine the default launch is the failure case rather than the baseline, and on a Blackwell card under Windows there is a second, unrelated reason.

python main.py --disable-pinned-memory --disable-async-offload

The first flag is about host memory, and it is the single most likely reason a reader of this page never gets a video out. ComfyUI page-locks host memory to speed up transfers to the GPU: MAX_PINNED_MEMORY is 90 % of system RAM on Linux and 40 % on Windows, and pinned_hostbuf_size() sizes the per-model buffer at twice the model size. For the 19.530 GiB transformer that is a 39.060 GiB request. Pinned pages can be neither swapped nor reclaimed, so on a 32 GB machine the kernel's only remaining move is to kill the process. That arithmetic is the entire reason the flag is in the launch line, and it needs no measurement to hold — but it has one. A 15-second RTX 3090 write-up ran the same model and the same 362 frames twice on a box with 31,997 MB of RAM, changing only this flag: 29,866 MB of host RAM on defaults, killed by the kernel OOM-killer, against 7,508 MB with --disable-pinned-memory, completed in 23 min 17 s. A 24 GB Ampere card rather than your 12 GB Blackwell one, which is exactly why it transfers: pinning is sized from the transformer and your system RAM, never from your VRAM. He derives the same MAX_PINNED_MEMORY = ram * 0.90 line independently. A weaker second report agrees in direction — on the repack's discussion #6 a 5070 Ti owner posting as UdonJP logs a 45.4 GiB resident set with no flags on this page's exact four files, one person and one job, with his own limit attached: "I have not verified any of this on an actual 16 GB or 32 GB RAM machine — it is inference from a 125 GB box."

So what the flag saves is measured; what it costs in time is not, and the reason is structural — nobody has published a completed run on both sides of it, because the unflagged run is the one that gets killed. Any percentage you have read for this flag came from a write-up its author withdrew as unverified (see the note under VRAM usage), and it is deleted here rather than hedged. The mechanism is not in doubt even so: with 125 GiB of RAM the 42.47 GB weight set sits in page cache whether or not it is page-locked, so unpinning changes only where the bytes live; with 32 GB it cannot be cached, so the streaming this card cannot avoid arrives off the SSD instead of out of RAM. Take the flag at 32 GB regardless — the alternative is not a slower render, it is the OOM killer — and put the weights on the fastest NVMe you own. At 64 GB you keep both the flag and the page cache, which is why the Requirements row says 64 GB rather than 32.

The second flag is specific to your architecture and does not appear on this family's pre-Blackwell pages. ComfyUI issue #15337 reports the official H3 image-to-video template killing the whole process with a native access violation during video VAE decode, on an RTX 5070 Ti — Blackwell sm_120 under Windows WDDM, cu130, 48 GB RAM — with default flags and again with --disable-async-offload alone. Only the pair cleared it: "full success, prompt executed in 155 s". The report is open, community-filed and from a single machine, so read it as a cheap precaution rather than a certainty; on Linux you may never meet it. --fast-disk attacks the pinned-memory problem from the other end, moving weights into reclaimable page cache — comfy/cli_args.py describes it as "Prefer disk-backed dynamic loading and offload over unpinned RAM." — read that as an alternative rather than a second dose. Whether it adds anything on top of --disable-pinned-memory has never been measured: the only published --fast-disk figure is discussion #6's, taken with pinning still on, and nobody has run the two together. Do not reach for --lowvram: its own help text in that file says "Doesn't do anything if dynamic vram is enabled."

Set the canvas down. On this card it is the biggest lever you have.

Queue the template unchanged first, and know that "unchanged" is not what the generation node's widgets say. Its width and height are wired inputs fed by a ResolutionSelector set to 16:9 at 0.4 megapixels with a multiple of 32, and a connected input beats a stored widget — so the 1344×768 sitting in the node's widgets never reaches the sampler and you get 864×480. Frame count is snapped onto a 17k+5 grid by the template's own math node, so a 5-second request becomes 124 frames; the node's tooltip gives the trained range as 124-362.

The template ships its own megapixel reference table, and every canvas anyone has reported on a 12 GB card is a row in it:

megapixels16:9 outputreported at this canvas — and on which card
0.4864 × 480the template default. The 155 s i2v run in issue #15337 (RTX 5070 Ti 16GB) and the 4.5-minute 8-step Turbo run below (RTX 3060 12GB)
0.5960 × 544a working ref2va run on an RTX 3060 12GB, reported in discussion #16
0.981344 × 768H3's native canvas — BASE_SHORT_EDGE is 768 and MAX_PIXELS is 768 * 1344 in comfy_extras/nodes_minimax_h3.py
1.01376 × 768the 20-minute run below (RTX 3060 12GB) — one row above the model's own cap

Stay at 0.4 while you are still iterating. The cost curve is steeper than pixel count alone suggests, because on a card under permanent offload pressure every extra token is both more arithmetic and more weight traffic across the bus. The owner of both 3060 runs below put it plainly in discussion #30: "render times grow exponentially as the resolution, video length, and the number of steps increase". Frame count is the other half of the same lever — 124 frames is five seconds and 362 is fifteen — and expect the longer clip to cost considerably more than the 2.9× its frame count suggests. Nobody has published an exponent for this model that survives checking, so measure your own two points before you plan a long job.

Output lands in ComfyUI/output/video/ as an MP4 with the stereo track already muxed in.

Results

  • Speed — no RTX 5070 measurement exists, and this page will not invent one. Our catalogue holds none either: /check/minimax-h3/rtx-5070 returns verdict: unknown with an empty benchmark list. What exists sits on either side of this card, and the honest thing is to say which side each number is on.

    From below, on capacity's twin: an RTX 3060 12GB owner reported in discussion #30"RTX 3060 12GB | T2V | 1376x768 | 24 steps | 3 sec (20 min was crazy!)" — twenty minutes for three seconds near the native canvas, and separately, in that thread and again in discussion #35, "Everything was tested on an RTX 3060 12GB. Rendering a 5-second video at 864x480 resolution with Turbo at 8 steps took 4.5 minutes." Same capacity, two generations older. Both are pessimistic bounds your card should beat, but do not scale them by a shader-throughput ratio: at 8.721 GiB of transformer permanently off-card the clock is set by how fast bytes reach the GPU, and a newer GPU does not by itself widen the host link or speed up your SSD.

    From above, on architecture's twin: an RTX 5070 Ti 16GB — Blackwell sm_120, cu130, Windows, 48 GB RAM — ran the official template at its stock 0.4 MP / 5 s / 20 steps in issue #15337, where run 3 logged "sampling succeeds (~6.8 s/it, so the cu130 optimized kernels work fine)" and run 4 gave "full success, prompt executed in 155 s". Read those as two different things: the first is a per-sampler-iteration rate as the tqdm bar reports it, the second is the whole job. Two caveats before you use either. It is the image-to-video template rather than the text-to-video one installed above — same four files, same defaults, a different conditioning path. And note what that card has that yours does not: at 16 GiB the text encoder clears the reserve by 0.200 GiB and genuinely becomes resident — on the repack's discussion #6, UdonJP sampled a 5070 Ti at one-second intervals and logged "24.1 GiB after TE load (VRAM 15,219 MiB, 100% util = encoding)", one person's trace putting the encode reading within 259 MiB of the encoder's staged size — while at 12 GiB it is 3.800 GiB short and streams like everything else. So 155 s is an optimistic bound, with the extra cost on your card landing mostly in the encode stage — and it is one machine, one run, filed in a bug report rather than a benchmark.

    Your card sits between those two, and neither is a prediction. A measured run posted through /contribute would replace this entire bullet, and it is the single most useful thing missing here.

  • VRAM usage: 20.721 GiB of demand at the binding denoise stage — 19.530 GiB of int8 transformer weights plus ComfyUI's 1.191 GiB inference reserve floor — against a 12 GiB card, so at most 10.809 GiB is resident and at least 8.721 GiB streams. The text-encode stage is 15.800 GiB and is short by 3.800 GiB, so it streams too. Both figures are derived from on-disk byte counts and ComfyUI's own constants, not measured. For scale, the nearest published measurements are one tier up on a 16 GB RTX 5070 Ti, they are whole-run peaks, and as of this writing there are exactly two of them: on the repack's discussion #6, UdonJP reports "VRAM peak was 14,197 MiB for 30 s @ 640x480 and 14,437 MiB for 5 s @ 1344x768" — one person, one machine, carrying his own caveat that "it is inference from a 125 GB box." No published trace for this model decomposes a peak by stage, on any card.

    A fuller write-up used to stand behind those two numbers and no longer does. Its author withdrew the whole document on 2026-08-08, stating that its content could not be vouched for, so the accelerator-by-accelerator peak table and the wider peak band that circulated out of it have been removed from this page rather than pinned to a commit — a pin preserves checkability, not truth. If you meet a node-by-node VRAM table for H3 elsewhere, that is where it came from. What the two surviving readings still show is the only part this page needs: both exceed a 12 GiB card outright, which is the cleanest available evidence that this card must offload rather than fit — and that it does not simply OOM is the point of the page. Live data, when it exists, will be at /check/minimax-h3/rtx-5070.

  • Quality notes: the model's known weakness is faces, and it is a property of the model rather than of your card — no canvas or capacity buys you out of it. The RTX 3060 owner quoted above opened discussion #30 with "MiniMax heavily distorts faces on wide shots. Distortions happen regardless of input res (even at 720p, very bad). Close/medium shots look fine!" and reported the same artefacts after re-testing higher. Frame for close and medium shots. On accelerators, keep one habit whatever any table tells you: judge an attention patch by watching the frames, not by a pixel-difference score against a baseline. A difference score separates changed from unchanged; it does not separate working from broken, and on this model the failure mode is a completed render that looks like a successful one.

For the full benchmark data, see /check/minimax-h3/rtx-5070.

Optional: the fp8 transformer, which is a real fork on this card

The repack ships a second pruned transformer, minimax_h3_fl2va_pruned_fp8_scaled.safetensors, at 20,958,205,608 B = 19.519 GiB. That is 11.61 MiB smaller than the int8 file — the same memory, to a rounding error — so on a card this size the swap costs nothing and buys nothing in capacity. What differs is which kernels run, and on Blackwell both files have a live fast path:

  • int8_convrot: 200 descriptors, none carrying an opt-out, dispatching through comfy-kitchen's convrot kernels on a cu130 build.
  • fp8_scaled: 200 descriptors, of which 150 are a bare {"format": "float8_e4m3fn"} and 50 — every block's mlp.fc2 — carry full_precision_matrix_mult. It also ships 150 input_scale tensors that the int8 file has none of. supports_fp8_compute() returns True from compute capability 8.9 upward, so on sm_120 those 150 layers take a native FP8 matmul; on an Ampere card they would be forced back to full precision.

Nobody has published a comparison. The question was put directly to the repack's maintainer in discussion #29 by a 4090 owner asking whether fp8_scaled suited his card better than int8_convrot, and it went unanswered in that thread. So keep int8_convrot as the lead — it is what the official template references and what every published report on this model used — and treat fp8_scaled as an unmeasured experiment you are well placed to run. Temper your expectations while you do: with the transformer permanently 8.721 GiB off-card, the arithmetic format is close to the least of what decides your wall clock.

Optional: the 8-step Turbo path

Step count is the largest single lever on a streaming-bound card, which makes few-step LoRAs more interesting here than on a 24 GB card. larryvrh/MiniMax-H3-Turbo-Lora and its companion node pack Larryvrh/ComfyUI-MiniMax-H3-Turbo appeared on 5–6 August 2026, and the drbaph/MiniMax-H3-Turbo-Lora-ComfyUI conversion of the same weights is the variant that loads against the pruned checkpoint this page installs.

The fastest published figure on a 12 GB card comes from that path — the 4.5 minutes for five seconds at 864×480 quoted in Results — and it is an RTX 3060 12GB run that changed three things away from stock at once: the Turbo LoRA, a third-party node pack, and Kijai's experimental int8 video VAE, which needs a ComfyUI newer than the v0.30.2 tag installed above. One run, one person, three non-stock components. On Blackwell specifically, the only sign that the Turbo path runs at all is incidental: the reporter in KJNodes #723 was driving an H3 turbo workflow on a 5070 Ti when it crashed, and states no canvas, step count or clip length — so his ~140 s is evidence the configuration executes, not a timing you can use.

Follow this if you are willing to run experimental components; do not plan a schedule on it. Note too that an adapter's permissive licence tag covers the adapter — the base weights it loads against stay under the territorial agreement at the top of this page.

Troubleshooting

ComfyUI is killed, or throws MemoryError, while loading the model

System RAM, not VRAM, is what usually ends an H3 run on this tier, which is why --disable-pinned-memory is in the launch command rather than here. If it dies during the model load even with the flag set, grep the startup log for the line Enabled pinned memory — if it is present, the flag did not take effect. Adding swap does not help on its own, because pinned pages cannot be paged out. Useful arithmetic while you size a box: the startup log prints what each module stages — the … MB Staged line in comfy/model_patcher.py — and that figure tracks the file on disk rather than an expanded copy, because the per-module size it accumulates is measured on the QuantizedTensor itself wherever a weight is quantised. Weights are staged in host RAM at their quantised size. A worked instance sits in discussion #36, where a pasted log reads 25882MB Staged for the int8 text encoder — a file that is 25,884 MiB on disk.

A MemoryError raised specifically by UNETLoader has a second, duller cause worth eliminating first — a truncated download that is the right byte size and the wrong hash. A user who hit exactly that on this repack came back two days later with "So it was really failed download, same size, but different hash." Re-hashing a 21 GB file is cheaper than re-diagnosing it.

The whole process dies with an access violation during VAE decode

That is the Blackwell-specific failure in the launch line above, reported at ComfyUI issue #15337 from an RTX 5070 Ti on Windows. It is a native crash rather than a Python exception, so there is no traceback to read. --disable-async-offload --disable-pinned-memory together cleared it there; neither alone did.

The sage patch refuses to load

Check pip show sageattention first. If it says 1.0.6 you have the PyPI package, which cannot satisfy the KJNodes path on any architecture — see Installation step 3, and note that SageAttention 3 installs under a different package name (sageattn3) that --use-sage-attention does not resolve. Separately, advice to "update ComfyUI to 0.31" circulates and is wrong: no such release exists, and v0.30.2 was the newest tag when this page was written.

The render completes and every frame is noise

Check the token count before anything else, and check whether sage is in the graph. This is the sm_120 FP8 PV failure in ComfyUI issue #15263: it produces a completed render of pure noise, in the video and the audio, with no warning and no exception. Per the table in Installation step 3 it needs roughly 160k tokens to appear, which a 12 GB card working inside H3's canvas and frame limits does not reach — so if you are seeing it, the first question is whether you have pushed length past the trained 362 frames or set a canvas well above the 768×1344 area cap. Turning sage off entirely is the reliable fix on this architecture; pinning a different sage kernel is not, for the reasons in that step. The issue is open and the fix is expected to be arch-aware rather than a blanket opt-out, so re-check it before assuming the state described here still holds.

Generation is far slower than the numbers above

Two lines in the startup log decide this, and both fail quietly. Grep for a comfy_kitchen import failure and for the cu130 warning quoted in Installation step 1; either one takes the int8-convrot kernels out of play while ComfyUI keeps running as though nothing happened. Per the census above, that transformer has no per-layer opt-out — the only way it ends up on a slow path is one of these two environment faults, so check them before you conclude the card is at fault. The same log is where you confirm the reverse: nvfp4 under Native ops tells you sm_120 was detected, even though nothing here will use it.

VRAM readings that make no sense, or a peak you cannot reproduce

Poll faster before you theorise. This workload's peak is short and stage-bound, so a five-second nvidia-smi interval can miss it outright and hand you a reading in which a larger canvas appears to use less VRAM than a smaller one. Sample at one- to two-second intervals: the only published trace on this model that resolves stage boundaries at all — UdonJP's in discussion #6 — was taken at one second, and it is what makes its 15,219 MiB encode reading legible as an encode reading.

You have a second GPU in the machine

Dynamic VRAM streaming has an open multi-GPU failure — HostBuffer.read_file_slice failed cascading into a spurious CUDA out-of-memory — tracked at ComfyUI issue #15255, where the maintainers' note says it has been reported to NVIDIA and gives --cuda-device 0 or --disable-pinned-memory as the workaround. The second of those is already your launch line.

You want 2K output

You cannot get it locally today. See the note at the top: H3-Regenerate-2K is not part of the open-weights release, and the official route to 2K is to feed your local 768p result back to MiniMax's hosted API — a call that falls under the same territorial licence.

Nothing here matches your problem

Runtime errors belong at ComfyUI/issues, template problems at workflow_templates/issues, and attention-patch problems at ComfyUI-KJNodes/issues. And if you get a clean run on this card, a timing sent through /contribute is worth more to the next reader than every derived number on this page — no RTX 5070 run on this model surfaced anywhere this page could search — not in the repack's 36 discussion threads, not in the ComfyUI or KJNodes trackers, not in either of the two independent write-ups — and one stock-path 864×480 run would change that.

common questions
How much VRAM does MiniMax H3 (Hailuo 3) need?

About 12 GB — the minimum this recipe targets.

Which GPUs is MiniMax H3 (Hailuo 3) tested on?

RTX 5070 (12 GB).

How hard is this setup?

Advanced — follow the steps above.