# التخزين المؤقت

يعيد التخزين المؤقت استخدام مخرجات الطبقات الوسيطة عبر خطوات إزالة الضوضاء لتسريع الاستدلال. يستهلك ذاكرة أكثر ولا يتطلب تدريبًا. فعّل طريقة باستخدام إعداد على محوّل يدعم التخزين المؤقت.

## اختر طريقة تخزين مؤقت

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

| الطريقة | استخدم عند | ملاحظات |
|--------|----------|-------|
| [ذاكرة KV النصية](#text-kv-cache) | صورة NucleusMoE، إعادة استخدام إسقاطات K/V للنص عبر الخطوات | حاليًا، يربط كتل صور NucleusMoE |
| [SeaCache](#seacache) | توليد الفيديو في Cosmos 3 | غالبًا لا تنتقل الإعدادات عبر النماذج |
| [FirstBlockCache](#firstblockcache) | هل تريد وجود مقبض رئيسي واحد للتحكم في السرعة/الجودة في نموذج تحويلي مسجّل | يتحكم `threshold` واحد في تكرار تخطي الخطوات |
| [MagCache](#magcache) | هل لديك نسب السعة لنقطة الحفظ وجدولك الزمني، أم ستقوم بالمعايرة أولاً | تختلف النسب باختلاف نقطة الحفظ ومجدول التعلم |
| [TaylorSeer](#taylorseer-cache) | هل تريد التنبؤ بتنشيطات لاحقة من خطوات سابقة | استخدام قيمة أعلى لـ `max_order` يستهلك ذاكرة أكبر |
| [PAB](#pyramid-attention-broadcast) | فيديو، على استعداد لضبط إعادة استخدام الانتباه (نطاقات تخطي الكتلة والخطوة الزمنية لكل نوع من أنواع الانتباه) | تتطلب نطاقات التخطي ضبطاً لكل نموذج |
| [FasterCache](#fastercache) | مثل PAB، مع خيار إضافي لتخطي فرع CFG | تجريبي |

## بث الانتباه الهرمي

يقوم [Pyramid Attention Broadcast (PAB)](https://huggingface.co/papers/2408.12588) بتقريب الانتباه عبر خطوات إزالة الضوضاء من خلال إعادة استخدام مخرجات الانتباه لبعض الكتل وخطوات الزمن بدلاً من إعادة الحساب في كل خطوة. يميّز الإعداد بين أنواع الانتباه (المكانية، الزمنية، المتقاطعة) عندما تتوفر في النموذج. لا يكشف كل نموذج فيديو عن الأنواع الثلاثة، لذا اضبط فقط النطاقات التي تتطابق مع الكتل المتوفرة لديك.

يستخدم كل نوع `*_attention_block_skip_range` (تكرار إعادة الحساب مقابل إعادة الاستخدام داخل النافذة) و`*_attention_timestep_skip_range` (خطوات إزالة الضوضاء التي يمكن تجاوزها). يجب عليك تمرير `current_timestep_callback` حتى يتمكن الخطاف من قراءة الخطوة الزمنية الحالية للخط. عادةً ما تعني التجاوزات الأوسع أو الأكثر عدوانية مزيدًا من السرعة ومزيدًا من مخاطر الجودة.

مرّر [PyramidAttentionBroadcastConfig](/docs/diffusers/main/ar/api/cache#diffusers.PyramidAttentionBroadcastConfig) لتفعيله.

```python
import torch
from diffusers import CogVideoXPipeline, PyramidAttentionBroadcastConfig

pipe = CogVideoXPipeline.from_pretrained("THUDM/CogVideoX-5b", dtype=torch.bfloat16)
pipe.to("cuda")  # or "mps", "xpu", "cpu"

config = PyramidAttentionBroadcastConfig(
    spatial_attention_block_skip_range=2,
    spatial_attention_timestep_skip_range=(100, 800),
    current_timestep_callback=lambda: pipe.current_timestep,
)
pipe.transformer.enable_cache(config)
```

## FasterCache

يخزّن [FasterCache](https://huggingface.co/papers/2410.19355) ميزات الانتباه ويعيد استخدامها بطريقة مشابهة لـ [PAB](#pyramid-attention-broadcast). كما يمكنه تجاوز الفرع غير الشرطي في التوجيه الحر من التصنيف وتقديره من الفرع الشرطي عندما تكون الكمونيات المتتالية متكررة بما يكفي.

مرّر [FasterCacheConfig](/docs/diffusers/main/ar/api/cache#diffusers.FasterCacheConfig) لتفعيله. وبالمثل مع PAB، اضبط `*_attention_block_skip_range` و`*_attention_timestep_skip_range` لأنواع الانتباه التي لديك، بالإضافة إلى خيارات تخطي فرع CFG عندما ترغب في ذلك.

```python
import torch
from diffusers import CogVideoXPipeline, FasterCacheConfig

pipe = CogVideoXPipeline.from_pretrained("THUDM/CogVideoX-5b", dtype=torch.bfloat16)
pipe.to("cuda")  # or "mps", "xpu", "cpu"

config = FasterCacheConfig(
    spatial_attention_block_skip_range=2,
    spatial_attention_timestep_skip_range=(-1, 681),
    current_timestep_callback=lambda: pipe.current_timestep,
    attention_weight_callback=lambda _: 0.3,
    unconditional_batch_skip_range=5,
    unconditional_batch_timestep_skip_range=(-1, 781),
    tensor_format="BFCHW",
)
pipe.transformer.enable_cache(config)
```

## SeaCache

يقارن [SeaCache](https://huggingface.co/papers/2602.18993) مؤشرات التطور الطيفي الواعي (SEA) بين خطوات إزالة الضوضاء المتتالية. عندما يبقى التغيير المتراكم دون حد معين، يتخطى مجموعة كتل التحويلي ويتنبأ بالمخرجات من بقايا مخزنة مسبقًا. الطريقة تقريبية ومصممة لتوليد الفيديو.

تشمل المكيّفات المدمجة في SeaCache ما يلي:

- Cosmos 3 هو التكامل الأساسي المُحسَّن والمُقيَّم.
- يستخدم Wan T2V مسار كتل التكرار العام كنموذج توضيحي لكيفية توفير كامنات الرؤية الخام إلى SeaCache. قد لا تنطبق نفس معاملات التخزين المؤقت على Wan أو غيرها من متغيرات Wan.

فعّل SeaCache على المحوّل. يربط حلقة إزالة الضوضاء في Cosmos 3 خطوة المجدول، وقيمة sigma، وعدد الخطوات إلى كل `cache_context`، لذا لا حاجة إلى أي معاملات إضافية.

```python
from diffusers import Cosmos3OmniPipeline, SeaCacheConfig

pipe = Cosmos3OmniPipeline.from_pretrained("nvidia/Cosmos3-Nano")
pipe.transformer.enable_cache(SeaCacheConfig(threshold=0.2, max_consecutive_cached=2))
```

قد تُغيّر SeaCache المخرجات. استدعِ `pipe.transformer.disable_cache()` عندما تحتاج إلى تشغيل كل خطوة عبر المحوّل الكامل. يعمل نفس استدعاء التفعيل مع [Cosmos3OmniPipeline](/docs/diffusers/main/ar/api/pipelines/cosmos3#diffusers.Cosmos3OmniPipeline) و[Cosmos3OmniModularPipeline](/docs/diffusers/main/ar/api/pipelines/cosmos3#diffusers.Cosmos3OmniModularPipeline) و[Cosmos3DistilledModularPipeline](/docs/diffusers/main/ar/api/pipelines/cosmos3#diffusers.Cosmos3DistilledModularPipeline).

لاستخدام SeaCache مع محوّل فيديو آخر، اتبع [إضافة التخزين المؤقت إلى نموذج جديد](#add-caching-to-a-new-model). كما يحتاج SeaCache إلى `step_index` و`sigma` و`num_inference_steps` في كل `cache_context`، وإلى `raw_vision_callback` عندما لا يتوفر مُكيّف مدمج. اضبط المعلمات لكل نموذج ومجدول.

## FirstBlockCache

يتحقق [FirstBlockCacheConfig](/docs/diffusers/main/ar/api/cache#diffusers.FirstBlockCacheConfig) من مقدار تغيّر الطبقات المبكرة في مُزيل الضوضاء من خطوة زمنية إلى التالية. إذا كان التغير صغيراً، يتخطّى النموذج الطبقات اللاحقة المكلفة ويعيد استخدام المخرجات السابقة.

فعّله عبر `enable_cache` حتى تبقى `disable_cache` و`is_cache_enabled` متزامنة. القيمة الافتراضية لـ`threshold` هي `0.05`. القيمة الأعلى مثل `0.2` تتخطى العملية بشكل متكرر أكثر لتحقيق سرعة إضافية، لكن جودة التوليد قد تنخفض.

```python
import torch
from diffusers import DiffusionPipeline, FirstBlockCacheConfig

pipe = DiffusionPipeline.from_pretrained(
    "Qwen/Qwen-Image", dtype=torch.bfloat16
)
pipe.transformer.enable_cache(FirstBlockCacheConfig(threshold=0.2))
```

## TaylorSeer ذاكرة مؤقتة

يعمل [TaylorSeer Cache](https://huggingface.co/papers/2503.06923) على تسريع استنتاج النماذج الانتشارية (Diffusion) باستخدام توسعات متسلسلة تايلور عبر خطوات إزالة الضوضاء. فهو يتنبأ بتفعيلات الخطوات اللاحقة بناءً على تفعيلات الخطوات السابقة، ويعيد استخدام تلك التنبؤات لعدة خطوات، مما يقلل من حجم العمل الكامل الذي يقوم به نموذج التحويل (Transformer).

- `cache_interval`: عدد الخطوات لإعادة استخدام المخرجات المخزنة مؤقتًا قبل إجراء تمرير أمامي كامل
- `disable_cache_before_step`: الخطوات الأولية التي تستخدم الحسابات الكاملة لجمع البيانات للتقديرات
- `max_order`: يمكن أن تكون رتب تايلور الأعلى أكثر دقة لكنها تستهلك ذاكرة أكبر. حافظ على هذا عند `1` ما لم يكن لديك سبب لتغييره.

```python
import torch
from diffusers import FluxPipeline, TaylorSeerCacheConfig

pipe = FluxPipeline.from_pretrained(
    "black-forest-labs/FLUX.1-dev",
    dtype=torch.bfloat16,
).to("cuda")  # or "mps", "xpu", "cpu"

config = TaylorSeerCacheConfig(
    cache_interval=5,
    max_order=1,
    disable_cache_before_step=10,
    taylor_factors_dtype=torch.bfloat16,
)
pipe.transformer.enable_cache(config)
```

## MagCache

يتخطى [MagCache](https://github.com/Zehong-Ma/MagCache) كتل التحويل بناءً على مقدار التحديث المتبقي. تتناقص مقادير التحديث بشكل متوقع عبر عملية إزالة الضوضاء، ويتتبع MagCache ميزانية خطأ من نسب المقادير المحسوبة مسبقًا (`mag_ratios`) لتحديد متى يكون إعادة الاستخدام آمنة. هذه النسب مرتبطة بنقطة الحفظ ومجدول التدرج المحدد. يمكن استيفاء النسب المستمدة من عدد خطوات عالٍ لتقليل عدد الخطوات.

> [!TIP]
> تم قياس `FLUX_MAG_RATIOS` المرفقة على FLUX.1. تحتاج النماذج الأخرى، بما في ذلك Flux2 وFlux2 Klein، إلى إجراء معايرة خاص بها.

يتبع MagCache خطوتين:

1. المعايرة: نفّذ الاستدلال مرة واحدة مع `calibrate=True`. يقيس الخطاف (hook) أحجام البواقي (residuals) ويُطبع النسب المحسوبة.
2. الاستدلال: عطّل ذاكرة التخزين المؤقت للمعايرة، ثم مرّر تلك النسب إلى `MagCacheConfig` للتسريع.

قد يؤثر التوجيه الحر من التصنيف على المعايرة. تدخل خطوط الأنابيب التي تستخدم CFG الحقيقي مع سياقات متسلسلة، مثل Flux عندما يكون `true_cfg_scale > 1`، إلى `cache_context("cond")` و`cache_context("uncond")` بشكل منفصل. قد تطبع المعايرة مصفوفة واحدة لكل سياق، لكن عليك استخدام المصفوفة الشرطية في معظم الحالات. تنتج خطوط الأنابيب التي تجمع CFG عن طريق دمج المدخلات الشرطية وغير الشرطية (على سبيل المثال، CogVideoX) مصفوفة مشتركة واحدة يمكنك استخدامها مباشرة.

```python
import torch
from diffusers import FluxPipeline, MagCacheConfig
from diffusers.hooks.mag_cache import FLUX_MAG_RATIOS

pipe = FluxPipeline.from_pretrained(
    "black-forest-labs/FLUX.1-schnell",
    dtype=torch.bfloat16
).to("cuda")  # or "mps", "xpu", "cpu"

# 1. Calibration Step
# Run full inference to measure model behavior.
calib_config = MagCacheConfig(calibrate=True, num_inference_steps=4)
pipe.transformer.enable_cache(calib_config)

# Run a prompt to trigger calibration
pipe("A cat playing chess", num_inference_steps=4)
# Prints: [MagCache] Calibration Complete. Copy these values to MagCacheConfig(mag_ratios=...):

# 2. Inference Step
# Disable calibration hooks before enabling MagCache for inference.
pipe.transformer.disable_cache()

# Apply ratios from calibration, or use the Flux defaults:
# mag_ratios=FLUX_MAG_RATIOS
mag_config = MagCacheConfig(
    mag_ratios=[1.0, 1.37, 0.97, 0.87],
    num_inference_steps=4
)

pipe.transformer.enable_cache(mag_config)

image = pipe("A cat playing chess", num_inference_steps=4).images[0]
```

## ذاكرة التخزين المؤقت لنص KV

يحسب [TextKVCacheConfig](/docs/diffusers/main/ar/api/cache#diffusers.TextKVCacheConfig) إسقاطات المفاتيح والقيم للنص مرة واحدة ويعيد استخدامها في كل خطوة إزالة ضوضاء بدلاً من إعادة حسابها. حالياً، لا يربط [apply_text_kv_cache()](/docs/diffusers/main/ar/api/cache#diffusers.apply_text_kv_cache) سوى `NucleusMoEImageTransformerBlock`. فعّله باستخدام `enable_cache`.

```python
import torch
from diffusers import NucleusMoEImagePipeline, TextKVCacheConfig

pipe = NucleusMoEImagePipeline.from_pretrained(
    "NucleusAI/NucleusMoE-Image", dtype=torch.bfloat16
)
pipe.to("cuda")  # or "mps", "xpu", "cpu"

pipe.transformer.enable_cache(TextKVCacheConfig())

image = pipe("A cat holding a sign that says hello world", num_inference_steps=50).images[0]
```

## إضافة التخزين المؤقت إلى نموذج جديد

تُربط طرق التخزين المؤقت (Cache) بالنموذج عبر الخطافات (hooks)، وتعتمد هذه الخطافات على فئة النموذج، ومكاتب التحويل (transformer blocks) الخاصة به، وحلقة إزالة الضوضاء (denoising loop) في خط المعالجة. قم بإعداد جميع العناصر الثلاثة الثلاثة قبل استدعاء `enable_cache` على نموذج جديد.

1. ورث من [CacheMixin](/docs/diffusers/main/ar/api/cache#diffusers.CacheMixin) في فئة التحويل. يضيف هذا `enable_cache` و`disable_cache` و`cache_context`.
2. سجّل تخطيط المخرجات للكتلة المحوّلة (transformer block) في `_register_transformer_blocks_metadata` داخل `hooks/_helpers.py`. تستخدم الطرق التي تتخطى أو تعيد استخدام كتل كاملة، مثل FirstBlockCache وMagCache وSeaCache، هذا التخطيط للعثور على الحالات المخفية (hidden states) في مخرجات الكتلة.

    ```py
    TransformerBlockRegistry.register(
        model_class=MyTransformerBlock,
        metadata=TransformerBlockMetadata(
            return_hidden_states_index=0,
            return_encoder_hidden_states_index=None,
        ),
    )
    ```

3. غلّف كل استدعاء لمحوّل داخل حلقة إزالة الضوضاء في خط المعالجة بـ`cache_context`. استخدم أسماء منفصلة، مثل `"cond"` و`"uncond"`، عندما يشغّل التوجيه الحر من التصنيف الفروع الشرطية وغير الشرطية كاستدعاءات منفصلة، بحيث يحتفظ كل فرع بحالة ذاكرته المؤقتة الخاصة به.

    ```py
    with self.transformer.cache_context("cond"):
        noise_pred = self.transformer(hidden_states=latents, timestep=timestep, ...)[0]
    ```

تحتاج PAB وFasterCache أيضًا إلى `current_timestep_callback` حتى تتمكن الخطافات من قراءة الخطوة الزمنية الحالية. تحقق من جودة المخرجات على النموذج الجديد، لأن إعدادات الكاش المُحسَّنة لنموذج واحد غالبًا لا تنتقل إلى نموذج آخر.

