Tomo
Add DMAD Turbo LoRA with its four-step re-noise sampler
f8655ba
|
Raw History Blame Contribute Delete
31.7 kB

A newer version of the Gradio SDK is available: 6.31.0

Upgrade
metadata
title: MiniMax H3 Turbo LoRA
emoji: 🎬
colorFrom: purple
colorTo: indigo
sdk: gradio
sdk_version: 6.20.0
app_file: app.py
pinned: true
short_description: Video generation with a synchronized soundtrack
suggested_hardware: zero-a10g

MiniMax-H3 — video and synchronized audio across two Spaces

This Space generates video and its soundtrack using the public MiniMaxAI/MiniMax-H3 checkpoint. The transformer runs in bfloat16 without quantization; the video and audio VAEs stay in float32. The latter is intentional: the released autoencoders declare _keep_in_fp32_modules, and forcing the audio VAE to bf16 affected volume in the original deployment's tests.

The local pipeline contains the transformer, two VAEs and schedulers. A remote qwen3vl-conditioner Space produces the text and image embeddings for every request, including when prompt upsampling is disabled. Prompts and uploaded keyframes or reference media are therefore sent to that service; cloning this repository does not create an offline application. Mixed-reference mode reuses the current FL2VA weights and is experimental; it does not download the separately trained transformer_ref checkpoint.

Generation and API

The English-language studio has two input modes: Basic / keyframes for text with an optional first and/or last image, and Mixed references for multiple images, videos and audio files together. Outputs are an MP4 with synchronized audio, a timing/settings report, and the rewritten prompt when requested. Turbo acceleration and ordinary style/character LoRAs have separate controls.

The UI shows service readiness, upload previews, queue state, elapsed time and actionable errors. Settings lock while a request runs. Prompt and non-file settings, including ordinary LoRA sources and strengths, are saved in this browser's local storage; file selections are not restored after a reload. Each page entry selects an available Turbo adapter and its suggested steps from the server, replacing old saved Off/step defaults. Explicit changes within the open page, including Off, are respected. The last successful settings can be reused, and output settings can be downloaded with the result. Mode changes remember each mode's sampling choices within the page. Turbo choices supply suggested steps, with a button to restore that suggestion after manual changes. Cancel cancels waiting for the request; a running GPU job may continue and is not guaranteed to stop immediately.

Setting Current behavior
Canvas 16 presets; Basic mode matches each newly uploaded first frame to the closest supported aspect ratio, preferring the smaller canvas on a tie; otherwise defaults to 960x544 · 16:9 fast
Aspect ratios Landscape, portrait, square, 4:3, 3:4 and 21:9; the exact labels come from /studio-config
Duration slider 2–14 seconds, default 5 seconds
Output frame rate 24 fps
Output frame count Rounded up to 17 * n + 5; requested 2 / 5 / 14 seconds become 2.333 / 5.167 / 14.375 seconds
Sampling steps Slider 2–40; both modes default to premerged Larry v4 at 6 unless the deployment selects another startup adapter
Prompt upsampling Optional remote prompt rewrite, not video upscaling
Negative prompt / CFG No controls exposed by this application

The app lowers the upstream pipeline's five-second minimum to permit short clips. API requests validate the same 2–14 second and 2–40 step limits, a nonempty prompt and a non-negative integer seed up to 2**53 - 1. Uploaded keyframes are EXIF-oriented, converted to RGB and center-cropped to the selected canvas in temporary copies. In the UI, first-frame dimensions are read locally with EXIF orientation; automatic matching does not call the conditioner or book a GPU. Manual Canvas changes after upload are retained. The last frame does not choose the canvas, and Mixed references keeps its selected canvas. Arbitrary source ratios can still require cropping to the nearest supported preset. API callers continue to pass an explicit canvas, even with two keyframes. Each keyframe is limited to 128 MiB and 40 million pixels.

index.html is a custom frontend served by gradio.Server. @app.api(name="generate") retains Gradio's queue, SSE events, concurrency handling, ZeroGPU bookings and gradio_client compatibility. The custom routes are /status and /studio-config; the latter also advertises modes, per-mode defaults and reference/LoRA limits. Gradio owns /config; replacing it would break client discovery. The single app.launch() listens on 0.0.0.0:7860, shows errors and allows Gradio to serve files from OUTPUT_DIR.

The /generate API accepts lora="larry", "larry_v4", "lightx", "dmad" or "off". An explicit selection takes precedence over the legacy use_lora boolean. In Basic mode, with lora="", use_lora=True selects larry and False selects off, preserving older clients. Reference mode with an empty lora uses the available startup Turbo adapter when use_lora=True, or off when false. An unknown explicit name is an error. API calls keep the supplied steps value; the frontend reads each loaded adapter's suggested steps and display name from /studio-config, and updates the step slider both on initial load and when switching adapters.

Mixed-reference input

Set /generate's mode="reference" and supply reference_images, reference_audios and reference_videos as lists of Gradio FileData uploads (gradio_client.handle_file(...) for clients). Do not combine them with Basic mode's image_path or last_image_path. At least one image or video is required; independent audio alone is not accepted. Reference files can be combined in one request under these limits:

Input Limit
Still images Up to 9; at most 40 million pixels each; aspect ratio 1:4–4:1
Videos Up to 3; at most 16,777,216 pixels per frame and 120 fps; aspect ratio 1:4–4:1
Independent audio files Up to 3
Total reference files Up to 12
Upload size At most 128 MiB per file and 384 MiB combined
Video / independent audio duration Each 2–15 seconds; all videos together at most 15 seconds, and all independent audio together at most 15 seconds
Soundtracks Mono or stereo; video soundtracks are retained and must also be at most 15 seconds
Decoded reference RAM Estimated at most 2 GiB by default, including temporary raw/resized frame copies; compressed file sizes alone do not determine this limit

The order is fixed: images → independent audio → videos. Order within each group follows its file list. Prompts can use the resulting <Picture 1>, <Audio 1> and <Video 1> tags. A video containing a soundtrack also receives an audio tag, so later video audio continues numbering after independent audio files. The /reference_plan Gradio API accepts the same three lists and returns ordered names, tags and probed metadata without booking a GPU. Output duration still comes from the 2–14 second request and frame alignment; this UI does not automatically match a reference soundtrack's duration.

Reference conditioning calls the configured conditioner's /encode_ref2va endpoint. Uploaded files are probed on CPU, then decoded into upstream MiniMax-H3 reference objects inside the GPU worker. The local reference pipeline shares the existing transformer, VAEs, processors and schedulers with Basic mode by object identity. No second transformer or extra model checkpoint is downloaded. The upstream reference denoiser is normally paired with separately trained Ref2VA weights; reusing the current FL2VA weights here does not establish equivalent reference-following quality. Both modes default to the premerged Larry v4 / 6 for speed. Turbo can be switched off manually; the suggested base-model setting is 28. Turbo quality with this shared-weight reference mode depends on the inputs and is not established by shape compatibility. More reference tokens also increase attention work and memory use even though model weight storage is shared.

Ordinary style and character LoRAs

Ordinary LoRAs are independent of the Turbo selector: up to 4 compatible adapters can be stacked, each with an enabled checkbox and a strength from -2 to 2. Use Inspect on a Hugging Face repository or file link to list its .safetensors files. A repository with several such files requires an explicit file choice; the app never guesses which one is an adapter. Ordinary LoRAs do not automatically change the sampling-step recommendation.

/generate accepts a custom_loras JSON string, for example:

[
  {
    "source": "owner/h3-style-lora",
    "filename": "adapter_model.safetensors",
    "revision": "main",
    "strength": 0.8,
    "enabled": true
  }
]

Replace the example repository with a compatible H3 adapter. source may be owner/repo, its https://huggingface.co/owner/repo URL, or a full Hub blob/resolve .safetensors link. filename and revision are optional when supplied by the link; conflicting link and field values are rejected. Missing revision means main; each request resolves it to an immutable commit before downloading. The /inspect_lora Gradio API takes source, optional filename and optional revision, returning repository information and files: list[str] without downloading tensor weights. Private or gated repositories work only when the deployment's existing Hub credentials have access; the browser does not request or save a Hugging Face token.

Supported weights are two-dimensional H3 reference-layout or diffusers/PEFT lora_A / lora_B pairs, with or without the PEFT .default suffix, native diffusers lora.down / lora.up pairs, and recognized H3 Kohya/Comfy lora_unet_…lora_down/lora_up pairs. Reference QKV and SwiGLU rows receive the same conversion as the base model. Reference and flattened Kohya names also support the video/audio input and output projections, text projection and timestep projections. These direct projections are renamed without permuting their LoRA factors; the model's FP32 input/output heads retain their original dtype and exact off restoration. Alpha scaling comes from per-module alpha tensors, then PEFT alpha_pattern / lora_alpha, then supported safetensors alpha metadata; absent alpha defaults to the actual rank. Target names, shapes and finite values are validated against the loaded transformer. Other model architectures, unknown tensors, missing partners, bias or saved-module updates, DoRA, rank-stabilized LoRA and pickle checkpoint formats are rejected explicitly. Supporting these layouts does not mean every published adapter has been tested or will give useful results.

Downloads and validation finish before GPU booking. Files must be at most 2 GiB each, the ordinary stack at most 4 GiB, and the CPU LRU cache defaults to 2 GiB. Downloads use a temporary local_dir and remove it on normal completion or exceptions, without retaining a second ordinary-LoRA checkpoint in the global Hub cache. The downloader checks free temporary disk space for the file plus a 256 MiB reserve before starting. This does not reserve storage against other processes or guarantee cleanup after a process is forcibly killed. Existing Hub/Xet caches, outputs and model packs still need capacity planning.

The CPU cache limit is not a total process-memory limit. Active adapter stacks, immutable base weights, temporary float32 merge buffers and ZeroGPU worker copies/shared memory are additional. Spaces transfers CPU tensors through PyTorch multiprocessing's shared-storage handles; its first transfer can still require a shared-memory copy and sufficient shared-memory capacity. This app does not globally change PyTorch's sharing strategy or promise that the maximum allowed stack fits every deployment.

Turbo LoRAs

Larry v4 is premerged at startup and selected on page entry for both modes. A fresh ZeroGPU worker already has these weights, so the default request avoids merging all 363 target weights again. The original Larry adapter remains selectable, and legacy Basic API requests using only use_lora retain their original mapping.

API value Source Suggested steps
larry larryvrh/MiniMax-H3-Turbo-Lora, minimax_h3_turbo_4step_ema_ckpt850.safetensors 6
larry_v4 Same repository, minimax_h3_turbo_v4_step600_ema.safetensors 6 (model card recommends 6–8)
lightx lightx2v/Minimax-h3-Turbo, minimax_h3_fl2v_turbo_4step_v0.1.safetensors 4
dmad ZhengmingYu/DMAD, minimax_h3/dmad_minimax_h3_4step_full_critic.safetensors 4 actual denoising iterations; 8 or 12 can also be tried
off No Turbo adapter; ordinary LoRAs, if selected, still apply 28

These are starting points, not quality or speed guarantees. Check the respective model cards when choosing strength, steps and input type. LoRA acceleration reduces the number of denoising steps; it does not reduce the base model's weight footprint.

DMAD uses its official Full Critic checkpoint by default, pinned to revision bcfb2f971bc2c999418c678707e70505a9ec88da. To use the official Paper EMA variant in the same menu option, set H3_DMAD_FILE=minimax_h3/dmad_minimax_h3_4step_lora_critic.safetensors. Selecting DMAD also selects its re-noise sampler, with separate video/audio shifts of 12/2 and the same seeded CPU generator used for the initial latents. Its requested steps count actual model forwards: 4 means four iterations. The sampler is scoped to that request and restores the pipeline's original video/audio schedulers on completion or failure. The existing keyframe/reference loop still supplies its anchors. Official DMAD validation covers text-to-video-with-audio; keyframes and multimodal references in this app are experimental adaptations. This integration has not been timed or quality-tested on the Space. DMAD can be combined with ordinary LoRAs; their effect on the distilled model is unverified.

h3_lora.py converts Larry's reference-model keys to the diffusers layout, including fused QKV splitting, SwiGLU gate/value reordering and the shared AdaLN layout. LightX uses native diffusers keys and its alpha / rank scale. DMAD uses native diffusers attention lora.down/up and feed-forward lora_A/B pairs, with rank and alpha both 128. Adapters are merged into the live parameters so AoTI can see them without runtime LoRA wrapper modules.

When the live parameters are on CUDA, switching merges 512-row FP32 chunks on that GPU. The immutable CPU base is staged in blocks of at most 256 MiB in its original dtype; each target's low-rank factors transfer once. This reduces small host-to-device copies without allocating a second full GPU checkpoint. CPU startup merges remain on CPU. CUDA merging temporarily disables autocast and TF32 and restores the caller's settings; turning all adapters off still restores the original bits. CPU and CUDA matrix products can differ slightly in rounding, while every switch on either path starts from the same immutable base. Logs identify the merge device. The first switch can still be substantially slower than later switches when the original CPU pages must be read back from storage. A warm-cache timing is not a guarantee for a newly started Space.

Switches rebuild affected parameters from the immutable original base plus the selected Turbo delta and every ordinary adapter delta, accumulated in float32 and cast once to the parameter dtype. They never subtract a rounded previous update. Turbo off leaves the ordinary stack active; Turbo off plus custom_loras="[]" restores the original stored values bit for bit as long as the parameter dtype has not changed. This app keeps its transformer in BF16. Repeated switches do not accumulate rounding drift. Invalid adapters are rejected before changing model weights; an interrupted or overflowing merge marks the model state invalid so the next attempt rebuilds every captured target before inference.

At initialization, the loader retains references to the original CPU tensors, normally backed by the downloaded safetensors files, and clones each affected live parameter once to separate it from that base. Subsequent switches use in-place copies, preserving the live storage used by compiled blocks. If initialization receives GPU parameters, it copies the base to CPU instead and keeps the existing GPU storage. The original three adapters (Larry v1/v4 and LightX) together target 363 weights, whose original BF16 storage totals approximately 61.603 GiB; their low-rank factors total approximately 2.74 GiB. Those figures are the original baseline; the additionally loaded DMAD checkpoint contributes approximately 1.384 GB of factors and file storage. An ordinary adapter targeting previously untouched parameters captures their original values on first use, which can increase retained base storage beyond these figures.

For memory-mapped weights, keeping the original references avoids a separate anonymous CPU allocation for the entire base and does not write a second checkpoint. The original file-backed pages can be reclaimed by the OS, but the live CPU clones, pages in use, factors and temporary delta computation still consume memory. If a loader materializes ordinary CPU tensors instead of mappings, retaining the base requires that additional CPU storage. Switching therefore has real memory, computation and transfer costs; it is not a free pointer swap.

A process-local lock covers the complete _generate operation, including adapter switching and inference. Concurrent calls in the same process cannot change weights while another request is using them; this protection does not rely on Gradio's default queue concurrency.

Placement, downloads and GPU bookings

The split avoids downloading the full model into one Space. The original deployment recorded these sizes:

Service Components Download Resident model weights
Conditioner text_encoder/, tokenizer/, processor/ About 66.7 GB About 62.15 GiB bf16
This generator transformer/, vae/, audio_vae/ About 77.3 GB About 61.73 GiB bf16 + 10.43 GiB float32

These totals exclude LoRA factors, the base/live-storage separation used for switching, activations, compiled packages and other process overhead. They are not a current peak-memory or disk-capacity guarantee. The code has no small-GPU quantization path; enabling offload does not by itself establish that a machine has enough RAM or VRAM.

import spaces precedes CUDA initialization so model loading can happen at startup. Default placement is pack: only the transformer is moved to the ZeroGPU startup CUDA placeholder and packed; the float32 VAEs move on the first GPU call. Packing every component previously exceeded the original deployment's 150 GB disk quota because packing needs another on-disk representation.

Retained base mappings keep the original transformer shards alive: the Spaces 0.51.3 pack cleanup cannot reclaim those files after packing. Plan for approximately 77.3 GB of original model downloads plus 66.3 GB of packed transformer data plus 2.94 GB of the original three adapters, before package caches, outputs and other files. Adding the default 1.384 GB DMAD file brings that 146.5 GB baseline to about 147.9 GB before overhead, very close to a 150 GB quota. Set H3_DMAD_FILE=off to skip its download and loading. Keeping additional DMAD checkpoint variants in the Hub cache also uses additional disk space. The base strategy avoids writing another checkpoint but does not promise lower disk usage or that this configuration fits every Space. Check the actual storage quota, startup RAM and peak usage for the selected placement and adapter set.

lazy moves the transformer before merging adapters on the first GPU call. Both lazy and pack then enqueue the two VAE transfers before synchronizing, avoiding a host synchronization after each parameter copy. offload delegates placement to ComponentsManager.enable_auto_cpu_offload; the app also arms hooks for direct VAE encode() and decode() calls. Their performance and memory costs differ. Startup loading and remote conditioning happen outside this Space's GPU booking. Placement, adapter switching, denoising and decoding happen within _generate's booking; MP4 encoding happens afterwards.

The @spaces.GPU duration is calculated by get_duration() from canvas size, aligned frame count, keyframes, text tokens, generated audio, reference rows and step count, with reference-encoding/decode/placement margins and a 60-second minimum. Loaded adapters add a switch allowance. For pack and lazy, the estimate uses CUDA transfer volume, low-rank matrix-product work and target scheduling overhead, with a 60-second minimum. Slow CPU startup merges do not inflate this CUDA estimate. The CPU/offload path retains the measured startup estimate: max(60, ceil(1.5 * startup_merge_seconds * (1 + ordinary_count) + base_bytes / 2e9 + 15)), or 120 * (1 + ordinary_count) seconds when no startup merge was measured. Every request with adapters reserves a margin because the parent process cannot reliably infer which adapter a GPU worker holds. H3_LORA_SWITCH_SECONDS can override the margin with a finite, non-negative number of seconds. It affects the requested GPU booking and therefore quota availability. Logs report the requested wall-clock seconds; ZeroGPU accounts for xlarge at twice that duration when checking quota. There is no H3_GPU_DURATION setting in the current app. These are scheduling estimates, especially sensitive to placement, storage, CPU speed and whether AoTI is active; they do not guarantee a completion time.

The result report separates remote conditioning, LoRA switching, placement, pipeline execution and request overhead (queue/startup/transfer). Pipeline execution includes media encoding, denoising and decoding; it is not divided by the requested steps as though all that time were transformer inference. For Larry, LightX and Turbo off, the pinned scheduler counts the final zero in the requested sigma-grid size: 6 requested steps produce 5 denoising iterations. DMAD instead uses one extra grid point so 4 requested steps produce 4 denoising iterations. The report shows the executed schedule length when available. Disabling Enhance prompt avoids a remote rewrite, while the required text/media encoding still runs in the conditioner Space.

Optional AoTI compilation

AoTI is off by default. Set H3_AOTI=1 to request the compiled transformer blocks from multimodalart/minimax-h3-aoti. The default artifact key is bf16/torch2.11/sm120/dynamic; the transformer's precision, Torch version, GPU architecture and shape settings must match the package. The loader falls back to eager execution when CUDA is unavailable, the key mismatches, the loader is missing or the package cannot be fetched. This is not a portable package for arbitrary GPUs.

The package contains a reusable transformer block graph and binds each block's live weights. The loader refreshes bindings when parameter/buffer storage or versions change, and LoRA switches explicitly invalidate cached bindings while preserving parameter storage. The status line distinguishes a package ready for its first call, successful compiled execution, eager fallback and runtime errors. Dynamic sequence support still depends on the exported shape bounds and H3_AOTI_TEMB_ROWS matching the artifact. Requests estimated above 262,144 packed rows are rejected before denoising; the compiled forward also checks its actual 2,048–262,144-row range.

The export/build helpers in h3_aoti.py are inherited from a wider project. export_block() imports h3_core, which is not included in this repository, and expects its full-pipeline interfaces. Loading a published package is supported here; exporting a new one requires that additional integration and compatible GPU tooling.

How the pipeline is split

The upstream modular pipeline follows this sequence:

before_encode -> text_encoder -> vae_encoder -> denoise -> after_denoise -> decode

h3_split_blocks.py removes the text_encoder stage from the generator. Its absent component declarations mean load_components() fetches the generator components without text_encoder/ or transformer_ref/. The generator instead receives prompt_embeds and text_token_tags as inputs. The conditioner sends those tensors in a safetensors file with resolved height, width and num_frames metadata and a plan. Both sides must agree on canvas labels and image preparation.

Space variables

Variable Default Meaning
H3_MODEL_REPO MiniMaxAI/MiniMax-H3 Diffusers-layout checkpoint.
H3_CONDITIONER multimodalart/qwen3vl-conditioner Remote encoding Space.
H3_PLACEMENT pack Pack the transformer at startup; lazy moves the full pipeline on demand; offload enables automatic CPU offload.
H3_ATTENTION _native_cudnn Transformer attention backend; speed and support depend on hardware and software.
H3_GPU_SIZE xlarge Requested ZeroGPU allocation size.
H3_LORA minimax_h3_turbo_4step_ema_ckpt850.safetensors Original Larry file; off skips this adapter only.
H3_LORA_REPO larryvrh/MiniMax-H3-Turbo-Lora Shared repository for the original Larry and v4 checkpoints.
H3_LORA_STRENGTH 1.0 Original Larry adapter strength.
H3_LORA_V4 minimax_h3_turbo_v4_step600_ema.safetensors Larry v4 file; off skips this adapter only.
H3_LORA_V4_STRENGTH 1.0 Larry v4 adapter strength.
H3_LIGHTX on Set off to skip LightX.
H3_LIGHTX_REPO lightx2v/Minimax-h3-Turbo LightX repository.
H3_LIGHTX_FILE minimax_h3_fl2v_turbo_4step_v0.1.safetensors LightX checkpoint.
H3_DMAD_REPO ZhengmingYu/DMAD DMAD repository.
H3_DMAD_FILE minimax_h3/dmad_minimax_h3_4step_full_critic.safetensors Native DMAD checkpoint; off skips this adapter. Changing the file replaces the same dmad option.
H3_DMAD_REVISION bcfb2f971bc2c999418c678707e70505a9ec88da Pinned DMAD Hub revision.
H3_DMAD_STRENGTH 1.0 DMAD adapter strength.
H3_LORA_DEFAULT larry_v4 Startup selection among loaded adapters or off; matching this selection avoids a request-time merge.
H3_LORA_SWITCH_SECONDS Estimated by merge device Optional non-negative GPU booking margin for adapter switching; see above.
H3_CUSTOM_LORA_MAX_FILE_BYTES 2147483648 (2 GiB) Maximum downloaded ordinary-LoRA file size.
H3_CUSTOM_LORA_MAX_STACK_BYTES 4294967296 (4 GiB) Maximum combined ordinary-LoRA tensor budget.
H3_CUSTOM_LORA_CACHE_BYTES 2147483648 (2 GiB) CPU LRU cache budget; excludes active stacks, base weights and worker memory.
H3_MAX_DECODED_REFERENCE_BYTES 2147483648 (2 GiB) Estimated decoded reference RAM budget, including raw and resized frame copies; trim or downscale inputs to fit.
H3_AOTI 0 Set 1 to request compiled blocks.
H3_AOTI_REPO multimodalart/minimax-h3-aoti Compiled artifact repository.
H3_AOTI_REPO_TYPE model Hub repository type for artifacts.
H3_AOTI_KEY bf16/torch2.11/sm120/dynamic Required artifact key.
H3_AOTI_SHAPE dynamic Shape component of the runtime artifact key.
H3_AOTI_TEMB_ROWS 4 Padded timestep rows; must match the compiled artifact.

Quota and secrets

The generator extracts the incoming x-ip-token header from Gradio's request and explicitly forwards it to a per-request conditioner client. This attributes the remote booking to the caller when the token is present; automatic LocalContext forwarding was not reliable in Server mode. With no token, the cached public client falls back to the Space pod IP and its shared quota. Quota availability and limits depend on Hugging Face.

The default checkpoints and conditioner are public, so inference does not require an additional repository secret. Uploading a compiled artifact with the developer helper requires HF_TOKEN with appropriate access.

Dependencies and build

requirements.txt pins Torch and torchaudio 2.11.0, Transformers 5.8.0 and Gradio 6.20.0. Torchaudio is required by the upstream reference-audio loading/resampling path; PyAV probes media and encodes the output. Ordinary LoRA handling uses the existing Torch, safetensors and huggingface-hub dependencies. Hugging Face's Gradio Space builder supplies the spaces version; do not add a conflicting exact pin to requirements.txt. packages.txt uses LF line endings so the builder reads ffmpeg as a valid Debian package name.

The pipeline depends on a pinned diffusers revision, 665f578278365ea4a3318cb8c9b66ce6c01204b9, from huggingface/diffusers#14371. These wrappers use that revision's modular-pipeline internals. Recheck h3_split_blocks.py, LoRA conversion and AoTI compatibility before upgrading; the moving PR head is not automatically compatible.

The CPU regression tests use small tensors and mock the compiled loader; they do not download model weights. With the app dependencies and pytest installed, run python -m pytest -q tests; run the frontend checks with node --test tests/test_frontend_studio.mjs. They cover exact LoRA restoration, retained safetensors mappings, adapter loading, multi-adapter composition, URL/format/shape validation, download and cache budgets, AoTI binding refresh, reference validation, shared component identity, API configuration and generation locking. Real CUDA/AoTI package compatibility and full-model resource usage still need deployment validation.

Historical measurements from the original author

The following results predate the current adapter-switching changes and are retained as context. They have not been rerun on this fork and do not establish current startup time, peak host RAM, speed or a speed advantage over other deployments.

An rtx-pro-6000 Job used an RTX PRO 6000 Blackwell (sm120, reported 95.0 GiB), 1344×768, 124 frames, 30 steps, bf16 transformer, float32 VAEs, cuDNN attention and resident model weights:

Measurement Historical result
load_components with warm Xet cache 43 s
Initial .to("cuda") 10 s
Resident model weights 72.16 GiB
Denoise + decode 317 s, reported 10.58 s/step
Peak CUDA allocated / reserved 78.54 / 85.37 GiB
Output H.264 1344×768, 24 fps, 5.167 s, stereo AAC at 32 kHz

Historical eager/AoTI step comparisons on that GPU family were 10.20/9.73 seconds at 768×1344, 6.46/5.88 at 640×1152 and 4.02/3.58 at 544×960. Those graph/hardware-specific observations do not guarantee the same savings with another package, adapter or request. Older Space measurements used lazy placement and a different startup path; they should not be used as timings for the current default pack deployment.