양자화
양자화 (Quantization)
큰 모델을 돌리려다 메모리가 부족해 난감했던 적 있으신가요? 양자화(Quantization) 는 모델의 정밀도를 낮추는 대신 메모리 사용량을 크게 줄여, 더 넓은 범위의 디바이스에서 큰 모델을 실행할 수 있게 해주는 기법이에요. 이 페이지에서는 vLLM이 지원하는 양자화 포맷들과 하드웨어 호환성, 그리고 커스텀 양자화 방법을 등록하는 방법을 정리할게요.
💡 팁: 양자화를 처음 시작한다면 LLM Compressor를 먼저 보세요. vLLM 배포용 모델을 최적화하는 라이브러리로, FP8, INT8, INT4 등 다양한 양자화 포맷을 지원합니다.
지원되는 양자화 포맷 (Supported quantization formats)
vLLM이 지원하는 양자화 포맷은 다음과 같아요.
- AutoAWQ
- BitsAndBytes
- GPTQModel
- Intel Neural Compressor
- LLM Compressor
- NVIDIA Model Optimizer
- Online Quantization
- AMD Quark
- Quantized KV Cache
- TorchAO
- FP8 ViT Encoder Attention
지원 하드웨어 (Supported Hardware)
아래 표는 vLLM에서 다양한 양자화 구현들이 서로 다른 하드웨어 플랫폼과 얼마나 호환되는지 보여줘요.
| Implementation | Volta | Turing | Ampere | Ada | Hopper | AMD GPU | Intel GPU | x86 CPU | Arm CPU |
|---|---|---|---|---|---|---|---|---|---|
| AWQ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ |
| GPTQ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ |
| Marlin (GPTQ/AWQ/FP8/FP4) | ❌ | ✅* | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ |
| llm-compressor INT8 (W8A8) | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ✅ | ✅ |
| llm-compressor INT8 (W4A8) | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ |
| llm-compressor FP8 (W8A8) | ❌ | ❌ | ❌ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ |
| bitsandbytes | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ |
| DeepSpeedFP | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ |
| GGUF | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ |
표를 해석할 때 알아둘 점이 있어요.
- Volta는 SM 7.0, Turing은 SM 7.5, Ampere는 SM 8.0/8.6, Ada는 SM 8.9, Hopper는 SM 9.0을 의미해요.
- ✅는 해당 하드웨어에서 양자화 방법이 지원된다는 뜻, ❌는 지원되지 않는다는 뜻입니다.
- Intel Gaudi 양자화 지원은 모두 vLLM-Gaudi로 이관됐어요.
- Turing은 Marlin MXFP4를 지원하지 않아요.
📌 참고: Google TPU에서의 양자화 지원에 대해서는 TPU-Inference Recommended Models and Features 문서를 참고하세요.
📌 참고: 이 호환성 표는 vLLM이 하드웨어 플랫폼과 양자화 방법에 대한 지원을 계속 확장함에 따라 변경될 수 있어요. 가장 최신 정보는 vllm/model_executor/layers/quantization를 참고하거나 vLLM 개발팀에 문의하세요.
트리 밖 양자화 플러그인 (Out-of-Tree Quantization Plugins)
vLLM은 @register_quantization_config 데코레이터를 사용해 커스텀, 트리 밖(out-of-tree) 양자화 방법을 등록하는 것을 지원해요. 이렇게 하면 vLLM 코드베이스를 수정하지 않고도 자신만의 양자화 스킴을 구현해서 쓸 수 있죠.
커스텀 양자화 방법 등록하기 (Registering a Custom Quantization Method)
커스텀 양자화 방법을 등록하려면, QuantizationConfig에서 상속받는 클래스를 만들고 @register_quantization_config로 데코레이션하면 돼요. get_quant_method는 레이어 유형에 따라 적절한 양자화 메서드로 디스패치합니다.
import torch
from vllm.model_executor.layers.quantization import (
register_quantization_config,
)
from vllm.model_executor.layers.quantization.base_config import (
QuantizationConfig,
QuantizeMethodBase,
)
from vllm.model_executor.layers.linear import LinearBase
from vllm.model_executor.layers.fused_moe import FusedMoE
@register_quantization_config("my_quant")
class MyQuantConfig(QuantizationConfig):
"""Custom quantization config."""
def get_name(self) -> str:
return "my_quant"
def get_supported_act_dtypes(self) -> list:
return [torch.float16, torch.bfloat16]
@classmethod
def get_min_capability(cls) -> int:
# Minimum GPU compute capability, -1 for no restriction
return -1
@staticmethod
def get_config_filenames() -> list[str]:
# Config files to search for in model directory
return []
@classmethod
def from_config(cls, config: dict) -> "MyQuantConfig":
# Create config from model's quantization config
return cls()
def get_quant_method(
self, layer: torch.nn.Module, prefix: str
) -> QuantizeMethodBase | None:
# Dispatch based on layer type
# NOTE: you only need to implement methods you care about
if isinstance(layer, LinearBase):
return MyQuantLinearMethod()
elif isinstance(layer, FusedMoE):
return MyQuantMoEMethod(layer.moe_config)
return None
필수 QuantizationConfig 메서드 (Required QuantizationConfig Methods)
커스텀 QuantizationConfig 서브클래스는 다음 추상 메서드들을 구현해야 해요.
| 메서드 | 설명 |
|---|---|
get_name() |
양자화 방법의 이름을 반환 |
get_supported_act_dtypes() |
지원되는 활성화 dtype 목록 반환 (예: torch.float16) |
get_min_capability() |
최소 GPU 컴퓨트 능력 반환 (예: Ampere는 80, 제한 없음은 -1) |
get_config_filenames() |
모델 디렉토리에서 찾을 config 파일명 목록 반환 |
from_config(config) |
모델의 양자화 config 딕셔너리에서 config를 만드는 클래스 메서드 |
get_quant_method(layer, prefix) |
주어진 레이어의 양자화 메서드 반환, None이면 건너뜀 |
양자화된 Linear 메서드 구현 (Implementing a Quantized Linear Method)
Linear 레이어의 경우 get_quant_method에서 QuantizeMethodBase 서브클래스를 반환하면 돼요. UnquantizedLinearMethod를 시작점으로 확장할 수 있습니다.
from vllm.model_executor.layers.linear import UnquantizedLinearMethod
class MyQuantLinearMethod(UnquantizedLinearMethod):
"""Custom quantization method for linear layers."""
def create_weights(
self, layer: torch.nn.Module, *weight_args, **extra_weight_attrs
):
# Create quantized weights for the layer
...
def apply(
self,
layer: torch.nn.Module,
x: torch.Tensor,
bias: torch.Tensor | None = None,
) -> torch.Tensor:
# Apply custom quantization logic here
...
양자화된 MoE 메서드 구현 (Implementing a Quantized MoE Method)
Mixture of Experts(MoE) 모델의 경우 get_quant_method에서 FusedMoEMethodBase 서브클래스를 반환하면 돼요. UnquantizedFusedMoEMethod를 사용하면 MoE 양자화를 건너뛸 수도 있어요.
from vllm.model_executor.layers.fused_moe.layer import UnquantizedFusedMoEMethod
from vllm.model_executor.layers.fused_moe.fused_moe_method_base import (
FusedMoEMethodBase,
)
from vllm.model_executor.layers.fused_moe.config import FusedMoEQuantConfig
class MyQuantMoEMethod(FusedMoEMethodBase):
"""Custom quantization method for MoE layers."""
def create_weights(
self,
layer: torch.nn.Module,
num_experts: int,
hidden_size: int,
intermediate_size_per_partition: int,
params_dtype: torch.dtype,
**extra_weight_attrs,
):
# Create quantized weights for the MoE layer
...
def apply(
self,
layer: torch.nn.Module,
router: "FusedMoERouter",
x: torch.Tensor,
router_logits: torch.Tensor,
) -> torch.Tensor:
# Apply MoE computation with quantized weights
...
def get_fused_moe_quant_config(
self, layer: torch.nn.Module
) -> FusedMoEQuantConfig | None:
# Return the MoE quantization configuration
...
참고 구현으로는 vllm/model_executor/layers/quantization/fp8.py의 Fp8MoEMethod를 보면 좋아요.
플러그인 사용하기 (Using the Plugin)
등록이 끝나면 커스텀 양자화 방법을 vLLM에서 그냥 사용할 수 있어요.
# Register your quantization method (import the module containing your config)
import my_quant_plugin
from vllm import LLM
# Use the custom quantization method
llm = LLM(model="your-model", quantization="my_quant")