# تحميل الأوزان الديناميكي

غالبًا ما تُسلسَل نقاط التفتيش (Checkpoints) بتنسيق لا يتطابق مع ما يتوقعه النموذج وقت التشغيل. وتشمل السيناريوهات الشائعة ما يلي:

1. **الأوزان المدمجة**: تحفظ نقاط التفتيش أوزانًا منفصلة لـ`gate_proj` و`up_proj`، لكن النموذج يستخدم `gate_up_proj` مدمجًا من أجل الكفاءة.
2. **توحيد خبراء MoE**: يجب تجميع أوزان الخبراء الفردية (`experts.0.weight`، `experts.1.weight`، ...) في متجه ثلاثي الأبعاد واحد.
3. **التسمية القديمة**: تستخدم نقاط التفتيش القديمة تسميات مختلفة (مثل `LayerNorm.gamma` مقابل `LayerNorm.weight`).
4. **النماذج المركبة**: يحتوي نموذج اللغة والرؤية على وحدتي فرعية من نوع `PreTrainedModel`، ولكل منهما اتفاقية نقاط تفتيش خاصة به.
5. **التكميم**: قد تُخزَّن الأوزان في صيغ مكمّمة تتطلب فكّ التسلسل.

يعالج تحميل الأوزان الديناميكي هذه المشكلة من خلال تطبيق عمليات مجدولة وقابلة للعكس على متجهات نقطة الحفظ أثناء تحميلها. يوفّر [WeightConverter](/docs/transformers/main/ar/internal/modeling_utils#transformers.WeightConverter) و`WeightRenaming` هذه الميزة، حيث تصف كيفية خرائط مفتاح واحد أو أكثر من نقاط الحفظ إلى معامل واحد أو أكثر من النموذج، وأي عمليات التحويل القابلة للتركيب [ConversionOps](/docs/transformers/main/ar/internal/modeling_utils#transformers.ConversionOps) التي يجب تنفيذها على المتجهات المطابقة. يتكيّف هذا النهج مع تخطيطات الأوزان الجديدة، ويدعم مزيج الخبراء (MoE) المكمّم، ويتكامل مع توازي المتجهات.

يُبيّن هذا الدليل كيفية استخدام [WeightConverter](/docs/transformers/main/ar/internal/modeling_utils#transformers.WeightConverter) لتحويل المتجهات. توجد خرائط التحويل في [`conversion_mapping.py`](https://github.com/huggingface/transformers/blob/main/src/transformers/conversion_mapping.py)؛ ويُفهرس كل تحويل مسجّل إما بواسطة سلسلة `model_type` (مثل `"mixtral"`) أو بواسطة اسم فئة (مثل `"LlavaModel"`).

## خط أنابيب التحميل الكامل

تخضع جميع النماذج لنظام تحميل الأوزان الديناميكي. يُعدّ تعيين التحويل خطوة **اختيارية ضمن ذلك النظام** لا تُفعَّل إلا عندما يحتوي النموذج على إدخالات مسجّلة باسم فئته أو `model_type`.

```
Checkpoint File → from_pretrained() → convert_and_load_state_dict_in_model()
                                              ↓
                         ┌───────────────────────────────────────────────────────────┐
                         │  For each weight in checkpoint:                           │
                         │  1. Match renamed/processed source key to model parameter │
                         │  2. Shard the weight and send to device (async)           │
                         │  3. Collect tensors with the same source_pattern together │
                         │     (e.g. MoE experts, gate_up_proj)                      │
                         │  4. Apply dequantization/deserialization (if pre-quant)   │
                         │  5. Apply conversion (if defined)                         │
                         │  6. Apply quantization (if enabled and step 4 not used)   │
                         │  7. Set parameter on model                                │
                         └───────────────────────────────────────────────────────────┘
```

| الخطوة | عند تفعيله |
|------|-------------------|
| التحميل الديناميكي | دائمًا، لجميع النماذج |
| خريطة التحويل | فقط عندما تكون فئة النموذج أو `model_type` مسجّلة في `_MODEL_TO_CONVERSION_PATTERN` |
| تقسيم TP | فقط عند استخدام `DistributedConfig(tp_size=N)` وامتلاك النموذج `base_model_tp_plan` |
| إلغاء التكميم/إلغاء التسلسل | فقط عند تحميل نقطة تفتيش مُكمّاة مسبقًا |
| التكميم | فقط عند توفير إعدادات التكميم وعدم كون الأوزان مُكمَّمة مسبقًا |

### النماذج الكثيفة (مثل Llama)

بالنسبة لمعظم النماذج الكثيفة، يتطابق تنسيق نقطة الحفظ مع تنسيق النموذج مباشرة، لذا لا حاجة إلى خرائط تحويل. قد لا تزال بعض النماذج تتطلب إعادة تسمية (مثل تسميات الأسماء القديمة). لا يزال تقسيم TP ساري المفعول عند تفعيله.

```
Checkpoint:                             Model:
model.layers.0.self_attn.q_proj.weight  →  model.layers.0.self_attn.q_proj.weight
model.layers.0.self_attn.k_proj.weight  →  model.layers.0.self_attn.k_proj.weight
model.layers.0.mlp.gate_proj.weight     →  model.layers.0.mlp.gate_proj.weight
model.layers.0.mlp.up_proj.weight       →  model.layers.0.mlp.up_proj.weight
model.layers.0.mlp.down_proj.weight     →  model.layers.0.mlp.down_proj.weight
```

قد تستخدم نقاط التفتيش القديمة تسميات أقدم يتم التعامل معها عبر إعادة تسمية مدمجة تُطبَّق على جميع النماذج:

```
Checkpoint:                          Model:
LayerNorm.gamma              →       LayerNorm.weight
LayerNorm.beta               →       LayerNorm.bias
```

### نماذج MoE (مثل Mixtral)

في نماذج MoE، يختلف تنسيق نقطة التفتيش عن تنسيق النموذج. يقوم خرائط التحويل بتحويل أوزان الخبراء المنفصلة إلى متجهات ثلاثية الأبعاد مدمجة، وتُطبَّق تقسيمات TP بعد التحويل.

```
Checkpoint:                              Model:
experts.0.w1.weight  ─┐
experts.1.w1.weight   │ MergeModulelist
...                   ├───────────────→  experts.gate_up_proj (8, hidden, 2*intermediate)
experts.0.w3.weight   │ + Concatenate
experts.1.w3.weight  ─┘
```

### النماذج المركبة (مثل نماذج الرؤية واللغة)

قد يحتوي `PreTrainedModel` على وحدات فرعية أخرى من نوع `PreTrainedModel`. يمكن لكل نموذج فرعي أن يملك خريطته الخاصة للتحويل، المسجلة إما باسم صفته أو بـ`model_type` الخاص به. عند تحميل النموذج الأب، يتجول `get_model_conversion_mapping` في النماذج الفرعية بترتيب عمق أولاً، ويجمع خرائطها، و**يحدد نطاق** كل تحويل تلقائياً إلى مسار وحدته الفرعية عبر `scope_prefix`.

```
Composite model:                              Per-submodel mappings (auto-scoped):
LlavaForConditionalGeneration
├── vision_model: SiglipVisionModel    →     SiglipVisionModel mapping (scope="vision_model")
└── language_model: LlamaForCausalLM   →     LlamaForCausalLM mapping  (scope="language_model")
```

`scope_prefix` هو المسار المنقّط للوحدة الفرعية (`"vision_model"`، `"language_model.model"`، وما إلى ذلك). لا يُطلق التحويل المُحدَّد النطاق إلا على المفاتيح التي تبدأ بـ `f"{scope_prefix}."`؛ حيث يُستأصل البادئة قبل مطابقة النمط ثم تُعاد إلحاقها بعد الاستبدال، بحيث تُكتب خريطة كل نموذج فرعي *بشكل نسبي بالنسبة للنموذج الفرعي*، تمامًا كما لو كان هو الجذر.

## البنية

يُبنى النظام حول عدة مكونات رئيسية معرّفة في [`core_model_loading.py`](https://github.com/huggingface/transformers/blob/main/src/transformers/core_model_loading.py):

**المرحلة 1 — المعالجة لكل مفتاح** (يتكرر على مفاتيح نقطة التفتيش):

1. **مرّر قائمة التحويلات** مرة واحدة. كل `WeightRenaming` يطابق يُفعَّل (مثلًا `block_sparse_moe` → `mlp`)، وقد يدّعي **مفتاح واحد على الأكثر** [WeightConverter](/docs/transformers/main/ar/internal/modeling_utils#transformers.WeightConverter) (مثلًا `experts.*.w1.weight`).
2. **تجزئة (TP) والإرسال إلى الجهاز** بشكل غير متزامن عبر `ThreadPoolExecutor`.
3. **اجمع** الموترات التي تشترك في نفس `source_pattern` معاً (على سبيل المثال، جميع أوزان خبراء MoE، أو إسقاطات gate + up).

**المرحلة 2 — المعالجة لكل تعيين** (تتكرر على التعيينات المجموعة):

1. **إلغاء التكميم/إلغاء التسلسل** (نقاط التفتيش المُكمَّمة مسبقًا فقط).
2. **تطبيق سلسلة [ConversionOps](/docs/transformers/main/ar/internal/modeling_utils#transformers.ConversionOps)**: `Chunk`، `Concatenate`، `MergeModulelist`، `Transpose`، وما إلى ذلك.
3. **تكميم** أثناء التشغيل (إذا لم يكن مُكمَّمًا مسبقًا).
4. **تعيين المعامل** على النموذج.

### WeightTransform

الفئة الأساسية التي تتعامل مع مطابقة الأنماط وجمع المصفوفات:

- **تجميع الأنماط**: أنماط المصدر هي تعبيرات نمطية كاملة تُطابَق باستخدام `re.search()`. يطابق الرمز البرّي `*` أي مكوّن قابل للفهرسة ويجمع جميع التطابقات معاً لعمليات الدفعة.
- **مجموعات الالتقاط والمراجع العكسية**: يمكن الإشارة إلى مجموعات الالتقاط في الأنماط المصدرية على أنها `\1`، `\2`، ... في الأنماط المستهدفة للحفاظ على المقاطع الفرعية (مثل فهارس الطبقات) عبر عملية إعادة التسمية.
- **تحديد النطاق**: `scope_prefix` (يُعيَّن تلقائيًا لكل نموذج فرعي بواسطة `get_model_conversion_mapping`) يقيّد التحويل بالمفاتيح الموجودة تحت ذلك المسار. يُستأصل البادئة قبل المطابقة ثم تُعاد إلحاقها بعد الاستبدال.
- **إعادة تسمية المفاتيح**: يطبّق `rename_source_key()` تعبيرًا منتظمًا (مع معالجة النطاق) ويعيد `(renamed_key, source_pattern)` حتى يعرف المُحمِّل أي مُحوِّل، إن وُجد، ادّعى المفتاح.
- **مجموعة المصفوفات**: تُراكم الدالة `add_tensor()` المصفوفات المُحلّة (أو `Future`) تحت `source_pattern` الخاص بها، بحيث تُجمَّع جميع المصفوفات المطلوبة لتحويل واحد (مثل أوزان جميع خبراء MoE) معًا قبل تشغيل سلسلة العمليات.
- **قابلية العكس**: `reverse_transform()` يبدّل أنماط المصدر ↔ الهدف ويعكس كل عملية، بحيث تُستخدم نفس القائمة المعكوسة لتوجيه عملية الحفظ.
- **التتبع**: يُبلّغ `was_used()` عما إذا كان التحويل قد طابق أي مفتاح فعليًا أثناء التحميل؛ وهذا ضروري حتى يمكن إعادة تطبيق إعادة التسميات غير الثنائية (مثل `PrefixChange` الذي يضيف بادئة قد تكون موجودة مسبقًا) بشكل متماثل عند الحفظ.

### WeightRenaming

`WeightRenaming` هو `WeightTransform` مخصص لإعادة تسمية المفاتيح فقط دون أي عمليات على المصفوفات. على عكس [WeightConverter](/docs/transformers/main/ar/internal/modeling_utils#transformers.WeightConverter)، لا يقوم `WeightRenaming` بـ **claim** للمفتاح، مما يسمح بسلسلة إعادة تسمية متعددة بحرية. في مسار التحميل، تُنفَّذ جميع عمليات إعادة التسمية قبل المحوّل؛ وفي مسار الحفظ (القائمة المعكوسة)، تُنفَّذ جميع عمليات إعادة التسمية المعكوسة بعد المحوّل المعكوس — راجع قاعدة الترتيب أعلاه.

```py
# Legacy checkpoint compatibility
WeightRenaming("LayerNorm.gamma", "LayerNorm.weight")

# Module path changes
WeightRenaming(".block_sparse_moe.", ".mlp.")
```

`PrefixChange` هو غلاف على مستوى أعلى لـ `WeightRenaming` للحالة الشائعة المتمثلة في إزالة أو إضافة مكوّن مسار كامل. يحدد الخياري `model_prefix` نطاق العملية على المفاتيح الموجودة تحت ذلك الاسم:

```py
# "model.layers.bad_prefix.weight" → "model.layers.weight"
PrefixChange(prefix_to_remove="bad_prefix", model_prefix="model.layers")
# "layers.0.weight" → "model.layers.0.weight"
PrefixChange(prefix_to_add="model")
```

### WeightConverter

يمتد [WeightConverter](/docs/transformers/main/ar/internal/modeling_utils#transformers.WeightConverter) من `WeightTransform` مع سلسلة من [ConversionOps](/docs/transformers/main/ar/internal/modeling_utils#transformers.ConversionOps) تعمل على الموترات المجمّعة. الأربعة أنواع المدعومة من حيث العدد هي:

| العدد | أنماط المصدر | أنماط الاستهداف | العملية النموذجية |
|-------------|-----------------|-----------------|-------------------|
| واحد لواحد | 1 | 1 | `Transpose`، [PermuteForRope](/docs/transformers/main/ar/internal/modeling_utils#transformers.PermuteForRope) |
| من واحد إلى متعدد | 1 | >1 | [تجزئة](/docs/transformers/main/ar/internal/modeling_utils#transformers.Chunk) (مثل فك حزمة `qkv_proj`) |
| من متعدد إلى واحد | >1 | 1 | [Concatenate](/docs/transformers/main/ar/internal/modeling_utils#transformers.Concatenate)، [MergeModulelist](/docs/transformers/main/ar/internal/modeling_utils#transformers.MergeModulelist) (مثل دمج الخبراء) |
| من-إلى-كثير | >1 | >1 | فقط مع العمليات التي تدعمه بشكل صريح (مثل `ErnieFuseAndSplitTextVisionExperts`) |

```python
WeightConverter(
    source_patterns=[".experts.*.w1.weight", ".experts.*.w3.weight"],
    target_patterns=".experts.gate_up_proj",
    operations=[MergeModulelist(dim=0), Concatenate(dim=1)],
)
```

يُعدّ `WeightConverter` قابلًا للعكس أيضًا: حيث يقوم `reverse_transform()` بتبديل المصدر ↔ الهدف، ويستبدل كل عملية بـ `reverse_op` الخاص بها، مما يجعل خرائط التحويل المسجّلة ثنائية الاتجاه بالبنية (فالتحميل يستخدم القائمة كما هي، بينما يستخدم الحفظ القائمة معكوسة).

### ترتيب عمليات إعادة التسمية والمحوّلات

قائمة إدخالات `WeightRenaming` قبل إدخالات `WeightConverter`، مع إبقاء أوراقها منفصلة: فعمليات إعادة التسمية تطبّع المفاتيح التي تستهلكها محوّلات الوزن، لكنها لا تستهدف أبداً ورقة ينتجها محوّل. يعتمد مسار الحفظ على ذلك لعكس الترميز في مرحلتين (عكس المحوّلات أولاً، ثم عكس عمليات إعادة التسمية).

يتم المرور عبر قائمة التحويلات بالترتيب، مرة واحدة لكل مفتاح نقطة تفتيش. لكل مفتاح:

- كل `WeightRenaming` يطابق يُفعَّل؛ ويمكن أن تتسلسل عمليات إعادة التسمية المتعددة.
- أول `WeightConverter` يطابق **claims** المفتاح. يتم تجاوز المحوِّلات اللاحقة — وهذا يضمن توجيه المصفوفة إلى محوِّل واحد فقط لخطوة الدمج/التقسيم، وهو السبب في أن وجود محوِّلَين بنطاقات متداخلة يُعدّ خطأً في الإعداد.

```python
weight_mapping = [
    WeightRenaming("^old_prefix", "encoder"),              # rename runs always
    WeightConverter(                                       # converter claims the key
        "attn.qkv_proj.weight",
        ["attn.q_proj.weight", "attn.k_proj.weight", "attn.v_proj.weight"],
        operations=[Chunk(dim=0)],
    ),
]
# Load:  "old_prefix.attn.qkv_proj.weight"
#   → WeightRenaming  → "encoder.attn.qkv_proj.weight"
#   → WeightConverter → "encoder.attn.{q,k,v}_proj.weight"
#
# Save: list reversed, each transform inverted:
#   → rev(WeightConverter) repacks QKV → "encoder.attn.qkv_proj.weight"
#   → rev(WeightRenaming)  fixes prefix → "old_prefix.attn.qkv_proj.weight"
```

## عمليات التحويل

تحتوي فئة [WeightConverter](/docs/transformers/main/ar/internal/modeling_utils#transformers.WeightConverter) على عدة عمليات تُنفَّذ عند استدعاء [from_pretrained()](/docs/transformers/main/ar/main_classes/model#transformers.PreTrainedModel.from_pretrained) لتحويل تينسورات المصدر من نقطة الحفظ إلى تينسورات الهدف في النموذج.

العمليات قابلة للعكس بالكامل. يعكس الحفظ التحويلات ويعيد نقطة التفتيش الأصلية، مما يتيح لك العمل بسهولة عبر أطر عمل مختلفة.

| العملية | عكس |
|-----------|---------|
| `Chunk(dim)` | `Concatenate(dim)` |
| `Concatenate(dim)` | `Chunk(dim)` |
| `MergeModulelist(dim)` | `SplitModulelist(dim)` |
| `SplitModulelist(dim)` | `MergeModulelist(dim)` |
| `Transpose(d0, d1)` | `Transpose(d1, d0)` |
| `PermuteForRope()` | `PermuteForRope()` |
| `Conv3dToLinear(...)` | `LinearToConv3d(...)` |

### مقطع

يقوم عمل [Chunk](/docs/transformers/main/ar/internal/modeling_utils#transformers.Chunk) بتقسيم الموتر إلى أجزاء متساوية على طول بُعد معين. على سبيل المثال، إذا كان النموذج يتوقع Q و K و V كموترات منفصلة بدلاً من موتر واحد.

```py
WeightConverter(
    "self_attn.qkv_proj",
    ["self_attn.q_proj", "self_attn.k_proj", "self_attn.v_proj"],
    operations=[Chunk(dim=0)],
)
```

### دمج

تقوم عملية [Concatenate](/docs/transformers/main/ar/internal/modeling_utils#transformers.Concatenate) بدمج متجهات منفصلة في متجه واحد. على سبيل المثال، إذا كان النموذج يتوقع Q و K و V كمتجه واحد بدلاً من متجهات منفصلة.

```py
WeightConverter(
    ["self_attn.q_proj", "self_attn.k_proj", "self_attn.v_proj"],
    "self_attn.qkv_proj",
    operations=[Concatenate(dim=0)],
)
```

### MergeModulelist

[MergeModulelist](/docs/transformers/main/ar/internal/modeling_utils#transformers.MergeModulelist) يدمج قائمة من المصفوفات ثنائية الأبعاد في مصفوفة ثلاثية الأبعاد واحدة. على سبيل المثال، يمكنك تركيب [MergeModulelist](/docs/transformers/main/ar/internal/modeling_utils#transformers.MergeModulelist) مع [Concatenate](/docs/transformers/main/ar/internal/modeling_utils#transformers.Concatenate) لرتب الخبراء في نموذج MoE وتجميعهم في مصفوفة واحدة.

```py
WeightConverter(
    ["block_sparse_moe.experts.*.w1.weight", "block_sparse_moe.experts.*.w3.weight"],
    "mlp.experts.gate_up_proj",
    operations=[MergeModulelist(dim=0), Concatenate(dim=1)],
)
```

### SplitModulelist

يقوم [SplitModulelist](/docs/transformers/main/ar/internal/modeling_utils#transformers.SplitModulelist) بتقسيم متجه ثلاثي الأبعاد (3D) مرة أخرى إلى قائمة من المتجهات ثنائية الأبعاد (2D). على سبيل المثال، يمكنك تقسيم مجموعة من الخبراء (experts) إلى خبراء فرديين.

```py
WeightConverter(
    "mlp.experts.down_proj",
    "block_sparse_moe.experts.*.w2.weight",
    operations=[SplitModulelist(dim=0)],
)
```

### PermuteForRope

يحوّل [PermuteForRope](/docs/transformers/main/ar/internal/modeling_utils#transformers.PermuteForRope) الأوزان من التنسيق المتشابك إلى استخدام تنسيق sin/cos. على سبيل المثال، يمكنك تركيب [Chunk](/docs/transformers/main/ar/internal/modeling_utils#transformers.Chunk) مع [PermuteForRope](/docs/transformers/main/ar/internal/modeling_utils#transformers.PermuteForRope) لتقسيم متجه QKV المدمج وتطبيق تبديل RoPE الخاص بـ sin/cos على Q و K.

```py
WeightConverter(
    ["model.layers.*.self_attn.qkv_proj.weight"],
    [
        "model.layers.*.self_attn.q_proj.weight",
        "model.layers.*.self_attn.k_proj.weight",
        "model.layers.*.self_attn.v_proj.weight",
    ],
    operations=[Chunk(dim=0), PermuteForRope()],
)
```

### استبدال

`Transpose` تبديل أبعاد الموتر. مفيد لتحويل تخطيطات الأوزان بين معايير مختلفة.

```py
WeightConverter(
    source_patterns="mlp.gate.weight",
    target_patterns="mlp.text_moe.gate.weight",
    operations=[Transpose(dim0=0, dim1=1)],
)
```

## سلسلة العمليات

يمكن ربط العمليات لتنفيذ تحويلات معقدة. تُنفَّذ العمليات بالترتيب، حيث يصبح ناتج كل عملية مدخلاً للعملية التالية.

### مثال: تحويل Mixtral MoE

```python
WeightConverter(
    source_patterns=[
        ".experts.*.w1.weight",  # gate_proj per expert
        ".experts.*.w3.weight",  # up_proj per expert
    ],
    target_patterns=".experts.gate_up_proj",
    operations=[
        MergeModulelist(dim=0),  # Stack all experts: (n_experts, in, out)
        Concatenate(dim=1),      # Fuse gate+up: (n_experts, in, 2*out)
    ],
)
```

**تدفق البيانات:**
```
Input:
  ".experts.*.w1.weight": [tensor_0, tensor_1, ..., tensor_7]  # 8 experts
  ".experts.*.w3.weight": [tensor_0, tensor_1, ..., tensor_7]  # 8 experts

After MergeModulelist(dim=0):
  ".experts.*.w1.weight": (8, 4096, 14336)  # stacked gate
  ".experts.*.w3.weight": (8, 4096, 14336)  # stacked up

After Concatenate(dim=1):
  ".experts.gate_up_proj": (8, 4096, 28672)  # fused gate_up
```

### قواعد مطابقة الأنماط

- أنماط المصدر هي تعبيرات نمطية كاملة تُقيَّم باستخدام `re.search()`. يثبّت `^` موضع البداية للمفتاح **المحدَّد النطاق** (بعد إزالة `scope_prefix`).
- `*` هو نمط عام لكل فهرس يجمع جميع المتجهات المطابقة تحت نفس نمط المصدر (مع الحفاظ على ترتيب نقاط الحفظ لضمان دقة الدمج).
- يمكن الإشارة إلى المجموعات الملتقطة في الأنماط المصدرية على أنها `\1`، `\2`، ... في الأنماط المستهدفة للحفاظ على أجزاء من المفتاح الأصلي (مثل فهارس الطبقات).
- تطابق التحويلات النطاقية (عند ضبط `scope_prefix`) فقط مع المفاتيح التي تبدأ بـ `f"{scope_prefix}."`.

## تسجيل خريطة تحويل

تُسجَّل قائمة تحويل مقابل مفتاح نصي — إما `model_type` (مثل `"mixtral"`) أو اسم فئة (مثل `"LlavaModel"`):

```python
from transformers.conversion_mapping import register_checkpoint_conversion_mapping

register_checkpoint_conversion_mapping(
    "my_model_type",
    [
        WeightRenaming(".old.", ".new."),
        WeightConverter(
            ".experts.*.w1.weight",
            ".experts.gate_proj",
            operations=[MergeModulelist(dim=0)],
        ),
    ],
)
```

### قواعد الاستعلام

عندما يعالج `get_model_conversion_mapping` نموذجًا من نوع `PreTrainedModel`، يتم زيارة كل نموذج فرعي من نوع `PreTrainedModel` بترتيب DFS (أي `nn.Module.named_modules()` مُصفّى ليحتوي على حالات `PreTrainedModel` فقط). يتم تحديد كل نموذج فرعي في مرحلتين: حيث يُنفَّذ مرشح الكود المخصص أولًا، ثم يُبحث عن التحويل المسجَّل.

تُتخطى نماذج الأكواد المخصصة قبل حدوث أي عملية بحث. يُحتسب النموذج الفرعي كنموذج أكواد مخصصة عندما تُرجع [is_custom_code()](/docs/transformers/main/ar/main_classes/model#transformers.PreTrainedModel.is_custom_code) القيمة `True`، ويشمل ذلك النماذج المحمّلة من Hub باستخدام `trust_remote_code=True` وأي فئة نموذج غير موجودة في Transformers. لا ترث نماذج الأكواد المخصصة خرائط التحويل لأن اسم فئتها أو `model_type` قد يتعارض مع نموذج أصلي. على سبيل المثال، لن تحصل بنية مخصصة تضبط `model_type="mixtral"` على تحويلات دمج الخبراء المدمجة في Mixtral.

> [!IMPORTANT]
> سجّل نموذج كود مخصص صراحةً باستخدام `register_checkpoint_conversion_mapping` لتطبيق خريطة تحويل. يضيف التسجيل اسم الفئة أو `model_type` إلى مجموعة خرائط التسجيل التي قام بها المستخدم، مما يعفي النموذج من تخطي الكود المخصص ويوجّهه عبر البحث العادي أدناه.

لكل نموذج فرعي يجتاز مرشح الشيفرة المخصصة:

1. يتم أولاً محاولة **البحث باسم الفئة**، ثم `model_type`. إذا كان كلاهما مسجلاً لنفس الوحدة، فإن **تعيين اسم الفئة هو الغالب** ويُتجاهل تعيين `model_type` لتلك الوحدة — وهذا يتيح لرأس المهمة (مثل `LlavaForConditionalGeneration`) تجاوز خط الأساس المشترك `model_type` (`"llava"`).
2. يتم تعيين `scope_prefix` في الترميز المحدد إلى المسار المنقّط للوحدة الفرعية (`""` للجذر).
3. يقرر **إزالة التكرار بناءً على الأسلاف** ما إذا كان يجب الإبقاء على الترميز:
   - إذا كان مسار **السلف** قد استحوذ بالفعل على المعرّف نفسه (اسم الفئة أو `model_type`)، يتم **تخطي** الوحدة الفرعية — لأن إسناد السلف غير النطاق أو ذو النطاق الأعلى يغطي هذا الشجرة الفرعية بالفعل.
   - إذا كان **الأخ** هو من ادّعى الحق فيه فقط، فإن الوحدة الفرعية **تُحفظ** مع `scope_prefix` الخاص بها. يحصل كل أخ على خريطته النطاقية الخاصة.

تُتتبَّع قوائم «المشاهَد» الخاصة باسم الفئة و`model_type` بشكل منفصل، مع وجود تفصيل دقيق: عند مطابقة وحدة **عبر اسم فئتها**، لا يُضاف `model_type` الخاص بها إلى قائمة المشاهَد *بشكل صريح*. وذلك حتى تبقى الوحدات الأخرى التي تشترك في نفس `model_type` لكن دون وجود إسناد محدد للفئة (مثل `DetrModel` تحت `DetrForSegmentation`) قابلة للوصول من خلال البحث في `model_type`.

### الخرائط القائمة على الفئات مقابل مستعرات `model_type`

تتعايش الأسلوبان معًا في `_MODEL_TO_CONVERSION_PATTERN`:

```python
_MODEL_TO_CONVERSION_PATTERN = {
    # model_type aliases (lookup by config.model_type)
    "minimax": "mixtral",
    "qwen3_moe": "qwen2_moe",
    "mistral3": "llava",
    # class-name aliases (lookup by type(submodule).__name__)
    "PaliGemmaModel": "LlavaModel",
    "MaskFormerDetrDecoder": "DetrModel",
    ...
}
```

يُفضَّل استخدام مفاتيح اسم الفئة عندما يكون `model_type` مشتركًا، لكن فئة محددة تتطلب سلوكًا مختلفًا.

## تكامل تقسيم الموتر

يتكامل نظام التحميل الديناميكي مع توازي الموترات (TP) من خلال التسلسل الهرمي `TensorParallelLayer` المُعرَّف في `src/transformers/integrations/tensor_parallel.py`.

عند تفعيل TP، يتم تقسيم المتجهات **أثناء** الماديّة (materialization)، وليس بعد ذلك. وهذا يعني أن كل رتبة (rank) لا تُحمّل سوى الجزء من المتجه الذي تحتاجه.

```python
def spawn_tp_materialize(thread_pool, tensor, sharding_method, tensor_idx, device, dtype):
    def _job():
        return sharding_method.shard_tensor(tensor, tensor_idx=tensor_idx, device=device, dtype=dtype)
    return thread_pool.submit(_job)
```

### أنماط التوازي المتاحة

| الأسلوب | بُعد شريحة الأوزان | الوصف |
|-------|------------------|-------------|
| `colwise` | -2 | على مستوى الأعمدة: تقسيم ميزات الإخراج |
| `rowwise` | -1 | على مستوى الصفوف: تم تقسيم ميزات الإدخال |
| `packed_colwise` | -2 | لأوزان مُدمجة (gate_up_proj) |
| `packed_rowwise` | -1 | لأوزان مدمجة |
| `embedding_rowwise` | 0 | توازي المفردات |
| `grouped_gemm` | 0 | التوازي الخبير لـ MoE |
| `sequence_parallel` | لا شيء | لا يوجد تقسيم للأوزان |

### معالجة الأوزان المعبأة

يتطلب الأوزان المدمجة مثل `gate_up_proj` عناية خاصة لتقسيمها بشكل صحيح:

```python
def get_packed_weights(param, empty_param, device_mesh, rank, dim):
    """
    Interleaves gate and up shards correctly.

    Packed tensor: [G0 G1 G2 G3 | U0 U1 U2 U3]

    With TP=2:
    - Rank 0 gets: [G0 G1 | U0 U1]
    - Rank 1 gets: [G2 G3 | U2 U3]
    """
```

يُخزَّن تشغيل TP في `WeightTransform` ويُطبَّق بعد عمليات التحويل:

```python
if matched_tp_pattern := tp_plan_alt.search(renamed_key):
    tp_layer = ALL_PARALLEL_STYLES[model.tp_plan[matched_tp_pattern]]
    mapping.distributed_operation = tp_layer(
        device_mesh=device_mesh,
        rank=device_mesh.get_local_rank(),
        empty_param=empty_param.clone()
    )
```

## تكامل التكميم

تتداخل عملية التكميم مع خط تحميل النموذج بطريقتين، وذلك اعتمادًا على ما إذا كان نقطة الحفظ (checkpoint) مُكمَّمةً بالفعل:

- **نقاط التفتيش المُكمّاة مسبقًا**: يوفّر المُكمّاة أمثلة من [WeightConverter](/docs/transformers/main/ar/internal/modeling_utils#transformers.WeightConverter) (عبر `get_weight_conversions()`) لفكّ تسلسل الموترات المُكمّاة. يتم الحفاظ على أنواع البيانات (dtypes) في نقاط التفتيش لتجنّب التحويلات غير المرغوبة.
- **التكميم الفوري**: يوفّر مُكمِّم عملية تكميم تُطبَّق بعد عمليات التحويل، حيث يتم تكميم الأوزان أثناء تحميلها.

يمكن أيضًا للمكمِّم إعادة كتابة قائمة التحويل بأكملها في نهاية `get_model_conversion_mapping` عبر `update_weight_conversions(...)` — على سبيل المثال، يضيف مكمِّم FP8 عملية `Fp8Dequantize` في بداية كل محوِّل موجود، بحيث تُطبَّق مقاييس كل كتلة *قبل* أن تُسطِّح عمليات دمج الخبراء / الربط البنيوى الخاص بكل خبير.

## تحميل النماذج بسرعة وكفاءة

يكون تحميل النموذج أسرع ويستهلك ذاكرة أقل لأنّ المُحمِّل يعرف أيّ المتجهات (tensors) مطلوبة للعمليات، ويجدول تجسيدها (materialization) بشكل كسول (lazy).

يفحص المُحمِّل نقطة التفتيش *مرة واحدة* لاكتشاف التطابقات مع الأنماط وجمع المتجهات. يخزّنها ككائنات `Future` ويقدّمها إلى مجموعة خيوط (thread pool) للتحميل غير المتزامن دون تعطيل GIL. يبدأ تحميل المعامل فور توفّر خيط متاح له.

إذا كان نظامك يشغّل عمليات أخرى كثيفة، فقد تُبطئ الخيوط المتعددة عملية التحميل بدلاً من تسريعها. في هذه الحالة، اضبط متغير البيئة `HF_DEACTIVATE_ASYNC_LOAD=1` لتحميل الأوزان بشكل تسلسلي.

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

### التحميل غير المتزامن مقابل المتزامن

```python
def spawn_materialize(thread_pool, tensor, device, dtype) -> Future | Callable:
    def _job():
        return _materialize_copy(tensor, device, dtype)

    if thread_pool is not None:
        return thread_pool.submit(_job)  # Async: returns Future
    else:
        return _job  # Sync: returns Callable (deferred execution)
```

يُستخدم التحميل المتزامن في الحالات التالية:
- يتم تعيين متغير البيئة `HF_DEACTIVATE_ASYNC_LOAD=1`.
- تم تفعيل تفريغ القرص (تتطلب قيود الذاكرة التحميل التسلسلي).
- يتم تفعيل التكميم الفوري (لتجنب تقدّم خيوط العمل على خطوة التكميم).

### تدفق المادي

```
1. Checkpoint iteration (Phase 1):
   - For each key, walk the transform list once
   - Submit materialization job to ThreadPoolExecutor
   - Job returns Future (async) or Callable (sync)
   - Collect into the matching WeightConverter / WeightRenaming

2. Per-mapping processing (Phase 2, one mapping at a time):
   - materialize_tensors() waits for this mapping's Futures only
   - Apply conversion operations chain (self.operations)
   - Apply quantization operation (if on-the-fly)
   - Set parameters on model
   - Delete realized tensors immediately

3. Cleanup:
   - Thread pool shutdown (with cancel_futures=True for interrupts)
```

### كفاءة الذاكرة

عند تحويل وزن، ينتظر المحوّل حتى تتجسّد جميع الموترات المطلوبة إذا لم تكن قد تم تحميلها بعد. على سبيل المثال، تتطلب عملية [MergeModulelist](/docs/transformers/main/ar/internal/modeling_utils#transformers.MergeModulelist) تحميل جميع الأوزان داخل `ModuleList` قبل الدمج.

يتطلب دمج الموترات (tensors) نسخة مؤقتة، لذا فإن عمليات مثل [MergeModulelist](/docs/transformers/main/ar/internal/modeling_utils#transformers.MergeModulelist) و [Concatenate](/docs/transformers/main/ar/internal/modeling_utils#transformers.Concatenate) تحتاج إلى ضعف ذاكرة الموترات الأساسية أثناء التحويل. بعد الدمج، يبقى الموتر الناتج فقط في الذاكرة. ذروة الذاكرة النظرية في أسوأ الحالات هي حجم النموذج بالإضافة إلى الموترات المطلوبة لأكبر عملية [MergeModulelist](/docs/transformers/main/ar/internal/modeling_utils#transformers.MergeModulelist) أو [Concatenate](/docs/transformers/main/ar/internal/modeling_utils#transformers.Concatenate).

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

1. جميع المعاملات التي تم تحميلها بشكل غير متزامن قبل بدء عملية التحويل المكثفة (كانت مجموعة الخيوط أسرع من طابور التحويل).
2. التحويل المتطلب هو الأخير.

على سبيل المثال، في نموذج MoE يستخدم [MergeModulelist](/docs/transformers/main/ar/internal/modeling_utils#transformers.MergeModulelist) للخبراء في كل طبقة، يكون ذروة الذاكرة النظرية في أسوأ الحالات هي حجم النموذج مضافًا إليه الخبراء في طبقة واحدة.

هذه السيناريوهات الأسوأ نادرة الحدوث. تميل ذروة الذاكرة الفعلية إلى البقاء قريبة من حجم النموذج.

## قابلية العكس

يدعم النظام حفظ النماذج مع التحويلات العكسية، مما يتيح عملية حفظ/تحميل ذهاباً وإياباً. يتم تنفيذ الحفظ في مرحلتين: أولاً المحوِّلات العكسية (حيث يتطابق كل متجه مع محوِّل واحد على الأكثر)، ثم إعادة التسمية العكسية، وفقاً لقاعدة الترتيب المذكورة أعلاه.

```python
def revert_weight_conversion(model, state_dict):
    """Applies reverse conversions for saving."""
    weight_conversions = getattr(model, "_weight_conversions", None)

    # Reverse all transforms
    reverse_weight_conversion = [
        conversion.reverse_transform() for conversion in weight_conversions
    ]

    # Apply in reverse
    for first_param_name, reversed_converter in conversion_mapping.items():
        realized_value = reversed_converter.convert(first_param_name, model=model)
```

يتم تخزين قائمة التحويلات المستخدمة عند التحميل على النموذج باسم `_weight_conversions` (حيث تُحفظ فقط العناصر التي تم تفعيلها فعليًا، مما يضمن إعادة تطبيق إعادة التسميات غير الثنائية مثل `PrefixChange` بشكل متماثل بشكل صحيح). إذا تم إنشاء النموذج دون استخدام `from_pretrained` (وبالتالي لا يحتوي على `_weight_conversions`)، فإن `revert_weight_conversion` يلجأ إلى إعادة حساب التحويل عبر `get_model_conversion_mapping` مع استبعاد أي `PrefixChange` منه (لأننا لا نستطيع معرفة ما إذا كان نقطة الفحص الأصلية تحتوي على البادئة).

قد تحتوي الأنماط المستهدفة على عناصر تعبيرات نمطية تحتاج إلى معالجة للاتجاه العكسي:

```python
def process_target_pattern(pattern: str) -> tuple[str, str | None]:
    """
    - Removes `^` and `$` anchors
    - Removes negative lookahead/lookbehind
    - Detects capturing groups, replaces with \1
    """
```

## أمثلة واقعية

### نمط Mixtral من MoE

**تنسيق نقطة التفتيش:**
```
model.layers.0.block_sparse_moe.experts.0.w1.weight  # gate per expert
model.layers.0.block_sparse_moe.experts.0.w2.weight  # down per expert
model.layers.0.block_sparse_moe.experts.0.w3.weight  # up per expert
...
model.layers.0.block_sparse_moe.experts.7.w1.weight
```

**تنسيق النموذج:**
```
model.layers.0.mlp.experts.gate_up_proj  # (8, 4096, 28672)
model.layers.0.mlp.experts.down_proj     # (8, 14336, 4096)
```

**خريطة التحويل** (من `conversion_mapping.py`):
```python
"mixtral": [
    WeightRenaming(".block_sparse_moe.", ".mlp."),
    WeightConverter(
        source_patterns=[".experts.*.w1.weight", ".experts.*.w3.weight"],
        target_patterns=".experts.gate_up_proj",
        operations=[MergeModulelist(dim=0), Concatenate(dim=1)],
    ),
    WeightConverter(
        source_patterns=[".experts.*.w2.weight"],
        target_patterns=".experts.down_proj",
        operations=[MergeModulelist(dim=0)],
    ),
],
```

### نموذج رؤية ولغة مركّب (Gemma3)

يتميز Gemma3 بالتكوين القياسي المتمثل في "منطق بادئة مختلف للنموذج الرئيسي مقارنةً بالنموذج الأساسي". يتم تسجيل إدخالات (هنا عبر مستعرات تشير إلى قوائم `"llava"` / `"LlavaModel"` المشتركة):

```python
# model_type: applies to Gemma3ForConditionalGeneration / Gemma3ForSequenceClassification
"gemma3": "llava"           # → adds "model." in front of language_model / vision_tower / ...

# class:    applies to the inner Gemma3Model only
"Gemma3Model": "LlavaModel"  # → minimal rename inside the already-prefixed namespace
```

مسار DFS لـ `Gemma3ForConditionalGeneration`:

1. الجذر — تفشل عملية البحث عن الفئة (`Gemma3ForConditionalGeneration` غير مسجّلة)، بينما تنجح عملية البحث عن model_type (`"gemma3"`) → تُضاف عمليات إعادة الكتابة التي تبدأ ببادئة `"llava"` **بدون نطاق**، مما يضع `language_model` و`vision_tower` و`multi_modal_projector` تحت `model.*`.
2. النموذج الداخلي `model: Gemma3Model` — **إصابات البحث عن الفئة** (`Gemma3Model` → `LlavaModel`) → يُطبَّق فقط إسناد `LlavaModel`، محصور النطاق على `"model"`. عمليات إعادة التسمية الأوسع بكثير للمنتصف `"gemma3"` (=`"llava"`) **لا** تُعاد تطبيقها هنا، وهذا بالضبط ما تريده: النموذج الداخلي موجود في مساحة أسماء حيث يكون المنتصف صحيحًا بالفعل.

يستخدم كل نموذج VLM من عائلة Llava نفس شكل الزوج (`PaliGemma`، `InternVL`، `Mistral3`، ...). يتولى إدخال model_type إجراء تعديل البادئة على نموذج الرأس، بينما يحافظ إدخال class على خرائط النموذج الأساسي الداخلي بأقل قدر ممكن.

### تضمين أعمق مع تجاوز محدد للرأس (DETR)

يُظهر `DetrForSegmentation` تجاوزًا محددًا للرأس (head) مُطبَّقًا فوق مستويين متداخلين:

```
DetrForSegmentation                  (class registered: segmentation-only renames)
├── detr: DetrForObjectDetection     (no mapping; just walked through)
│   └── model: DetrModel             (class registered: shared base transforms)
│       └── backbone, encoder, ...
└── mask_head, bbox_attention        (head-specific weights)
```

يُشترك في ذلك خريطتان (واحدة لكل مفتاح مسجّل):

```python
"DetrModel":           [WeightRenaming("backbone.conv_encoder", "backbone"), ...]      # shared base
"DetrForSegmentation": [WeightRenaming("mask_head.lay1", "mask_head.conv1.conv"), ...] # head-specific
```

مسار DFS:

1. يتطابق الجذر `DetrForSegmentation` حسب الفئة → تمت إضافة إعادة تسمية التقطيع **unscoped**.
2. `detr: DetrForObjectDetection` غير مسجّل → لم تُضَف أي تحويلات؛ يستمر DFS في التعمق بداخله.
3. يتطابق `detr.model: DetrModel` عبر الفئة → تُضاف التحويلات الأساسية مع `scope_prefix="detr.model"`.

ولهذا السبب لا يحتاج `DetrForObjectDetection` إلى تعيين خاص به: فالتعيين المسجّل الوحيد في شجرة فرعيه (`DetrModel`) يُطبَّق تلقائيًا على المسار الصحيح.

تعيد مستعرات مفاتيح الفئة استخدام الترميز الأساسي دون تسجيل إضافي: `"MaskFormerDetrDecoder": "DetrModel"` يجعل مُفكّك `MaskFormer` يتبنّى نفس التحويلات تحت اسم فئته الخاصة.

### عمليات مخصصة (ERNIE 4.5 VL MoE)

عندما لا تكون العمليات المدمجة كافية، يمكنك إنشاء فئة فرعية مخصصة من [ConversionOps](/docs/transformers/main/ar/internal/modeling_utils#transformers.ConversionOps). على سبيل المثال، يحتاج نموذج ERNIE 4.5 VL MoE إلى تقسيم قائمة الخبراء المشتركة بين نمطي النص والرؤية — وهو أمر لا تعالجه أي عملية مدمجة واحدة. تقوم العملية المخصصة `ErnieFuseAndSplitTextVisionExperts` بتقسيم الخبراء وإعادة تجميعهم عبر مفتاحين مستهدفين:

```python
"ernie4_5_vl_moe": [
    WeightRenaming("vision_model", "vision_tower"),
    WeightConverter(
        source_patterns=["experts.*.down_proj.weight"],
        target_patterns=[
            "text_moe.experts.down_proj",
            "vision_moe.experts.down_proj",
        ],
        operations=[ErnieFuseAndSplitTextVisionExperts(stack_dim=0, concat_dim=1)],
    ),
],
```

يجب أن تنفّذ العمليات المخصّصة `convert()` وخاصية `reverse_op` لدعم حفظ/تحميل ذهاباً وإياباً.

### أسماء مستعارة لأنواع النماذج

تشارك العديد من النماذج أنماط تحويل مشتركة:

```python
_MODEL_TO_CONVERSION_PATTERN = {
    "mixtral": "mixtral",
    "minimax": "mixtral",
    "qwen2_moe": "qwen2_moe",
    "deepseek_v2": "qwen2_moe",
    "deepseek_v3": "qwen2_moe",
    "qwen3_moe": "qwen2_moe",
    "olmoe": "qwen2_moe",
    ...
}
```

## إعادة استخدام مكونات التحميل الديناميكي

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

على مستوى عالٍ، يبدو العقد على النحو التالي:

1. **جهّز مساحة أسماء النموذج.** تأكد من وجود الوحدات/المعاملات التي تريد تحميلها وأن أسماءها مطابقة لما تستهدفه خريطتك. بالنسبة للمُكيّفات، يعني ذلك استدعاء `inject_adapter_in_model(...)` حتى توجد وحدات المُكيّف قبل التحميل. أما بالنسبة للرؤوس المخصصة أو الوحدات الإضافية، فأنشئها على النموذج أولاً.
2. **اشرح كيفية تعيين الأوزان.** أنشئ قائمة تحويل/إعادة تسمية (على سبيل المثال، في دالة مساعدة مثل `_build_peft_weight_mapping(...)`) باستخدام [WeightConverter](/docs/transformers/main/ar/internal/modeling_utils#transformers.WeightConverter) أو `WeightRenaming`. هنا تُعبّر عن كيفية تحويل مفاتيح نقطة التفتيش أو تقسيمها أو دمجها أو إعادة تسميتها لتتطابق مع نطاق اسم النموذج الخاص بك. يمكنك القيام بأشياء ثلاثة تقريبًا:
    - أضِف العمليات إلى قائمة المحوِّلات: ستُطبَّق هذه العمليات على جميع الأوزان باستثناء تلك التي تم جمعها في أي من `WeightConverter`. وعادةً ما تكون هذه العمليات من نوع `WeightRenaming`
    - أضِف عمليات إلى قائمة عمليات كل محوِّل: وهذا ما يحدث في حالة `Quantization`، حيث نضيف عملية تكميم بعد قائمة عمليات أي `WeightConverter`.
    - استبدال عمليات / map بعمليات مخصّصة: هذا ما يحدث مع `peft`. نستبدل عملية `Concatenate` الخاصة بـ `mixtral` مثلًا، لتصبح `PeftConcatenate` (التي تُعرَّف في PEFT). وبهذه الطريقة، عند قراءة نقطة التفتيش الخاصة بالمُكيّف، يتم جمع الأوزان التي يجب دمجها، وتنسيقها بشكل صحيح من أجل `peft`
3. **التحميل + الإكمال + الإبلاغ.** استخدم المحمّل الأساسي لتنفيذ التحويل وملء المتجهات، ثم أكمل العملية وسجّل النتائج. تحديداً، هذا التدفق هو:
   - `LoadStateDictConfig(...)` + `_load_pretrained_model(...)` لتحميل النموذج وتحويله.
   - `_finalize_load_state_dict(...)` لنقل أي تينسورات مفقودة أو غير متطابقة من `meta`، وتبديئتها، وربط الأوزان.
   - `log_state_dict_report(...)` للإبلاغ عن المفاتيح المفقودة/غير المتوقعة/غير المتطابقة (وأخطاء التحويل).

تُتاح هذه الواجهات البرمجية (APIs) لتمكينك من التعامل مع أكواد مخصصة وتنسيقات أوزان مخصصة، مع ضمان استفادتك في الوقت نفسه من تحميل الأوزان الأكثر كفاءةً وتقسيمها وجودة تجربة الاستخدام العالية في واجهة `transformers` البرمجية!

## مرجع الملفات الرئيسية

| ملف | الغرض |
|------|---------|
| `src/transformers/core_model_loading.py` | منطق التحميل الأساسي، `WeightConverter`، `WeightRenaming`، `ConversionOps` |
| `src/transformers/conversion_mapping.py` | الخرائط المدمجة وتكوين فرعي النموذج (`get_model_conversion_mapping`) |
| `src/transformers/integrations/tensor_parallel.py` | فئات ومساعدات تقسيم TP |
| `src/transformers/quantizers/base.py` | خطافات التكميم والفئة الأساسية |

