Buckets:

mishig's picture
|
download
raw
19.8 kB
# bitsandbytes
[bitsandbytes](https://huggingface.co/docs/bitsandbytes/index) هي الخيار الأسهل لتكميم النموذج إلى 8 و4 بت. يقوم تكميم 8 بت بضرب القيم الشاذة في fp16 مع القيم غير الشاذة في int8، ثم يعيد تحويل القيم غير الشاذة إلى fp16، ويجمعها معًا لإرجاع الأوزان في fp16. يقلل هذا من التأثير التدهوري الذي تتركه القيم الشاذة على أداء النموذج.
تضغط عملية التكميم بدقة 4 بت النموذج بشكل أكبر، وتُستخدم بشكل شائع مع [QLoRA](https://hf.co/papers/2305.14314) لضبط نماذج اللغة الكبيرة المكمّمة.
يُبيّن هذا الدليل كيف يمكن أن تُمكّن عملية التكميم (Quantization) من تشغيل [FLUX.1-dev](https://huggingface.co/black-forest-labs/FLUX.1-dev) على ذاكرة عرض أقل من 16 جيجابايت، بل وحتى على نسخة مجانية من Google Colab.
![comparison image](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/quant-bnb/comparison.png)
لاستخدام bitsandbytes، تأكد من تثبيت المكتبات التالية:
```bash
pip install diffusers transformers accelerate bitsandbytes -U
```
الآن يمكنك تكميم نموذج عن طريق تمرير [BitsAndBytesConfig](/docs/diffusers/main/ar/api/quantization#diffusers.BitsAndBytesConfig) إلى [from_pretrained()](/docs/diffusers/main/ar/api/models/overview#diffusers.ModelMixin.from_pretrained). يعمل هذا مع أي نموذج في أي نمط، طالما أنه يدعم التحميل باستخدام [Accelerate](https://hf.co/docs/accelerate/index) ويحتوي على طبقات `torch.nn.Linear`.
يُقلّل تكميم النموذج بدقة 8 بت من استهلاك الذاكرة إلى النصف:
يُؤيَّد bitsandbytes في كلٍّ من Transformers وDiffusers، لذا يمكنك تكميم كلٍّ من [FluxTransformer2DModel](/docs/diffusers/main/ar/api/models/flux_transformer#diffusers.FluxTransformer2DModel) و[T5EncoderModel](https://huggingface.co/docs/transformers/main/en/model_doc/t5#transformers.T5EncoderModel).
لوحات Ada وشرائح GPU من السلاسل الأعلى، ننصح بتغيير `dtype` إلى `torch.bfloat16`.
> [!TIP]
> لا يتم تكميم `CLIPTextModel` و[AutoencoderKL](/docs/diffusers/main/ar/api/models/autoencoderkl#diffusers.AutoencoderKL) لأنهما صغيران الحجم بالفعل، ولأن [AutoencoderKL](/docs/diffusers/main/ar/api/models/autoencoderkl#diffusers.AutoencoderKL) يحتوي على عدد قليل فقط من طبقات `torch.nn.Linear`.
```py
from diffusers import BitsAndBytesConfig as DiffusersBitsAndBytesConfig
from transformers import BitsAndBytesConfig as TransformersBitsAndBytesConfig
import torch
from diffusers import AutoModel
from transformers import T5EncoderModel
quant_config = TransformersBitsAndBytesConfig(load_in_8bit=True,)
text_encoder_2_8bit = T5EncoderModel.from_pretrained(
"black-forest-labs/FLUX.1-dev",
subfolder="text_encoder_2",
quantization_config=quant_config,
dtype=torch.float16,
)
quant_config = DiffusersBitsAndBytesConfig(load_in_8bit=True,)
transformer_8bit = AutoModel.from_pretrained(
"black-forest-labs/FLUX.1-dev",
subfolder="transformer",
quantization_config=quant_config,
dtype=torch.float16,
)
```
بشكل افتراضي، يتم تحويل جميع الوحدات الأخرى مثل `torch.nn.LayerNorm` إلى `torch.float16`. يمكنك تغيير نوع البيانات لهذه الوحدات باستخدام معامل `dtype`.
```diff
transformer_8bit = AutoModel.from_pretrained(
"black-forest-labs/FLUX.1-dev",
subfolder="transformer",
quantization_config=quant_config,
+ dtype=torch.float32,
)
```
لنقم بتوليد صورة باستخدام نماذجنا المُكمّاة.
يؤدي تعيين `device_map="auto"` إلى ملء جميع المساحة المتاحة على وحدات معالجة الرسوميات (GPU) أولاً، ثم وحدة المعالجة المركزية (CPU)، وأخيراً القرص الصلب (وهو الخيار الأبطأ على الإطلاق) إذا لم تكن هناك ذاكرة كافية بعد.
```py
from diffusers import FluxPipeline
pipe = FluxPipeline.from_pretrained(
"black-forest-labs/FLUX.1-dev",
transformer=transformer_8bit,
text_encoder_2=text_encoder_2_8bit,
dtype=torch.float16,
device_map="auto",
)
pipe_kwargs = {
"prompt": "A cat holding a sign that says hello world",
"height": 1024,
"width": 1024,
"guidance_scale": 3.5,
"num_inference_steps": 50,
"max_sequence_length": 512,
}
image = pipe(**pipe_kwargs, generator=torch.manual_seed(0),).images[0]
```
عند توفر ذاكرة كافية، يمكنك أيضًا نقل خط الأنابيب مباشرةً إلى وحدة معالجة الرسوميات باستخدام `.to("cuda")` وتطبيق [enable_model_cpu_offload()](/docs/diffusers/main/ar/api/pipelines/overview#diffusers.DiffusionPipeline.enable_model_cpu_offload) لتحسين استخدام ذاكرة وحدة معالجة الرسوميات.
Once a model is quantized, you can push the model to the Hub with the [push_to_hub()](/docs/diffusers/main/ar/api/schedulers/overview#diffusers.utils.PushToHubMixin.push_to_hub) method. The quantization `config.json` file is pushed first, followed by the quantized model weights. You can also save the serialized 8-bit models locally with [save_pretrained()](/docs/diffusers/main/ar/api/models/overview#diffusers.ModelMixin.save_pretrained).
يُقلّل تكميم النموذج بدقة 4 بت من استهلاك الذاكرة أربع مرات:
يُؤيَّد bitsandbytes في كلٍّ من Transformers وDiffusers، لذا يمكنك تكميم كلٍّ من [FluxTransformer2DModel](/docs/diffusers/main/ar/api/models/flux_transformer#diffusers.FluxTransformer2DModel) و[T5EncoderModel](https://huggingface.co/docs/transformers/main/en/model_doc/t5#transformers.T5EncoderModel).
لوحات Ada وشرائح GPU من السلاسل الأعلى، ننصح بتغيير `dtype` إلى `torch.bfloat16`.
> [!TIP]
> لا يتم تكميم `CLIPTextModel` و[AutoencoderKL](/docs/diffusers/main/ar/api/models/autoencoderkl#diffusers.AutoencoderKL) لأنهما صغيران الحجم بالفعل، ولأن [AutoencoderKL](/docs/diffusers/main/ar/api/models/autoencoderkl#diffusers.AutoencoderKL) يحتوي على عدد قليل فقط من طبقات `torch.nn.Linear`.
```py
from diffusers import BitsAndBytesConfig as DiffusersBitsAndBytesConfig
from transformers import BitsAndBytesConfig as TransformersBitsAndBytesConfig
import torch
from diffusers import AutoModel
from transformers import T5EncoderModel
quant_config = TransformersBitsAndBytesConfig(load_in_4bit=True,)
text_encoder_2_4bit = T5EncoderModel.from_pretrained(
"black-forest-labs/FLUX.1-dev",
subfolder="text_encoder_2",
quantization_config=quant_config,
dtype=torch.float16,
)
quant_config = DiffusersBitsAndBytesConfig(load_in_4bit=True,)
transformer_4bit = AutoModel.from_pretrained(
"black-forest-labs/FLUX.1-dev",
subfolder="transformer",
quantization_config=quant_config,
dtype=torch.float16,
)
```
بشكل افتراضي، يتم تحويل جميع الوحدات الأخرى مثل `torch.nn.LayerNorm` إلى `torch.float16`. يمكنك تغيير نوع البيانات لهذه الوحدات باستخدام معامل `dtype`.
```diff
transformer_4bit = AutoModel.from_pretrained(
"black-forest-labs/FLUX.1-dev",
subfolder="transformer",
quantization_config=quant_config,
+ dtype=torch.float32,
)
```
لنقم بتوليد صورة باستخدام نماذجنا المُكمّاة.
يؤدي تعيين `device_map="auto"` إلى ملء جميع المساحة المتاحة على وحدات معالجة الرسوميات (GPU) أولاً، ثم وحدة المعالجة المركزية (CPU)، وأخيراً القرص الصلب (وهو الخيار الأبطأ على الإطلاق) إذا لم تكن هناك ذاكرة كافية بعد.
```py
from diffusers import FluxPipeline
pipe = FluxPipeline.from_pretrained(
"black-forest-labs/FLUX.1-dev",
transformer=transformer_4bit,
text_encoder_2=text_encoder_2_4bit,
dtype=torch.float16,
device_map="auto",
)
pipe_kwargs = {
"prompt": "A cat holding a sign that says hello world",
"height": 1024,
"width": 1024,
"guidance_scale": 3.5,
"num_inference_steps": 50,
"max_sequence_length": 512,
}
image = pipe(**pipe_kwargs, generator=torch.manual_seed(0),).images[0]
```
عند توفر ذاكرة كافية، يمكنك أيضًا نقل خط الأنابيب مباشرةً إلى وحدة معالجة الرسوميات باستخدام `.to("cuda")` وتطبيق [enable_model_cpu_offload()](/docs/diffusers/main/ar/api/pipelines/overview#diffusers.DiffusionPipeline.enable_model_cpu_offload) لتحسين استخدام ذاكرة وحدة معالجة الرسوميات.
Once a model is quantized, you can push the model to the Hub with the [push_to_hub()](/docs/diffusers/main/ar/api/schedulers/overview#diffusers.utils.PushToHubMixin.push_to_hub) method. The quantization `config.json` file is pushed first, followed by the quantized model weights. You can also save the serialized 4-bit models locally with [save_pretrained()](/docs/diffusers/main/ar/api/models/overview#diffusers.ModelMixin.save_pretrained).
> [!WARNING]
> يدعم التدريب بأوزان 8 بت و4 بت تدريب *معاملات إضافية* فقط.
تحقق من بصمتك في الذاكرة باستخدام طريقة `get_memory_footprint`:
```py
print(model.get_memory_footprint())
```
لاحظ أن هذا يخبرك فقط بحجم الذاكرة الذي تشغله معاملات النموذج ولا _يقوم_ بتقدير متطلبات الذاكرة للاستدلال.
يمكن تحميل النماذج المُكمّمة من طريقة [from_pretrained()](/docs/diffusers/main/ar/api/models/overview#diffusers.ModelMixin.from_pretrained) دون الحاجة إلى تحديد معاملات `quantization_config`:
```py
from diffusers import AutoModel, BitsAndBytesConfig
quantization_config = BitsAndBytesConfig(load_in_4bit=True)
model_4bit = AutoModel.from_pretrained(
"hf-internal-testing/flux.1-dev-nf4-pkg", subfolder="transformer"
)
```
## 8-بت (خوارزمية LLM.int8())
> [!TIP]
> تعرف على المزيد من التفاصيل حول التكميم بدقة 8 بت في هذا [المقال](https://huggingface.co/blog/hf-bitsandbytes-integration)!
يستكشف هذا القسم بعض الميزات المحددة لنماذج 8-بت، مثل حدود القيم الشاذة وتخطي تحويل الوحدات.
### حدّ القيم الشاذة
يُعدّ "القيمة الشاذة" (outlier) قيمةً لحالة مخفية تتجاوز حدًّا معينًا، وتُحسب هذه القيم بدقة fp16. وعلى الرغم من أن القيم موزعة عادةً بشكل طبيعي ([-3.5, 3.5])، إلا أن هذا التوزيع قد يختلف اختلافًا كبيرًا في النماذج الكبيرة ([-60, 6] أو [6, 60]). يعمل التكميم بدقة 8 بت بشكل جيد للقيم التي تبلغ حوالي 5، ولكن عند تجاوز ذلك، يظهر عقوبة أداء كبيرة. القيمة الافتراضية الجيدة للحد هي 6، لكن قد يكون هناك حاجة إلى حد أدنى للنماذج الأقل استقرارًا (النماذج الصغيرة أو أثناء الضبط الدقيق).
لإيجاد أفضل حد عتبة لنموذجك، نقترح تجربة معامل `llm_int8_threshold` في [BitsAndBytesConfig](/docs/diffusers/main/ar/api/quantization#diffusers.BitsAndBytesConfig):
```py
from diffusers import AutoModel, BitsAndBytesConfig
quantization_config = BitsAndBytesConfig(
load_in_8bit=True, llm_int8_threshold=10,
)
model_8bit = AutoModel.from_pretrained(
"black-forest-labs/FLUX.1-dev",
subfolder="transformer",
quantization_config=quantization_config,
)
```
### تخطي تحويل الوحدة
في بعض النماذج، لا حاجة إلى تكميم كل وحدة إلى 8 بت، إذ قد يؤدي ذلك فعلياً إلى عدم استقرار. على سبيل المثال، في نماذج الانتشار مثل [Stable Diffusion 3](../api/pipelines/stable_diffusion/stable_diffusion_3)، يمكن تجاوز وحدة `proj_out` باستخدام معامل `llm_int8_skip_modules` في [BitsAndBytesConfig](/docs/diffusers/main/ar/api/quantization#diffusers.BitsAndBytesConfig):
```py
from diffusers import SD3Transformer2DModel, BitsAndBytesConfig
quantization_config = BitsAndBytesConfig(
load_in_8bit=True, llm_int8_skip_modules=["proj_out"],
)
model_8bit = SD3Transformer2DModel.from_pretrained(
"stabilityai/stable-diffusion-3-medium-diffusers",
subfolder="transformer",
quantization_config=quantization_config,
)
```
## 4 بت (خوارزمية QLoRA)
> [!TIP]
> تعرف على مزيد من التفاصيل في [هذا المنشور على المدونة](https://huggingface.co/blog/4bit-transformers-bitsandbytes).
يستكشف هذا القسم بعض الميزات المحددة لنماذج 4-بت، مثل تغيير نوع بيانات الحساب، واستخدام نوع بيانات Normal Float 4 (NF4)، واستخدام التكميم المتداخل.
### نوع بيانات الحساب
لتسريع الحساب، يمكنك تغيير نوع البيانات من float32 (القيمة الافتراضية) إلى bf16 باستخدام معامل `bnb_4bit_compute_dtype` في [BitsAndBytesConfig](/docs/diffusers/main/ar/api/quantization#diffusers.BitsAndBytesConfig):
```py
import torch
from diffusers 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 بت. يمكن ضبط ذلك عبر معامل `bnb_4bit_quant_type` في [BitsAndBytesConfig](/docs/diffusers/main/ar/api/quantization#diffusers.BitsAndBytesConfig):
```py
from diffusers import BitsAndBytesConfig as DiffusersBitsAndBytesConfig
from transformers import BitsAndBytesConfig as TransformersBitsAndBytesConfig
from diffusers import AutoModel
from transformers import T5EncoderModel
quant_config = TransformersBitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type="nf4",
)
text_encoder_2_4bit = T5EncoderModel.from_pretrained(
"black-forest-labs/FLUX.1-dev",
subfolder="text_encoder_2",
quantization_config=quant_config,
dtype=torch.float16,
)
quant_config = DiffusersBitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type="nf4",
)
transformer_4bit = AutoModel.from_pretrained(
"black-forest-labs/FLUX.1-dev",
subfolder="transformer",
quantization_config=quant_config,
dtype=torch.float16,
)
```
في الاستدلال، لا يُحدث `bnb_4bit_quant_type` تأثيراً كبيراً على الأداء. ومع ذلك، للبقاء متوافقاً مع أوزان النموذج، يجب عليك استخدام قيم `bnb_4bit_compute_dtype` و`dtype`.
### التكميم المتداخل
التكميم المتداخل هو تقنية يمكنها توفير ذاكرة إضافية دون أي تكلفة أداء إضافية. يقوم هذا الميزة بتنفيذ تكميم ثانوي للأوزان المُكمَّمة مسبقًا لتوفير 0.4 بت/معامل إضافي.
```py
from diffusers import BitsAndBytesConfig as DiffusersBitsAndBytesConfig
from transformers import BitsAndBytesConfig as TransformersBitsAndBytesConfig
from diffusers import AutoModel
from transformers import T5EncoderModel
quant_config = TransformersBitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_use_double_quant=True,
)
text_encoder_2_4bit = T5EncoderModel.from_pretrained(
"black-forest-labs/FLUX.1-dev",
subfolder="text_encoder_2",
quantization_config=quant_config,
dtype=torch.float16,
)
quant_config = DiffusersBitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_use_double_quant=True,
)
transformer_4bit = AutoModel.from_pretrained(
"black-forest-labs/FLUX.1-dev",
subfolder="transformer",
quantization_config=quant_config,
dtype=torch.float16,
)
```
## إلغاء تكميم نماذج `bitsandbytes`
بمجرد تكميم النموذج، يمكنك إلغاء تكميمه إلى دقته الأصلية، لكن قد يؤدي ذلك إلى فقدان طفيف في الجودة. تأكد من توفر ذاكرة GPU كافية لاستيعاب النموذج بعد إلغاء التكميم.
```python
from diffusers import BitsAndBytesConfig as DiffusersBitsAndBytesConfig
from transformers import BitsAndBytesConfig as TransformersBitsAndBytesConfig
from diffusers import AutoModel
from transformers import T5EncoderModel
quant_config = TransformersBitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_use_double_quant=True,
)
text_encoder_2_4bit = T5EncoderModel.from_pretrained(
"black-forest-labs/FLUX.1-dev",
subfolder="text_encoder_2",
quantization_config=quant_config,
dtype=torch.float16,
)
quant_config = DiffusersBitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_use_double_quant=True,
)
transformer_4bit = AutoModel.from_pretrained(
"black-forest-labs/FLUX.1-dev",
subfolder="transformer",
quantization_config=quant_config,
dtype=torch.float16,
)
text_encoder_2_4bit.dequantize()
transformer_4bit.dequantize()
```
## torch.compile
تسريع الاستدلال باستخدام `torch.compile`. تأكد من تثبيت أحدث إصدار من `bitsandbytes` كما نوصي بتثبيت [PyTorch nightly](https://pytorch.org/get-started/locally/).
```py
torch._dynamo.config.capture_dynamic_output_shape_ops = True
quant_config = DiffusersBitsAndBytesConfig(load_in_8bit=True)
transformer_4bit = AutoModel.from_pretrained(
"black-forest-labs/FLUX.1-dev",
subfolder="transformer",
quantization_config=quant_config,
dtype=torch.float16,
)
transformer_4bit.compile(fullgraph=True)
```
```py
quant_config = DiffusersBitsAndBytesConfig(load_in_4bit=True)
transformer_4bit = AutoModel.from_pretrained(
"black-forest-labs/FLUX.1-dev",
subfolder="transformer",
quantization_config=quant_config,
dtype=torch.float16,
)
transformer_4bit.compile(fullgraph=True)
```
على بطاقة RTX 4090 مع التجميع، اكتمل توليد Flux بدقة 4 بت في 25.809 ثانية مقابل 32.570 ثانية دون التجميع.
اطّلع على [سكربت القياس](https://gist.github.com/sayakpaul/0db9d8eeeb3d2a0e5ed7cf0d9ca19b7d) لمزيد من التفاصيل.
## الموارد
* [دفتر ملاحظات شامل يُظهر استنتاج نموذج Flux.1 Dev في بيئة Colab المجانية](https://gist.github.com/sayakpaul/c76bd845b48759e11687ac550b99d8b4)
* [التدريب](https://github.com/huggingface/diffusers/blob/8c661ea586bf11cb2440da740dd3c4cf84679b85/examples/dreambooth/README_hidream.md#using-quantization)

Xet Storage Details

Size:
19.8 kB
·
Xet hash:
68ee000a37c6bd14790d86151cde9f080c7d15e309577ad6e2bdd7360da99799

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.