49 lines
2.7 KiB
Python
49 lines
2.7 KiB
Python
"""Generate a minimal direct, video-only H3 T2V preview without ComfyUI."""
|
|
|
|
import argparse
|
|
from pathlib import Path
|
|
import subprocess
|
|
import warnings
|
|
|
|
warnings.filterwarnings("ignore", message="Found GPU0 NVIDIA GB10 which is of cuda capability 12.1.*", category=UserWarning)
|
|
|
|
import torch
|
|
|
|
from h3_blackwell_runtime.checkpoint import H3Checkpoint
|
|
from h3_blackwell_runtime.denoiser import H3PackedDenoiser
|
|
from h3_blackwell_runtime.packing import H3PromptPacker
|
|
from h3_blackwell_runtime.qwen3vl_text import Qwen3VLPromptConditioner
|
|
from h3_blackwell_runtime.sampler import sample_video_res_multistep
|
|
from h3_blackwell_runtime.t2v import empty_av_latents
|
|
from h3_blackwell_runtime.token_refiner import H3TokenRefiner
|
|
from h3_blackwell_runtime.vae_decoder import MiniMaxH3VideoVAE
|
|
|
|
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument("--prompt", default="A brass-and-paper dragon flies above a rain-washed old city at blue hour.")
|
|
parser.add_argument("--output", type=Path, default=Path("/output/direct-h3-preview.mp4"))
|
|
parser.add_argument("--width", type=int, default=320)
|
|
parser.add_argument("--height", type=int, default=192)
|
|
parser.add_argument("--frames", type=int, default=22)
|
|
parser.add_argument("--steps", type=int, default=12)
|
|
parser.add_argument("--seed", type=int, default=440204)
|
|
parser.add_argument("--attention", choices=("sage2", "sdpa", "sage3"), default="sage2")
|
|
args = parser.parse_args()
|
|
|
|
torch.manual_seed(args.seed)
|
|
checkpoint = H3Checkpoint("/models/minimax_h3_fl2va_pruned_nvfp4.safetensors")
|
|
conditioner = Qwen3VLPromptConditioner("/text-encoders/qwen3vl_32b_minimax_h3_nvfp4_awq.safetensors", "/opt/h3-blackwell-runtime/qwen25_tokenizer")
|
|
video, audio, frames = empty_av_latents(args.width, args.height, args.frames)
|
|
video.normal_()
|
|
model = H3PackedDenoiser.from_checkpoint(checkpoint, attention_backend=args.attention).eval()
|
|
text = H3TokenRefiner(checkpoint)(conditioner(args.prompt))
|
|
latent = sample_video_res_multistep(model, H3PromptPacker(checkpoint), text, video, audio, steps=args.steps)
|
|
vae = MiniMaxH3VideoVAE.from_safetensors("/vae/minimax_h3_video_vae_fp16.safetensors", device="cuda").eval()
|
|
pixels = vae.decode(latent.to(next(vae.parameters()).dtype))[:, :, :frames]
|
|
pixels = ((pixels[0].permute(1, 2, 3, 0).clamp(-1, 1) + 1) * 127.5).to(torch.uint8).cpu()
|
|
args.output.parent.mkdir(parents=True, exist_ok=True)
|
|
raw = args.output.with_suffix(".rgb")
|
|
pixels.numpy().tofile(raw)
|
|
subprocess.run(["ffmpeg", "-y", "-f", "rawvideo", "-pixel_format", "rgb24", "-video_size", f"{pixels.shape[2]}x{pixels.shape[1]}", "-framerate", "24", "-i", str(raw), "-an", "-c:v", "libx264", "-pix_fmt", "yuv420p", str(args.output)], check=True)
|
|
raw.unlink()
|
|
print({"output": str(args.output), "frames": frames, "shape": tuple(pixels.shape)})
|