양자화

양자화 (Quantization)

큰 모델을 돌리려다 메모리가 부족해 난감했던 적 있으신가요? 양자화(Quantization) 는 모델의 정밀도를 낮추는 대신 메모리 사용량을 크게 줄여, 더 넓은 범위의 디바이스에서 큰 모델을 실행할 수 있게 해주는 기법이에요. 이 페이지에서는 vLLM이 지원하는 양자화 포맷들과 하드웨어 호환성, 그리고 커스텀 양자화 방법을 등록하는 방법을 정리할게요.

출처: vLLM 공식 문서 — quantization

💡 : 양자화를 처음 시작한다면 LLM Compressor를 먼저 보세요. vLLM 배포용 모델을 최적화하는 라이브러리로, FP8, INT8, INT4 등 다양한 양자화 포맷을 지원합니다.

지원되는 양자화 포맷 (Supported quantization formats)

vLLM이 지원하는 양자화 포맷은 다음과 같아요.

지원 하드웨어 (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.pyFp8MoEMethod를 보면 좋아요.

플러그인 사용하기 (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")

더 알아보기 (Learn more)