Diffusers documentation
SANA-WM
SANA-WM
SANA-WM هو نموذج عالم لتحويل الصور إلى فيديو يتحكم فيه الكاميرا، مبني على أساس SANA. عند تقديم صورة للإطار الأول، وموجّه نصي، ومسار كاميرا (إما أوضاع c2w صريحة أو سلسلة إجراءات WASD/IJKL)، يولّد النموذج فيديو يتبع حركته المسار المطلوب للكاميرا.
تعمل الاستدلال في مرحلتين:
- المرحلة 1 — SANA-WM DiT. نموذج DiT ثنائي الاتجاه يحتوي على 1.6 مليار معامل، ويعتمد على انتباه خطي GDN-Triton وفرع تحكم في الكاميرا UCPE. يستخدم العينة جدولة أويلر مطابقة للتدفق بنمط LTX مع خطوات زمنية لكل رمز؛ حيث تكون الإطار الكامن الأول هو نقطة الارتكاز للشروط.
- المرحلة 2 — مُحسّن LTX-2 (اختياري). خط أنابيب مُحسّن أويلر ثنائي الاتجاه منفصل
(SanaWMLTX2Refiner) يغلّف SanaWMLTX2RefinerTransformer3DModel +
LTX2TextConnectorsومشفّر نصوص Gemma-3، ويُنفَّذ لثلاث خطوات سيجما مُقطّرة.
تقوم كلتا المرحلتين بفك الترميز عبر AutoencoderKLLTX2Video VAE.
النماذج المتاحة:
| النموذج | نوع البيانات الموصى به |
|---|---|
Efficient-Large-Model/SANA-WM_bidirectional-diffusers | torch.bfloat16 |
Efficient-Large-Model/SANA-WM_bidirectional-diffusers-refiner | torch.bfloat16 |
يتم تدريب SANA-WM بدقة ثابتة تبلغ 704×1280. النوع الموصى به لأوزان المحول هو
torch.bfloat16— حافظ على مشفر النص فيtorch.bfloat16وVAE فيtorch.float32للحصول على أفضل دقة رقمية. يتوقع خط الأنابيب معاملات الكاميرا الداخلية[fx, fy, cx, cy]بإحداثيات بكسل الصورة الأصلية؛ حيث يتم تطبيق تحويل إعادة الحجم والقص المركزي داخلياً.
الاستدلال
import torch
from PIL import Image
from diffusers import SanaWMPipeline
from diffusers.utils import export_to_video
pipe = SanaWMPipeline.from_pretrained(
"Efficient-Large-Model/SANA-WM_bidirectional-diffusers",
torch_dtype=torch.bfloat16,
)
pipe.enable_model_cpu_offload() # ~45 GB of weights — offload between stages
# SANA-WM was trained on the LTX-2 VAE in framewise mode with tiling enabled. Without these
# settings the VAE encodes the whole (B, C, T, H, W) clip in one shot, which gives subtly
# different numerics from the released checkpoint.
pipe.vae.enable_tiling()
pipe.vae.use_framewise_encoding = True
pipe.vae.use_framewise_decoding = True
pipe.vae.tile_sample_stride_num_frames = 64
pipe.vae.tile_sample_min_num_frames = 96
prompt = "A car driving across a vast desert plain at golden hour."
output = pipe(
image=Image.open("input.png").convert("RGB"),
prompt=prompt,
action="w-80,jw-40,w-40", # WASD-style action DSL: forward 80f, jump+forward 40f, forward 40f
intrinsics=[800.0, 800.0, 845.0, 464.0], # fx, fy, cx, cy in original-image pixels
num_frames=161,
num_inference_steps=60,
guidance_scale=5.0,
generator=torch.Generator(device="cuda").manual_seed(42),
output_type="latent", # hand the latents to the refiner below
)مرّر action=None وفّر وضعيات c2w الخاصة بك ((F, 4, 4) مصفوفة numpy) لتحديد مسار الكاميرا بشكل صريح. احذف output_type="latent" للحصول على الفيديو مباشرة من المرحلة 1 وتخطي المُحسّن.
المرحلة 2 — مُحسّن LTX-2
يُصدر SanaWMLTX2Refiner كمستودع مستقل، على غرار تقسيم SDXL بين النموذج الأساسي والمُحسّن. مرّر وحدة VAE الخاصة بالخط الأساسي حتى تُشارك الأوزان بدلاً من تحميلها مرتين:
from diffusers import SanaWMLTX2Refiner
refiner = SanaWMLTX2Refiner.from_pretrained(
"Efficient-Large-Model/SANA-WM_bidirectional-diffusers-refiner",
vae=pipe.vae,
torch_dtype=torch.bfloat16,
)
refiner.enable_model_cpu_offload()
frames = refiner(output.latent, prompt, fps=16)
export_to_video(list(frames), "sana_wm.mp4", fps=16)بدون vae، يعيد المُحسِّن كامنات مُحسَّنة بدلاً من الفيديو، وهو أمر مفيد إذا كنت ترغب في فك الترميز بنفسك.
فعّل التحميل الجزئي على خطّتي المعالجة معًا، أو حرّر المرحلة 1 قبل المرحلة 2 (
pipe.transformer.to("cpu")). يبلغ حجم المرحلتين معًا حوالي 45 جيجابايت فيtorch.bfloat16، وإبقاء المرحلتين مقيمتين على بطاقة واحدة بسعة 80 جيجابايت لا يترك مساحة كافية للتفعيلات. لاحظ أيضًا أن المرحلة 2 تحترمtorch_dtype: فحمّل المُحسّن فيtorch.float32يضاعف ذاكرته تقريبًا ويغيّر المخرجات قليلاً.
إذا لم تكن لديك معاملات الكاميرا الداخلية، يمكن لـ الكتلة المعيارية المستضافة تقديرها من إطار واحد. وهي موجودة خارج diffusers لأنها تجلب Pi3X — وهو اعتماد إضافي ونقطة تحقق ثانية — لذا لن يتم تنزيل أي شيء حتى تطلب ذلك:
from diffusers import ModularPipeline
# One-time per image. Requires `pip install pi3-vision`.
estimator = ModularPipeline.from_pretrained(
"Efficient-Large-Model/pi3x-intrinsics-estimator", trust_remote_code=True
)
estimator.load_components(dtype=torch.bfloat16)
intrinsics = estimator(image=Image.open("input.png").convert("RGB"), output="intrinsics")تحويل نقطة التفتيش المُصدَّرة
إذا كان لديك إصدار SANA-WM الأصلي (وليس لقطة diffusers المحوّلة مسبقًا)، فنفّذ سكربت التحويل مرة واحدة:
python scripts/convert_sana_wm_to_diffusers.py \
--src Efficient-Large-Model/SANA-WM_bidirectional \
--dst ./SANA-WM_bidirectional-diffusersيكتب هذا الأمر مجلدين: خط الأنابيب الأساسي في --dst، ومُحسِّن المرحلة الثانية بجانبه في ./SANA-WM_bidirectional-diffusers-refiner (يمكن تجاوز ذلك باستخدام --dst-refiner). ثم حمّل كلًا منهما من مساره المحلي كما هو معتاد.
المكوّنات
tokenizer—GemmaTokenizerFasttext_encoder— Gemma-2 (يعيد حالات المخفية للوحّاد)vae— AutoencoderKLLTX2Video (LTX-2، مكاني ×32 / زمني ×8)transformer— SanaWMTransformer3DModel، نموذج DiT ثنائي الاتجاه يحتوي على 1.6 مليار معاملscheduler— FlowMatchEulerDiscreteScheduler
المُحسِّن في المرحلة الثانية هو مستودع مستقل يحتوي على transformer خاص به (SanaWMLTX2RefinerTransformer3DModel)، وconnectors (LTX2TextConnectors)، وtokenizer، وtext_encoder الخاص بنموذج Gemma-3، وscheduler. لا يحتوي على vae خاص به — قم بتمرير الخاص بخط الأنابيب الأساسي.
SanaWMPipeline
فئة diffusers.SanaWMPipeline
< source >( tokenizer: GemmaTokenizer | GemmaTokenizerFasttext_encoder: Gemma2PreTrainedModelvae: AutoencoderKLLTX2Videotransformer: SanaWMTransformer3DModelscheduler: FlowMatchEulerDiscreteScheduler )
المعاملات
- tokenizer ([GemmaTokenizer] أو [GemmaTokenizerFast]) — مُجزِّئ Gemma-2.
- text_encoder ([Gemma2PreTrainedModel]) — مُشفِّر النص في Gemma-2.
- vae ([AutoencoderKLLTX2Video]) — نموذج VAE الخاص بـ LTX-2.
- transformer ([SanaWMTransformer3DModel]) — نموذج DiT ثنائي الاتجاه بحجم 1600M الخاص بـ SANA-WM.
- scheduler ([FlowMatchEulerDiscreteScheduler]) — جدول زمني أويلر لمطابقة التدفق (خطوات زمنية لكل رمز على غرار LTX). الكامنات مباشرة.
خط أنابيب تحويل الصورة إلى فيديو معتمد على الكاميرا في SANA-WM.
يولّد مقطع فيديو من صورة الإطار الأول، وموجّه نصي، ومسار كاميرا (إحداثيات c2w صريحة أو سلسلة إجراءات WASD/IJKL). يستخدم نموذج SANA DiT ثنائي الاتجاه بحجم 1600M للعينات في المرحلة الأولى، ومُحسّن Euler ثنائي الاتجاه الخاص بـ LTX-2 للتحسين في المرحلة الثانية؛ وكلاهما يُفكّك عبر VAE الخاص بـ LTX-2.
__call__
< source >( image: PIL.Image.Image | str | Pathprompt: strc2w: np.ndarray | None = Noneaction: str | None = Noneintrinsics: np.ndarray | list[float] | None = Noneheight: int = 704width: int = 1280num_frames: int = 161fps: int = 16num_inference_steps: int = 60guidance_scale: float = 5.0negative_prompt: str = ''generator: torch.Generator | list[torch.Generator] | None = Noneprompt_embeds: torch.Tensor | None = Noneprompt_attention_mask: torch.Tensor | None = Nonenegative_prompt_embeds: torch.Tensor | None = Nonenegative_prompt_attention_mask: torch.Tensor | None = Nonemax_sequence_length: int = 300chi_prompt: list[str] | None = Noneoutput_type: Literal['np', 'pil', 'pt', 'latent'] = 'np'callback_on_step_end: Callable[[DiffusionPipeline, int, int, dict], dict] | None = Nonecallback_on_step_end_tensor_inputs: list[str] = ['latents']return_dict: bool = True )
المعاملات
- image (PIL.Image.Image أو str) — صورة الإطار الأول (PIL أو مسار).
- prompt (str) — موجّه نصي.
- c2w (np.ndarray، اختياري) —
(F, 4, 4)أوضاع الكاميرا إلى العالم. متنافي مع action. - action (str، اختياري) —
نص Action-DSL مثل
"w-80,jw-40,w-40". متنافٍ مع c2w. - intrinsics (np.ndarray أو list[float]) —
[fx, fy, cx, cy]بإحداثيات بكسل الصورة الأصلية. يطبّق خط المعالجة تحويل إعادة الحجم والقص داخليًا. - height (int، القيمة الافتراضية 704) — ارتفاع الإطار الناتج (ثابت في النموذج العام).
- width (int، القيمة الافتراضية 1280) — عرض إطار المخرجات (ثابت للنموذج العام).
- num_frames (int، القيمة الافتراضية 161) —
عدد الإطارات المستهدف؛ يُقرب إلى
8k+1(قيود VTX-2 VAE). - fps (int، القيمة الافتراضية 16) — معدل الإخراج لكل إطار (يُمرَّر أيضًا إلى المُحسِّن).
- num_inference_steps (int، القيمة الافتراضية 60) — عدد خطوات أخذ العينات في المرحلة الأولى من DiT.
- guidance_scale (float، القيمة الافتراضية 5.0) — مقياس التوجيه الحر من التصنيف.
- negative_prompt (str، الافتراضي "") — موجّه سلبي اختياري.
- generator (torch.Generator أو list[torch.Generator]، اختياري) — مولّد أو أكثر من مولّدات torch لجعل أخذ عينات الضوضاء حتمياً. إذا كان None، فإن أخذ العينات غير حتمي.
- prompt_embeds (torch.Tensor، اختياري) — تضمينات نصية محسوبة مسبقًا، لتخطي مُشفِّر النص. يجب تمريرها معًا مع prompt_attention_mask.
- prompt_attention_mask (torch.Tensor، اختياري) — قناع الانتباه (Attention mask) الخاص بـ prompt_embeds.
- negative_prompt_embeds (torch.Tensor، اختياري) — تضمينات نصية سالبة محسوبة مسبقًا. يجب تمريرها معًا مع negative_prompt_attention_mask.
- negative_prompt_attention_mask (torch.Tensor، اختياري) — قناع الانتباه (Attention mask) الخاص بـ negative_prompt_embeds.
- max_sequence_length (int، القيمة الافتراضية 300) — الحد الأقصى لرموز الاستعلام.
- chi_prompt (list[str]، اختياري) — تجاوز بادئة chi-prompt (الافتراضي يعكس الإصدار العام).
- output_type (“np”، “pil”، “pt”، أو “latent”، الافتراضي هو “np”) — صيغة المخرجات.
- callback_on_step_end (Callable، اختياري) — يُستدعى في نهاية كل خطوة إزالة ضوضاء على شكل callback_on_step_end(self, step, timestep, callback_kwargs)، حيث يحتوي callback_kwargs على الموترات (tensors) المذكورة في callback_on_step_end_tensor_inputs. تستبدل الموترات الموجودة في القاموس المُعاد الموترات الخاصة بخط الأنابيب.
- callback_on_step_end_tensor_inputs (list[str]، القيمة الافتراضية [“latents”]) — المصفوفات التي سيتم تمريرها إلى callback_on_step_end؛ يجب أن تكون مجموعة فرعية من ._callback_tensor_inputs.
- return_dict (bool، القيمة الافتراضية True) — إرجاع [SanaWMPipelineOutput] مقابل tuple.
أنشئ فيديوًا مُتحكَّمًا فيه بالكاميرا باستخدام SANA-WM.
أمثلة:
>>> import torch
>>> from PIL import Image
>>> from diffusers import SanaWMPipeline
>>> pipe = SanaWMPipeline.from_pretrained(
... "Efficient-Large-Model/SANA-WM_bidirectional-diffusers", torch_dtype=torch.bfloat16
... ).to("cuda")
>>> output = pipe(
... image=Image.open("input.png").convert("RGB"),
... prompt="A car driving across a vast desert plain at golden hour.",
... action="w-80,jw-40,w-40",
... intrinsics=[800.0, 800.0, 845.0, 464.0], # fx, fy, cx, cy in original-image pixels
... num_inference_steps=60,
... )
>>> # output.frames is (T, H, W, 3) float np.ndarray in [0, 1] (diffusers convention).check_inputs
< source >( c2w: np.ndarray | Noneaction: str | Noneintrinsics: np.ndarray | list[float] | Nonecallback_on_step_end_tensor_inputs: list[str] | None = None )
تحقق من مدخلات __call__. يرمي استثناءً عند وجود مدخل غير صالح ولا يعيد شيئًا.
encode_prompt
< source >( prompt: strnegative_prompt: str = ''device: torch.device | None = Nonemax_sequence_length: int = 300chi_prompt: list[str] | None = Noneprompt_embeds: torch.Tensor | None = Noneprompt_attention_mask: torch.Tensor | None = Nonenegative_prompt_embeds: torch.Tensor | None = Nonenegative_prompt_attention_mask: torch.Tensor | None = None )
ترميز الموجه والموجه السلبي عبر Gemma-2.
يعكس حيلة بادئة موجهات SANA: يُضاف موجه تشي إلى بداية موجه المستخدم، ثم يأخذ مقطع select_index = [0, -L+1, ..., -1] رمز BOS بالإضافة إلى آخر max_sequence_length - 1 رموز.
prepare_camera_trajectory
< source >( c2w: np.ndarray | Noneaction: str | Noneintrinsics: np.ndarray | list[float]num_frames: int )
قَيِّم مدخلات الكاميرا إلى (c2w_(F, 4, 4), intrinsics_(F, 4)).
كما يُقرب num_frames إلى أقرب قيمة صالحة لـ VAE على شكل 8k+1 ويقصّ المصفوفتين لتتطابق. أما الصورة المقصوصة والمداخلات المعاد تحجيمها فتأتي لاحقاً، بمجرد معرفة الدقة المستهدفة.
prepare_latents
< source >( first_latent: torch.Tensornum_frames: intheight: intwidth: intdtype: torch.dtypedevice: torch.devicegenerator: torch.Generator )
استخرج كوابئ أولية عشوائية وثبّت الإطار الأول كنقطة مرجعية للتكييف.
يعيد (latents, condition_mask) حيث يحتوي condition_mask على قيم 1 عند رموز الإطار الأول (تُحافظ على نظافتها طوال عملية العينة) وقيم 0 في بقية المواضع.
SanaWMLTX2Refiner
يعمل مُحسّن المرحلة الثانية من LTX-2 كخط أنابيب DiffusionPipeline مستقل يستقبل كامنات المرحلة الأولى. قدّم له vae (الخاص بخط الأنابيب الأساسي، بحيث تُشارك الأوزان) ليُفكّك الترميز إلى فيديو؛ وبدونه يعيد كامنات مُحسّنة.
فئة diffusers.SanaWMLTX2Refiner
< source >( transformer: SanaWMLTX2RefinerTransformer3DModelconnectors: LTX2TextConnectorstokenizer: GemmaTokenizer | GemmaTokenizerFasttext_encoder: Gemma3ForConditionalGenerationscheduler: FlowMatchEulerDiscreteSchedulervae: AutoencoderKLLTX2Video | None = Nonetext_max_sequence_length: int = 1024 )
المعاملات
- transformer ([SanaWMLTX2RefinerTransformer3DModel]) — نموذج DiT الخاص بمقاطع الفيديو LTX-2 مع ذاكرة KV النافذة المنزلقة السببية المقسّمة.
- connectors ([LTX2TextConnectors]) — موصلات نص LTX-2.
- tokenizer — مُقسِّم Gemma-3.
- text_encoder — مُشفِّر النص في Gemma-3.
- scheduler ([FlowMatchEulerDiscreteScheduler]) —
جدول زمني أويلر لمطابقة التدفق. يُنشأ مع
shift=1.0بحيث تمر قيم سيجما المُقطّرة دون أي تعديل. - vae ([AutoencoderKLLTX2Video], اختياري) — نفس نموذج VAE المستخدم في [SanaWMPipeline]؛ مرّر vae=pipe.vae لمشاركة الأوزان. عند تقديمه، يقوم المُحسّن بفك الترميز إلى فيديو، وإلا فإنه يعيد قيم latents المُحسّنة.
- text_max_sequence_length (int، القيمة الافتراضية 1024) — الحد الأقصى لعدد الرموز المُمرَّرة إلى مُجزِّئ Gemma-3.
LTX-2 sink-bidirectional Euler refiner — المرحلة 2 من SANA-WM، كخط أنابيب مستقل.
يغلّف مكوّنات LTX-2 (محوّل المُحسّن + مُوصِّلات النص + مُشفِّر النص Gemma-3 + مُجزِّئ الرموز) بالإضافة إلى [FlowMatchEulerDiscreteScheduler] الذي يحمل جدول سيجما المُقطَّر وينفّذ خطوات أويلر. يتم تسجيله كمكوّن اختياري في [SanaWMPipeline] ويمكن استخدامه أيضاً بشكل مستقل لتحسين الكامنات من المرحلة الأولى.
__call__
< source >( sana_latent: torch.Tensorprompt: strfps: floatsink_size: int = 1generator: torch.Generator | None = Noneblock_size: int = 3kv_max_frames: int = 11sigmas: tuple[float, ...] = (0.909375, 0.725, 0.421875, 0.0)output_type: str = 'np' ) → torch.Tensor
المعاملات
- sana_latent — كامن المرحلة الأولى
(B, C, F, H, W). - prompt — نصّ الأمر.
- fps — معدل إطارات الفيديو (يُشغّل التدرّج الزمني لـ LTX-2 RoPE).
- sink_size — عدد الإطارات الخام
z_sanaالأولية التي تُثبَّت كحوض للانتباه (القيمة القياسية: 1). - generator — torch.Generator لضوضاء نقطة النهاية في FM. القيمة الافتراضية هي مولّد مُبذَّر بالرقم 42 حتى تكون النتائج قابلة للتكرار دون أي إعداد مسبق.
- block_size — عدد الإطارات الكامنة لكل كتلة AR (القيمة القياسية: 3).
- kv_max_frames — الحد الأقصى لإطارات السياق والإطارات النشطة التي يتم الاحتفاظ بها في النافذة المنزلقة (القيمة القياسية: 11 = 1 إطار غارق + 10 إطارات حديثة).
- sigmas — جدول أويلر تنازلي ينتهي عند 0.0 (المُقطَّر القياسي بثلاث خطوات:
(0.909375, 0.725, 0.421875, 0.0)). يُمرَّر إلىself.scheduler(باستثناء القيمة 0.0 في النهاية، حيث يضيفها المُجدوِل بنفسه). - output_type — “latent” يعيد الكامنات المُحسَّنة. أي قيمة أخرى تُفكَّك عبر self.vae ثم تُعالَج لاحقًا لتحويلها إلى ذلك النوع (“np”، “pt”، “pil”)؛ وفي حال عدم وجود vae، تُعاد الكامنات على أي حال.
يعيد
torch.Tensor
كعوب VAE المُحسَّنة ذات الشكل (B, C, F, H, W) — تحمل الإطارات الأولى sink_size كعوب sink الخام من المرحلة 1 دون تغيير، بينما تحمل البقية المخرجات المُحسَّنة.
شغّل مُحسّن LTX-2 وأعدّ كامنات VAE المُحسَّنة.
يستخدم وصف AR السببي المقطعي الذي تم تدريب النموذج عليه (block_size=3، kv_max_frames=11): يتم تغذية نافذة منزلقة من [source_sink + recent_history + active_block] من K/V إلى الترانسفورمر كتلةً تلو الأخرى، بحيث تكون تكلفة الحساب لكل كتلة محدودة، وتتكلف التكرار الإجمالي تتناسب خطياً مع طول الفيديو.
SanaWMPipelineOutput
فئة diffusers.SanaWMPipelineOutput
< source >( frames: typing.Union[torch.Tensor, numpy.ndarray, list[list[PIL.Image.Image]]]c2w: numpy.ndarray | None = Nonelatent: typing.Optional[torch.Tensor] = None )
المعاملات
- frames (torch.Tensor أو np.ndarray أو list[PIL.Image.Image]) —
الفيديو المولّد: مصفوفة
np.ndarrayمن نوع float بأبعاد(T, H, W, 3)ضمن المدى[0, 1]عندoutput_type="np"، أو مُتَنسِج بأبعاد(T, 3, H, W)عند"pt"، أو قائمة تحتوي علىTمن `PIL.Imageعند"pil"، أو مُتَنسِج الكامِن بأبعاد(B, C, T_lat, H_lat, W_lat)عند"latent". - c2w (np.ndarray) —
إحداثيات الكاميرا بالنسبة للعالم
(T, 4, 4)متطابقة معframes(تُزيل أداة التحسين إطار المرساة؛ ويُعاد محاذاة هذا المصفوفة وفقًا لذلك عند تشغيل أداة التحسين). - latent (torch.Tensor, اختياري) —
مصفوفة كامنة في فضاء LTX-2 VAE، شكلها
(B, C, T_lat, H_lat, W_lat). تُعاد عند `output_type=“latent”“.
فئة الإخراج لخط أنابيب تحويل الصورة إلى فيديو في SANA-WM.