샘플링 파라미터
샘플링 파라미터 (Sampling Parameters)
모델이 다음 토큰을 고르는 방식을 직접 제어하고 싶다면 샘플링 파라미터를 이해해야 해요. 이 문서는 SGLang Runtime이 제공하는 저수준 엔드포인트인 /generate가 받는 파라미터를 설명합니다. 채팅 템플릿을 자동으로 처리해 주는 고수준 엔드포인트가 필요하다면 OpenAI Compatible API를 쓰는 편이 낫습니다.
/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. text와 input_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-p는 min_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 제약을 지원.
- XGrammar는 현재 GGML BNF 형식을 사용.
- 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)
/generate를 실제로 호출하는 예시는 Sending a request를 참고해요.- 채팅 템플릿을 자동 처리하는 고수준 API는 OpenAI APIs - Completions에 있어요.
- 제약 디코딩은 Structured Outputs에서 다룹니다.