본문으로 건너뛰기

[vLLM] Sampling Parameters: 전체 샘플링 파라미터 정리

들어가며

LLM 추론에서 샘플링 파라미터는 생성 품질과 다양성을 직접 제어하는 핵심 설정이다. vLLM의 SamplingParams 클래스는 OpenAI API 호환 파라미터에 더해, 구조화된 출력, 반복 패턴 감지, 로그 확률 제어 등 고급 기능까지 통합적으로 관리한다. 이번 글에서는 전체 파라미터를 카테고리별로 분석한다.

공식 문서

vLLM 공식 문서: Custom LogitsProcessors vLLM 공식 문서: Custom Arguments

핵심 구조/코드 분석

SamplingParams 클래스 구조

SamplingParamsmsgspec.Struct와 Pydantic을 결합한 하이브리드 구조다:

class SamplingParams(
    PydanticMsgspecMixin,
    msgspec.Struct,
    omit_defaults=True,
    dict=True,
):
    """Sampling parameters for text generation.
    Overall, we follow the sampling parameters from the OpenAI text
    completion API."""

omit_defaults=True로 기본값과 같은 필드는 직렬화에서 제외하여 네트워크 전송량을 줄인다.

기본 샘플링 파라미터

n: int = 1                        # 생성할 출력 수
temperature: float = 1.0          # 랜덤성 제어 (0=greedy)
top_p: float = 1.0                # nucleus sampling 임계값
top_k: int = 0                    # 상위 k개 토큰만 고려 (0=전체)
min_p: float = 0.0                # 최소 확률 필터링
seed: int | None = None           # 재현성을 위한 시드

temperature는 매우 작은 양수값(< 0.01)일 때 수치 불안정을 방지하기 위해 자동 클램핑된다:

def __post_init__(self) -> None:
    if 0 < self.temperature < _MAX_TEMP:
        logger.warning(
            "temperature %s is less than %s, which may cause numerical "
            "errors nan or inf in tensors.",
            self.temperature, _MAX_TEMP, _MAX_TEMP,
        )
        self.temperature = max(self.temperature, _MAX_TEMP)

반복 제어 파라미터

세 가지 방식의 반복 페널티를 지원한다:

presence_penalty: float = 0.0     # 등장 여부 기반 페널티
frequency_penalty: float = 0.0    # 등장 빈도 기반 페널티
repetition_penalty: float = 1.0   # 곱셈 기반 반복 페널티
  • presence_penalty: 토큰이 이미 등장했는지 여부(0/1)에 기반. 양수면 새로운 토큰 선호.
  • frequency_penalty: 등장 횟수에 비례. 양수면 반복 억제.
  • repetition_penalty: 1보다 크면 반복 억제, 1보다 작으면 반복 장려. 프롬프트+생성 텍스트 모두 참조.

정지 조건

stop: str | list[str] | None = None        # 정지 문자열
stop_token_ids: list[int] | None = None    # 정지 토큰 ID
ignore_eos: bool = False                    # EOS 무시 여부
max_tokens: int | None = 16                # 최대 생성 토큰 수
min_tokens: int = 0                         # 최소 생성 토큰 수

min_tokens는 EOS나 stop_token_ids가 최소 토큰 수 이전에는 발생하지 않도록 보장한다.

로그 확률 제어

logprobs: int | None = None               # 출력 토큰별 로그 확률 수
prompt_logprobs: int | None = None        # 프롬프트 토큰별 로그 확률
logprob_token_ids: list[int] | None = None # 특정 토큰의 로그 확률
flat_logprobs: bool = False                # 플랫 포맷 (GC 최적화)

logprob_token_ids는 전체 어휘의 로그 확률(logprobs=-1) 대신 특정 토큰만 조회하여 성능을 최적화한다. 스코어링 작업에 유용하다.

구조화된 출력 (Structured Outputs)

class StructuredOutputsParams:
    json: str | dict | None = None         # JSON 스키마
    regex: str | None = None               # 정규식 패턴
    choice: list[str] | None = None        # 선택지
    grammar: str | None = None             # 문법 규칙
    json_object: bool | None = None        # JSON 객체 강제
    structural_tag: str | None = None      # 구조적 태그

6가지 구조화 방식을 지원하며, 상호 배타적이다:

def __post_init__(self):
    count = sum([
        self.json is not None,
        self.regex is not None,
        self.choice is not None,
        self.grammar is not None,
        self.json_object is not None,
        self.structural_tag is not None,
    ])
    if count > 1:
        raise ValueError("You can only use one kind of structured outputs")

반복 패턴 감지

class RepetitionDetectionParams:
    max_pattern_size: int = 0   # 감지할 최대 N-gram 크기
    min_pattern_size: int = 0   # 최소 N-gram 크기
    min_count: int = 0          # 반복 횟수 임계값 (>= 2)

LLM이 "abcdabcdabcd..."처럼 무한 반복에 빠지는 현상을 조기 감지하여 생성을 중단한다. max_pattern_size=10, min_count=3이면 "10 토큰 이하의 패턴이 3번 이상 반복되면 중단"이라는 의미다.

고급 옵션

bad_words: list[str] | None = None          # 금지 단어
logit_bias: dict[int, float] | None = None  # 토큰별 로짓 바이어스
allowed_token_ids: list[int] | None = None  # 허용 토큰 ID
thinking_token_budget: int | None = None    # 사고 토큰 예산
extra_args: dict[str, Any] | None = None    # 커스텀 인자

thinking_token_budget은 Chain-of-Thought 추론에서 사고 과정에 할당할 최대 토큰 수를 제한한다.

왜 이 설계인가

  1. OpenAI API 호환: 기본 파라미터는 OpenAI의 Completion API와 동일한 이름과 의미를 사용하여, 기존 코드의 마이그레이션을 쉽게 한다.

  2. msgspec + Pydantic 하이브리드: msgspec.Struct의 빠른 직렬화와 Pydantic의 유효성 검증을 결합한다. omit_defaults=True로 네트워크 효율을 높이면서도, __post_init__에서 값 범위를 검증한다.

  3. SamplingType 분류: temperature에 따라 GREEDY(0), RANDOM(> 0), RANDOM_SEED(시드 있음)로 분류한다. 이 분류는 내부적으로 배치 스케줄링과 CUDA 커널 선택에 활용된다.

  4. skip_clone 최적화: 단일 요청 전용으로 수정되지 않을 것이 보장되는 경우, 깊은 복사를 건너뛰어 객체 생성 오버헤드를 줄인다.

참고 자료

댓글

관련 포스트

vLLM 의 다른글