샘플링 파라미터

샘플링 파라미터 (Sampling Parameters)

모델이 다음 토큰을 고르는 방식을 직접 제어하고 싶다면 샘플링 파라미터를 이해해야 해요. 이 문서는 SGLang Runtime이 제공하는 저수준 엔드포인트인 /generate가 받는 파라미터를 설명합니다. 채팅 템플릿을 자동으로 처리해 주는 고수준 엔드포인트가 필요하다면 OpenAI Compatible API를 쓰는 편이 낫습니다.

출처: 공식 문서 - Sampling Parameters

/generate 엔드포인트

/generate는 JSON 형식으로 다음 파라미터를 받습니다. 자세한 사용법은 native API doc을, 객체 정의는 io_struct.py::GenerateReqInput을 참고해요. 더 많은 인자와 설명은 소스 코드에서도 확인할 수 있습니다.

Argument Type/Default Description
text Optional[Union[List[str], str]] = None 입력 프롬프트. 하나 또는 배치(리스트)로 줄 수 있어요.
input_ids Optional[Union[List[List[int]], List[int]]] = None 텍스트 대신 토큰 ID. textinput_ids 중 하나를 지정하면 됩니다.
input_embeds Optional[Union[List[List[List[float]]], List[List[float]]]] = None input_ids에 넣을 임베딩. text, input_ids, input_embeds 중 하나를 지정해요.
image_data Optional[Union[List[List[ImageDataItem]], List[ImageDataItem], ImageDataItem]] = None 이미지 입력. (1) Raw 이미지: PIL Image, 파일 경로, URL, base64 문자열 / (2) Processor 출력: format: "processor_output" 딕셔너리로 HuggingFace 프로세서 출력 / (3) Precomputed embeddings: format: "precomputed_embedding"feature에 미리 계산한 비주얼 임베딩. 단일 이미지, 이미지 리스트, 리스트의 리스트 모두 가능해요. 자세한 형식은 Multimodal Input Formats 참고.
audio_data Optional[Union[List[AudioDataItem], AudioDataItem]] = None 오디오 입력. 파일 이름, URL, base64 문자열 가능.
sampling_params Optional[Union[List[Dict], Dict]] = None 아래 절에서 설명하는 샘플링 파라미터.
rid Optional[Union[List[str], str]] = None 요청 ID.
return_logprob Optional[Union[List[bool], bool]] = None 토큰에 대한 로그 확률을 반환할지 여부.
logprob_start_len Optional[Union[List[int], int]] = None return_logprob일 때 로그 확률을 반환할 프롬프트 시작 위치. 기본 -1은 출력 토큰에 대해서만 로그 확률을 반환.
top_logprobs_num Optional[Union[List[int], int]] = None return_logprob일 때 각 위치에서 반환할 상위 로그 확률 개수.
token_ids_logprob Optional[Union[List[List[int]], List[int]]] = None return_logprob일 때 로그 확률을 반환할 토큰 ID.
return_text_in_logprobs bool = False 반환하는 로그 확률에서 토큰을 텍스트로 디토크나이즈할지 여부.
stream bool = False 출력을 스트리밍할지 여부.
lora_path Optional[Union[List[Optional[str]], Optional[str]]] = None LoRA 경로.
custom_logit_processor Optional[Union[List[Optional[str]], str]] = None 고급 샘플링 제어용 커스텀 로짓 프로세서. CustomLogitProcessor 인스턴스를 to_str()로 직렬화해 넣어야 해요.
return_hidden_states Union[List[bool], bool] = False 히든 스테이트를 반환할지 여부.
return_routed_experts bool = False MoE 모델의 전문가 라우팅 결과를 반환할지 여부. --enable-return-routed-experts 서버 플래그 필요. 기본 routed_experts_start_len=0이면 전체 시퀀스 [0, seqlen - 1)를 반환해요 (RL 워크플로우가 전체 시퀀스가 필요하기 때문). 결과는 base64 인코딩된 int32 전문가 ID로, 논리 형상은 [num_tokens, num_layers, top_k].
routed_experts_start_len int = 0 return_routed_experts일 때 반환할 라우팅 결과의 절대 시작 위치. 0이면 기본 전체 시퀀스를 유지하고, 누적 프리픽스 길이로 설정하면 [routed_experts_start_len, seqlen - 1)만 반환해요. 예를 들어 멀티턴 RL 롤아웃에서 이전 턴의 라우팅 결과는 이미 수집됐으니, 이 값을 설정하면 병목을 일으키는 불필요한 전송을 피할 수 있어요. [0, prompt_tokens] 안이어야 합니다.

샘플링 파라미터 (Sampling parameters)

객체 정의는 sampling_params.py::SamplingParams에 있어요. 소스 코드에서 더 많은 인자를 찾을 수 있습니다.

기본값에 대한 참고 (Note on defaults)

기본적으로 SGLang은 모델의 generation_config.json에서 여러 샘플링 파라미터를 초기화해요 (서버를 --sampling-defaults model로 띄울 때, 이것이 기본 동작). SGLang/OpenAI 상수 기본값을 쓰고 싶다면 --sampling-defaults openai로 서버를 시작하세요. 어떤 파라미터든 요청마다 sampling_params로 덮어쓸 수 있습니다.

# Use model-provided defaults from generation_config.json (default behavior)
python -m sglang.launch_server --model-path <MODEL> --sampling-defaults model

# Use SGLang/OpenAI constant defaults instead
python -m sglang.launch_server --model-path <MODEL> --sampling-defaults openai

핵심 파라미터 (Core parameters)

Argument Type/Default Description
max_new_tokens int = 128 토큰 단위의 최대 출력 길이.
stop Optional[Union[str, List[str]]] = None 하나 이상의 stop word. 이 단어 중 하나가 샘플링되면 생성이 멈춰요.
stop_token_ids Optional[List[int]] = None 토큰 ID 형태의 stop word. 이 토큰 ID 중 하나가 샘플링되면 생성이 멈춥니다.
stop_regex Optional[Union[str, List[str]]] = None 이 리스트의 정규식 패턴 중 하나에 걸리면 멈춰요.
temperature float (model default; fallback 1.0) 다음 토큰을 샘플링할 때의 Temperature. temperature = 0은 그리디 샘플링이고, 값이 높을수록 다양성이 커집니다.
top_p float (model default; fallback 1.0) Top-p는 누적 확률이 top_p를 넘는 가장 작은 정렬 집합에서 토큰을 골라요. top_p = 1이면 전체 토큰에서 제한 없이 샘플링하는 것과 같습니다.
top_k int (model default; fallback -1) Top-k는 확률이 가장 높은 k개 토큰에서 무작위로 선택해요.
min_p float (model default; fallback 0.0) Min-pmin_p * highest_token_probability보다 확률이 큰 토큰에서 샘플링합니다.

패널티 (Penalizers)

Argument Type/Default Description
frequency_penalty float = 0.0 지금까지 생성에서 등장한 빈도에 따라 토큰에 패널티를 줘요. -2에서 2 사이여야 하며, 음수면 토큰 반복을 장려하고 양수면 새 토큰 샘플링을 장려합니다. 패널티 규모는 토큰이 등장할 때마다 선형으로 커집니다.
presence_penalty float = 0.0 지금까지 생성에 등장했으면 토큰에 패널티를 줍니다. -2에서 2 사이여야 하며, 음수면 반복을 장려하고 양수면 새 토큰을 장려해요. 패널티 규모는 토큰이 한 번이라도 등장하면 일정합니다.
repetition_penalty float = 1.0 이전에 생성된 토큰의 로짓을 조정해 반복을 억제(값 > 1)하거나 장려(값 < 1)해요. 유효 범위는 (0, 2]이고, 1.0은 확률을 그대로 둡니다.
min_new_tokens int = 0 stop word나 EOS 토큰이 샘플링될 때까지 최소 min_new_tokens만큼 생성하도록 강제합니다. 분포가 특정 토큰으로 크게 치우친 경우 예상 밖의 동작이 생길 수 있으니 주의하세요.

제약 디코딩 (Constrained decoding)

다음 파라미터는 전용 가이드인 constrained decoding에서 자세히 다룹니다.

Argument Type/Default Description
json_schema Optional[str] = None 구조화된 출력용 JSON 스키마.
regex Optional[str] = None 구조화된 출력용 정규식.
ebnf Optional[str] = None 구조화된 출력용 EBNF.
structural_tag Optional[str] = None 구조화된 출력용 structural tag.

기타 옵션 (Other options)

Argument Type/Default Description
n int = 1 요청당 생성할 출력 시퀀스 개수. (한 요청에서 여러 출력을 생성하는 n > 1은 권장하지 않아요. 같은 프롬프트를 여러 번 반복하는 편이 제어와 효율이 더 좋습니다.)
ignore_eos bool = False EOS 토큰이 샘플링돼도 생성이 멈추지 않게 해요.
skip_special_tokens bool = True 디코딩 중 특수 토큰을 제거합니다.
spaces_between_special_tokens bool = True 디토크나이즈 중 특수 토큰 사이에 공백을 넣을지 여부.
no_stop_trim bool = False 생성된 텍스트에서 stop word나 EOS 토큰을 잘라내지 않습니다.
custom_params Optional[List[Optional[Dict[str, Any]]]] = None CustomLogitProcessor를 쓸 때 사용. 아래 사용법 참고.

예시 (Examples)

일반 (Normal)

서버를 띄웁니다:

python -m sglang.launch_server --model-path meta-llama/Meta-Llama-3-8B-Instruct --port 30000

요청을 보냅니다:

import requests

response = requests.post(
    "http://localhost:30000/generate",
    json={
        "text": "The capital of France is",
        "sampling_params": {
            "temperature": 0,
            "max_new_tokens": 32,
        },
    },
)
print(response.json())

자세한 예시는 send request에 있어요.

스트리밍 (Streaming)

요청을 보내면서 출력을 스트리밍으로 받는 방법입니다.

import requests, json

response = requests.post(
    "http://localhost:30000/generate",
    json={
        "text": "The capital of France is",
        "sampling_params": {
            "temperature": 0,
            "max_new_tokens": 32,
        },
        "stream": True,
    },
    stream=True,
)

prev = 0
for chunk in response.iter_lines(decode_unicode=False):
    chunk = chunk.decode("utf-8")
    if chunk and chunk.startswith("data:"):
        if chunk == "data: [DONE]":
            break
        data = json.loads(chunk[5:].strip("\n"))
        output = data["text"].strip()
        print(output[prev:], end="", flush=True)
        prev = len(output)
print("")

자세한 예시는 openai compatible api를 참고해요.

멀티모달 (Multimodal)

서버를 띄웁니다:

python3 -m sglang.launch_server --model-path lmms-lab/llava-onevision-qwen2-7b-ov

이미지를 내려받습니다:

curl -o example_image.png -L https://github.com/sgl-project/sglang/blob/main/examples/assets/example_image.png?raw=true

요청을 보냅니다:

import requests

response = requests.post(
    "http://localhost:30000/generate",
    json={
        "text": "<|im_start|>system\nYou are a helpful assistant.<|im_end|>\n"
                "<|im_start|>user\n<image>\nDescribe this image in a very short sentence.<|im_end|>\n"
                "<|im_start|>assistant\n",
        "image_data": "example_image.png",
        "sampling_params": {
            "temperature": 0,
            "max_new_tokens": 32,
        },
    },
)
print(response.json())

image_data는 파일 이름, URL, 또는 base64 인코딩 문자열이 될 수 있어요. 참고: python/sglang/srt/utils.py:load_image.

스트리밍도 위의 스트리밍과 같은 방식으로 지원됩니다.

자세한 예시는 OpenAI API Vision에 있어요.

구조화된 출력 (JSON, Regex, EBNF)

JSON 스키마, 정규식, 또는 EBNF를 지정해 모델 출력을 제약할 수 있어요. 모델 출력은 주어진 제약을 반드시 따르게 됩니다. 요청당 제약 파라미터(json_schema, regex, ebnf)는 하나만 지정할 수 있어요.

SGLang은 두 가지 문법 백엔드를 지원합니다:

  • XGrammar (기본): JSON 스키마, 정규식, EBNF 제약을 지원.
  • Outlines: JSON 스키마와 정규식 제약을 지원.

Outlines 백엔드를 쓰고 싶으면 --grammar-backend outlines 플래그로 초기화할 수 있습니다:

python -m sglang.launch_server --model-path meta-llama/Meta-Llama-3.1-8B-Instruct \
--port 30000 --host 0.0.0.0 --grammar-backend [xgrammar|outlines] # xgrammar or outlines (default: xgrammar)
import json
import requests

json_schema = json.dumps({
    "type": "object",
    "properties": {
        "name": {"type": "string", "pattern": "^[\\w]+$"},
        "population": {"type": "integer"},
    },
    "required": ["name", "population"],
})

# JSON (works with both Outlines and XGrammar)
response = requests.post(
    "http://localhost:30000/generate",
    json={
        "text": "Here is the information of the capital of France in the JSON format.\n",
        "sampling_params": {
            "temperature": 0,
            "max_new_tokens": 64,
            "json_schema": json_schema,
        },
    },
)
print(response.json())

# Regular expression (Outlines backend only)
response = requests.post(
    "http://localhost:30000/generate",
    json={
        "text": "Paris is the capital of",
        "sampling_params": {
            "temperature": 0,
            "max_new_tokens": 64,
            "regex": "(France|England)",
        },
    },
)
print(response.json())

# EBNF (XGrammar backend only)
response = requests.post(
    "http://localhost:30000/generate",
    json={
        "text": "Write a greeting.",
        "sampling_params": {
            "temperature": 0,
            "max_new_tokens": 64,
            "ebnf": 'root ::= "Hello" | "Hi" | "Hey"',
        },
    },
)
print(response.json())

자세한 예시는 structured outputs에 있어요.

커스텀 로짓 프로세서 (Custom logit processor)

--enable-custom-logit-processor 플래그를 켜고 서버를 띄웁니다.

python -m sglang.launch_server \
  --model-path meta-llama/Meta-Llama-3-8B-Instruct \
  --port 30000 \
  --enable-custom-logit-processor

항상 특정 토큰 ID를 샘플링하는 커스텀 로짓 프로세서를 정의합니다.

from sglang.srt.sampling.custom_logit_processor import CustomLogitProcessor

class DeterministicLogitProcessor(CustomLogitProcessor):
    """A dummy logit processor that changes the logits to always
    sample the given token id.
    """

    def __call__(self, logits, custom_param_list):
        # Check that the number of logits matches the number of custom parameters
        assert logits.shape[0] == len(custom_param_list)
        key = "token_id"

        for i, param_dict in enumerate(custom_param_list):
            # Mask all other tokens
            logits[i, :] = -float("inf")
            # Assign highest probability to the specified token
            logits[i, param_dict[key]] = 0.0
        return logits

요청을 보냅니다:

import requests

response = requests.post(
    "http://localhost:30000/generate",
    json={
        "text": "The capital of France is",
        "custom_logit_processor": DeterministicLogitProcessor().to_str(),
        "sampling_params": {
            "temperature": 0.0,
            "max_new_tokens": 32,
            "custom_params": {"token_id": 5},
        },
    },
)
print(response.json())

OpenAI 채팅 컴플리션 요청도 보낼 수 있어요:

import openai
from sglang.utils import print_highlight

client = openai.Client(base_url="http://127.0.0.1:30000/v1", api_key="None")

response = client.chat.completions.create(
    model="meta-llama/Meta-Llama-3-8B-Instruct",
    messages=[
        {"role": "user", "content": "List 3 countries and their capitals."},
    ],
    temperature=0.0,
    max_tokens=32,
    extra_body={
        "custom_logit_processor": DeterministicLogitProcessor().to_str(),
        "custom_params": {"token_id": 5},
    },
)

print_highlight(f"Response: {response}")

더 알아보기 (Learn more)