Buckets:
| # Text-to-video | |
| [ModelScope Text-to-Video Technical Report](https://huggingface.co/papers/2308.06571) is by Jiuniu Wang, Hangjie Yuan, Dayou Chen, Yingya Zhang, Xiang Wang, Shiwei Zhang. | |
| The abstract from the paper is: | |
| *This paper introduces ModelScopeT2V, a text-to-video synthesis model that evolves from a text-to-image synthesis model (i.e., Stable Diffusion). ModelScopeT2V incorporates spatio-temporal blocks to ensure consistent frame generation and smooth movement transitions. The model could adapt to varying frame numbers during training and inference, rendering it suitable for both image-text and video-text datasets. ModelScopeT2V brings together three components (i.e., VQGAN, a text encoder, and a denoising UNet), totally comprising 1.7 billion parameters, in which 0.5 billion parameters are dedicated to temporal capabilities. The model demonstrates superior performance over state-of-the-art methods across three evaluation metrics. The code and an online demo are available at https://modelscope.cn/models/damo/text-to-video-synthesis/summary.* | |
| You can find additional information about Text-to-Video on the [project page](https://modelscope.cn/models/damo/text-to-video-synthesis/summary), [original codebase](https://github.com/modelscope/modelscope/), and try it out in a [demo](https://huggingface.co/spaces/damo-vilab/modelscope-text-to-video-synthesis). Official checkpoints can be found at [damo-vilab](https://huggingface.co/damo-vilab) and [cerspense](https://huggingface.co/cerspense). | |
| ## Usage example | |
| ### `text-to-video-ms-1.7b` | |
| Let's start by generating a short video with the default length of 16 frames (2s at 8 fps): | |
| ```python | |
| import torch | |
| from diffusers import DiffusionPipeline | |
| from diffusers.utils import export_to_video | |
| pipe = DiffusionPipeline.from_pretrained("damo-vilab/text-to-video-ms-1.7b", torch_dtype=torch.float16, variant="fp16") | |
| pipe = pipe.to("cuda") | |
| prompt = "Spiderman is surfing" | |
| video_frames = pipe(prompt).frames[0] | |
| video_path = export_to_video(video_frames) | |
| video_path | |
| ``` | |
| Diffusers supports different optimization techniques to improve the latency | |
| and memory footprint of a pipeline. Since videos are often more memory-heavy than images, | |
| we can enable CPU offloading and VAE slicing to keep the memory footprint at bay. | |
| Let's generate a video of 8 seconds (64 frames) on the same GPU using CPU offloading and VAE slicing: | |
| ```python | |
| import torch | |
| from diffusers import DiffusionPipeline | |
| from diffusers.utils import export_to_video | |
| pipe = DiffusionPipeline.from_pretrained("damo-vilab/text-to-video-ms-1.7b", torch_dtype=torch.float16, variant="fp16") | |
| pipe.enable_model_cpu_offload() | |
| # memory optimization | |
| pipe.enable_vae_slicing() | |
| prompt = "Darth Vader surfing a wave" | |
| video_frames = pipe(prompt, num_frames=64).frames[0] | |
| video_path = export_to_video(video_frames) | |
| video_path | |
| ``` | |
| It just takes **7 GBs of GPU memory** to generate the 64 video frames using PyTorch 2.0, "fp16" precision and the techniques mentioned above. | |
| We can also use a different scheduler easily, using the same method we'd use for Stable Diffusion: | |
| ```python | |
| import torch | |
| from diffusers import DiffusionPipeline, DPMSolverMultistepScheduler | |
| from diffusers.utils import export_to_video | |
| pipe = DiffusionPipeline.from_pretrained("damo-vilab/text-to-video-ms-1.7b", torch_dtype=torch.float16, variant="fp16") | |
| pipe.scheduler = DPMSolverMultistepScheduler.from_config(pipe.scheduler.config) | |
| pipe.enable_model_cpu_offload() | |
| prompt = "Spiderman is surfing" | |
| video_frames = pipe(prompt, num_inference_steps=25).frames[0] | |
| video_path = export_to_video(video_frames) | |
| video_path | |
| ``` | |
| Here are some sample outputs: | |
| An astronaut riding a horse. | |
| Darth vader surfing in waves. | |
| ### `cerspense/zeroscope_v2_576w` & `cerspense/zeroscope_v2_XL` | |
| Zeroscope are watermark-free model and have been trained on specific sizes such as `576x320` and `1024x576`. | |
| One should first generate a video using the lower resolution checkpoint [`cerspense/zeroscope_v2_576w`](https://huggingface.co/cerspense/zeroscope_v2_576w) with [TextToVideoSDPipeline](/docs/diffusers/main/en/api/pipelines/text_to_video#diffusers.TextToVideoSDPipeline), | |
| which can then be upscaled using [VideoToVideoSDPipeline](/docs/diffusers/main/en/api/pipelines/text_to_video#diffusers.VideoToVideoSDPipeline) and [`cerspense/zeroscope_v2_XL`](https://huggingface.co/cerspense/zeroscope_v2_XL). | |
| ```py | |
| import torch | |
| from diffusers import DiffusionPipeline, DPMSolverMultistepScheduler | |
| from diffusers.utils import export_to_video | |
| from PIL import Image | |
| pipe = DiffusionPipeline.from_pretrained("cerspense/zeroscope_v2_576w", torch_dtype=torch.float16) | |
| pipe.enable_model_cpu_offload() | |
| # memory optimization | |
| pipe.unet.enable_forward_chunking(chunk_size=1, dim=1) | |
| pipe.enable_vae_slicing() | |
| prompt = "Darth Vader surfing a wave" | |
| video_frames = pipe(prompt, num_frames=24).frames[0] | |
| video_path = export_to_video(video_frames) | |
| video_path | |
| ``` | |
| Now the video can be upscaled: | |
| ```py | |
| pipe = DiffusionPipeline.from_pretrained("cerspense/zeroscope_v2_XL", torch_dtype=torch.float16) | |
| pipe.scheduler = DPMSolverMultistepScheduler.from_config(pipe.scheduler.config) | |
| pipe.enable_model_cpu_offload() | |
| # memory optimization | |
| pipe.unet.enable_forward_chunking(chunk_size=1, dim=1) | |
| pipe.enable_vae_slicing() | |
| video = [Image.fromarray(frame).resize((1024, 576)) for frame in video_frames] | |
| video_frames = pipe(prompt, video=video, strength=0.6).frames[0] | |
| video_path = export_to_video(video_frames) | |
| video_path | |
| ``` | |
| Here are some sample outputs: | |
| Darth vader surfing in waves. | |
| ## Tips | |
| Video generation is memory-intensive and one way to reduce your memory usage is to set `enable_forward_chunking` on the pipeline's UNet so you don't run the entire feedforward layer at once. Breaking it up into chunks in a loop is more efficient. | |
| Check out the [Text or image-to-video](../../using-diffusers/text-img2vid) guide for more details about how certain parameters can affect video generation and how to optimize inference by reducing memory usage. | |
| > [!TIP] | |
| > Make sure to check out the Schedulers [guide](../../using-diffusers/schedulers) to learn how to explore the tradeoff between scheduler speed and quality, and see the [reuse components across pipelines](../../using-diffusers/loading#reuse-a-pipeline) section to learn how to efficiently load the same components into multiple pipelines. | |
| ## TextToVideoSDPipeline[[diffusers.TextToVideoSDPipeline]] | |
| #### diffusers.TextToVideoSDPipeline[[diffusers.TextToVideoSDPipeline]] | |
| [Source](https://github.com/huggingface/diffusers/blob/main/src/diffusers/pipelines/text_to_video_synthesis/pipeline_text_to_video_synth.py#L70) | |
| __call__diffusers.TextToVideoSDPipeline.__call__https://github.com/huggingface/diffusers/blob/main/src/diffusers/pipelines/text_to_video_synthesis/pipeline_text_to_video_synth.py#L448[{"name": "prompt", "val": ": str | list[str] = None"}, {"name": "height", "val": ": int | None = None"}, {"name": "width", "val": ": int | None = None"}, {"name": "num_frames", "val": ": int = 16"}, {"name": "num_inference_steps", "val": ": int = 50"}, {"name": "guidance_scale", "val": ": float = 9.0"}, {"name": "negative_prompt", "val": ": str | list[str] | None = None"}, {"name": "eta", "val": ": float = 0.0"}, {"name": "generator", "val": ": torch._C.Generator | list[torch._C.Generator] | None = None"}, {"name": "latents", "val": ": torch.Tensor | None = None"}, {"name": "prompt_embeds", "val": ": torch.Tensor | None = None"}, {"name": "negative_prompt_embeds", "val": ": torch.Tensor | None = None"}, {"name": "output_type", "val": ": str | None = 'np'"}, {"name": "return_dict", "val": ": bool = True"}, {"name": "callback", "val": ": typing.Optional[typing.Callable[[int, int, torch.Tensor], NoneType]] = None"}, {"name": "callback_steps", "val": ": int = 1"}, {"name": "cross_attention_kwargs", "val": ": dict[str, typing.Any] | None = None"}, {"name": "clip_skip", "val": ": int | None = None"}]- **prompt** (`str` or `list[str]`, *optional*) -- | |
| The prompt or prompts to guide image generation. If not defined, you need to pass `prompt_embeds`. | |
| - **height** (`int`, *optional*, defaults to `self.unet.config.sample_size * self.vae_scale_factor`) -- | |
| The height in pixels of the generated video. | |
| - **width** (`int`, *optional*, defaults to `self.unet.config.sample_size * self.vae_scale_factor`) -- | |
| The width in pixels of the generated video. | |
| - **num_frames** (`int`, *optional*, defaults to 16) -- | |
| The number of video frames that are generated. Defaults to 16 frames which at 8 frames per seconds | |
| amounts to 2 seconds of video. | |
| - **num_inference_steps** (`int`, *optional*, defaults to 50) -- | |
| The number of denoising steps. More denoising steps usually lead to a higher quality videos at the | |
| expense of slower inference. | |
| - **guidance_scale** (`float`, *optional*, defaults to 7.5) -- | |
| A higher guidance scale value encourages the model to generate images closely linked to the text | |
| `prompt` at the expense of lower image quality. Guidance scale is enabled when `guidance_scale > 1`. | |
| - **negative_prompt** (`str` or `list[str]`, *optional*) -- | |
| The prompt or prompts to guide what to not include in image generation. If not defined, you need to | |
| pass `negative_prompt_embeds` instead. Ignored when not using guidance (`guidance_scale 0[TextToVideoSDPipelineOutput](/docs/diffusers/main/en/api/pipelines/text_to_video#diffusers.pipelines.text_to_video_synthesis.TextToVideoSDPipelineOutput) or `tuple`If `return_dict` is `True`, [TextToVideoSDPipelineOutput](/docs/diffusers/main/en/api/pipelines/text_to_video#diffusers.pipelines.text_to_video_synthesis.TextToVideoSDPipelineOutput) is | |
| returned, otherwise a `tuple` is returned where the first element is a list with the generated frames. | |
| The call function to the pipeline for generation. | |
| Examples: | |
| ```py | |
| >>> import torch | |
| >>> from diffusers import TextToVideoSDPipeline | |
| >>> from diffusers.utils import export_to_video | |
| >>> pipe = TextToVideoSDPipeline.from_pretrained( | |
| ... "damo-vilab/text-to-video-ms-1.7b", torch_dtype=torch.float16, variant="fp16" | |
| ... ) | |
| >>> pipe.enable_model_cpu_offload() | |
| >>> prompt = "Spiderman is surfing" | |
| >>> video_frames = pipe(prompt).frames[0] | |
| >>> video_path = export_to_video(video_frames) | |
| >>> video_path | |
| ``` | |
| **Parameters:** | |
| prompt (`str` or `list[str]`, *optional*) : The prompt or prompts to guide image generation. If not defined, you need to pass `prompt_embeds`. | |
| height (`int`, *optional*, defaults to `self.unet.config.sample_size * self.vae_scale_factor`) : The height in pixels of the generated video. | |
| width (`int`, *optional*, defaults to `self.unet.config.sample_size * self.vae_scale_factor`) : The width in pixels of the generated video. | |
| num_frames (`int`, *optional*, defaults to 16) : The number of video frames that are generated. Defaults to 16 frames which at 8 frames per seconds amounts to 2 seconds of video. | |
| num_inference_steps (`int`, *optional*, defaults to 50) : The number of denoising steps. More denoising steps usually lead to a higher quality videos at the expense of slower inference. | |
| guidance_scale (`float`, *optional*, defaults to 7.5) : A higher guidance scale value encourages the model to generate images closely linked to the text `prompt` at the expense of lower image quality. Guidance scale is enabled when `guidance_scale > 1`. | |
| negative_prompt (`str` or `list[str]`, *optional*) : The prompt or prompts to guide what to not include in image generation. If not defined, you need to pass `negative_prompt_embeds` instead. Ignored when not using guidance (`guidance_scale 1`. | |
| - **negative_prompt** (`str` or `list[str]`, *optional*) -- | |
| The prompt or prompts to guide what to not include in video generation. If not defined, you need to | |
| pass `negative_prompt_embeds` instead. Ignored when not using guidance (`guidance_scale 0[TextToVideoSDPipelineOutput](/docs/diffusers/main/en/api/pipelines/text_to_video#diffusers.pipelines.text_to_video_synthesis.TextToVideoSDPipelineOutput) or `tuple`If `return_dict` is `True`, [TextToVideoSDPipelineOutput](/docs/diffusers/main/en/api/pipelines/text_to_video#diffusers.pipelines.text_to_video_synthesis.TextToVideoSDPipelineOutput) is | |
| returned, otherwise a `tuple` is returned where the first element is a list with the generated frames. | |
| The call function to the pipeline for generation. | |
| Examples: | |
| ```py | |
| >>> import torch | |
| >>> from diffusers import DiffusionPipeline, DPMSolverMultistepScheduler | |
| >>> from diffusers.utils import export_to_video | |
| >>> pipe = DiffusionPipeline.from_pretrained("cerspense/zeroscope_v2_576w", torch_dtype=torch.float16) | |
| >>> pipe.scheduler = DPMSolverMultistepScheduler.from_config(pipe.scheduler.config) | |
| >>> pipe.to("cuda") | |
| >>> prompt = "spiderman running in the desert" | |
| >>> video_frames = pipe(prompt, num_inference_steps=40, height=320, width=576, num_frames=24).frames[0] | |
| >>> # safe low-res video | |
| >>> video_path = export_to_video(video_frames, output_video_path="./video_576_spiderman.mp4") | |
| >>> # let's offload the text-to-image model | |
| >>> pipe.to("cpu") | |
| >>> # and load the image-to-image model | |
| >>> pipe = DiffusionPipeline.from_pretrained( | |
| ... "cerspense/zeroscope_v2_XL", torch_dtype=torch.float16, revision="refs/pr/15" | |
| ... ) | |
| >>> pipe.scheduler = DPMSolverMultistepScheduler.from_config(pipe.scheduler.config) | |
| >>> pipe.enable_model_cpu_offload() | |
| >>> # The VAE consumes A LOT of memory, let's make sure we run it in sliced mode | |
| >>> pipe.vae.enable_slicing() | |
| >>> # now let's upscale it | |
| >>> video = [Image.fromarray(frame).resize((1024, 576)) for frame in video_frames] | |
| >>> # and denoise it | |
| >>> video_frames = pipe(prompt, video=video, strength=0.6).frames[0] | |
| >>> video_path = export_to_video(video_frames, output_video_path="./video_1024_spiderman.mp4") | |
| >>> video_path | |
| ``` | |
| **Parameters:** | |
| prompt (`str` or `list[str]`, *optional*) : The prompt or prompts to guide image generation. If not defined, you need to pass `prompt_embeds`. | |
| video (`list[np.ndarray]` or `torch.Tensor`) : `video` frames or tensor representing a video batch to be used as the starting point for the process. Can also accept video latents as `image`, if passing latents directly, it will not be encoded again. | |
| strength (`float`, *optional*, defaults to 0.8) : Indicates extent to transform the reference `video`. Must be between 0 and 1. `video` is used as a starting point, adding more noise to it the larger the `strength`. The number of denoising steps depends on the amount of noise initially added. When `strength` is 1, added noise is maximum and the denoising process runs for the full number of iterations specified in `num_inference_steps`. A value of 1 essentially ignores `video`. | |
| num_inference_steps (`int`, *optional*, defaults to 50) : The number of denoising steps. More denoising steps usually lead to a higher quality videos at the expense of slower inference. | |
| guidance_scale (`float`, *optional*, defaults to 7.5) : A higher guidance scale value encourages the model to generate images closely linked to the text `prompt` at the expense of lower image quality. Guidance scale is enabled when `guidance_scale > 1`. | |
| negative_prompt (`str` or `list[str]`, *optional*) : The prompt or prompts to guide what to not include in video generation. If not defined, you need to pass `negative_prompt_embeds` instead. Ignored when not using guidance (`guidance_scale < 1`). | |
| eta (`float`, *optional*, defaults to 0.0) : Corresponds to parameter eta (η) from the [DDIM](https://huggingface.co/papers/2010.02502) paper. Only applies to the [DDIMScheduler](/docs/diffusers/main/en/api/schedulers/ddim#diffusers.DDIMScheduler), and is ignored in other schedulers. | |
| generator (`torch.Generator` or `list[torch.Generator]`, *optional*) : A [`torch.Generator`](https://pytorch.org/docs/stable/generated/torch.Generator.html) to make generation deterministic. | |
| latents (`torch.Tensor`, *optional*) : Pre-generated noisy latents sampled from a Gaussian distribution, to be used as inputs for video generation. Can be used to tweak the same generation with different prompts. If not provided, a latents tensor is generated by sampling using the supplied random `generator`. Latents should be of shape `(batch_size, num_channel, num_frames, height, width)`. | |
| prompt_embeds (`torch.Tensor`, *optional*) : Pre-generated text embeddings. Can be used to easily tweak text inputs (prompt weighting). If not provided, text embeddings are generated from the `prompt` input argument. | |
| negative_prompt_embeds (`torch.Tensor`, *optional*) : Pre-generated negative text embeddings. Can be used to easily tweak text inputs (prompt weighting). If not provided, `negative_prompt_embeds` are generated from the `negative_prompt` input argument. | |
| output_type (`str`, *optional*, defaults to `"np"`) : The output format of the generated video. Choose between `torch.Tensor` or `np.array`. | |
| return_dict (`bool`, *optional*, defaults to `True`) : Whether or not to return a [TextToVideoSDPipelineOutput](/docs/diffusers/main/en/api/pipelines/text_to_video#diffusers.pipelines.text_to_video_synthesis.TextToVideoSDPipelineOutput) instead of a plain tuple. | |
| callback (`Callable`, *optional*) : A function that calls every `callback_steps` steps during inference. The function is called with the following arguments: `callback(step: int, timestep: int, latents: torch.Tensor)`. | |
| callback_steps (`int`, *optional*, defaults to 1) : The frequency at which the `callback` function is called. If not specified, the callback is called at every step. | |
| cross_attention_kwargs (`dict`, *optional*) : A kwargs dictionary that if specified is passed along to the `AttentionProcessor` as defined in [`self.processor`](https://github.com/huggingface/diffusers/blob/main/src/diffusers/models/attention_processor.py). | |
| clip_skip (`int`, *optional*) : Number of layers to be skipped from CLIP while computing the prompt embeddings. A value of 1 means that the output of the pre-final layer will be used for computing the prompt embeddings. | |
| **Returns:** | |
| `[TextToVideoSDPipelineOutput](/docs/diffusers/main/en/api/pipelines/text_to_video#diffusers.pipelines.text_to_video_synthesis.TextToVideoSDPipelineOutput) or `tuple`` | |
| If `return_dict` is `True`, [TextToVideoSDPipelineOutput](/docs/diffusers/main/en/api/pipelines/text_to_video#diffusers.pipelines.text_to_video_synthesis.TextToVideoSDPipelineOutput) is | |
| returned, otherwise a `tuple` is returned where the first element is a list with the generated frames. | |
| #### encode_prompt[[diffusers.VideoToVideoSDPipeline.encode_prompt]] | |
| [Source](https://github.com/huggingface/diffusers/blob/main/src/diffusers/pipelines/text_to_video_synthesis/pipeline_text_to_video_synth_img2img.py#L194) | |
| Encodes the prompt into text encoder hidden states. | |
| **Parameters:** | |
| prompt (`str` or `list[str]`, *optional*) : prompt to be encoded | |
| device : (`torch.device`): torch device | |
| num_images_per_prompt (`int`) : number of images that should be generated per prompt | |
| do_classifier_free_guidance (`bool`) : whether to use classifier free guidance or not | |
| negative_prompt (`str` or `list[str]`, *optional*) : The prompt or prompts not to guide the image generation. If not defined, one has to pass `negative_prompt_embeds` instead. Ignored when not using guidance (i.e., ignored if `guidance_scale` is less than `1`). | |
| prompt_embeds (`torch.Tensor`, *optional*) : Pre-generated text embeddings. Can be used to easily tweak text inputs, *e.g.* prompt weighting. If not provided, text embeddings will be generated from `prompt` input argument. | |
| negative_prompt_embeds (`torch.Tensor`, *optional*) : Pre-generated negative text embeddings. Can be used to easily tweak text inputs, *e.g.* prompt weighting. If not provided, negative_prompt_embeds will be generated from `negative_prompt` input argument. | |
| lora_scale (`float`, *optional*) : A LoRA scale that will be applied to all LoRA layers of the text encoder if LoRA layers are loaded. | |
| clip_skip (`int`, *optional*) : Number of layers to be skipped from CLIP while computing the prompt embeddings. A value of 1 means that the output of the pre-final layer will be used for computing the prompt embeddings. | |
| ## TextToVideoSDPipelineOutput[[diffusers.pipelines.text_to_video_synthesis.TextToVideoSDPipelineOutput]] | |
| #### diffusers.pipelines.text_to_video_synthesis.TextToVideoSDPipelineOutput[[diffusers.pipelines.text_to_video_synthesis.TextToVideoSDPipelineOutput]] | |
| [Source](https://github.com/huggingface/diffusers/blob/main/src/diffusers/pipelines/text_to_video_synthesis/pipeline_output.py#L13) | |
| Output class for text-to-video pipelines. | |
| PIL image sequences of length `num_frames.` It can also be a NumPy array or Torch tensor of shape | |
| `(batch_size, num_frames, channels, height, width)` | |
| **Parameters:** | |
| frames (`torch.Tensor`, `np.ndarray`, or list[list[PIL.Image.Image]]) : list of video outputs - It can be a nested list of length `batch_size,` with each sub-list containing denoised | |
Xet Storage Details
- Size:
- 21 kB
- Xet hash:
- 07a1fcdd749fd9c81625efc95f5a857c50450cf477f11ddacd93a534afa6a362
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.