Diffusers documentation

bitsandbytes

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v0.42.1).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

bitsandbytes

bitsandbytes, bir modeli 8 ve 4-bit'e kuantize etmek için en kolay seçenektir. 8-bit kuantizasyon, fp16'daki aykırı değerleri int8'deki aykırı olmayan değerlerle çarpar, aykırı olmayan değerleri fp16'ya geri dönüştürür ve ardından bunları toplayarak ağırlıkları fp16'da geri döndürür. Bu, aykırı değerlerin bir modelin performansına olan bozucu etkisini azaltır.

4-bit kuantizasyon bir modeli daha da sıkıştırır ve kuantize edilmiş LLM'leri ince ayar yapmak için genellikle QLoRA ile birlikte kullanılır.

Bu kılavuz, kuantizasyonun FLUX.1-dev'in 16GB'tan az VRAM ile ve hatta ücretsiz bir Google Colab örneğinde çalıştırılmasını nasıl mümkün kıldığını göstermektedir.

comparison image

bitsandbytes'i kullanmak için aşağıdaki kütüphanelerin yüklü olduğundan emin olun:

pip install diffusers transformers accelerate bitsandbytes -U

Artık from_pretrained() fonksiyonuna BitsAndBytesConfig geçirerek bir modeli kuantize edebilirsiniz. Bu, Accelerate ile yüklemeyi destekleyen ve torch.nn.Linear katmanları içeren herhangi bir modalitedeki herhangi bir model için geçerlidir.

8-bit
4-bit

Bir modeli 8-bit olarak kuantize etmek bellek kullanımını yarıya indirir:

bitsandbytes, hem Transformers hem de Diffusers tarafından desteklenir; bu sayede hem FluxTransformer2DModel hem de T5EncoderModel için kuantizasyon yapabilirsiniz.

Ada ve daha yüksek serisi GPU'lar için dtype'yi torch.bfloat16 olarak değiştirmenizi öneririz.

CLIPTextModel ve AutoencoderKL boyutları zaten küçük olduğu ve AutoencoderKL yalnızca birkaç torch.nn.Linear katmanına sahip olduğu için kuantize edilmez.

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,
)

Varsayılan olarak, torch.nn.LayerNorm gibi diğer tüm modüller torch.float16 olarak dönüştürülür. Bu modüllerin veri türünü dtype parametresiyle değiştirebilirsiniz.

transformer_8bit = AutoModel.from_pretrained(
    "black-forest-labs/FLUX.1-dev",
    subfolder="transformer",
    quantization_config=quant_config,
+   dtype=torch.float32,
)

Kantize modellerimizi kullanarak bir görüntü oluşturalım.

device_map="auto" ayarlandığında, önce GPU(lar) üzerindeki tüm kullanılabilir alan, ardından CPU ve hâlâ yeterli bellek yoksa sabit disk (mutlak olarak en yavaş seçenek) otomatik olarak doldurulur.

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]

Yeterli bellek varsa, .to("cuda") ile pipeline'ı doğrudan GPU'ya taşıyabilir ve GPU bellek kullanımını optimize etmek için enable_model_cpu_offload() uygulayabilirsiniz.

Bir model kuantize edildikten sonra, modeli push_to_hub() yöntemiyle Hub'a yükleyebilirsiniz. Kuantizasyon config.json dosyası önce yüklenir, ardından kuantize edilmiş model ağırlıkları yüklenir. Seri hale getirilmiş 8-bit modelleri ayrıca save_pretrained() ile yerel olarak da kaydedebilirsiniz.

8-bit ve 4-bit ağırlıklarla eğitim yalnızca ekstra parametrelerin eğitimini destekler.

Bellek ayak izinizi get_memory_footprint yöntemiyle kontrol edin:

print(model.get_memory_footprint())

Bu, yalnızca model parametrelerinin bellek ayak izini belirtir ve çıkarım bellek gereksinimlerini tahmin etmez.

Kantize modeller, quantization_config parametrelerini belirtmeye gerek kalmadan from_pretrained() yöntemiyle yüklenebilir:

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-bit (LLM.int8() algoritması)

8-bit kuantizasyonun detayları hakkında bu blog yazısında daha fazla bilgi edinin!

Bu bölüm, 8-bit modellerin aykırı değer eşikleri ve modül dönüşümünün atlanması gibi bazı özel özelliklerini ele alır.

Aykırı değer eşiği

“Outlier” (aykırı değer), belirli bir eşiğin üzerindeki gizli durum değeridir ve bu değerler fp16 ile hesaplanır. Değerler genellikle normal dağılıma sahiptir ([-3.5, 3.5]), ancak büyük modellerde bu dağılım çok farklı olabilir ([-60, 6] veya [6, 60]). 8-bit kuantizasyon ~5 civarındaki değerler için iyi çalışır, ancak bu değerin ötesinde önemli bir performans cezası vardır. İyi bir varsayılan eşik değeri 6'dır, ancak daha az kararlı modeller (küçük modeller veya ince ayar) için daha düşük bir eşik gerekebilir.

Modeliniz için en iyi eşiği bulmak için BitsAndBytesConfig içindeki llm_int8_threshold parametresiyle deneyler yapmanızı öneririz:

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,
)

Modül dönüşümünü atla

Bazı modellerde, her modülü 8-bit'e küçültmek zorunda değilsiniz; bu durum aslında kararsızlığa yol açabilir. Örneğin, Stable Diffusion 3 gibi difüzyon modellerinde, proj_out modülü, BitsAndBytesConfig içindeki llm_int8_skip_modules parametresi kullanılarak atlanabilir:

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-bit (QLoRA algoritması)

Detayları hakkında bu blog yazısında daha fazla bilgi edinin.

Bu bölüm, hesaplama veri türünü değiştirme, Normal Float 4 (NF4) veri türünü kullanma ve iç içe geçmiş kuantizasyonu kullanma gibi 4-bit modellerin bazı özel özelliklerini ele alır.

Hesaplama veri türü

Hesaplama hızını artırmak için BitsAndBytesConfig içindeki bnb_4bit_compute_dtype parametresini kullanarak veri türünü float32 (varsayılan değer) yerine bf16 olarak değiştirebilirsiniz:

import torch
from diffusers import BitsAndBytesConfig

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

Normal Float 4 (NF4)

NF4, QLoRA makalesinden gelen ve normal dağılımdan başlatılan ağırlıklar için uyarlanmış 4-bit bir veri türüdür. 4-bit taban modellerini eğitmek için NF4 kullanmalısınız. Bu, BitsAndBytesConfig içindeki bnb_4bit_quant_type parametresiyle yapılandırılabilir:

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,
)

Çıkarım için bnb_4bit_quant_type performans üzerinde büyük bir etkiye sahip değildir. Ancak, model ağırlıklarıyla tutarlı kalmak için bnb_4bit_compute_dtype ve dtype değerlerini kullanmalısınız.

İç içe nicelleştirme

İç içe nicelleştirme, ek performans maliyeti olmadan ek bellek tasarrufu sağlayabilen bir tekniktir. Bu özellik, zaten nicelleştirilmiş ağırlıkların ikinci kez nicelleştirilmesini gerçekleştirerek ek olarak 0,4 bit/parametre tasarruf sağlar.

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 modellerini dekuantize etme

Model kuantize edildikten sonra, orijinal hassasiyetine dekuantize edilebilir; ancak bu, küçük bir kalite kaybına yol açabilir. Dekuantize edilmiş modelin sığması için yeterli GPU RAM'e sahip olduğunuzdan emin olun.

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 ile çıkarımı hızlandırın. En güncel bitsandbytes paketinin yüklü olduğundan emin olun ve ayrıca PyTorch nightly paketinin yüklenmesini öneririz.

8-bit
4-bit
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)

RTX 4090 üzerinde derleme ile 4-bit Flux üretimi, derleme olmadan 32.570 saniyeye kıyasla 25.809 saniyede tamamlandı.

Daha fazla ayrıntı için benchmarking script'ine göz atın.

Kaynaklar

Update on GitHub