# Quanto

> [!WARNING]
> Quanto 백엔드는 비추천(deprecated) 상태이며 1.0.0 버전에서 제거됩니다. [bitsandbytes](./bitsandbytes) 또는 [torchao](./torchao)와 같은 다른 지원되는 [양자화 백엔드](./overview)로 전환하는 것을 고려해 보세요.

[Quanto](https://github.com/huggingface/optimum-quanto)는 [Optimum](https://huggingface.co/docs/optimum/en/index)을 위한 PyTorch 양자화 백엔드입니다. 다용도와 단순함을 염두에 두고 설계되었습니다:

- 모든 기능이 eager mode(추적할 수 없는 모델과 호환)에서 사용할 수 있습니다
- 양자화 인식 학습을 지원합니다
- 양자화 모델은 `torch.compile`과 호환됩니다
- 양자화 모델은 Device와 무관합니다(예: CUDA, XPU, MPS, CPU).

Quanto 백엔드를 사용하려면 먼저 `optimum-quanto>=0.2.6`과 `accelerate`를 설치해야 합니다.

```shell
pip install optimum-quanto accelerate
```

`QuantoConfig` 객체를 `from_pretrained()` 메서드에 전달하여 모델을 양자화할 수 있습니다. Quanto 라이브러리는 `nn.Conv2d` 및 `nn.LayerNorm` 모듈의 양자화를 허용하지만, 현재 Diffusers는 모델의 `nn.Linear` 레이어에 있는 가중치만 양자화하는 것을 지원합니다. 다음 스니펫은 Quanto를 사용하여 `float8` 양자화를 적용하는 방법을 보여줍니다.

```python
import torch
from diffusers import FluxTransformer2DModel, QuantoConfig

model_id = "black-forest-labs/FLUX.1-dev"
quantization_config = QuantoConfig(weights_dtype="float8")
transformer = FluxTransformer2DModel.from_pretrained(
      model_id,
      subfolder="transformer",
      quantization_config=quantization_config,
      dtype=torch.bfloat16,
)

pipe = FluxPipeline.from_pretrained(model_id, transformer=transformer, dtype=dtype)
pipe.to("cuda")  # or "mps", "xpu", "cpu"

prompt = "A cat holding a sign that says hello world"
image = pipe(
    prompt, num_inference_steps=50, guidance_scale=4.5, max_sequence_length=512
).images[0]
image.save("output.png")
```

## 특정 모듈에서 양자화 건너뛰기

`QuantoConfig`의 `modules_to_not_convert` 인수를 사용하여 특정 모듈에 양자화를 적용하지 않도록 할 수 있습니다. 이 인수로 전달하는 모듈이 `state_dict`의 모듈 키와 일치하는지 확인하십시오.

```python
import torch
from diffusers import FluxTransformer2DModel, QuantoConfig

model_id = "black-forest-labs/FLUX.1-dev"
quantization_config = QuantoConfig(weights_dtype="float8", modules_to_not_convert=["proj_out"])
transformer = FluxTransformer2DModel.from_pretrained(
      model_id,
      subfolder="transformer",
      quantization_config=quantization_config,
      dtype=torch.bfloat16,
)
```

## `from_single_file`를 사용하여 Quanto Backend 적용

`QuantoConfig`은 `~FromOriginalModelMixin.from_single_file`와 호환됩니다.

```python
import torch
from diffusers import FluxTransformer2DModel, QuantoConfig

ckpt_path = "https://huggingface.co/black-forest-labs/FLUX.1-dev/blob/main/flux1-dev.safetensors"
quantization_config = QuantoConfig(weights_dtype="float8")
transformer = FluxTransformer2DModel.from_single_file(ckpt_path, quantization_config=quantization_config, dtype=torch.bfloat16)
```

## 양자화 모델 저장

Diffusers는 `~ModelMixin.save_pretrained` 메서드를 사용하여 Quanto 모델을 직렬화하는 것을 지원합니다.

Quanto 라이브러리로 직접 양자화된 모델과 Diffusers에서 Quanto를 백엔드로 사용하여 양자화된 모델의 직렬화 및 로딩 요구사항은 다릅니다. 현재 `~ModelMixin.from_pretrained`를 사용하여 Quanto로 직접 양자화된 모델을 Diffusers에 로드하는 것은 불가능합니다.

```python
import torch
from diffusers import FluxTransformer2DModel, QuantoConfig

model_id = "black-forest-labs/FLUX.1-dev"
quantization_config = QuantoConfig(weights_dtype="float8")
transformer = FluxTransformer2DModel.from_pretrained(
      model_id,
      subfolder="transformer",
      quantization_config=quantization_config,
      dtype=torch.bfloat16,
)
# save quantized model to reuse
transformer.save_pretrained("<your quantized model save path>")

# you can reload your quantized model with
model = FluxTransformer2DModel.from_pretrained("<your quantized model save path>")
```

## `torch.compile`을 사용한 Quanto

현재 Quanto 백엔드는 다음 양자화 유형에 대해 `torch.compile`을 지원합니다:

- `int8` 가중치

```python
import torch
from diffusers import FluxPipeline, FluxTransformer2DModel, QuantoConfig

model_id = "black-forest-labs/FLUX.1-dev"
quantization_config = QuantoConfig(weights_dtype="int8")
transformer = FluxTransformer2DModel.from_pretrained(
    model_id,
    subfolder="transformer",
    quantization_config=quantization_config,
    dtype=torch.bfloat16,
)
transformer = torch.compile(transformer, mode="max-autotune", fullgraph=True)

pipe = FluxPipeline.from_pretrained(
    model_id, transformer=transformer, dtype=dtype
)
pipe.to("cuda")  # or "mps", "xpu", "cpu"
images = pipe("A cat holding a sign that says hello").images[0]
images.save("flux-quanto-compile.png")
```

## 지원되는 양자화 유형

### 가중치

- float8
- int8
- int4
- int2

