결정적 추론

결정적 추론 (Deterministic Inference)

SGLang의 결정적 추론(deterministic inference) 기능을 설명합니다. 같은 입력에 대해 실행을 반복해도 항상 동일한 LLM 출력이 나오도록 보장하는 기능으로, 강화학습·테스트·프로덕션 환경에서 특히 유용해요.

출처: 문서

본문

결정적 추론이 왜 중요한가 (Why Deterministic Inference Matters)

결정적 추론은 실행을 반복해도 일관된 LLM 출력을 보장하며, 다음에서 중요합니다:

  • 강화학습 (Reinforcement Learning): 실행마다 일관된 logprobs를 보장해 확률적 노이즈를 줄이고, RL 훈련을 더 안정적·재현 가능·디버깅 가능하게 만듦
  • 테스트 및 디버깅 (Testing & Debugging): 재현 가능한 검증을 가능하게 함
  • 프로덕션 (Production): 신뢰성과 사용자 경험을 개선

temperature=0에서도 표준 LLM 추론은 동적 배칭(dynamic batching)과 GPU 커널의 감소 순서(reduction order) 변화 때문에 다른 출력을 만들 수 있습니다.

비결정성의 근본 원인 (The Root Cause of Non-Determinism)

주요 원인은 가변 배치 크기(varying batch sizes) 입니다. 배치 크기가 다르면 GPU 커널이 감소 연산(reduction operations)을 다르게 분할해 덧셈 순서가 달라집니다. 부동 소수점의 비결합성(non-associativity, (a + b) + c ≠ a + (b + c)) 때문에 동일한 입력이라도 다른 결과가 나옵니다.

SGLang의 해결책 (SGLang's Solution)

Thinking Machines Lab의 batch-invariant operators를 기반으로, SGLang은 chunked prefill, CUDA graphs, radix cache, non-greedy sampling과의 호환성을 유지하면서 완전히 결정적인 추론을 달성합니다. 결정적 추론 기능의 개발 로드맵은 이 issue에서 확인할 수 있습니다.

지원 백엔드 (Supported Backends)

결정적 추론은 다음 세 가지 어텐션 백엔드에서만 지원됩니다: FlashInfer, FlashAttention 3 (FA3), Triton.

다음 표는 어텐션 백엔드별 결정적 추론의 기능 호환성을 보여줍니다:

Attention Backend CUDA Graph Chunked Prefill Radix Cache Non-greedy Sampling (Temp > 0)
FlashInfer ✅ Yes ✅ Yes ❌ No ✅ Yes
FlashAttention 3 (FA3) ✅ Yes ✅ Yes ✅ Yes ✅ Yes
Triton ✅ Yes ✅ Yes ✅ Yes ✅ Yes

사용법 (Usage)

기본 사용법 (Basic Usage)

--enable-deterministic-inference 플래그를 추가해 결정적 추론을 활성화합니다:

python3 -m sglang.launch_server \
    --model-path Qwen/Qwen3-8B \
    --attention-backend fa3 \
    --enable-deterministic-inference

서버 인자 (Server Arguments)

Argument Type/Default Description
--enable-deterministic-inference flag; default: disabled Batch-invariant 연산으로 결정적 추론 활성화
--attention-backend string; default: fa3 어텐션 백엔드 선택 (flashinfer, fa3, or triton)

예제 설정 (Example Configurations)

Qwen3-8B

python3 -m sglang.launch_server \
    --model-path Qwen/Qwen3-8B \
    --attention-backend flashinfer \
    --enable-deterministic-inference

Llama 모델 (Llama Models)

python3 -m sglang.launch_server \
    --model-path meta-llama/Llama-3.1-8B-Instruct \
    --attention-backend fa3 \
    --enable-deterministic-inference

Qwen3-30B-A3B (MoE 모델)

python3 -m sglang.launch_server \
    --model-path Qwen/Qwen3-30B-A3B \
    --attention-backend fa3 \
    --enable-deterministic-inference

비탐욕 샘플링과 함께하는 결정적 추론 (Temperature > 0)

SGLang은 샘플링 시드(sampling seeds)를 사용해 비탐욕 샘플링에서도 결정적 추론을 지원합니다. 이는 GRPO(Group Relative Policy Optimization)처럼 다양하지만 재현 가능한 여러 응답이 필요한 강화학습 시나리오에서 특히 유용해요.

기본 동작 (Default Behavior)

기본적으로 SGLang은 재현 가능한 샘플링을 위해 시드 42를 사용합니다:

import requests

response = requests.post(
    "http://localhost:30000/generate",
    json={
        "text": "Tell me a joke",
        "sampling_params": {
            "temperature": 0.8,  # Non-greedy sampling
            "max_new_tokens": 128,
        },
    },
)
print(response.json())
# This will always produce the same response across runs

여러 재현 가능한 응답 생성 (Generating Multiple Reproducible Responses)

같은 프롬프트에서 서로 다른 응답을 샘플링하면서도 재현성을 유지하려면(예: GRPO 훈련), 요청에 서로 다른 샘플링 시드를 제공하세요:

import requests

# Prepare a list of sampling seeds for different responses
sampling_seeds = [42, 43, 44, 45, 46]

responses = []
for seed in sampling_seeds:
    response = requests.post(
        "http://localhost:30000/generate",
        json={
            "text": "Tell me a joke",
            "sampling_params": {
                "temperature": 0.8,
                "max_new_tokens": 128,
                "sampling_seed": seed,  # Specify sampling seed
            },
        },
    )
    responses.append(response.json())

# Each seed will produce a different but reproducible response
# Using the same seed will always produce the same response

이 접근 방식은 다음을 보장합니다:

  • 서로 다른 시드는 다양한 응답을 생성
  • 같은 시드는 실행을 달리해도 항상 같은 응답 생성
  • 디버깅과 평가를 위해 결과가 재현 가능

검증 (Verification)

결정적 테스트를 실행해 일관된 출력을 검증하세요:

# Single test: same prompt, varying batch sizes
python3 -m sglang.test.test_deterministic --test-mode single --n-trials 50

# Prefix test: prompts with different prefix lengths
python3 -m sglang.test.test_deterministic --test-mode prefix --n-trials 50

# Radix Cache Consistency mode: test radix cache determinism (cached vs uncached prefill)
python3 -m sglang.test.test_deterministic --test-mode radix_cache

기대 결과: 모든 테스트가 Unique samples: 1(완벽히 결정적)을 보여야 합니다.

더 알아보기 (Learn more)