TensorScale MiniMax H3 Video (Soze)
Text, first-frame, or bookended
- first_image
- last_image
- video
- video_path
- request_id
- config
- status
MiniMax H3 is one of the few frontier video models that comes back with a real audio track baked in - speech, foley, and music generated alongside the picture. This node serves it through TensorScale, an inference service that works differently from the FAL nodes: instead of polling for a job, it holds the connection open and streams the finished clip straight back. One POST, one file, no job ID juggling.
The inputs that matter
The required set is small: prompt, duration_seconds, aspect_ratio, and seed. The prompt describes the whole scene including what it sounds like - that's the H3 twist. "A train pulls into a rainy station; announce the arrival over the PA" is the shape of a prompt that uses the model's full capability.
duration_seconds(1–60) gets snapped server-side to H3's native 24 fps / 17n+5 frame boundary, so don't expect a clip of exactly 8.0 seconds.aspect_ratioruns from4:1ultrawide to1:4tall; 16:9 renders at 1344x768, 1:1 at 768x768. A free-formaspect_ratio_override(e.g."2:1") replaces the dropdown if you need something in between.
The optional framing inputs are where H3 gets interesting. Leave both empty and you get pure text-to-video+audio. Connect first_image and it becomes the opening frame (stretched to the canvas). Add last_image too and you've bookended the clip - H3 animates between your two endpoints, the first/last-frame (FL2VA) mode. URLs in first_image_url/last_image_url override the sockets.
Then the tuning knobs, all optional: num_inference_steps (native profile is 50), flow_shift (video scheduler, profile wants 12.0), audio_flow_shift (audio scheduler, profile wants 3.0). The defaults match the service profile - leave them alone until you have a reason not to.
How it works
TensorScale's model-scoped API means your key must carry the minimax-h3 scope, and it's read from the env var named by api_key_env (default TENSORSCALE_API_KEY_MINIMAX_H3, falling back to TENSORSCALE_API_KEY). The node POSTs to /v2/MiniMax-H3/fl2va and the socket stays open for the whole generation - the timeout widget (default 1800s) is a read timeout, so long clips legitimately take minutes.
The critical gotcha: the request body is capped at 10 MiB, and connected images are inlined as base64 data URIs by default. A couple of hi-res PNGs can bust the cap. If you're feeding frames, flip use_fal_upload on - it pushes the media to FAL's CDN and sends URLs instead (which means that toggle needs a working FAL_KEY even though the generation is TensorScale).
Outputs: video (the VIDEO object - preview or save it), video_path (where the mp4 landed), request_id, config (a summary string of what ran), and status.
Install and key
From the Soze pack ("Quality of Life Nodes for ComfyUI"), via ComfyUI Manager or:
cd ComfyUI/custom_nodes
git clone https://github.com/SozeInc/ComfyUI_Soze.git
pip install -r ComfyUI_Soze/requirements.txt
Restart, then set TENSORSCALE_API_KEY (or the model-scoped TENSORSCALE_API_KEY_MINIMAX_H3) as an environment variable or in a .env file in the repo root. Never commit it.
Common issues
- "Request body is X MiB, over TensorScale's 10 MiB limit." Your reference frames are being inlined. Turn on
use_fal_uploador use URL widgets. - Clip length isn't what you asked for. H3 snaps to its frame grid - 8.0s comes back as whatever 17n+5 lands nearest. That's the model, not a bug.
use_fal_uploadfails. It needsFAL_KEYconfigured even though this is a TensorScale call - the upload hop goes through FAL's CDN.
Inputs (16)
| Name | Type | Default | Description |
|---|---|---|---|
| prompt | STRING | — | |
| duration_seconds | FLOAT | 5.01–60 | Target length. Aligned server-side to the 24 fps / 17n+5 frame grid. |
| aspect_ratio | COMBO | 16:9 | 8 options: 16:9, 9:16, 1:1, 4:3, 3:4, 21:9, +2 |
| seed | INT | 11010–4294967295 | — |
| first_imageopt | IMAGE | Optional first-frame anchor. | |
| last_imageopt | IMAGE | Optional last-frame anchor. Pair with first_image for FF/LF. | |
| first_image_urlopt | STRING | Public HTTPS URL. Overrides the first_image socket. | |
| last_image_urlopt | STRING | Public HTTPS URL. Overrides the last_image socket. | |
| aspect_ratio_overrideopt | STRING | Any W:H from 1:4 to 4:1, e.g. '2:1'. Replaces the dropdown when set. | |
| num_inference_stepsopt | INT | 502–200 | Scheduler points. The native profile uses 50. |
| flow_shiftopt | FLOAT | 12.00–50 | Video scheduler flow shift. The service profile requires 12.0. |
| audio_flow_shiftopt | FLOAT | 3.00–50 | Audio scheduler flow shift. The service profile requires 3.0. |
| use_fal_uploadopt | BOOLEAN | false | Upload connected images to FAL's CDN and send URLs instead of inline base64. Keeps the body under the 10 MiB cap. |
| image_formatopt | COMBO | PNG | Encoding used for inline data URIs. |
| api_key_envopt | STRING | TENSORSCALE_API_KEY_MINIMAX_H3 | Environment variable holding the model-scoped key. Falls back to TENSORSCALE_API_KEY when unset. |
| timeoutopt | INT | 180060–7200 | Read timeout in seconds. These endpoints are synchronous — the socket stays open for the whole generation. |
Outputs (5)
| Name | Type | Description |
|---|---|---|
| video | VIDEO | — |
| video_path | STRING | — |
| request_id | STRING | — |
| config | STRING | — |
| status | STRING | — |