# Bitsandbytes

توفّر مكتبة [bitsandbytes](https://github.com/bitsandbytes-foundation/bitsandbytes) أدوات للكمّية (Quantization) لنماذج اللغة الكبيرة (LLMs) من خلال غلاف بايثون خفيف الوزن حول دوال مُسرِّعات الأجهزة. وتُمكّن من العمل مع النماذج الكبيرة باستخدام موارد حوسبة محدودة عن طريق تقليل بصمتها الذاكرة.

في جوهره، يوفر bitsandbytes:

- **طبقات خطية مُكمّمة**: طبقات `Linear8bitLt` و`Linear4bit` التي تحل محل طبقات PyTorch الخطية القياسية ببدائل مُكمّمة موفّرة للذاكرة
- **المُحسِّنات المُحسَّنة**: إصدارات 8 بت من المُحسِّنات الشائعة عبر وحدة `optim`، مما يتيح تدريب النماذج الكبيرة مع تقليل متطلبات الذاكرة
- **ضرب المصفوفات**: عمليات ضرب مصفوفات مُحسّنة تستفيد من التنسيق المُكمَّم

توفر مكتبة bitsandbytes ميزتين رئيسيتين للكمّية:

1. **LLM.int8()** - طريقة تكميم بدقة 8 بت تجعل الاستدلال أكثر قابلية للوصول دون تدهور كبير في الأداء. على عكس التكميم البسيط، يحافظ [LLM.int8()](https://hf.co/papers/2208.07339) ديناميكيًا على دقة أعلى للحسابات الحرجة، مما يمنع فقدان المعلومات في الأجزاء الحساسة من النموذج.

2. **QLoRA** - تقنية تكميم بدقة 4 بت تضغط النماذج بشكل أكبر مع الحفاظ على قابليتها للتدريب من خلال إدراج مجموعة صغيرة من أوزان التكيف منخفضة الرتبة القابلة للتدريب (LoRA).

> **ملاحظة:** للحصول على تجربة كمّية سهلة الاستخدام، يمكنك استخدام `bitsandbytes` [مساحة المجتمع](https://huggingface.co/spaces/bnb-community/bnb-my-repo).

شغّل الأمر أدناه لتثبيت bitsandbytes.

```bash
pip install --upgrade transformers accelerate bitsandbytes
```

لترجمة الشيفرة من المصدر، اتبع التعليمات الواردة في [دليل تثبيت bitsandbytes](https://huggingface.co/docs/bitsandbytes/main/en/installation).

## توافق الأجهزة

يُؤمَّن دعم bitsandbytes على وحدات معالجة الرسوميات من NVIDIA لإصدارات CUDA من 11.8 إلى 13.0، وعلى Intel XPU، وIntel Gaudi (HPU)، وعلى المعالج المركزي (CPU). وهناك جهود مستمرة لدعم منصات إضافية. إذا كنت مهتمًا بتقديم ملاحظات أو إجراء اختبارات، فتفضل بزيارة [مستودع bitsandbytes](https://github.com/bitsandbytes-foundation/bitsandbytes) لمزيد من المعلومات.

### وحدات معالجة رسومات من إنفيديا (CUDA)

يُؤمَّن هذا الواجهة الخلفية على منصات Linux x86-64 وLinux aarch64 وWindows.

| ميزة | الحد الأدنى من متطلبات العتاد |
|---------|-------------------------------|
| مُحسِّنات 8-بت | وحدات معالجة رسومية من NVIDIA Pascal (سلسلة GTX 10X0، P100) أو أحدث * |
| LLM.int8() | وحدات معالجة رسومات من NVIDIA Turing (سلسلة RTX 20X0، T4) أو أحدث |
| تكميم NF4/FP4 | وحدات معالجة رسومية من NVIDIA Pascal (سلسلة GTX 10X0، P100) أو أحدث * |

### بطاقات الرسوميات من إنتل (XPU)

يُؤمَّن هذا الواجهة الخلفية على منصات Linux x86-64 و Windows x86-64.

### Intel Gaudi (وحدة المعالجة HPU)

يُؤمَّن هذا الواجهة الخلفية على نظام Linux x86-64 لمعالجي Gaudi2 و Gaudi3.

### وحدة المعالجة المركزية

يُؤمَّن هذا الواجهة الخلفية على منصات Linux x86-64 وLinux aarch64 وWindows x86-64.

## أمثلة على التكميم

قم بتكميم نموذج عن طريق تمرير [BitsAndBytesConfig](/docs/transformers/v5.23.0/ar/main_classes/quantization#transformers.BitsAndBytesConfig) إلى [from_pretrained()](/docs/transformers/v5.23.0/ar/main_classes/model#transformers.PreTrainedModel.from_pretrained). يعمل هذا مع أي نموذج في أي نمط، طالما أنه يدعم [Accelerate](https://huggingface.co/docs/accelerate/index) ويحتوي على طبقات [torch.nn.Linear](https://pytorch.org/docs/stable/generated/torch.nn.Linear.html).

يُقلّل تكميم النموذج بدقة 8 بتات من استهلاك الذاكرة إلى النصف، وللمodels الكبيرة، اضبط `device_map="auto"` لتوزيع الأوزان بكفاءة على جميع وحدات معالجة الرسوميات المتاحة.

```py
from transformers import AutoModelForCausalLM, BitsAndBytesConfig

quantization_config = BitsAndBytesConfig(load_in_8bit=True)

model_8bit = AutoModelForCausalLM.from_pretrained(
    "bigscience/bloom-1b7", 
    device_map="auto",
    quantization_config=quantization_config
)
```

بشكل افتراضي، تُضبط جميع الوحدات الأخرى مثل [torch.nn.LayerNorm](https://pytorch.org/docs/stable/generated/torch.nn.LayerNorm.html) على نوع البيانات الافتراضي في torch. يمكنك تغيير نوع بيانات هذه الوحدات باستخدام معامل `dtype`. عند تعيين `dtype="auto"`، يتم تحميل النموذج بنوع البيانات المعرّف في ملف `config.json` الخاص بالنموذج.

```py
import torch
from transformers import AutoModelForCausalLM, BitsAndBytesConfig

quantization_config = BitsAndBytesConfig(load_in_8bit=True)

model_8bit = AutoModelForCausalLM.from_pretrained(
    "facebook/opt-350m", 
    device_map="auto",
    quantization_config=quantization_config, 
    dtype="auto"
)
model_8bit.model.decoder.layers[-1].final_layer_norm.weight.dtype
```

بمجرد تكميم النموذج إلى 8 بت، لا يمكنك رفع الأوزان المكمّمة إلى Hub إلا إذا كنت تستخدم أحدث إصدار من Transformers وbitsandbytes. إذا كان لديك أحدث الإصدارات، فيمكنك رفع النموذج المكمّم إلى 8 بت إلى Hub باستخدام [push_to_hub()](/docs/transformers/v5.23.0/ar/main_classes/model#transformers.utils.PushToHubMixin.push_to_hub). يتم رفع ملف إعدادات التكميم config.json أولاً، يليه أوزان النموذج المكمّم.

```py
from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig

quantization_config = BitsAndBytesConfig(load_in_8bit=True)

model = AutoModelForCausalLM.from_pretrained(
    "bigscience/bloom-560m", 
    device_map="auto",
    quantization_config=quantization_config
)

model.push_to_hub("bloom-560m-8bit")
```

يُقلّل تكميم النموذج بدقة 4 بت من استهلاك الذاكرة أربع مرات، وللموديلات الكبيرة، اضبط `device_map="auto"` لتوزيع الأوزان بكفاءة على جميع وحدات معالجة الرسوميات المتاحة.

```py
from transformers import AutoModelForCausalLM, BitsAndBytesConfig

quantization_config = BitsAndBytesConfig(load_in_4bit=True)

model_4bit = AutoModelForCausalLM.from_pretrained(
    "bigscience/bloom-1b7",
    device_map="auto",
    quantization_config=quantization_config
)
```

بشكل افتراضي، يتم تحويل جميع الوحدات الأخرى مثل [torch.nn.LayerNorm](https://pytorch.org/docs/stable/generated/torch.nn.LayerNorm.html) إلى `torch.float16`. يمكنك تغيير نوع البيانات لهذه الوحدات باستخدام معامل `dtype`. عند تعيين `dtype="auto"`، يتم تحميل النموذج بنوع البيانات المعرّف في ملف `config.json` الخاص بالنموذج.

```py
import torch
from transformers import AutoModelForCausalLM, BitsAndBytesConfig

quantization_config = BitsAndBytesConfig(load_in_4bit=True)

model_4bit = AutoModelForCausalLM.from_pretrained(
    "facebook/opt-350m",
    device_map="auto",
    quantization_config=quantization_config, 
    dtype="auto"
)
model_4bit.model.decoder.layers[-1].final_layer_norm.weight.dtype
```

تأكد من أنك تستخدم أحدث إصدار من مكتبة bitsandbytes حتى تتمكن من تسلسل نماذج 4-بت ودفعها إلى Hub باستخدام [push_to_hub()](/docs/transformers/v5.23.0/ar/main_classes/model#transformers.utils.PushToHubMixin.push_to_hub). استخدم [save_pretrained()](/docs/transformers/v5.23.0/ar/main_classes/model#transformers.PreTrainedModel.save_pretrained) لحفظ نموذج 4-بت محلياً.

```py
from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig

quantization_config = BitsAndBytesConfig(load_in_4bit=True)

model = AutoModelForCausalLM.from_pretrained(
    "bigscience/bloom-560m", 
    device_map="auto",
    quantization_config=quantization_config
)

model.push_to_hub("bloom-560m-4bit")
```

> [!WARNING]
> يدعم التدريب بدقة 8 و4 بت تدريب *extra* للمعاملات الإضافية فقط.

تحقق من بصمتك الذاكرة باستخدام `get_memory_footprint`.

```py
print(model.get_memory_footprint())
```

حمّل النماذج المُكمّاة باستخدام [from_pretrained()](/docs/transformers/v5.23.0/ar/main_classes/model#transformers.PreTrainedModel.from_pretrained) دون `quantization_config`.

```py
from transformers import AutoModelForCausalLM, AutoTokenizer

model = AutoModelForCausalLM.from_pretrained("{your_username}/bloom-560m-8bit", device_map="auto")
```

## LLM.int8

يستكشف هذا القسم بعض الميزات المحددة لتكميم 8 بت، مثل التفريغ، وحدود القيم الشاذة، وتخطي تحويل الوحدات، والتدريب الدقيق.

### إخلاء

يمكن لنماذج 8-بت نقل الأوزان بين المعالج المركزي (CPU) وبطاقة الرسوميات (GPU) لتناسب النماذج الكبيرة جداً في الذاكرة. تُخزَّن الأوزان المُرسَلة إلى المعالج المركزي بصيغة **float32** ولا يتم تحويلها إلى 8-بت. على سبيل المثال، فعّل النقل الخارجي للنموذج [bigscience/bloom-1b7](https://huggingface.co/bigscience/bloom-1b7) عبر [BitsAndBytesConfig](/docs/transformers/v5.23.0/ar/main_classes/quantization#transformers.BitsAndBytesConfig).

```py
from transformers import AutoModelForCausalLM, BitsAndBytesConfig

quantization_config = BitsAndBytesConfig(llm_int8_enable_fp32_cpu_offload=True)
```

صمّم خريطة أجهزة مخصصة لتناسب كل شيء على وحدة معالجة الرسوميات الخاصة بك باستثناء `lm_head`، حيث يتم توجيهها إلى وحدة المعالجة المركزية.

```py
device_map = {
    "transformer.word_embeddings": 0,
    "transformer.word_embeddings_layernorm": 0,
    "lm_head": "cpu",
    "transformer.h": 0,
    "transformer.ln_f": 0,
}
```

الآن حمّل نموذجك باستخدام `device_map` و`quantization_config` المخصصين.

```py
model_8bit = AutoModelForCausalLM.from_pretrained(
    "bigscience/bloom-1b7",
    dtype="auto",
    device_map=device_map,
    quantization_config=quantization_config,
)
```

### حدّ القيم الشاذة

يُعدّ "القيمة الشاذة" (outlier) قيمةً لحالة مخفية تتجاوز حدًّا معينًا، وتُحسب هذه القيم بدقة fp16. وعلى الرغم من أن القيم عادةً ما تكون موزعة بشكل طبيعي ([-3.5, 3.5])، إلا أن هذا التوزيع قد يختلف اختلافًا كبيرًا في النماذج الكبيرة ([-60, 6] أو [6, 60]). تعمل التكميم بدقة 8 بت بشكل جيد للقيم التي تكون حوالي 5، ولكن عند تجاوز ذلك، ينشأ انخفاض ملحوظ في الأداء. القيمة الافتراضية الجيدة للحد هي 6، لكن قد يكون من الضروري استخدام حد أدنى للنماذج الأقل استقرارًا (النماذج الصغيرة أو أثناء الضبط الدقيق).

لاستحديد أفضل عتبة لنموذجك، جرّب استخدام معامل `llm_int8_threshold` في [BitsAndBytesConfig](/docs/transformers/v5.23.0/ar/main_classes/quantization#transformers.BitsAndBytesConfig). على سبيل المثال، ضبط العتبة على `0.0` يسرّع الاستدلال بشكل كبير على حساب احتمال فقدان بعض الدقة.

```py
from transformers import AutoModelForCausalLM, BitsAndBytesConfig

model_id = "bigscience/bloom-1b7"

quantization_config = BitsAndBytesConfig(
    llm_int8_threshold=0.0,
    llm_int8_enable_fp32_cpu_offload=True
)

model_8bit = AutoModelForCausalLM.from_pretrained(
    model_id,
    dtype="auto",
    device_map=device_map,
    quantization_config=quantization_config,
)
```

### تخطي تحويل الوحدة

بالنسبة لبعض النماذج، مثل Jukebox، لا حاجة إلى تكميم كل وحدة إلى 8 بت لأن ذلك قد يسبب عدم استقرار فعلياً. في حالة Jukebox، توجد عدة وحدات `lm_head` يجب تجاوزها باستخدام معامل `llm_int8_skip_modules` في [BitsAndBytesConfig](/docs/transformers/v5.23.0/ar/main_classes/quantization#transformers.BitsAndBytesConfig).

```py
from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig

model_id = "bigscience/bloom-1b7"

quantization_config = BitsAndBytesConfig(
    llm_int8_skip_modules=["lm_head"],
)

model_8bit = AutoModelForCausalLM.from_pretrained(
    model_id,
    dtype="auto",
    device_map="auto",
    quantization_config=quantization_config,
)
```

### ضبط

تدعم مكتبة [PEFT](https://github.com/huggingface/peft) ضبط النماذج الكبيرة مثل [flan-t5-large](https://huggingface.co/google/flan-t5-large) و[facebook/opt-6.7b](https://huggingface.co/facebook/opt-6.7b) باستخدام التكميم الثماني البت. لا تحتاج إلى تمرير معامل `device_map` للتدريب لأنها تُحمّل نموذجك تلقائياً على وحدة معالجة رسومية. ومع ذلك، يمكنك دائماً تخصيص خريطة الأجهزة باستخدام معامل `device_map` (يجب استخدام `device_map="auto"` للاستدلال فقط).

## QLoRA

يستكشف هذا القسم بعض الميزات المحددة لتكميم 4 بت، مثل تغيير نوع بيانات الحساب، ونوع بيانات Normal Float 4 (NF4)، والتكميم المتداخل.

### نوع بيانات الحساب

غيّر نوع البيانات من float32 (القيمة الافتراضية) إلى bf16 في [BitsAndBytesConfig](/docs/transformers/v5.23.0/ar/main_classes/quantization#transformers.BitsAndBytesConfig) لتسريع الحسابات.

```py
import torch
from transformers import BitsAndBytesConfig

quantization_config = BitsAndBytesConfig(load_in_4bit=True, bnb_4bit_compute_dtype=torch.bfloat16)
```

### الفاصلة العائمة العادية 4 (NF4)

NF4 هو نوع بيانات من 4 بت من ورقة [QLoRA](https://hf.co/papers/2305.14314)، مُعدّل للأوزان المُهيّأة من توزيع طبيعي. يجب عليك استخدام NF4 لتدريب النماذج الأساسية بدقة 4 بت.

```py
from transformers import BitsAndBytesConfig

nf4_config = BitsAndBytesConfig(
    load_in_4bit=True,
    bnb_4bit_quant_type="nf4",
)

model_nf4 = AutoModelForCausalLM.from_pretrained(model_id, dtype="auto", quantization_config=nf4_config)
```

في الاستدلال، لا يكون لـ`bnb_4bit_quant_type` تأثير كبير على الأداء. ومع ذلك، للبقاء متسقاً مع أوزان النموذج، يجب عليك استخدام قيم `bnb_4bit_compute_dtype` و`dtype`.

### التكميم المتداخل

يمكن أن توفر التكميم المتداخل ذاكرة إضافية دون أي تكلفة أداء إضافية. يقوم هذا الميزة بتنفيذ تكميم ثانوي للأوزان المُكمَّمة مسبقاً لتوفير 0.4 بت/معامل إضافي. على سبيل المثال، باستخدام التكميم المتداخل، يمكنك ضبط نموذج [Llama-13b](https://huggingface.co/meta-llama/Llama-2-13b) على بطاقة NVIDIA T4 GPU بسعة 16 جيجابايت مع طول تسلسل يبلغ 1024، وحجم دفعة يساوي 1، مع تفعيل تراكم التدرجات على 4 خطوات.

```py
from transformers import BitsAndBytesConfig

double_quant_config = BitsAndBytesConfig(
    load_in_4bit=True,
    bnb_4bit_use_double_quant=True,
)

model_double_quant = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-2-13b-chat-hf", dtype="auto", quantization_config=double_quant_config)
```

## إلغاء تكميم نماذج bitsandbytes

بمجرد إجراء التكميم، يمكنك [إلغاء تكميم](/docs/transformers/v5.23.0/ar/main_classes/model#transformers.PreTrainedModel.dequantize) النموذج إلى الدقة الأصلية، لكن قد يؤدي ذلك إلى بعض فقدان الجودة. تأكد من توفر ذاكرة GPU كافية لاستيعاب النموذج بعد إلغاء التكميم.

```python
from transformers import AutoModelForCausalLM, BitsAndBytesConfig, AutoTokenizer

model = AutoModelForCausalLM.from_pretrained("facebook/opt-125m", BitsAndBytesConfig(load_in_4bit=True))
model.dequantize()
```

## الموارد

تعرف على المزيد من التفاصيل حول التكميم الثماني البت في [مقدمة لطيفة إلى ضرب المصفوفات الثماني البت لتحويلات على نطاق واسع باستخدام Hugging Face Transformers و Accelerate و bitsandbytes](https://huggingface.co/blog/hf-bitsandbytes-integration).

جرّب التكميم بدقة 4 بت في هذا [دفتر ملاحظات](https://colab.research.google.com/drive/1ge2F1QSK8Q7h0hn3YKuBCOAS0bK8E0wf) وتعرّف على مزيد من التفاصيل حول ذلك في [جعل نماذج اللغة الكبيرة أكثر قابلية للوصول باستخدام bitsandbytes والتكميم بدقة 4 بت وQLoRA](https://huggingface.co/blog/4bit-transformers-bitsandbytes).

