Diffusers 文档

文本或图像到视频

Hugging Face's logo
加入 Hugging Face 社区

并获得增强的文档体验

开始使用

文本或图像到视频

在文本到图像扩散模型成功的推动下,生成视频模型能够从文本提示或初始图像生成短视频片段。这些模型通过在架构中添加某种类型的时间和/或空间卷积层来扩展预训练的扩散模型以生成视频。使用图像和视频的混合数据集来训练模型,该模型学习根据文本或图像条件输出一系列视频帧。

本指南将向您展示如何生成视频、如何配置视频模型参数以及如何控制视频生成。

热门模型

在 Hub 上发现其他酷炫和流行的视频生成模型 这里!

Stable Video Diffusions (SVD), I2VGen-XL, AnimateDiff, 和 ModelScopeT2V 是用于视频扩散的流行模型。每个模型都各不相同。例如,AnimateDiff 将运动建模模块插入到冻结的文本到图像模型中,以生成个性化的动画图像,而 SVD 完全是从头开始通过三阶段训练过程进行预训练,以生成高质量的短视频。

CogVideoX 是另一个流行的视频生成模型。该模型是一个多维 transformer,集成了文本、时间和空间。它在注意力模块中采用完全注意力,并在层级包含一个专家块,以在空间上对齐文本和视频。

CogVideoX

CogVideoX 使用 3D 变分自编码器 (VAE) 沿空间和时间维度压缩视频。

首先加载 CogVideoXPipeline 并传递初始文本或图像以生成视频。

CogVideoX 可用于图像到视频和文本到视频。THUDM/CogVideoX-5b-I2V 使用 CogVideoXImageToVideoPipeline 进行图像到视频。THUDM/CogVideoX-5bTHUDM/CogVideoX-2b 可用于文本到视频,使用 CogVideoXPipeline

import torch
from diffusers import CogVideoXImageToVideoPipeline
from diffusers.utils import export_to_video, load_image

prompt = "A vast, shimmering ocean flows gracefully under a twilight sky, its waves undulating in a mesmerizing dance of blues and greens. The surface glints with the last rays of the setting sun, casting golden highlights that ripple across the water. Seagulls soar above, their cries blending with the gentle roar of the waves. The horizon stretches infinitely, where the ocean meets the sky in a seamless blend of hues. Close-ups reveal the intricate patterns of the waves, capturing the fluidity and dynamic beauty of the sea in motion."
image = load_image(image="cogvideox_rocket.png")
pipe = CogVideoXImageToVideoPipeline.from_pretrained(
    "THUDM/CogVideoX-5b-I2V",
    torch_dtype=torch.bfloat16
)
 
pipe.vae.enable_tiling()
pipe.vae.enable_slicing()

video = pipe(
    prompt=prompt,
    image=image,
    num_videos_per_prompt=1,
    num_inference_steps=50,
    num_frames=49,
    guidance_scale=6,
    generator=torch.Generator(device="cuda").manual_seed(42),
).frames[0]

export_to_video(video, "output.mp4", fps=8)
初始图像
生成的视频

Stable Video Diffusion

SVD 基于 Stable Diffusion 2.1 模型,并在图像、然后是低分辨率视频,最后是较小的高分辨率视频数据集上进行训练。此模型从初始图像生成 2-4 秒的短视频。您可以在 Stable Video Diffusion 指南中了解有关模型(如微条件控制)的更多详细信息。

首先加载 StableVideoDiffusionPipeline 并传递初始图像以从中生成视频。

import torch
from diffusers import StableVideoDiffusionPipeline
from diffusers.utils import load_image, export_to_video

pipeline = StableVideoDiffusionPipeline.from_pretrained(
    "stabilityai/stable-video-diffusion-img2vid-xt", torch_dtype=torch.float16, variant="fp16"
)
pipeline.enable_model_cpu_offload()

image = load_image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/svd/rocket.png")
image = image.resize((1024, 576))

generator = torch.manual_seed(42)
frames = pipeline(image, decode_chunk_size=8, generator=generator).frames[0]
export_to_video(frames, "generated.mp4", fps=7)
初始图像
生成的视频

I2VGen-XL

I2VGen-XL 是一个扩散模型,它可以生成比 SVD 更高分辨率的视频,并且还能够接受文本提示以及图像。该模型使用两个分层编码器(细节和全局编码器)来更好地捕获图像中的低级和高级细节。这些学习到的细节用于训练视频扩散模型,该模型细化生成视频中的视频分辨率和细节。

您可以使用 I2VGen-XL,方法是加载 I2VGenXLPipeline,并传递文本和图像提示以生成视频。

import torch
from diffusers import I2VGenXLPipeline
from diffusers.utils import export_to_gif, load_image

pipeline = I2VGenXLPipeline.from_pretrained("ali-vilab/i2vgen-xl", torch_dtype=torch.float16, variant="fp16")
pipeline.enable_model_cpu_offload()

image_url = "https://huggingface.co/datasets/diffusers/docs-images/resolve/main/i2vgen_xl_images/img_0009.png"
image = load_image(image_url).convert("RGB")

prompt = "Papers were floating in the air on a table in the library"
negative_prompt = "Distorted, discontinuous, Ugly, blurry, low resolution, motionless, static, disfigured, disconnected limbs, Ugly faces, incomplete arms"
generator = torch.manual_seed(8888)

frames = pipeline(
    prompt=prompt,
    image=image,
    num_inference_steps=50,
    negative_prompt=negative_prompt,
    guidance_scale=9.0,
    generator=generator
).frames[0]
export_to_gif(frames, "i2v.gif")
初始图像
生成的视频

AnimateDiff

AnimateDiff 是一个 adapter 模型,它将运动模块插入到预训练的扩散模型中以使图像动画化。该 adapter 在视频片段上进行训练以学习运动,该运动用于调节生成过程以创建视频。仅训练 adapter 更快更容易,并且可以加载到大多数扩散模型中,有效地将它们变成“视频模型”。

首先加载一个 MotionAdapter

import torch
from diffusers import AnimateDiffPipeline, DDIMScheduler, MotionAdapter
from diffusers.utils import export_to_gif

adapter = MotionAdapter.from_pretrained("guoyww/animatediff-motion-adapter-v1-5-2", torch_dtype=torch.float16)

然后使用 AnimateDiffPipeline 加载微调的 Stable Diffusion 模型。

pipeline = AnimateDiffPipeline.from_pretrained("emilianJR/epiCRealism", motion_adapter=adapter, torch_dtype=torch.float16)
scheduler = DDIMScheduler.from_pretrained(
    "emilianJR/epiCRealism",
    subfolder="scheduler",
    clip_sample=False,
    timestep_spacing="linspace",
    beta_schedule="linear",
    steps_offset=1,
)
pipeline.scheduler = scheduler
pipeline.enable_vae_slicing()
pipeline.enable_model_cpu_offload()

创建一个 prompt 并生成视频。

output = pipeline(
    prompt="A space rocket with trails of smoke behind it launching into space from the desert, 4k, high resolution",
    negative_prompt="bad quality, worse quality, low resolution",
    num_frames=16,
    guidance_scale=7.5,
    num_inference_steps=50,
    generator=torch.Generator("cpu").manual_seed(49),
)
frames = output.frames[0]
export_to_gif(frames, "animation.gif")

ModelscopeT2V

ModelscopeT2V 向 UNet 添加了空间和时间卷积以及注意力机制,并在图像-文本和视频-文本数据集上进行了训练,以增强其在训练期间的学习效果。该模型接受 prompt,对其进行编码并创建文本嵌入,这些文本嵌入由 UNet 去噪,然后由 VQGAN 解码为视频。

由于 ModelScopeT2V 训练所用的数据集,它生成的视频带有水印。要使用无水印模型,请首先尝试使用 cerspense/zeroscope_v2_76w 模型和 TextToVideoSDPipeline,然后使用 cerspense/zeroscope_v2_XL 检查点和 VideoToVideoSDPipeline 对其输出进行放大。

将 ModelScopeT2V 检查点加载到 DiffusionPipeline 中,并提供 prompt 以生成视频。

import torch
from diffusers import DiffusionPipeline
from diffusers.utils import export_to_video

pipeline = DiffusionPipeline.from_pretrained("damo-vilab/text-to-video-ms-1.7b", torch_dtype=torch.float16, variant="fp16")
pipeline.enable_model_cpu_offload()
pipeline.enable_vae_slicing()

prompt = "Confident teddy bear surfer rides the wave in the tropics"
video_frames = pipeline(prompt).frames[0]
export_to_video(video_frames, "modelscopet2v.mp4", fps=10)

配置模型参数

您可以在 pipeline 中配置一些重要参数,这些参数会影响视频生成过程和质量。让我们仔细看看这些参数的作用以及更改它们如何影响输出。

帧数

num_frames 参数决定了每秒生成的视频帧数。帧是在其他帧序列中播放以创建运动或视频的图像。这会影响视频长度,因为 pipeline 每秒生成一定数量的帧(查看 pipeline 的 API 参考以获取默认值)。要增加视频时长,您需要增加 num_frames 参数。

import torch
from diffusers import StableVideoDiffusionPipeline
from diffusers.utils import load_image, export_to_video

pipeline = StableVideoDiffusionPipeline.from_pretrained(
    "stabilityai/stable-video-diffusion-img2vid", torch_dtype=torch.float16, variant="fp16"
)
pipeline.enable_model_cpu_offload()

image = load_image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/svd/rocket.png")
image = image.resize((1024, 576))

generator = torch.manual_seed(42)
frames = pipeline(image, decode_chunk_size=8, generator=generator, num_frames=25).frames[0]
export_to_video(frames, "generated.mp4", fps=7)
num_frames=14
num_frames=25

引导尺度

guidance_scale 参数控制生成的视频与文本提示或初始图像的对齐程度。较高的 guidance_scale 值意味着您生成的视频与文本提示或初始图像更对齐,而较低的 guidance_scale 值意味着您生成的视频对齐程度较低,这可能会给模型更多的“创造力”来解释条件输入。

SVD 使用 min_guidance_scalemax_guidance_scale 参数分别将引导应用于第一帧和最后一帧。

import torch
from diffusers import I2VGenXLPipeline
from diffusers.utils import export_to_gif, load_image

pipeline = I2VGenXLPipeline.from_pretrained("ali-vilab/i2vgen-xl", torch_dtype=torch.float16, variant="fp16")
pipeline.enable_model_cpu_offload()

image_url = "https://huggingface.co/datasets/diffusers/docs-images/resolve/main/i2vgen_xl_images/img_0009.png"
image = load_image(image_url).convert("RGB")

prompt = "Papers were floating in the air on a table in the library"
negative_prompt = "Distorted, discontinuous, Ugly, blurry, low resolution, motionless, static, disfigured, disconnected limbs, Ugly faces, incomplete arms"
generator = torch.manual_seed(0)

frames = pipeline(
    prompt=prompt,
    image=image,
    num_inference_steps=50,
    negative_prompt=negative_prompt,
    guidance_scale=1.0,
    generator=generator
).frames[0]
export_to_gif(frames, "i2v.gif")
guidance_scale=9.0
guidance_scale=1.0

负面 prompt

负面 prompt 阻止模型生成您不想要的东西。此参数通常用于通过删除较差或不良特征(例如“低分辨率”或“不良细节”)来提高整体生成质量。

import torch
from diffusers import AnimateDiffPipeline, DDIMScheduler, MotionAdapter
from diffusers.utils import export_to_gif

adapter = MotionAdapter.from_pretrained("guoyww/animatediff-motion-adapter-v1-5-2", torch_dtype=torch.float16)

pipeline = AnimateDiffPipeline.from_pretrained("emilianJR/epiCRealism", motion_adapter=adapter, torch_dtype=torch.float16)
scheduler = DDIMScheduler.from_pretrained(
    "emilianJR/epiCRealism",
    subfolder="scheduler",
    clip_sample=False,
    timestep_spacing="linspace",
    beta_schedule="linear",
    steps_offset=1,
)
pipeline.scheduler = scheduler
pipeline.enable_vae_slicing()
pipeline.enable_model_cpu_offload()

output = pipeline(
    prompt="360 camera shot of a sushi roll in a restaurant",
    negative_prompt="Distorted, discontinuous, ugly, blurry, low resolution, motionless, static",
    num_frames=16,
    guidance_scale=7.5,
    num_inference_steps=50,
    generator=torch.Generator("cpu").manual_seed(0),
)
frames = output.frames[0]
export_to_gif(frames, "animation.gif")
无负面 prompt
应用了负面 prompt

模型特定参数

有些 pipeline 参数是每个模型独有的,例如调整视频中的运动或向初始图像添加噪声。

Stable Video Diffusion
Text2Video-Zero

Stable Video Diffusion 为帧率提供了额外的微条件控制,使用 fps 参数,为运动提供了微条件控制,使用 motion_bucket_id 参数。这些参数共同允许调整生成视频中的运动量。

还有一个 noise_aug_strength 参数,它可以增加添加到初始图像的噪声量。改变此参数会影响生成的视频与初始图像的相似程度。较高的 noise_aug_strength 也会增加运动量。要了解更多信息,请阅读 微条件控制 指南。

控制视频生成

视频生成可以像控制文本到图像、图像到图像和图像修复一样进行控制,使用 ControlNetModel。唯一的区别是您需要使用 CrossFrameAttnProcessor,以便每帧都关注第一帧。

Text2Video-Zero

Text2Video-Zero 视频生成可以以姿势和边缘图像为条件,从而更好地控制生成视频中对象Subject的运动,或保留视频中主体/对象的身份。您还可以将 Text2Video-Zero 与 InstructPix2Pix 结合使用,以编辑带有文本的视频。

姿势控制
边缘控制
InstructPix2Pix

首先下载一个视频并从中提取姿势图像。

from huggingface_hub import hf_hub_download
from PIL import Image
import imageio

filename = "__assets__/poses_skeleton_gifs/dance1_corr.mp4"
repo_id = "PAIR/Text2Video-Zero"
video_path = hf_hub_download(repo_type="space", repo_id=repo_id, filename=filename)

reader = imageio.get_reader(video_path, "ffmpeg")
frame_count = 8
pose_images = [Image.fromarray(reader.get_data(i)) for i in range(frame_count)]

ControlNetModel 加载到姿势估计,并将检查点加载到 StableDiffusionControlNetPipeline 中。然后,您将为 UNet 和 ControlNet 使用 CrossFrameAttnProcessor

import torch
from diffusers import StableDiffusionControlNetPipeline, ControlNetModel
from diffusers.pipelines.text_to_video_synthesis.pipeline_text_to_video_zero import CrossFrameAttnProcessor

model_id = "stable-diffusion-v1-5/stable-diffusion-v1-5"
controlnet = ControlNetModel.from_pretrained("lllyasviel/sd-controlnet-openpose", torch_dtype=torch.float16)
pipeline = StableDiffusionControlNetPipeline.from_pretrained(
    model_id, controlnet=controlnet, torch_dtype=torch.float16
).to("cuda")

pipeline.unet.set_attn_processor(CrossFrameAttnProcessor(batch_size=2))
pipeline.controlnet.set_attn_processor(CrossFrameAttnProcessor(batch_size=2))

修复所有帧的潜在变量,然后将您的提示和提取的姿势图像传递给模型以生成视频。

latents = torch.randn((1, 4, 64, 64), device="cuda", dtype=torch.float16).repeat(len(pose_images), 1, 1, 1)

prompt = "Darth Vader dancing in a desert"
result = pipeline(prompt=[prompt] * len(pose_images), image=pose_images, latents=latents).images
imageio.mimsave("video.mp4", result, fps=4)

优化

视频生成需要大量内存,因为您一次生成许多视频帧。您可以牺牲一些推理速度来降低内存需求。尝试

  1. 将不再需要的管道组件卸载到 CPU
  2. 前馈分块以循环方式而不是一次性运行前馈层
  3. 将 VAE 必须解码的帧数分成块,而不是一次性解码所有帧
- pipeline.enable_model_cpu_offload()
- frames = pipeline(image, decode_chunk_size=8, generator=generator).frames[0]
+ pipeline.enable_model_cpu_offload()
+ pipeline.unet.enable_forward_chunking()
+ frames = pipeline(image, decode_chunk_size=2, generator=generator, num_frames=25).frames[0]

如果内存不是问题,并且您想优化速度,请尝试使用 torch.compile 包装 UNet。

- pipeline.enable_model_cpu_offload()
+ pipeline.to("cuda")
+ pipeline.unet = torch.compile(pipeline.unet, mode="reduce-overhead", fullgraph=True)
< > 在 GitHub 上更新