Diffusers documentation

البدء السريع

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

البدء السريع

يعتبر Modular Diffusers إطارًا لبناء خطوط أنابيب مرنة وقابلة للتخصيص بسرعة. يمكن لهذه الخطوط أن تتجاوز ما يمكن أن تفعله خطوط DiffusionPipeline القياسية. جوهر Modular Diffusers هو ModularPipelineBlocks التي يمكن دمجها مع كتل أخرى للتكيف مع سير عمل جديدة. يتم تحويل هذه الكتل إلى ModularPipeline، وهو واجهة موجهة للمستخدم وسهلة الاستخدام لتنفيذ مهام التوليد.

يُظهر لك هذا الدليل كيفية تشغيل خط أنابيب معياري، وفهم بنيته، وتخصيصه من خلال تعديل الوحدات المكوّنة له. إذا كنت على دراية بـ DiffusionPipeline، فاقرأ Coming from DiffusionPipeline أولاً لمعرفة ما الذي يعمل بشكل مختلف.

تشغيل خط أنابيب

ModularPipeline هو الواجهة الرئيسية لتحميل خطوط الأنابيب المعيارية وتشغيلها وإدارتها.

import torch
from diffusers import ModularPipeline, ComponentsManager

# Use ComponentsManager to enable auto CPU offloading for memory efficiency
manager = ComponentsManager()
manager.enable_auto_cpu_offload(device="cuda:0")

pipe = ModularPipeline.from_pretrained("Qwen/Qwen-Image", components_manager=manager)
pipe.load_components(dtype=torch.bfloat16)

image = pipe(
    prompt="cat wizard with red hat, gandalf, lord of the rings, detailed, fantasy, cute, adorable, Pixar, Disney",
).images[0]
image

يستخدم from_pretrained() التحميل الكسول - إذ يقرأ الإعدادات لمعرفة مكان تحميل كل مكوّن من، لكنه لا يحمّل أوزان النموذج فعليًا حتى تستدعي load_components(). ومنحًا لك ذلك سيطرة على متى وكيف يتم تحميل المكوّنات.

ينقل ComponentsManager مع enable_auto_cpu_offload النماذج تلقائيًا بين وحدة المعالجة المركزية (CPU) ووحدة معالجة الرسوميات (GPU) حسب الحاجة، مما يقلل من استهلاك الذاكرة للنماذج الكبيرة مثل Qwen-Image. لمعرفة المزيد، راجع دليل ComponentsManager.

إذا لم تكن بحاجة إلى نقل المكونات، احذف معامل components_manager وانقل خط الأنابيب إلى جهازك يدويًا باستخدام to("cuda").

تعرّف على المزيد حول إنشاء خطوط الأنابيب وتحميلها في دليلَي إنشاء خط أنابيب وتحميل المكونات.

فهم البنية

يتكون ModularPipeline من جزأين: تعريف (الكتل) وحالة (المكونات والإعدادات المحمّلة).

اطبع خط الأنابيب لرؤية حالته — المكونات وحالة تحميلها وإعداداتها.

print(pipe)
QwenImageModularPipeline {
  "_blocks_class_name": "QwenImageAutoBlocks",
  "_class_name": "QwenImageModularPipeline",
  "_diffusers_version": "0.37.0.dev0",
  "transformer": [
    "diffusers",
    "QwenImageTransformer2DModel",
    {
      "pretrained_model_name_or_path": "Qwen/Qwen-Image",
      "revision": null,
      "subfolder": "transformer",
      "type_hint": [
        "diffusers",
        "QwenImageTransformer2DModel"
      ],
      "variant": null
    }
  ],
  ...
}

الوصول إلى التعريف عبر pipe.blocks — هذا هو ModularPipelineBlocks الذي يحدد مسارات عمل خط المعالجة والمدخلات والمخرجات ومنطق الحساب.

print(pipe.blocks)
QwenImageAutoBlocks(
  Class: SequentialPipelineBlocks

  Description: Auto Modular pipeline for text-to-image, image-to-image, inpainting, and controlnet tasks using QwenImage.
      
      Supported workflows:
        - `text2image`: requires `prompt`
        - `image2image`: requires `prompt`, `image`
        - `inpainting`: requires `prompt`, `mask_image`, `image`
        - `controlnet_text2image`: requires `prompt`, `control_image`
        ...

  Components:
      text_encoder (`Qwen2_5_VLForConditionalGeneration`)
      vae (`AutoencoderKLQwenImage`)
      transformer (`QwenImageTransformer2DModel`)
      ...

  Sub-Blocks:
    [0] text_encoder (QwenImageAutoTextEncoderStep)
    [1] vae_encoder (QwenImageAutoVaeEncoderStep)
    [2] controlnet_vae_encoder (QwenImageOptionalControlNetVaeEncoderStep)
    [3] denoise (QwenImageAutoCoreDenoiseStep)
    [4] decode (QwenImageAutoDecodeStep)
)

يعيد المخرَج:

  • سير العمل المدعومة (text2image، image2image، inpainting، إلخ)
  • المكونات الفرعية التي يتكون منها (text_encoder، vae_encoder، denoise، decode)

سير العمل

يدعم هذا الخط أنماط عمل متعددة ويكيّف سلوكه بناءً على المدخلات التي تزوّده بها. فعلى سبيل المثال، إذا مرّرت image إلى الخط، فإنه ينفّذ نمط عمل من صورة إلى صورة بدلاً من النص إلى صورة. تعرّف على المزيد حول آلية العمل الداخلية في دليل AutoPipelineBlocks.

from diffusers.utils import load_image

input_image = load_image("https://github.com/Trgtuan10/Image_storage/blob/main/cute_cat.png?raw=true")

image = pipe(
    prompt="cat wizard with red hat, gandalf, lord of the rings, detailed, fantasy, cute, adorable, Pixar, Disney",
    image=input_image,
).images[0]

استخدم get_workflow() لاستخراج الكتل الخاصة بعملية محددة. مرر اسم العملية (مثل "image2image"، "inpainting"، "controlnet_text2image") للحصول على الكتل ذات الصلة بتلك العملية فقط. وهذا مفيد عندما تريد تخصيص عملية محددة أو تصحيح أخطائها. يمكنك التحقق من pipe.blocks.available_workflows لرؤية جميع العمليات المتاحة.

img2img_blocks = pipe.blocks.get_workflow("image2image")

الكتل الفرعية

يمكن أن تحتوي الكتل على كتل أخرى. يمنحك pipe.blocks تعريف الكتلة على المستوى الأعلى (وهنا QwenImageAutoBlocks)، بينما يتيح لك sub_blocks الوصول إلى الكتل الأصغر داخلها.

يتكوّن QwenImageAutoBlocks من: text_encoder، وvae_encoder، وcontrolnet_vae_encoder، وdenoise، وdecode.

تعمل هذه الكتل الفرعية تباعًا، ويتدفق الخطر بشكل خطي من كتلة إلى التالية — حيث تصبح intermediate_outputs لكل كتلة متاحة كـinputs للكتلة التالية. بهذه الطريقة تعمل SequentialPipelineBlocks.

يمكنك الوصول إليها من خلال خاصية sub_blocks. وتُعد خاصية doc مفيدة للاطلاع على التوثيق الكامل لأي كتلة، بما في ذلك مدخلاتها ومخرجاتها ومكوناتها.

vae_encoder_block = pipe.blocks.sub_blocks["vae_encoder"]
print(vae_encoder_block.doc)

يمكن تحويل هذا الكتلة إلى خط أنابيب بحيث يمكن تشغيله بشكل مستقل باستخدام init_pipeline().

vae_encoder_pipe = vae_encoder_block.init_pipeline()

# Reuse the VAE we already loaded, we can reuse it with update_components() method
vae_encoder_pipe.update_components(vae=pipe.vae)

# Run just this block
image_latents = vae_encoder_pipe(image=input_image).image_latents
print(image_latents.shape)

يعيد استخدام VAE من خط أنابيبنا الأصلي بدلاً من إعادة تحميله، مما يحافظ على كفاءة استخدام الذاكرة. لمعرفة المزيد، راجع دليل تحميل المكونات.

بما أن الكتل قابلة للتركيب، يمكنك تعديل تعريف خط الأنابيب عن طريق إضافة كتل أو إزالتها أو استبدالها لإنشاء مسارات عمل جديدة. في القسم التالي، سنضيف كتلة كشف الحواف باستخدام canny إلى خط أنابيب ControlNet، بحيث يمكنك تمرير صورة عادية بدلاً من خريطة حواف canny مُعالجة مسبقًا.

إنشاء سير عمل جديدة

لنقم بإضافة كتلة كشف الحواف باستخدام canny إلى خط أنابيب ControlNet. أولاً، حمّل كتلة canny جاهزة من Hub (انظر بناء كتل مخصصة لإنشاء كتلتك الخاصة).

from diffusers.modular_pipelines import ModularPipelineBlocks

# Load a canny block from the Hub
canny_block = ModularPipelineBlocks.from_pretrained(
    "diffusers-internal-dev/canny-filtering",
    trust_remote_code=True,
)

print(canny_block.doc)
class CannyBlock

  Inputs:
      image (`Union[Image, ndarray]`):
          Image to compute canny filter on
      low_threshold (`int`, *optional*, defaults to 50):
          Low threshold for the canny filter.
      high_threshold (`int`, *optional*, defaults to 200):
          High threshold for the canny filter.
      ...

  Outputs:
      control_image (`PIL.Image`):
          Canny map for input image

استخدم get_workflow لاستخراج سير عمل ControlNet من QwenImageAutoBlocks.

# Get the controlnet workflow that we want to work with
blocks = pipe.blocks.get_workflow("controlnet_text2image")
print(blocks.doc)
class SequentialPipelineBlocks

  Inputs:
      prompt (`str`):
          The prompt or prompts to guide image generation.
      control_image (`Image`):
          Control image for ControlNet conditioning.
      ...

السيرورة المستخرجة هي SequentialPipelineBlocks وهي تتطلب حاليًا control_image كمدخل. أدرج كتلة canny في البداية بحيث تقبل السيرورة صورة عادية بدلاً من ذلك.

# Insert canny at the beginning
blocks.sub_blocks.insert("canny", canny_block, 0)

# Check the updated structure: CannyBlock is now listed as first sub-block
print(blocks)
# Check the updated doc
print(blocks.doc)
class SequentialPipelineBlocks

  Inputs:
      image (`Union[Image, ndarray]`):
          Image to compute canny filter on
      low_threshold (`int`, *optional*, defaults to 50):
          Low threshold for the canny filter.
      high_threshold (`int`, *optional*, defaults to 200):
          High threshold for the canny filter.
      prompt (`str`):
          The prompt or prompts to guide image generation.
      ...

الآن يستقبل خط الأنابيب image كمدخل بدلاً من control_image. وبما أن الكتل في تسلسل ما تتشارك البيانات تلقائياً، فإن مخرج كتلة canny (control_image) يتدفق إلى كتلة إزالة الضوضاء التي تحتاج إليه، ويصبح مدخل كتلة canny (image) مدخلاً لخط الأنابيب لأن لا كتلة سابقة توفره.

أنشئ خط أنابيب من الكتل المعدّلة ثم حمّل نموذج ControlNet. نظراً لأن ControlNet ليس جزءاً من مستودع النموذج الأصلي، فحمّله بشكل منفصل وأضفه باستخدام update_components().

pipeline = blocks.init_pipeline("Qwen/Qwen-Image", components_manager=manager)

pipeline.load_components(dtype=torch.bfloat16)

# Load the ControlNet model
controlnet_spec = pipeline.get_component_spec("controlnet")
controlnet_spec.pretrained_model_name_or_path = "InstantX/Qwen-Image-ControlNet-Union"
controlnet = controlnet_spec.load(dtype=torch.bfloat16)
pipeline.update_components(controlnet=controlnet)

الآن شغّل خط الأنابيب - حيث يعالج كتلة canny الصورة مسبقًا من أجل ControlNet.

from diffusers.utils import load_image

prompt = "cat wizard with red hat, gandalf, lord of the rings, detailed, fantasy, cute, adorable, Pixar, Disney"
image = load_image("https://github.com/Trgtuan10/Image_storage/blob/main/cute_cat.png?raw=true")

output = pipeline(
    prompt=prompt,
    image=image,
).images[0]
output

الخطوات التالية

تعلم الأساسيات
بناء كتل مخصصة
مشاركة المكونات
الواجهة البصرية

افهم العناصر الأساسية المكوِّنة لـ Modular Diffusers:

Update on GitHub