Diffusers documentation

Compilar e descarregar modelos quantizados

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Compilar e descarregar modelos quantizados

A otimização de modelos geralmente envolve compensações entre velocidade de inferência e uso de memória. Por exemplo, embora o caching possa aumentar a velocidade de inferência, ele também aumenta o consumo de memória, pois precisa armazenar as saídas das camadas intermediárias de atenção. Uma estratégia de otimização mais equilibrada combina a quantização de um modelo, torch.compile e diversos métodos de offloading.

Consulte o guia de torch.compile para saber mais sobre compilação e como ela pode ser aplicada aqui. Por exemplo, a compilação regional pode reduzir significativamente o tempo de compilação sem abrir mão de nenhuma aceleração.

Para geração de imagens, a combinação de quantização e model offloading pode frequentemente oferecer o melhor equilíbrio entre qualidade, velocidade e memória. O group offloading não é tão eficaz para geração de imagens, pois geralmente não é possível sobrepor totalmente a transferência de dados se o kernel de computação terminar mais rápido. Isso resulta em algum overhead de comunicação entre a CPU e a GPU.

Para geração de vídeo, combinar quantização e group-offloading tende a ser melhor, pois os modelos de vídeo são mais limitados por computação.

A tabela abaixo fornece uma comparação das combinações de estratégias de otimização e seu impacto na latência e no uso de memória para o Flux.

combinaçãolatência (s)uso de memória (GB)
quantização32.60214.9453
quantização, torch.compile25.84714.9448
quantização, torch.compile, offloading do modelo para CPU32.31212.2369
These results are benchmarked on Flux with a RTX 4090. The transformer and text_encoder components are quantized. Refer to the benchmarking script if you're interested in evaluating your own model.

Este guia mostrará como compilar e descarregar um modelo quantizado com bitsandbytes. Certifique-se de estar usando PyTorch nightly e a versão mais recente do bitsandbytes.

Embora usemos bitsandbytes neste exemplo, outros backends de quantização, como TorchAO, também suportam esses recursos.

pip install -U bitsandbytes

Quantização e torch.compile

Comece quantizando um modelo para reduzir a memória necessária para armazenamento e compilando o modelo para acelerar a inferência.

Configure o Dynamo com capture_dynamic_output_shape_ops = True para lidar com saídas dinâmicas ao compilar modelos bitsandbytes.

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

torch._dynamo.config.capture_dynamic_output_shape_ops = True

# quantize
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"],
)
pipeline = DiffusionPipeline.from_pretrained(
    "black-forest-labs/FLUX.1-dev",
    quantization_config=pipeline_quant_config,
    dtype=torch.bfloat16,
).to("cuda")  # or "mps", "xpu", "cpu"

# compile
pipeline.transformer.to(memory_format=torch.channels_last)
pipeline.transformer.compile(mode="max-autotune", fullgraph=True)
pipeline("""
    cinematic film still of a cat sipping a margarita in a pool in Palm Springs, California
    highly detailed, high budget hollywood movie, cinemascope, moody, epic, gorgeous, film grain
"""
).images[0]

Quantização, torch.compile e offloading

Além da quantização e do torch.compile, experimente o offloading se precisar reduzir ainda mais o uso de memória. O offloading move várias camadas ou componentes do modelo da CPU para a GPU conforme necessário para os cálculos.

Configure o Dynamo cache_size_limit durante o offloading para evitar recompilações excessivas e defina capture_dynamic_output_shape_ops = True para lidar com saídas dinâmicas ao compilar modelos bitsandbytes.

offloading de modelo para CPU
offloading de grupo

Model CPU offloading move um componente individual do pipeline, como o modelo transformer, para a GPU quando ele é necessário para o cálculo. Caso contrário, ele é transferido para a CPU.

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

torch._dynamo.config.cache_size_limit = 1000
torch._dynamo.config.capture_dynamic_output_shape_ops = True

# quantize
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"],
)
pipeline = DiffusionPipeline.from_pretrained(
    "black-forest-labs/FLUX.1-dev",
    quantization_config=pipeline_quant_config,
    dtype=torch.bfloat16,
).to("cuda")  # or "mps", "xpu", "cpu"

# model CPU offloading
pipeline.enable_model_cpu_offload()

# compile
pipeline.transformer.compile()
pipeline(
    "cinematic film still of a cat sipping a margarita in a pool in Palm Springs, California, highly detailed, high budget hollywood movie, cinemascope, moody, epic, gorgeous, film grain"
).images[0]
Update on GitHub