Diffusers documentation

量子化モデルのコンパイルとオフロード

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

量子化モデルのコンパイルとオフロード

モデルの最適化では、推論速度とメモリ使用量のトレードオフが生じます。例えば、キャッシュは推論速度を向上させますが、中間アテンション層の出力を保存する必要があるため、メモリ消費量も増加します。よりバランスの取れた最適化戦略としては、モデルの量子化、torch.compile、およびさまざまなオフロード手法を組み合わせる方法があります。

コンパイルの詳細や、ここでどのように適用できるかについては、torch.compileのガイドを参照してください。例えば、地域別コンパイルを使用すると、速度向上を犠牲にすることなく、コンパイル時間を大幅に短縮できます。

画像生成において、量子化とモデルのオフロードを組み合わせることで、品質、速度、メモリ使用量のバランスを最適化できることが多いです。グループオフロードは画像生成ではあまり効果的ではありません。これは、計算カーネルがより早く完了した場合、データ転送を完全にオーバーラップさせることが通常できないためです。その結果、CPUとGPU間の通信オーバーヘッドが発生します。

動画生成では、動画モデルは計算量に制約されることが多いため、量子化とグループオフローディングを組み合わせる方が一般的に効果的です。

以下の表は、Flux における最適化戦略の組み合わせと、それらがレイテンシおよびメモリ使用量に与える影響を比較しています。

組み合わせレイテンシ (s)メモリ使用量 (GB)
量子化32.60214.9453
量子化、torch.compile25.84714.9448
量子化、torch.compile、モデルのCPUオフロード32.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.

このガイドでは、bitsandbytes を使用して量子化モデルをコンパイルおよびオフロードする方法を説明します。PyTorch nightly と bitsandbytes の最新バージョンを使用していることを確認してください。

この例ではbitsandbytesを使用していますが、TorchAOなどの他の量子化バックエンドもこれらの機能をサポートしています。

pip install -U bitsandbytes

Quantization と torch.compile

まず、モデルを量子化してストレージに必要なメモリを削減し、コンパイルして推論を高速化します。

bitsandbytes モデルをコンパイルする際に動的な出力を処理するため、Dynamo の capture_dynamic_output_shape_ops = True を設定してください。

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]

量子化、torch.compile、オフロード

量子化やtorch.compileに加えて、メモリ使用量をさらに削減する必要がある場合は、オフローディングを試してください。オフローディングでは、計算に必要なタイミングで、さまざまなレイヤーやモデルのコンポーネントをCPUからGPUへ移動します。

オフローディング時にDynamoのcache_size_limitを設定して過剰な再コンパイルを回避し、bitsandbytesモデルをコンパイルする際の動的な出力に対応するためにcapture_dynamic_output_shape_ops = Trueを設定します。

モデルのCPUオフロード
グループオフローディング

モデルのCPUオフロードでは、計算に必要になったタイミングで、transformerモデルなどの個別のパイプラインコンポーネントをGPUに移動します。それ以外の時間は、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