# SDNQ

[SDNQ](https://github.com/Disty0/sdnq)(SD.Next Quantization)는 SVD 보정, Hadamard 회전, 그리고 더 빠른 추론을 위한 양자화 INT8/FP8 matmul을 선택적으로 지원하는 학습 불필요 양자화 백엔드입니다. int8부터 2-bit, FP8 및 기타 저비트 float 포맷까지 다양한 weight dtype을 지원합니다. CUDA, ROCm, XPU, MPS, CPU에서 실행됩니다.

이 백엔드를 사용하려면 `sdnq` 라이브러리를 설치하세요.

```bash
pip install sdnq
```

## 사전 양자화 체크포인트 로드

사전 양자화된 SDNQ 체크포인트의 양자화 구성은 `config.json`에 저장되므로, `quantization_config` 인자가 필요 없이 다른 모델과 동일한 방식으로 로드됩니다. 유일한 요구 사항은 `sdnq`가 설치되어 있는 것입니다.

```python
import torch
from diffusers import DiffusionPipeline

pipe = DiffusionPipeline.from_pretrained(
    "Disty0/Z-Image-Turbo-SDNQ-uint4-svd-r32",
    dtype=torch.bfloat16,
).to("cuda")  # or "mps", "xpu", "cpu"

image = pipe("a cat holding a sign that says hello").images[0]
image.save("output.png")
```

> [!TIP]
> 모듈형 파이프라인에서 양자화된 텍스트 인코더나 독립형 LLM 컴포넌트처럼 SDNQ 양자화된 Transformers 모델을 단독으로 로드할 경우, Diffusers를 가져오기 전에 `DIFFUSERS_SDNQ_TRANSFORMERS=1`을 설정해야 합니다. 이렇게 하면 `sdnq`가 Transformers에 자신을 등록하여 양자화된 모델이 올바르게 로드됩니다. SDNQ 양자화된 diffusers transformer가 함께 로드되는 경우에는 이 설정이 필요하지 않습니다. 해당 transformer를 로드하는 과정에서 이미 `sdnq`가 가져와지고 등록되기 때문입니다. 기본적으로 이 설정은 꺼져 있어 SDNQ를 사용하지 않는 파이프라인은 `sdnq`를 가져오지 않습니다.

## 모델을 온더플라이로 양자화

`from_pretrained`에 [SDNQConfig](/docs/diffusers/main/ko/api/quantization#diffusers.SDNQConfig)를 전달하여 모델을 로드하는 동안 양자화를 수행합니다. 특정 파이프라인 구성 요소를 양자화하려면 [PipelineQuantizationConfig](/docs/diffusers/main/ko/api/quantization#diffusers.PipelineQuantizationConfig)를 사용합니다.

```python
import torch
from diffusers import DiffusionPipeline, PipelineQuantizationConfig, SDNQConfig

pipeline_quant_config = PipelineQuantizationConfig(
    quant_mapping={"transformer": SDNQConfig(weights_dtype="uint4", use_svd=True)}
)
pipe = DiffusionPipeline.from_pretrained(
    "Tongyi-MAI/Z-Image-Turbo",
    quantization_config=pipeline_quant_config,
    dtype=torch.bfloat16,
).to("cuda")  # or "mps", "xpu", "cpu"
```

…

```python
import torch
from diffusers import ZImageTransformer2DModel, SDNQConfig

transformer = ZImageTransformer2DModel.from_pretrained(
    "Tongyi-MAI/Z-Image-Turbo",
    subfolder="transformer",
    quantization_config=SDNQConfig(weights_dtype="int8"),
    dtype=torch.bfloat16,
)
```

모든 인수는 [`sdnq.SDNQConfig`](https://github.com/Disty0/sdnq)에 전달됩니다. 지원되는 dtype 및 옵션의 전체 목록은 SDNQ 문서를 참조하세요.

## 양자화할 레이어 선택

일부 레이어는 다른 레이어보다 양자화에 더 민감하며, 민감한 레이어를 건너뛰면 메모리 비용의 증가 없이 품질을 향상시킬 수 있습니다. SDNQ는 이를 기본적으로 지원합니다. 내장된 건너뛰기 목록(범용 목록과 다양한 아키텍처에 대한 모델별 목록)을 자동으로 적용하여, 설정 없이도 일반적인 민감한 레이어가 양자화되지 않도록 합니다. 더 정밀한 제어가 필요할 경우, 레이어별 양자화 오류를 측정하여 손실 임계값을 초과하는 레이어를 동적으로 선택하여 건너뛸 수도 있습니다. 자세한 내용은 [SDNQ 동적 양자화 가이드](https://github.com/vladmandic/sdnext/wiki/SDNQ-Quantization#dynamic-loss-threshold)를 참조하세요.

## 양수화된 matmul로 더 빠른 추론

기본적으로 SDNQ는 각 matmul을 수행하기 전에 가중치를 compute dtype로 역양자화합니다. 대신 양자화 matmul을 활성화하면 matmul을 저정밀도 dtype(INT8/FP8/FP16)에서 직접 실행하며, 이는 [Triton](https://github.com/triton-lang/triton) 설치(CUDA, ROCm, 또는 XPU)가 정상적으로 작동하는 하드웨어에서 더 빠릅니다.

`apply_sdnq_options_to_model`을 사용하여 로드된 모델에 활성화할 수 있습니다. 이 함수는 모델의 기존 양자화 구성을 읽고 옵션을 제자리에서 다시 적용합니다. `SDNQConfig`가 전달되지 않는 사전 양자화 체크포인트에도 작동합니다.

```python
import torch
from diffusers import DiffusionPipeline
from sdnq.common import use_torch_compile as triton_is_available
from sdnq.loader import apply_sdnq_options_to_model

pipe = DiffusionPipeline.from_pretrained(
    "Disty0/Z-Image-Turbo-SDNQ-uint4-svd-r32",
    dtype=torch.bfloat16,
).to("cuda")  # or "mps", "xpu", "cpu"

if triton_is_available and (torch.cuda.is_available() or torch.xpu.is_available()):
    pipe.transformer = apply_sdnq_options_to_model(pipe.transformer, use_quantized_matmul=True)
    pipe.text_encoder = apply_sdnq_options_to_model(pipe.text_encoder, use_quantized_matmul=True)
```

## torch.compile

SDNQ 양자화 모델은 [group offloading](../optimization/memory#group-offloading)과 함께 사용할 때를 포함하여 추가적인 속도 향상을 위해 [torch.compile](../optimization/fp16#torchcompile)과 호환됩니다.

```python
transformer.compile(fullgraph=True)
```

## 양자화된 모델 저장

양자화된 모델은 `save_pretrained`로 직렬화할 수 있으며, `quantization_config` 없이 다시 로드할 수 있습니다.

```python
transformer.save_pretrained("z-image-turbo-sdnq-int8")
```

## 리소스

- [SDNQ 저장소](https://github.com/Disty0/sdnq)
- [Hub의 사전 양자화 SDNQ 모델](https://huggingface.co/models?search=sdnq)

