Diffusers documentation
Pika H3 Flex
Pika H3 Flex
Pika H3 Flex 是 Pika 基于 MiniMax-H3 进行后训练得到的六步视频与音频生成器。它保留了 MiniMax-H3 的 packed sequence、Qwen3-VL conditioner 以及两个 VAE,并修改了两处:采样器,采用固定的六步调度,在每一步对干净预测进行原地再噪声化,以替代 Euler 更新;以及权重,在 MiniMax-H3 的两个 transformer 分区上各应用了一组 rank-128 的 LoRA 适配器。视频及其同步的立体声音轨均由相同的六次前向传播生成。
本次发布的核心是适配器:fl2va/adapter.safetensors 中的 FL2VA 适配器负责驱动 transformer/ 分区,用于文本和端点帧条件;ref2va/adapter.safetensors 中的 Ref2VA 适配器负责驱动 transformer_ref/,用于多模态参考。基础组件来自 MiniMaxAI/MiniMax-H3,且未作任何更改;该仓库包含这些组件的副本,以便其能够独立加载。
Pika H3 Flex 仅以 Modular Diffusers 块的形式集成,与 MiniMax-H3 类似:这些块及其 PikaH3FlexModularPipeline 构成了完整的集成,不存在 DiffusionPipeline 部分。
加载
Pipeline 的组装分为两个步骤:首先通过 modular_model_index.json 加载组件,该文件指定了 MiniMax-H3 的基础组件以及两个 scheduler 配置;然后使用 load_lora_weights() 在基础之上加载所选工作流的 adapter。这些 adapter 是 diffusers 模块名称的纯 PEFT 转储,并按其训练时的比例加载(alpha == rank,1.0)。
| 工作流 | 输入 | Transformer 分区 | 适配器 |
|---|---|---|---|
t2va | prompt | transformer/ | fl2va/adapter.safetensors |
fl2va | prompt 和 image 和/或 last_image | transformer/ | fl2va/adapter.safetensors |
ref2va | prompt 和 references | transformer_ref/ | ref2va/adapter.safetensors |
import torch
from diffusers import ModularPipeline
pipe = ModularPipeline.from_pretrained("Pika-Labs/Pika-H3-Flex", workflow="fl2va")
pipe.load_components(dtype={"vae": torch.float32, "audio_vae": torch.float32, "default": torch.bfloat16})
pipe.load_lora_weights("Pika-Labs/Pika-H3-Flex", weight_name="fl2va/adapter.safetensors")传入 workflow 会将块修剪至该任务,因此仅获取其自身的 transformer 分区,适配器路由到唯一存在的分区,且流水线仅接受该任务的请求——fl2va 流水线需要一个关键帧,而 t2va 流水线则不需要。同时持有两个分区的流水线(在未指定 workflow= 的情况下加载)需要明确指定 Ref2VA 适配器的位置:pipe.load_lora_weights(..., weight_name="ref2va/adapter.safetensors", load_into_transformer_ref=True)。两个 VAE 以 float32 发布并以 float32 进行解码,与发布的包保持一致;其余部分均以 bfloat16 运行。
pipe.doc会打印当前流水线所接受和返回的内容——包括每个输入及其默认值、预期的组件以及产生的输出。
重用已加载的 MiniMax-H3
基础组件来自 MiniMax-H3,因此一个已加载的 MiniMax-H3 流水线包含了除两个调度器和适配器之外的所有组件。本节将从这些已加载的组件组装一个 Pika H3 Flex 流水线,并让两个流水线并排保持就绪状态:一个 ComponentsManager 仅持有每个组件一次,并为两者执行卸载;Pika H3 Flex 流水线仅添加其两个调度器;而适配器则决定共享的 transformer 运行的是这两个模型中的哪一个。
import torch
from diffusers import ComponentsManager, ModularPipeline
dtype = {"vae": torch.float32, "audio_vae": torch.float32, "default": torch.bfloat16}
manager = ComponentsManager()
manager.enable_auto_cpu_offload(device="cuda")
# The MiniMax-H3 pipeline already in use, with every workflow loaded. `collection` registers its components in the
# manager under that name, so they can be fetched by it later.
minimax = ModularPipeline.from_pretrained("MiniMaxAI/MiniMax-H3", components_manager=manager, collection="minimax-h3")
minimax.load_components(dtype=dtype)
# The Pika H3 Flex pipeline, in its own collection. Only its own components are loaded: the two schedulers.
pika = ModularPipeline.from_pretrained("Pika-Labs/Pika-H3-Flex", components_manager=manager, collection="pika-h3-flex")
pika.load_components(names=["scheduler", "audio_scheduler"])
# The rest comes from the MiniMax-H3 collection, and `update_components` puts it in the Pika H3 Flex pipeline.
shared = ["text_encoder", "tokenizer", "processor", "vae", "audio_vae", "transformer", "transformer_ref"]
pika.update_components(**{name: manager.get_one(name=name, collection="minimax-h3") for name in shared})
# The adapters go into the shared transformers.
pika.load_lora_weights("Pika-Labs/Pika-H3-Flex", weight_name="fl2va/adapter.safetensors")
pika.load_lora_weights(
"Pika-Labs/Pika-H3-Flex", weight_name="ref2va/adapter.safetensors", load_into_transformer_ref=True
)print(manager) 显示的结果如下:每个共享组件仅列出一次,并同时属于两个集合;Pika H3 Flex 集合添加了它的两个调度器;两个 transformers 各带有一个适配器。
Models:
Name_ID | Class | Size (GB) | Collection
transformer_1397... | MiniMaxH3Transformer3DModel | 63.02 | minimax-h3
| | | pika-h3-flex
transformer_ref_13... | MiniMaxH3Transformer3DModel | 63.02 | minimax-h3
| | | pika-h3-flex
text_encoder_1397... | Qwen3VLForConditionalGeneration | 62.13 | minimax-h3
| | | pika-h3-flex
vae_1397... | AutoencoderKLMiniMaxH3 | 9.70 | minimax-h3
| | | pika-h3-flex
audio_vae_1397... | AutoencoderKLMiniMaxH3Audio | 0.56 | minimax-h3
| | | pika-h3-flex
Other Components:
ID | Class | Collection
scheduler_1397... | MiniMaxH3Scheduler | minimax-h3
audio_scheduler_1397... | MiniMaxH3Scheduler | minimax-h3
scheduler_1397... | MiniMaxH3Scheduler | pika-h3-flex
audio_scheduler_1397... | MiniMaxH3Scheduler | pika-h3-flex
tokenizer_1397... | Qwen2Tokenizer | minimax-h3
| | pika-h3-flex
processor_1397... | Qwen3VLProcessor | minimax-h3
| | pika-h3-flex
Additional Component Info:
transformer_1397...:
Adapters: ['default_0']
transformer_ref_13...:
Adapters: ['default_0']适配器决定了共享的 transformers 对应的是哪个模型。若要回到 MiniMax-H3,只需调用 pika.disable_lora() 即可:下一次 minimax(...) 请求将运行基础模型。pika.enable_lora() 会重新启用 Pika H3 Flex。期间不会重新加载任何内容;当任一 pipeline 到达某个组件时,管理器会将其在加速器上启用或禁用。
与 MiniMax-H3 的不同之处
- 六步,无需
num_inference_steps。 两个 MiniMaxH3Scheduler 实例(视频使用shift=12.0,音频使用shift=3.0)均基于流水线的denoising_step_list配置,以stochastic_sampling方式运行,采用已发布的调度[1000, 750, 500, 250, 100, 40, 0]:每一步都预测干净样本,除最后一步外,其余步骤均使用新的噪声将其重新加噪至下一个 sigma。步数是适配器的约定,并非输入参数。 - 每一步都使用全新的噪声。 请求会按照固定顺序从其
generator中采样:首先为条件噪声采样一次(每个关键帧或视觉参考各一次),然后依次采样视频噪声、音频噪声,以及前五个步骤中视频和音频的重新加噪采样。传入latents或audio_latents会替换前两次采样,其余采样保持不变。 - 关键帧会被裁剪,而不是拉伸。
fl2va关键帧会先按其自身分辨率以画布的宽高比进行居中裁剪,然后再调整大小以适配画布。 - 参考素材遵循画布的分辨率层级。Pika H3 Flex 基于分桶表进行生成——包含 480p 层级和 768p 层级,每个层级各有 11 种宽高比——
ref2va请求会根据其画布所属的层级进行条件约束:图像参考在低于 768 层级时以 1024 像素的短边进行编码,达到或超过该层级时则以 2048 像素进行编码;视频参考则遵循该层级自身的画布规则。每个视频或独立音频参考的时长为 2 至 15 秒,且所有视频时长之和与所有独立音频时长之和各自不超过 15 秒。
生成
发布的桶是 Pika H3 Flex 经过验证的画布。将其中一个作为 height 和 width 传入:
| 21:9 | 16:9 | 3:2 | 4:3 | 5:4 | 1:1 | 4:5 | 3:4 | 2:3 | 9:16 | 9:21 | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 480p | 960x416 | 832x480 | 704x480 | 640x480 | 608x480 | 480x480 | 480x608 | 480x640 | 480x704 | 480x832 | 416x960 |
| 768p | 1536x672 | 1344x768 | 1152x768 | 1024x768 | 960x768 | 768x768 | 768x960 | 768x1024 | 768x1152 | 768x1344 | 672x1536 |
import torch
from diffusers import ComponentsManager, ModularPipeline
from diffusers.utils import load_image
from diffusers.utils.export_utils import encode_video
# 61.7GB of transformer and 62.1GB of conditioner do not sit on one accelerator, so the components are
# registered in a manager that moves each one on and off as the blocks reach it.
manager = ComponentsManager()
manager.enable_auto_cpu_offload(device="cuda") # or "mps", "xpu", "cpu"
# Create one pipeline for all supported workflows, then load the `fl2va` workflow's components, which is
# enough to run both the fl2va and t2va requests below.
pipe = ModularPipeline.from_pretrained("Pika-Labs/Pika-H3-Flex", components_manager=manager)
pipe.load_components(
workflow="fl2va", dtype={"vae": torch.float32, "audio_vae": torch.float32, "default": torch.bfloat16}
)
pipe.load_lora_weights("Pika-Labs/Pika-H3-Flex", weight_name="fl2va/adapter.safetensors")
prompt = (
"integrated_multimodal_description: A cinematic close shot of a red ceramic cup on a wooden table beside an "
"open window. A soft breeze moves a linen curtain. The camera slowly pushes toward the cup as warm morning "
"light crosses the table.\n"
"overall_soundscape: Gentle wind through the window and faint birdsong outside. No speech.\n"
"non_diegetic_music: None.\n"
)
outputs = ["videos", "audio", "sampling_rate"]
# Text to video + audio on the 480p 16:9 bucket, 5 seconds.
results = pipe(
prompt=prompt,
height=480,
width=832,
num_frames=124,
generator=torch.Generator("cuda").manual_seed(42),
output=outputs
)
# First frame (and optionally `last_image`) to video + audio. The keyframe is center-cropped onto the canvas and
# held as the first frame, so the prompt describes the keyframe and what happens from it.
image = load_image(
"https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/astronaut.jpg"
)
i2va_prompt = (
"For the target video, at 0.00 seconds into the target video, <Picture 1> (from [Shot 1]) is fully referenced.\n\n"
"integrated_multimodal_description: [Shot 1] Begin with the supplied image of a small toy astronaut figurine "
"standing on a grey rocky moon surface, holding a white egg-shaped object. Preserve the figurine, its orange "
"visor and the rocks. The astronaut slowly turns its helmet toward the camera and lifts the egg a little; fine "
"dust drifts up around its boots. The camera slowly pushes in in one continuous shot. By the end the astronaut "
"stands still, egg held up.\n\n"
"overall_soundscape: Soft low wind and faint crunch of dust under the boots. No speech.\n\n"
"non_diegetic_music: N/A\n"
)
results = pipe(
prompt=i2va_prompt,
image=image,
height=480,
width=832,
num_frames=124,
generator=torch.Generator("cuda").manual_seed(42),
output=outputs,
)
encode_video(
results["videos"][0],
fps=24,
output_path="pika_h3_flex_fl2va.mp4",
audio=results["audio"][0],
audio_sample_rate=results["sampling_rate"],
)ref2va 工作流接收一个有序的参考列表——最多 9 张图片、3 个视频和 3 个音频片段,共 12 个——其方式与 MiniMax-H3 相同,每种模态对应一个参考类别。这也是对内存需求最高的请求:参考项会为序列添加各自的行,在 768p 分辨率下,仅 transformer 就会占满一张 80 GB 的显卡。因此,下例将 transformer 的块从 CPU 内存中逐个流式加载,同时管理器像往常一样将其他组件在设备上移动进出。它可以在单张 80 GB 显卡上运行 768p 的参考请求;如果不使用流式加载,则请限制在 480p。
import torch
from diffusers import ComponentsManager, ModularPipeline
from diffusers.modular_pipelines.pika_h3_flex import (
PikaH3FlexAudioReference,
PikaH3FlexImageReference,
PikaH3FlexVideoReference,
)
manager = ComponentsManager()
manager.enable_auto_cpu_offload(device="cuda") # or "mps", "xpu", "cpu"
pipe = ModularPipeline.from_pretrained(
"Pika-Labs/Pika-H3-Flex", workflow="ref2va", components_manager=manager
)
pipe.load_components(dtype={"vae": torch.float32, "audio_vae": torch.float32, "default": torch.bfloat16})
pipe.load_lora_weights("Pika-Labs/Pika-H3-Flex", weight_name="ref2va/adapter.safetensors")
# Keep the transformer in CPU memory and bring in one block at a time while it runs.
pipe.transformer_ref.enable_group_offload(
onload_device=torch.device("cuda"),
offload_device=torch.device("cpu"),
offload_type="block_level",
num_blocks_per_group=1,
use_stream=True,
)
results = pipe(
prompt="subject_definitions: <Subject 1> is the woman in <Picture 1>. summary: [reference generation] <Subject 1> waves at the camera.",
references=[
PikaH3FlexImageReference.from_file("subject.png"),
PikaH3FlexVideoReference.from_file("motion_ref.mp4"), # frames, their `fps` and the soundtrack
PikaH3FlexAudioReference.from_file("voice.wav"), # waveform and its `sample_rate`
],
height=768,
width=1344,
num_frames=124,
generator=torch.Generator("cuda").manual_seed(42),
output=["videos", "audio", "sampling_rate"],
)PikaH3FlexModularPipeline
class diffusers.PikaH3FlexModularPipeline
< source >( blocks: diffusers.modular_pipelines.modular_pipeline.ModularPipelineBlocks | None = Nonepretrained_model_name_or_path: str | os.PathLike | None = Nonecomponents_manager: diffusers.modular_pipelines.components_manager.ComponentsManager | None = Nonecollection: str | None = Noneworkflow: str | None = Nonemodular_config_dict: dict[str, typing.Any] | None = Noneconfig_dict: dict[str, typing.Any] | None = None**kwargs )
一个用于 Pika H3 Flex 的 ModularPipeline,支持联合视频 + 音频生成,采用经过后训练的六步 MiniMax-H3:针对 transformer/ 检查点分区的 t2va(仅文本)和 fl2va(首帧和/或尾帧关键帧)工作流,使用 fl2va 适配器;以及针对 transformer_ref/ 的 ref2va(全参考)工作流,使用 ref2va 适配器。
基础组件来自 MiniMax-H3,而 Pika H3 Flex 版本是在两个 transformer 分区之上添加的一对 rank-128 LoRA 适配器,因此流水线分两步组装:通过 modular_model_index.json 加载组件,该文件指定了基础组件和两个调度器,然后使用 load_lora_weights() 加载所选工作流的适配器。
import torch
from diffusers import ModularPipeline
pipe = ModularPipeline.from_pretrained("Pika-Labs/Pika-H3-Flex", workflow="fl2va")
pipe.load_components(dtype={"vae": torch.float32, "audio_vae": torch.float32, "default": torch.bfloat16})
pipe.load_lora_weights("Pika-Labs/Pika-H3-Flex", weight_name="fl2va/adapter.safetensors")与 MiniMax-H3 类似,Pika H3 Flex 对一条打包序列进行去噪,该序列同时承载文本条件、关键帧或参考条件潜变量、音频潜变量和视频潜变量。正因如此,各模块传递的是行布局,而非按模态划分的张量;同时,流水线携带两个调度器(视频使用 shift = 12.0,音频使用 shift = 3.0),并在单次 transformer 调用中步进。与 MiniMax-H3 不同的是,这两个调度器是 MiniMaxH3Scheduler 实例,在固定的六步 denoising_step_list 上执行 stochastic_sampling:不存在 num_inference_steps,且每一步都从请求的生成器中抽取新的噪声。
这些适配器与其基础模型一样,采用了引导蒸馏:没有 guider,也没有 negative_prompt 和 guidance_scale,并且每一步都只执行一次前向传播。
该模块承载了每个 block 所依赖的模型事实——由 config 派生的几何信息以属性形式提供,画布、tier 和帧数计算以函数形式提供——而 conditioning、encoding 和 noise 契约则直接定义在 block 本身之上。
PikaH3FlexBlocks
用于 Pika H3 Flex 联合视频 + 音频生成的 Auto Modular 流水线模块:包括 t2va(仅文本)、fl2va(首帧和/或尾帧关键帧)以及 ref2va(全参考)工作流,根据 references 和关键帧输入进行选择。t2va 和 fl2va 工作流使用 fl2va 适配器运行 transformer 分区,而 ref2va 则使用 ref2va 适配器运行 transformer_ref 分区,因此请加载请求所采用工作流对应的适配器。如果不指定 workflow=,加载组件时会拉取 两个 61.7GB 的 transformer 分区——请传入一个参数,以仅加载任务所需的内容。
支持的工作流:
t2va:需要promptfl2va:需要prompt、image或prompt、last_imageref2va:需要prompt、references
组件:
image_processor (VaeImageProcessor) text_encoder (Qwen3VLForConditionalGeneration) tokenizer
(Qwen2Tokenizer) processor (Qwen3VLProcessor) vae (AutoencoderKLMiniMaxH3) audio_vae
(AutoencoderKLMiniMaxH3Audio) scheduler (MiniMaxH3Scheduler) audio_scheduler (MiniMaxH3Scheduler)
transformer_ref (MiniMaxH3Transformer3DModel) transformer (MiniMaxH3Transformer3DModel) video_processor
(VideoProcessor)
配置: (默认值:768)(默认值:1032192)(默认值:[1000, 750, 500, 250, 100, 40, 0])
输入:
references (list, 可选):
用于条件化的参考内容,按模型应读取的顺序排列:该顺序决定了它们在提示词呈现中的标签,并决定了它们在共享旋转时钟上的布局,因此不同的顺序代表不同的请求。每种模态对应一个数据类,均持有内存中的媒体——一个 PikaH3FlexImageReference(最多 9 个)、一个以其自身 fps 为单位的 PikaH3FlexVideoReference(最多 3 个,其 audio 音轨也会作为条件),或一个以其自身 sample_rate 为单位的 PikaH3FlexAudioReference(最多 3 个)——参考内容总数最多为 12 个,且音频参考不能是唯一的内容。每个视频或独立音频参考的时长为 2 到 15 秒,且视频时长之和与独立音频时长之和各自不超过 15 秒。这些块从不打开媒体文件:请使用每个类的 from_file 类方法进行解码,该方法会一并带入采样率。
height (int, 可选):
生成视频的高度(以像素为单位),必须是 32 的倍数。
width (int, 可选):
生成视频的宽度(以像素为单位),必须是 32 的倍数。
num_frames (int, 可选):
要生成的帧数,固定为 24 fps:120 到 360,即 5 到 15 秒,向上取整到视频 VAE 可解码的下一个 17 * n + 5。若要生成与参考音轨一样长的视频,请传入 round(samples / sample_rate * 24)。
image (Image, 可选):
视频起始的关键帧。它会被中心裁剪至画布的宽高比并调整大小以适配画布;画布默认由其自身的宽高比推导得出。
last_image (Image, 可选):
视频结束的关键帧。可以单独传入以生成直至某一帧。它会被中心裁剪至画布的宽高比并调整大小以适配画布,与 image 相同。
prompt (str):
用于引导生成的提示词,为单个字符串。
normalized_references (list, 可选):
由设置步骤归一化的参考内容,按打包顺序排列。
keyframes (list, 可选):
放置在目标画布上的关键帧,按打包顺序排列。
condition_latents (list, 可选):
编码后的视频条件潜在变量,按打包顺序每个图像和视频参考对应一个。它们的形状决定了每个参考块几何信息的来源。
audio_condition_latents (list, 可选):
编码后的音频条件行,按打包顺序每个包含音频的参考对应一个。
generator (Generator, 可选):
请求的生成器。条件噪声首先从中抽取,每个条件抽取一次,然后才是生成行的噪声。
latents (Tensor):
形状为 (1, 24, num_latent_frames, latent_height, latent_width) 的预生成视频噪声,用于替代抽取操作。
audio_latents (Tensor):
形状为 (2, 32, num_audio_latents) 的预生成音频噪声。
*denoiser_input_fields (None,optional):
Transformer 按名称读取的打包序列的结构描述:token_tags、position_ids 以及三个行索引张量。
attention_kwargs (dict,optional):
用于注意力处理器的额外 kwargs。
keyframe_anchors (tuple,optional, 默认为 ()):
每个关键帧锚定到视频的哪一端,按打包顺序排列。
output_type (str,optional*, 默认为 pil):
输出格式:‘pil’、‘np’ 或 ‘pt’。
输出:
videos (list):
生成的视频。
audio (Tensor):
生成的音轨,形状为 (1, 2, num_samples)。
sampling_rate (int):
生成音轨的采样率,单位为 Hz。
PikaH3FlexImageReference
class diffusers.modular_pipelines.pika_h3_flex.PikaH3FlexImageReference
< source >( image: typing.Union[PIL.Image.Image, numpy.ndarray, torch.Tensor] )
主题、风格或场景参考:每次请求最多 9 个。
通过 load_image() 将图像文件加载到 PikaH3FlexImageReference 中。
PikaH3FlexVideoReference
class diffusers.modular_pipelines.pika_h3_flex.PikaH3FlexVideoReference
< source >( frames: typing.Union[list[PIL.Image.Image], numpy.ndarray, torch.Tensor]fps: float | None = Noneaudio: typing.Optional[torch.Tensor] = Nonesample_rate: int | None = None )
参数
- frames (
list[PIL.Image.Image]、np.ndarray或torch.Tensor) — 参考帧:一个图像列表、一个形状为(num_frames, height, width, 3)的数组,或一个形状为(num_frames, 3, height, width)的张量,数据类型为uint8或取值范围在[0, 1]内的浮点数。 - fps (
float,可选,默认值为 24.0) —frames所承载的帧率,该帧率决定了参考视频的视觉块如何对齐到条件器的 2 fps 网格上。MiniMax-H3 自身的时钟为 24 fps,因此任何其他帧率都会通过丢弃和复制整帧的方式重采样到 24 fps。如果帧数据来自文件,请务必正确设置此参数。 - audio (
torch.Tensor,形状为(channels, num_samples),可选) — 该视频的音轨,单声道或立体声。它作为参考自身的条件,而非作为其自身的参考条件。若省略此项,则参考仅以运动作为条件。 - sample_rate (
int, 可选) —audio的采样率。如果未指定,则使用音频 VAE 自身的采样率,此时样本保持不变;如果指定了其他采样率,则会将样本重采样到该速率。
动作和相机参考:每个请求最多 3 个,与其自身的音轨一起作为条件。
from_file
< source >( media ) → PikaH3FlexVideoReference
将视频文件解码为 PikaH3FlexVideoReference,保留其分辨率、帧率和音轨。
速率会落在 reference 上,这正是采用这种方式而非 load_video() 进行解码的意义所在:MiniMax-H3 会将 reference 重采样为其自身的 24 fps,因此输入过程中丢失的帧率意味着请求是在错误的速度下进行的条件化,且没有任何机制会对此发出警告。如果容器的元数据有误,可以通过在返回的 reference 上覆盖 fps 或 sample_rate 来修正。
需要 PyAV。
PikaH3FlexAudioReference
class diffusers.modular_pipelines.pika_h3_flex.PikaH3FlexAudioReference
< source >( audio: Tensorsample_rate: int | None = None )
语音或音乐参考:每次请求最多 3 个,且不能单独使用——音频参考必须与至少一个图像或视频参考配对。它不会到达 conditioner,而是仅由音频 VAE 进行编码。
from_file
< source >( media ) → PikaH3FlexAudioReference
将音频文件解码为 PikaH3FlexAudioReference,使用其自带的采样率。
需要 PyAV。