Diffusers documentation

ChronoEdit

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v0.42.1).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

LoRA

ChronoEdit

NVIDIA とトロント大学による、Jay Zhangjie Wu、Xuanchi Ren、Tianchang Shen、Tianshi Cao、Kai He、Yifan Lu、Ruiyuan Gao、Enze Xie、Shiyi Lan、Jose M. Alvarez、Jun Gao、Sanja Fidler、Zian Wang、Huan Ling による ChronoEdit: Towards Temporal Reasoning for Image Editing and World Simulation

要点: ChronoEditは画像編集を動画生成タスクとして再定式化し、入力画像と編集済み画像をそれぞれ開始フレームと終了フレームとして用いることで、時間的一貫性を備えた事前学習済み動画モデルの活用を実現します。時間的推論ステージでは、物理的に妥当な編集を保証し、編集の軌道を可視化するために推論トークンを導入します。

大規模生成モデルの最近の進歩により、画像編集とインコンテキスト画像生成の両方が大きく向上していますが、編集されたオブジェクトが整合性を保つという物理的一貫性を確保する点において、依然として重要なギャップが残っています。この機能は、ワールドシミュレーション関連のタスクにおいて特に重要です。本論文では、画像編集を動画生成問題として再定義するフレームワークである ChronoEdit を提案します。まず、ChronoEdit は入力画像と編集済み画像を動画の最初のフレームと最後のフレームとして扱い、オブジェクトの外観だけでなく、学習された時間的一貫性を通じて運動と相互作用の暗黙的な物理法則も捉える大規模事前学習済み動画生成モデルを活用します。次に、ChronoEdit は推論時に明示的に編集を行う時間的推論ステージを導入します。この設定下では、ターゲットフレームは推論トークンと共同でノイズ除去され、物理的に実現可能な変換に解空間を制約する妥当な編集軌道を想像します。その後、完全な動画のレンダリングに伴う高い計算コストを回避するため、数ステップ後に推論トークンを破棄します。ChronoEdit の検証のため、物理的一貫性が求められるコンテキスト向けの画像とプロンプトのペアからなる新しいベンチマーク PBench-Edit を導入し、ChronoEdit が視覚的忠実度と物理的妥当性の両面で最先端のベースラインを上回ることが示されました。コードとモデルのプロジェクトページ: this https URL。

ChronoEdit パイプラインは、ChronoEdit チームによって開発されました。元のコードはGitHubで利用可能であり、事前学習済みモデルは Hugging Face のnvidia/ChronoEditコレクションで確認できます。

利用可能なモデル/LoRA:

画像編集

import torch
import numpy as np
from diffusers import AutoencoderKLWan, ChronoEditTransformer3DModel, ChronoEditPipeline
from diffusers.utils import export_to_video, load_image
from transformers import CLIPVisionModel
from PIL import Image

model_id = "nvidia/ChronoEdit-14B-Diffusers"
image_encoder = CLIPVisionModel.from_pretrained(model_id, subfolder="image_encoder", dtype=torch.float32)
vae = AutoencoderKLWan.from_pretrained(model_id, subfolder="vae", dtype=torch.float32)
transformer = ChronoEditTransformer3DModel.from_pretrained(model_id, subfolder="transformer", dtype=torch.bfloat16)
pipe = ChronoEditPipeline.from_pretrained(model_id, image_encoder=image_encoder, transformer=transformer, vae=vae, dtype=torch.bfloat16)
pipe.to("cuda")  # or "mps", "xpu", "cpu"

image = load_image(
    "https://huggingface.co/spaces/nvidia/ChronoEdit/resolve/main/examples/3.png"
)
max_area = 720 * 1280
aspect_ratio = image.height / image.width
mod_value = pipe.vae_scale_factor_spatial * pipe.transformer.config.patch_size[1]
height = round(np.sqrt(max_area * aspect_ratio)) // mod_value * mod_value
width = round(np.sqrt(max_area / aspect_ratio)) // mod_value * mod_value
print("width", width, "height", height)
image = image.resize((width, height))
prompt = (
    "The user wants to transform the image by adding a small, cute mouse sitting inside the floral teacup, enjoying a spa bath. The mouse should appear relaxed and cheerful, with a tiny white bath towel draped over its head like a turban. It should be positioned comfortably in the cup’s liquid, with gentle steam rising around it to blend with the cozy atmosphere. "
    "The mouse’s pose should be natural—perhaps sitting upright with paws resting lightly on the rim or submerged in the tea. The teacup’s floral design, gold trim, and warm lighting must remain unchanged to preserve the original aesthetic. The steam should softly swirl around the mouse, enhancing the spa-like, whimsical mood."
)

output = pipe(
    image=image,
    prompt=prompt,
    height=height,
    width=width,
    num_frames=5,
    num_inference_steps=50,
    guidance_scale=5.0,
    enable_temporal_reasoning=False,
    num_temporal_reasoning_steps=0,
).frames[0]
Image.fromarray((output[-1] * 255).clip(0, 255).astype("uint8")).save("output.png")

必要に応じて、物理的な一貫性を向上させるために時間的推論を有効にします:

output = pipe(
    image=image,
    prompt=prompt,
    height=height,
    width=width,
    num_frames=29,
    num_inference_steps=50,
    guidance_scale=5.0,
    enable_temporal_reasoning=True,
    num_temporal_reasoning_steps=50,
).frames[0]
export_to_video(output, "output.mp4", fps=16)
Image.fromarray((output[-1] * 255).clip(0, 255).astype("uint8")).save("output.png")

8ステップ蒸留LoRAによる推論

import torch
import numpy as np
from diffusers import AutoencoderKLWan, ChronoEditTransformer3DModel, ChronoEditPipeline
from diffusers.schedulers import UniPCMultistepScheduler
from diffusers.utils import export_to_video, load_image
from transformers import CLIPVisionModel
from PIL import Image

model_id = "nvidia/ChronoEdit-14B-Diffusers"
image_encoder = CLIPVisionModel.from_pretrained(model_id, subfolder="image_encoder", dtype=torch.float32)
vae = AutoencoderKLWan.from_pretrained(model_id, subfolder="vae", dtype=torch.float32)
transformer = ChronoEditTransformer3DModel.from_pretrained(model_id, subfolder="transformer", dtype=torch.bfloat16)
pipe = ChronoEditPipeline.from_pretrained(model_id, image_encoder=image_encoder, transformer=transformer, vae=vae, dtype=torch.bfloat16)
pipe.load_lora_weights("nvidia/ChronoEdit-14B-Diffusers", weight_name="lora/chronoedit_distill_lora.safetensors", adapter_name="distill")
pipe.fuse_lora(adapter_names=["distill"], lora_scale=1.0)
pipe.scheduler = UniPCMultistepScheduler.from_config(pipe.scheduler.config, flow_shift=2.0)
pipe.to("cuda")  # or "mps", "xpu", "cpu"

image = load_image(
    "https://huggingface.co/spaces/nvidia/ChronoEdit/resolve/main/examples/3.png"
)
max_area = 720 * 1280
aspect_ratio = image.height / image.width
mod_value = pipe.vae_scale_factor_spatial * pipe.transformer.config.patch_size[1]
height = round(np.sqrt(max_area * aspect_ratio)) // mod_value * mod_value
width = round(np.sqrt(max_area / aspect_ratio)) // mod_value * mod_value
print("width", width, "height", height)
image = image.resize((width, height))
prompt = (
    "The user wants to transform the image by adding a small, cute mouse sitting inside the floral teacup, enjoying a spa bath. The mouse should appear relaxed and cheerful, with a tiny white bath towel draped over its head like a turban. It should be positioned comfortably in the cup’s liquid, with gentle steam rising around it to blend with the cozy atmosphere. "
    "The mouse’s pose should be natural—perhaps sitting upright with paws resting lightly on the rim or submerged in the tea. The teacup’s floral design, gold trim, and warm lighting must remain unchanged to preserve the original aesthetic. The steam should softly swirl around the mouse, enhancing the spa-like, whimsical mood."
)

output = pipe(
    image=image,
    prompt=prompt,
    height=height,
    width=width,
    num_frames=5,
    num_inference_steps=8,
    guidance_scale=1.0,
    enable_temporal_reasoning=False,
    num_temporal_reasoning_steps=0,
).frames[0]
export_to_video(output, "output.mp4", fps=16)
Image.fromarray((output[-1] * 255).clip(0, 255).astype("uint8")).save("output.png")

複数のLoRAを用いた推論

import torch
import numpy as np
from diffusers import AutoencoderKLWan, ChronoEditTransformer3DModel, ChronoEditPipeline
from diffusers.schedulers import UniPCMultistepScheduler
from diffusers.utils import export_to_video, load_image
from transformers import CLIPVisionModel
from PIL import Image

model_id = "nvidia/ChronoEdit-14B-Diffusers"
image_encoder = CLIPVisionModel.from_pretrained(model_id, subfolder="image_encoder", dtype=torch.float32)
vae = AutoencoderKLWan.from_pretrained(model_id, subfolder="vae", dtype=torch.float32)
transformer = ChronoEditTransformer3DModel.from_pretrained(model_id, subfolder="transformer", dtype=torch.bfloat16)
pipe = ChronoEditPipeline.from_pretrained(model_id, image_encoder=image_encoder, transformer=transformer, vae=vae, dtype=torch.bfloat16)
pipe.load_lora_weights("nvidia/ChronoEdit-14B-Diffusers-Paint-Brush-Lora", weight_name="paintbrush_lora_diffusers.safetensors", adapter_name="paintbrush")
pipe.load_lora_weights("nvidia/ChronoEdit-14B-Diffusers", weight_name="lora/chronoedit_distill_lora.safetensors", adapter_name="distill")
pipe.fuse_lora(adapter_names=["paintbrush", "distill"], lora_scale=1.0)
pipe.scheduler = UniPCMultistepScheduler.from_config(pipe.scheduler.config, flow_shift=2.0)
pipe.to("cuda")  # or "mps", "xpu", "cpu"

image = load_image(
    "https://raw.githubusercontent.com/nv-tlabs/ChronoEdit/refs/heads/main/assets/images/input_paintbrush.png"
)
max_area = 720 * 1280
aspect_ratio = image.height / image.width
mod_value = pipe.vae_scale_factor_spatial * pipe.transformer.config.patch_size[1]
height = round(np.sqrt(max_area * aspect_ratio)) // mod_value * mod_value
width = round(np.sqrt(max_area / aspect_ratio)) // mod_value * mod_value
print("width", width, "height", height)
image = image.resize((width, height))
prompt = (
    "Turn the pencil sketch in the image into an actual object that is consistent with the image’s content. The user wants to change the sketch to a crown and a hat."
)

output = pipe(
    image=image,
    prompt=prompt,
    height=height,
    width=width,
    num_frames=5,
    num_inference_steps=8,
    guidance_scale=1.0,
    enable_temporal_reasoning=False,
    num_temporal_reasoning_steps=0,
).frames[0]
export_to_video(output, "output.mp4", fps=16)
Image.fromarray((output[-1] * 255).clip(0, 255).astype("uint8")).save("output_1.png")

ChronoEditPipeline

class diffusers.ChronoEditPipeline

< >

( tokenizer: AutoTokenizertext_encoder: UMT5EncoderModelimage_encoder: CLIPVisionModelimage_processor: CLIPImageProcessorPiltransformer: ChronoEditTransformer3DModelvae: AutoencoderKLWanscheduler: FlowMatchEulerDiscreteScheduler )

パラメータ

  • tokenizer (T5Tokenizer) — T5 の Tokenizer、具体的には google/umt5-xxl バリアントです。
  • text_encoder (T5EncoderModel) — T5、具体的には google/umt5-xxl バリアントです。
  • image_encoder (CLIPVisionModel) — CLIP、具体的には clip-vit-huge-patch14 バリアントです。
  • transformer (WanTransformer3DModel) — 入力潜在変数をノイズ除去するための条件付き Transformer。
  • scheduler (UniPCMultistepScheduler) — transformer と組み合わせて、エンコードされた画像の潜在変数からノイズを除去するために使用するスケジューラ。
  • vae (AutoencoderKLWan) — 潜在表現へのエンコードとデコードを行う、動画用の変分オートエンコーダ (VAE) モデル。

Wan を使用した画像から動画への生成を行う Pipeline です。

このモデルは DiffusionPipeline を継承しています。すべてのパイプラインに実装されている汎用的なメソッド(ダウンロード、保存、特定のデバイスでの実行など)については、スーパークラスのドキュメントを参照してください。

__call__

< >

( image: typing.Union[PIL.Image.Image, numpy.ndarray, torch.Tensor, list[PIL.Image.Image], list[numpy.ndarray], list[torch.Tensor]]prompt: str | list[str] = Nonenegative_prompt: str | list[str] = Noneheight: int = 480width: int = 832num_frames: int = 81num_inference_steps: int = 50guidance_scale: float = 5.0num_videos_per_prompt: int | None = 1generator: typing.Union[torch.Generator, list[torch.Generator], NoneType] = Nonelatents: typing.Optional[torch.Tensor] = Noneprompt_embeds: typing.Optional[torch.Tensor] = Nonenegative_prompt_embeds: typing.Optional[torch.Tensor] = Noneimage_embeds: typing.Optional[torch.Tensor] = Noneoutput_type: str | None = 'np'return_dict: bool = Trueattention_kwargs: dict[str, typing.Any] | None = Nonecallback_on_step_end: typing.Optional[typing.Callable[[int, int, NoneType], diffusers.callbacks.PipelineCallback | diffusers.callbacks.MultiPipelineCallbacks]] = Nonecallback_on_step_end_tensor_inputs: list[str] = ['latents']max_sequence_length: int = 512enable_temporal_reasoning: bool = Falsenum_temporal_reasoning_steps: int = 0 ) → ~ChronoEditPipelineOutput or tuple

パラメータ

  • image (PipelineImageInput) — 生成を条件づけるための入力画像です。画像、画像のリスト、またはtorch.Tensorである必要があります。
  • prompt (str または list[str]、省略可) — 画像生成をガイドするためのプロンプトです。未定義の場合、代わりに prompt_embeds を渡す必要があります。
  • negative_prompt (str または list[str]、省略可) — 画像生成をガイドしないプロンプトです。未定義の場合、代わりに negative_prompt_embeds を渡す必要があります。ガイダンスを使用していない場合は無視されます(guidance_scale が 1 未満の場合は無視されます)。
  • height (int、デフォルト値は 480) — 生成される動画の高さです。
  • width (int、デフォルトは832) — 生成される動画の幅です。
  • num_frames (int、デフォルトは 81) — 生成される動画のフレーム数です。
  • num_inference_steps (int、デフォルトは 50) — デノイジングのステップ数です。ステップ数を増やすと、推論速度が遅くなる代わりに、通常はより高品質な画像が得られます。
  • guidance_scale (float、デフォルト値は5.0) — Classifier-Free Diffusion Guidanceで定義されているガイダンススケールです。 guidance_scaleは、Imagen Paperの式2におけるwとして定義されています。guidance_scale > 1を設定することでガイダンススケールが有効になります。ガイダンススケールを高くすると、promptのテキストと密接に関連した画像の生成が促されますが、通常は画像の品質が低下する傾向があります。
  • num_videos_per_prompt (int、省略可能、デフォルト値は 1)— プロンプトごとに生成する画像の数。
  • generator (torch.Generator または list[torch.Generator]、省略可) — 生成を決定論的にするための torch.Generator。
  • latents (torch.Tensor, 任意) — ガウス分布からサンプリングされた事前生成されたノイズ付き latents。画像生成のインプットとして使用します。異なるプロンプトで同じ生成を調整するために使用できます。指定されない場合、指定されたランダム generator を用いてサンプリングを行い、latents テンソルが生成されます。
  • prompt_embeds (torch.Tensor, 任意) — 事前に生成されたテキスト埋め込みです。テキスト入力(プロンプトの重み付けなど)を簡単に調整するために使用できます。指定されない場合、prompt 入力引数からテキスト埋め込みが生成されます。
  • negative_prompt_embeds (torch.Tensor, 任意) — 事前に生成されたテキスト埋め込み。テキスト入力(プロンプトの重み付け)を簡単に調整するために使用できます。指定されない場合、negative_prompt 入力引数からテキスト埋め込みが生成されます。
  • image_embeds (torch.Tensor, 任意) — 事前に生成された画像埋め込み。画像入力(重み付け)を簡単に調整するために使用できます。指定されない場合、image 入力引数から画像埋め込みが生成されます。
  • output_type (str、任意、デフォルトは "np") — 生成された画像の出力形式。PIL.Image または np.array から選択します。
  • return_dict (bool、任意、デフォルトは True) — ChronoEditPipelineOutput を返すか、プレーンなタプルを返すかを指定します。
  • attention_kwargs (dict, 省略可) — 指定された場合、diffusers.models.attention_processor で定義されている self.processor 内の AttentionProcessor に渡される kwargs 辞書です。
  • callback_on_step_end (Callable、PipelineCallback、MultiPipelineCallbacks、省略可) — 推論中の各デノイジングステップの終了時に呼び出される関数、またはPipelineCallbackまたはMultiPipelineCallbacksのサブクラスです。引数は以下の通りです: callback_on_step_end(self: DiffusionPipeline, step: int, timestep: int, callback_kwargs: Dict)。callback_kwargsには、callback_on_step_end_tensor_inputsで指定されたすべてのテンソルのリストが含まれます。
  • callback_on_step_end_tensor_inputs (List, 任意) — callback_on_step_end 関数へのテンソル入力の一覧です。リストで指定されたテンソルは、callback_kwargs 引数として渡されます。パイプラインクラスの ._callback_tensor_inputs 属性にリストされている変数のみを含めることができます。
  • max_sequence_length (int、デフォルトは512) — テキストエンコーダーの最大シーケンス長です。プロンプトがこの長さを超える場合は切り詰められ、短い場合はこの長さにパディングされます。
  • enable_temporal_reasoning (bool、任意、デフォルトは False) — 時間的推論を有効にするかどうかを指定します。
  • num_temporal_reasoning_steps (int、任意、デフォルトは0) — 時間的推論を有効にするステップ数。

戻り値

~ChronoEditPipelineOutput または tuple

return_dict が True の場合、ChronoEditPipelineOutput が返され、それ以外の場合は tuple が返されます。このとき、最初の要素は生成された画像のリスト、2番目の要素は対応する生成画像に「not-safe-for-work」(nsfw)コンテンツが含まれているかどうかを示す bool のリストです。

生成用の pipeline への呼び出し関数。

例:

>>> import torch
>>> import numpy as np
>>> from diffusers import AutoencoderKLWan, ChronoEditTransformer3DModel, ChronoEditPipeline
>>> from diffusers.utils import export_to_video, load_image
>>> from transformers import CLIPVisionModel

>>> # Available models: nvidia/ChronoEdit-14B-Diffusers
>>> model_id = "nvidia/ChronoEdit-14B-Diffusers"
>>> image_encoder = CLIPVisionModel.from_pretrained(
...     model_id, subfolder="image_encoder", torch_dtype=torch.float32
... )
>>> vae = AutoencoderKLWan.from_pretrained(model_id, subfolder="vae", torch_dtype=torch.float32)
>>> transformer = ChronoEditTransformer3DModel.from_pretrained(
...     model_id, subfolder="transformer", torch_dtype=torch.bfloat16
... )
>>> pipe = ChronoEditPipeline.from_pretrained(
...     model_id, vae=vae, image_encoder=image_encoder, transformer=transformer, torch_dtype=torch.bfloat16
... )
>>> pipe.to("cuda")

>>> image = load_image("https://huggingface.co/spaces/nvidia/ChronoEdit/resolve/main/examples/3.png")
>>> max_area = 720 * 1280
>>> aspect_ratio = image.height / image.width
>>> mod_value = pipe.vae_scale_factor_spatial * pipe.transformer.config.patch_size[1]
>>> height = round(np.sqrt(max_area * aspect_ratio)) // mod_value * mod_value
>>> width = round(np.sqrt(max_area / aspect_ratio)) // mod_value * mod_value
>>> image = image.resize((width, height))
>>> prompt = (
...     "The user wants to transform the image by adding a small, cute mouse sitting inside the floral teacup, enjoying a spa bath. The mouse should appear relaxed and cheerful, with a tiny white bath towel draped over its head like a turban. It should be positioned comfortably in the cup’s liquid, with gentle steam rising around it to blend with the cozy atmosphere. "
...     "The mouse’s pose should be natural—perhaps sitting upright with paws resting lightly on the rim or submerged in the tea. The teacup’s floral design, gold trim, and warm lighting must remain unchanged to preserve the original aesthetic. The steam should softly swirl around the mouse, enhancing the spa-like, whimsical mood."
... )

>>> output = pipe(
...     image=image,
...     prompt=prompt,
...     height=height,
...     width=width,
...     num_frames=5,
...     guidance_scale=5.0,
...     enable_temporal_reasoning=False,
...     num_temporal_reasoning_steps=0,
... ).frames[0]
>>> export_to_video(output, "output.mp4", fps=16)

encode_prompt

< >

( prompt: str | list[str]negative_prompt: str | list[str] | None = Nonedo_classifier_free_guidance: bool = Truenum_videos_per_prompt: int = 1prompt_embeds: typing.Optional[torch.Tensor] = Nonenegative_prompt_embeds: typing.Optional[torch.Tensor] = Nonemax_sequence_length: int = 226device: typing.Optional[torch.device] = Nonedtype: typing.Optional[torch.dtype] = None )

パラメータ

  • prompt (str または list[str]、省略可能) — エンコードするプロンプト
  • negative_prompt (str または list[str]、省略可) — 画像生成をガイドしないプロンプトです。未定義の場合、代わりに negative_prompt_embeds を渡す必要があります。ガイダンスを使用していない場合は無視されます(guidance_scale が 1 未満の場合は無視されます)。
  • do_classifier_free_guidance (bool、任意、デフォルトは True) — classifier free guidance を使用するかどうかを指定します。
  • num_videos_per_prompt (int、任意、デフォルトは 1) — プロンプトごとに生成する動画の数を指定します。結果の埋め込みを配置する torch デバイス
  • prompt_embeds (torch.Tensor, 任意) — 事前に生成されたテキスト埋め込み。テキスト入力の調整、例えばプロンプトの重み付けなどを容易に行うために使用できます。指定されない場合、prompt 入力引数からテキスト埋め込みが生成されます。
  • negative_prompt_embeds (torch.Tensor, 任意) — 事前に生成されたネガティブなテキスト埋め込みです。テキスト入力の調整、例えばプロンプトの重み付けなどを簡単に実行できます。指定されない場合、negative_prompt 入力引数から negative_prompt_embeds が生成されます。
  • device — (torch.device、任意): torch デバイス
  • dtype — (torch.dtype、省略可): torch の dtype

プロンプトをテキストエンコーダーの隠れ状態にエンコードします。

ChronoEditPipelineOutput

クラス diffusers.pipelines.chronoedit.pipeline_output.ChronoEditPipelineOutput

< >

( frames: Tensor )

パラメータ

  • 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 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).

ChronoEdit パイプライン用の出力クラスです。

Update on GitHub