利用 Diffusers 進行 Text-to-Video 生成

  • 隨著深度學習技術的發展,從文字描述生成影像或影片已成為熱門的研究方向。本篇教學將介紹如何利用 diffusers 框架中的 MochiPipeline,將一段文字描述轉換成一段影片。


  • 我們會使用以下主要組件:

    • Text Encoder:使用 T5 模型將文字 prompt 轉換成模型可理解的向量表示。
    • Transformer 模型:生成影片的中間隱藏表示,這裡使用的是 MochiTransformer3DModel。
    • VAE(變分自編碼器):將隱藏表示還原為真實的影像資料。
  • 此外,為了降低記憶體消耗,我們也會對部分模型進行量化,並啟用 CPU offload、tiling 與 slicing 等運行優化技巧。


  • Step 1: 引入所需模組與套件

    • 首先,我們需要載入 PyTorch、diffusers 模組、transformers 模型(T5EncoderModel)以及量化工具等必要套件。
    • 這些模組將協助我們建立模型、設置 pipeline 並輸出最終的影片檔案。
    • .
      import os
      import torch
      from diffusers import AutoencoderKLMochi, MochiTransformer3DModel, MochiPipeline
      from diffusers.utils import export_to_video
      from transformers.models.t5 import T5EncoderModel
      from torchao.quantization import quantize_, float8_weight_only

  • Step 2: 載入預訓練模型

    • 所有模型皆設定 torch_dtype 為 bfloat16,以提升計算效能與穩定性。


    • 在這一步,我們依序載入各個子模型:

      • Text Encoder:使用 T5EncoderModel,將文字轉換成語意向量。
      • Transformer 模型:使用 MochiTransformer3DModel 來生成影片的中間表示,並針對其使用量化技術(例如 float8_weight_only)以降低記憶體消耗。
      • VAE:使用 AutoencoderKLMochi 將隱藏表示還原成最終的影像。
    • .


      model_path = "VikramSingh178/mochi-diffuser-bf16"
      output_path = "./output"
      quantization = float8_weight_only

      # 載入文字編碼器
      text_encoder = T5EncoderModel.from_pretrained(
      model_path,
      subfolder="text_encoder",
      torch_dtype=torch.bfloat16,
      )

      # 載入 Transformer 並進行量化
      transformer = MochiTransformer3DModel.from_pretrained(
      model_path,
      subfolder="transformer",
      torch_dtype=torch.bfloat16,
      )
      quantize_(transformer, quantization())

      # 載入 VAE 模型
      vae = AutoencoderKLMochi.from_pretrained(
      model_path,
      subfolder="vae",
      torch_dtype=torch.bfloat16,
      )

  • Step 3: 建立並配置 Text-to-Video Pipeline

    • 接著,我們使用以上載入的各個模型來建立 MochiPipeline


    • 建立 pipeline 後,將其移至 GPU(例如 "cuda"),並啟用以下優化技巧:

      • CPU Offload:在 GPU 記憶體不足時自動將部分模型權重從 CPU 傳輸到 GPU。
      • VAE Tiling 與 Slicing:這兩個技巧可降低 VAE 在處理高解析度影像時的記憶體使用量。
    • .


      # 建立 pipeline 並移至 GPU
      pipe = MochiPipeline.from_pretrained(
      model_path,
      text_encoder=text_encoder,
      transformer=transformer,
      vae=vae,
      ).to("cuda")

      # 啟用 CPU offload 與 VAE 優化
      pipe.enable_model_cpu_offload()
      pipe.vae.enable_tiling()
      pipe.vae.enable_slicing()

  • Step 4: 配置生成參數並進行影片生成

    • 在此步驟中,我們設定影片生成所需的各項參數,例如:
      • prompt:文字描述,指導模型生成影片內容。
      • negative_prompt:排除不希望出現的內容(例如扭曲的物體、暗黑場景)。
      • 影片尺寸:設定影片的高度與寬度。
      • 推論步數、幀數與指導比例:調整生成影片的精細程度。
      • 隨機種子:使用 torch.Generator 設定種子,確保結果可重現。
    • 調用 pipeline 後,模型會根據這些參數生成包含多個幀的影片。
    • .
            
      prompt = "Donald Trump, holding a knife, approaches an access-controlled door, preparing to unlock it with precision and focus."

      video = pipe(
      height=480,
      width=864,
      negative_prompt="Twisted objects, escaped people, distorted faces, dark scenes",
      prompt=prompt,
      num_videos_per_prompt=1,
      num_inference_steps=50,
      num_frames=49,
      guidance_scale=7.5,
      generator=torch.Generator(device="cuda").manual_seed(42),
      )

  • Step 5: 將生成影片輸出為檔案

    • 生成影片的最後一步,就是將模型輸出的影像幀序列轉換成影片檔案(例如 MP4 格式)。
    • 我們使用 diffusers 中的 export_to_video 函數來完成這項工作,並將影片儲存至指定的輸出路徑。
    • .
            
      video_name = "mochi1_6s_trump_20250123_856x480_securityDoor1_llm"
      export_to_video(
      video.frames[0],
      os.path.join(output_path, video_name + ".mp4"),
      fps=8,
      )

  • 完整程式碼範例

    • 以下提供一份完整的 Text-to-Video 程式碼範例,結合上述所有步驟,方便大家直接參考與實作:
    • .
            
      import os
      import torch
      from diffusers import AutoencoderKLMochi, MochiTransformer3DModel, MochiPipeline
      from diffusers.utils import export_to_video
      from transformers.models.t5 import T5EncoderModel
      from torchao.quantization import quantize_, float8_weight_only

      # 模型與輸出路徑設定
      model_path = "VikramSingh178/mochi-diffuser-bf16"
      output_path = "./output"
      quantization = float8_weight_only

      # Step 1: 載入文字編碼器
      text_encoder = T5EncoderModel.from_pretrained(
      model_path,
      subfolder="text_encoder",
      torch_dtype=torch.bfloat16,
      )

      # Step 2: 載入 Transformer 並進行量化
      transformer = MochiTransformer3DModel.from_pretrained(
      model_path,
      subfolder="transformer",
      torch_dtype=torch.bfloat16,
      )
      quantize_(transformer, quantization())

      # Step 3: 載入 VAE 模型
      vae = AutoencoderKLMochi.from_pretrained(
      model_path,
      subfolder="vae",
      torch_dtype=torch.bfloat16,
      )

      # Step 4: 建立並配置 Pipeline
      pipe = MochiPipeline.from_pretrained(
      model_path,
      text_encoder=text_encoder,
      transformer=transformer,
      vae=vae,
      ).to("cuda")

      pipe.enable_model_cpu_offload()
      pipe.vae.enable_tiling()
      pipe.vae.enable_slicing()

      # 設定生成影片所需的參數
      prompt = "Donald Trump, holding a knife, approaches an access-controlled door, preparing to unlock it with precision and focus."

      video = pipe(
      height=480,
      width=864,
      negative_prompt="Twisted objects, escaped people, distorted faces, dark scenes",
      prompt=prompt,
      num_videos_per_prompt=1,
      num_inference_steps=50,
      num_frames=49,
      guidance_scale=7.5,
      generator=torch.Generator(device="cuda").manual_seed(42),
      )

      # Step 5: 輸出影片檔案
      video_name = "mochi1_6s_trump_20250123_856x480_securityDoor1_llm"
      export_to_video(
      video.frames[0],
      os.path.join(output_path, video_name + ".mp4"),
      fps=8,

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments