Diffusers documentation

Premiers pas

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Premiers pas

La quantisation consiste à représenter les données avec moins de bits tout en cherchant à préserver la précision des données d’origine. Cela implique souvent de convertir un type de données pour représenter les mêmes informations avec moins de bits. Par exemple, si les poids de votre modèle sont stockés en nombres flottants sur 32 bits et qu’ils sont quantifiés en nombres flottants sur 16 bits, la taille du modèle est divisée par deux, ce qui facilite son stockage et réduit l’utilisation de la mémoire. Une précision plus faible peut également accélérer l’inférence, car les calculs avec moins de bits prennent moins de temps.

Diffusers prend en charge plusieurs backends de quantification pour rendre les grands modèles de diffusion comme Flux plus accessibles. Ce guide montre comment utiliser la classe PipelineQuantizationConfig pour quantifier un pipeline lors de son initialisation à partir d'un checkpoint pré-entraîné ou non quantifié.

Quantification au niveau du pipeline

Il existe deux façons d’utiliser PipelineQuantizationConfig en fonction du niveau de personnalisation que vous souhaitez appliquer à la configuration de quantification.

  • pour les cas d'utilisation de base, définissez les arguments quant_backend, quant_kwargs et components_to_quantize
  • pour un contrôle granulaire de la quantification, définissez un quant_mapping qui fournit la configuration de quantification pour les composants individuels du modèle

Quantification de base

Initialisez PipelineQuantizationConfig avec les paramètres suivants.

  • quant_backend spécifie le backend de quantification à utiliser. Les backends actuellement pris en charge incluent : bitsandbytes_4bit, bitsandbytes_8bit, gguf, quanto et torchao.
  • quant_kwargs spécifie les arguments de quantification à utiliser.

Ces arguments quant_kwargs diffèrent selon chaque backend. Consultez la documentation de l'API de quantification pour afficher les arguments de chaque backend.

  • components_to_quantize spécifie le ou les composants du pipeline à quantiser. En général, vous devez quantiser les composants les plus gourmands en calcul, comme le transformer. L’encodeur de texte est un autre composant à prendre en compte pour la quantisation si le pipeline en comporte plus d’un, comme FluxPipeline. L’exemple ci-dessous quantifie l’encodeur de texte T5 dans FluxPipeline tout en conservant le modèle CLIP intact.

    components_to_quantize accepte soit une liste pour plusieurs modèles, soit une chaîne de caractères pour un modèle unique.

L'exemple ci-dessous charge le backend bitsandbytes avec les arguments suivants issus de BitsAndBytesConfig, load_in_4bit, bnb_4bit_quant_type et bnb_4bit_compute_dtype.

import torch
from diffusers import DiffusionPipeline
from diffusers.quantizers import PipelineQuantizationConfig

pipeline_quant_config = PipelineQuantizationConfig(
    quant_backend="bitsandbytes_4bit",
    quant_kwargs={"load_in_4bit": True, "bnb_4bit_quant_type": "nf4", "bnb_4bit_compute_dtype": torch.bfloat16},
    components_to_quantize=["transformer", "text_encoder_2"],
)

Passez pipeline_quant_config à from_pretrained() pour quantifier le pipeline.

pipe = DiffusionPipeline.from_pretrained(
    "black-forest-labs/FLUX.1-dev",
    quantization_config=pipeline_quant_config,
    dtype=torch.bfloat16,
).to("cuda")  # or "mps", "xpu", "cpu"

image = pipe("photo of a cute dog").images[0]

Quantification avancée

L'argument quant_mapping offre davantage d'options pour quantiser chaque composant individuel d'un pipeline, comme la combinaison de différents backends de quantification.

Initialisez PipelineQuantizationConfig et passez-lui un quant_mapping. Le quant_mapping vous permet de spécifier les options de quantisation pour chaque composant du pipeline, tel que le transformer et l'encodeur de texte.

L'exemple ci-dessous utilise deux backends de quantification, QuantoConfig et transformers.BitsAndBytesConfig, pour le transformer et l'encodeur de texte.

import torch
from diffusers import DiffusionPipeline
from diffusers import BitsAndBytesConfig as DiffusersBitsAndBytesConfig
from diffusers.quantizers.quantization_config import QuantoConfig
from diffusers.quantizers import PipelineQuantizationConfig
from transformers import BitsAndBytesConfig as TransformersBitsAndBytesConfig

pipeline_quant_config = PipelineQuantizationConfig(
    quant_mapping={
        "transformer": QuantoConfig(weights_dtype="int8"),
        "text_encoder_2": TransformersBitsAndBytesConfig(
            load_in_4bit=True, compute_dtype=torch.bfloat16
        ),
    }
)

Il existe un backend bitsandbytes distinct dans Transformers. Vous devez importer et utiliser transformers.BitsAndBytesConfig pour les composants provenant de Transformers. Par exemple, text_encoder_2 dans FluxPipeline est un T5EncoderModel de Transformers, il faut donc utiliser transformers.BitsAndBytesConfig au lieu de diffusers.BitsAndBytesConfig.

Utilisez la méthode de quantification de base ci-dessus si vous ne souhaitez pas gérer ces imports distincts ou si vous n’êtes pas sûr de l’origine de chaque composant du pipeline.

import torch
from diffusers import DiffusionPipeline
from diffusers import BitsAndBytesConfig as DiffusersBitsAndBytesConfig
from diffusers.quantizers import PipelineQuantizationConfig
from transformers import BitsAndBytesConfig as TransformersBitsAndBytesConfig

pipeline_quant_config = PipelineQuantizationConfig(
    quant_mapping={
        "transformer": DiffusersBitsAndBytesConfig(load_in_4bit=True, bnb_4bit_compute_dtype=torch.bfloat16),
        "text_encoder_2": TransformersBitsAndBytesConfig(
            load_in_4bit=True, compute_dtype=torch.bfloat16
        ),
    }
)

Passez pipeline_quant_config à from_pretrained() pour quantifier le pipeline.

pipe = DiffusionPipeline.from_pretrained(
    "black-forest-labs/FLUX.1-dev",
    quantization_config=pipeline_quant_config,
    dtype=torch.bfloat16,
).to("cuda")  # or "mps", "xpu", "cpu"

image = pipe("photo of a cute dog").images[0]

Chargement des points de contrôle pré-quantifiés

Certains backends de quantisation prennent en charge le chargement de points de contrôle déjà quantisés et téléversés sur le Hub. Dans ce cas, la configuration de quantisation est stockée dans le config.json du modèle et est lue automatiquement — vous n’avez pas besoin de créer un PipelineQuantizationConfig ni de passer un argument quantization_config.

import torch
from diffusers import DiffusionPipeline

pipe = DiffusionPipeline.from_pretrained(
    "rootonchair/ERNIE-Image-Turbo-nunchaku-lite-nvfp4",
    dtype=torch.bfloat16,
).to("cuda")  # or "mps", "xpu", "cpu"

Les backends suivants prennent en charge le chargement de points de contrôle préquantifiés sans configuration supplémentaire.

BackendNotes
bitsandbytesLa configuration est enregistrée dans config.json ; aucun argument supplémentaire n'est nécessaire. Prend en charge la quantification à la volée ainsi que le chargement de points de contrôle pré-quantifiés.
torchaoIdentique à ce qui précède.
GGUFUtilise from_single_file avec les classes de modèle ; le chargement au niveau du pipeline n'est pas pris en charge.
BFLCharge les points de contrôle monofichier fp8r et nvfp4 de Black Forest Labs avec from_single_file ; le chargement au niveau du pipeline n'est pas pris en charge.
AutoRoundSeul le chargement est pris en charge ; quantifiez d'abord avec l'interface en ligne de commande AutoRound ou l'API Python.
Nunchaku LiteLa configuration est enregistrée dans config.json ; le package kernels est requis. Seul le chargement est pris en charge.
ModelOptSeul le chargement de modèles pré-quantifiés est pris en charge.
SDNQPrend en charge la quantification à la volée et le chargement de modèles pré-quantifiés ; nécessite le package sdnq.

Ressources

Consultez les ressources ci-dessous pour en savoir plus sur la quantification.

Update on GitHub