# إعدادات كل طبقة

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

استخدم `per_layer_config` على [PreTrainedConfig](/docs/transformers/main/ar/main_classes/configuration#transformers.PreTrainedConfig) لتسجيل تلك الفروقات عند إنشاء إعداد أو فحصه، وعند استهلاك كود النموذج لها. كل إدخال يخزّن فقط ما يختلف عن الإعداد العام، بينما يرث الباقي.

> [!NOTE]
> تُعدّ التكوينات غير المتجانسة ميزةً قوية. إذا أصبحت الترتيبات غير المتجانسة معماريةً شائعة أو بارزة، فسنسعى إلى نمذجتها صراحةً في تنفيذ المعمارية بدلاً من الاعتماد على `per_layer_config`. يُفضَّل استخدام المعمارية الصريحة عندما تكون متاحة.

النماذج أدناه هي نقاط تحقق غير متجانسة. ليست الطبقات موحدة عبر المكدس. فهي تستخدم معمارية مخصصة مع `block_configs` ونوع نموذج خاص بها `model_type`، بدلاً من `per_layer_config` على معمارية قياسية.

| النموذج | مشتق من |
|---|---|
| [nvidia/Llama-3_3-Nemotron-Super-49B-v1_5](https://huggingface.co/nvidia/Llama-3_3-Nemotron-Super-49B-v1_5) | [meta-llama/Llama-3.3-70B-Instruct](https://huggingface.co/meta-llama/Llama-3.3-70B-Instruct) |
| [nvidia/Llama-3_1-Nemotron-Ultra-253B-v1](https://huggingface.co/nvidia/Llama-3_1-Nemotron-Ultra-253B-v1) | [meta-llama/Llama-3.1-405B-Instruct](https://huggingface.co/meta-llama/Llama-3.1-405B-Instruct) |
| [nvidia/gpt-oss-puzzle-88B](https://huggingface.co/nvidia/gpt-oss-puzzle-88B) | [openai/gpt-oss-120b](https://huggingface.co/openai/gpt-oss-120b) |
| [nvidia/NVIDIA-Nemotron-Labs-3-Puzzle-75B-A9B-BF16](https://huggingface.co/nvidia/NVIDIA-Nemotron-Labs-3-Puzzle-75B-A9B-BF16) | [nvidia/NVIDIA-Nemotron-3-Super-120B-A12B-BF16](https://huggingface.co/nvidia/NVIDIA-Nemotron-3-Super-120B-A12B-BF16) |

## تعريف تجاوزات لكل طبقة

مرّر `per_layer_config` إلى [LlamaConfig](/docs/transformers/main/ar/model_doc/llama2#transformers.LlamaConfig) على شكل تعيين من فهارس الطبقات إلى تجاوزات السمات. فهارس الطبقات تبدأ من الصفر. لا يلزم تحديد سوى السمات التي تختلف عن الإعداد العام.

يسجّل `per_layer_config` قيم الإعداد ويحلّها. ولا يغيّر بحد ذاته الوحدات التي ينشئها النموذج أو طريقة عمل تلك الوحدات. ويتطلّب تطبيق تجاوز الحجم أو `skip` كود نموذج يقرأ إعداد الطبقة المحلولة عند بناء كل طبقة أو تشغيلها. ويبني `LlamaModel` الحالي كل `LlamaDecoderLayer` بالإعداد العام، لذا تبقى إدخالات `skip` أدناه قيم إعداد بدلاً من إزالة الوحدات بعد `from_pretrained`.

يسجّل المثال التالي تجاوزات لأربع طبقات: تستخدم الطبقة 5 شبكة MLP أصغر، وتستخدم الطبقة 11 عددًا أقل من رؤوس المفتاح-القيمة، بينما تسجّل الطبقتان 23 و27 قيم `skip` للهياكات التي تدعمها.

```py
from transformers import LlamaConfig

config = LlamaConfig(
    hidden_size=4096,
    intermediate_size=14336,
    num_hidden_layers=32,
    num_attention_heads=32,
    num_key_value_heads=8,
    per_layer_config={
        # Use a smaller MLP in one layer.
        5: {"intermediate_size": 8192},

        # Use fewer key-value heads in another layer.
        11: {"num_key_value_heads": 4},

        # Record a request to skip the MLP in architectures that support it.
        23: {"skip": ["mlp"]},

        # Record a request to skip attention in architectures that support it.
        27: {"skip": ["attention"]},
    },
)
```

تُعرَّف الوحدات الفرعية التي يمكن للمعمارية تجاوزها (مثل `"mlp"` و`"attention"`) لكل معمارية على حدة. يقبل `skip` قائمة، لذا يمكن لطبقة واحدة أن تسجّل أكثر من تجاوز لوحدة فرعية.

يعود الوصول إلى `config.per_layer_config[layer_idx]` بإعداد طبقة محلول. يجمع الإعداد المحلول بين الإعداد العام والتجاوزات الخاصة بتلك الطبقة.

```py
# Layer 0 does not define overrides, so it inherits the global values.
config.per_layer_config[0].intermediate_size
# 14336

config.per_layer_config[0].num_key_value_heads
# 8

# Layer 5 overrides the MLP intermediate size.
config.per_layer_config[5].intermediate_size
# 8192

# Layer 11 overrides the number of key-value heads.
config.per_layer_config[11].num_key_value_heads
# 4

# Layer 23 records an MLP skip.
config.per_layer_config[23].skip
# ["mlp"]

# Layer 27 records an attention skip.
config.per_layer_config[27].skip
# ["attention"]
```

تدعم التكوينات التي تستخدم `per_layer_config` نفس دورة [save_pretrained()](/docs/transformers/main/ar/main_classes/configuration#transformers.PreTrainedConfig.save_pretrained) و[from_pretrained()](/docs/transformers/main/ar/main_classes/configuration#transformers.PreTrainedConfig.from_pretrained) مثل التكوينات الأخرى.

تعرّف كل بنية في كودها السمات التي تستهلكها على مستوى الطبقة. يوفر `per_layer_config` الآلية لتسجيل تلك الفروقات على مستوى الطبقة وحلّها مقابل الإعداد العام.

## الوصول إلى السمات العامة

لا يملك السمة التي تتضمن تجاوزات لكل طبقة قيمة واحدة موحدة على مستوى النموذج. فقد تكون `num_key_value_heads` بقيمة `8` في معظم الطبقات وقيمة `4` في طبقات محددة. لذا فإن قراءة `config.num_key_value_heads` خارج سياق الطبقة تكون غامضة.

بشكل افتراضي، يثير ذلك الوصول `AmbiguousGlobalPerLayerAttributeError` ويوجّهك إلى `config.per_layer_config[layer_idx]`. لا يزال السمة موجودة على الإعداد العام، لذا هذا ليس `AttributeError`. قراءة ذلك القيمة العامة دون مؤشر طبقة لا تزال خاطئة. الكود الذي يبني ذاكرة تخزين مؤقت للمفاتيح والقيم من `num_key_value_heads` عامة سيحسب أحجام الطبقات الخاطئة بشكل غير صحيح.

اضبط `allow_global_per_layer_attribute_access=True` فقط عندما تكون بحاجة متعمدة إلى الخيار الاحتياطي العام وقادراً على التعامل مع تراكيب غير متجانسة. في هذه الحالة، يُسمح بالوصول العام. ويُصدر تحذير مرة واحدة.

```py
config = LlamaConfig(
    hidden_size=4096,
    intermediate_size=14336,
    num_hidden_layers=32,
    num_attention_heads=32,
    num_key_value_heads=8,
    allow_global_per_layer_attribute_access=True,
    per_layer_config={
        11: {"num_key_value_heads": 4},
    },
)

config.num_key_value_heads
# 8
# Emits a one-time warning because num_key_value_heads has a per-layer override.
```

## التسلسل

`per_layer_config` يُسلسل بشكل متناثر افتراضيًا، حيث تُستثنى الطبقات التي لا تحتوي على تجاوزات. كما تُستثنى السمات المُتجاوزة التي تتطابق مع القيمة العامة.

```py
from transformers import LlamaConfig

config = LlamaConfig(
    hidden_size=4096,
    intermediate_size=14336,
    num_hidden_layers=4,
    num_attention_heads=32,
    num_key_value_heads=8,
    per_layer_config={
        0: {"num_key_value_heads": 8},
        2: {"num_key_value_heads": 4},
    },
)

config.to_dict()["per_layer_config"]
# {"2": {"num_key_value_heads": 4}}
```

اضبط `serialize_explicit_per_layer_config=True` لتشمل كل طبقة من الطبقات الخاصة بالسمات الممثلة في `per_layer_config`. وهذا يجعل فحص تخطيط الطبقات أسهل عندما لا تزال بعض القيم مطابقة للإعداد العام.

```py
explicit_config = LlamaConfig(
    hidden_size=4096,
    intermediate_size=14336,
    num_hidden_layers=4,
    num_attention_heads=32,
    num_key_value_heads=8,
    serialize_explicit_per_layer_config=True,
    per_layer_config={
        0: {"num_key_value_heads": 8},
        2: {"num_key_value_heads": 4},
    },
)

serialized_per_layer_config = explicit_config.to_dict()["per_layer_config"]

serialized_per_layer_config
# {
#     "0": {"num_key_value_heads": 8},
#     "1": {"num_key_value_heads": 8},
#     "2": {"num_key_value_heads": 4},
#     "3": {"num_key_value_heads": 8},
# }
```

استخدم التسلسل المتناثر (sparse serialization) للحصول على تراكيب مضغوطة، والتسلسل الصريح (explicit serialization) عندما تحتاج إلى التخطيط الكامل لكل طبقة من أجل وضوح القراءة أو لأغراض الأدوات.

