SGLang의 choices 메서드

SGLang의 choices 메서드

답변 후보가 정해져 있을 때 "이 중에서 하나 골라라"고 시킬 일이 잦아요. SGLang의 choices 프리미티브가 그 역할을 하는데, 후보 중 하나를 어떤 기준으로 고를지 정하는 게 choices_method 인자예요.

출처: 공식문서

선택 기준을 바꿀 수 있는 choices_method 인자는 RuntimeEndpoint 백엔드에서만 지원돼요. OpenAI 같은 다른 백엔드는 API 제약 때문에 각자 고유한 선택 방식을 써요.

메서드들

토큰 길이 정규화 (Token Length Normalized)

SGLang의 기본 choices 메서드예요. 각 후보의 모든 토큰에 걸친 평균 logprob이 가장 높은 후보를 골라요.

사용 예 (아니면 choices_method 인자를 그냥 생략해도 똑같아요):

@sgl.function
def example(s):
    s += sgl.user("What is the capital of France?")
    s += sgl.assistant(
        sgl.gen(
            "answer",
            choices=["London", "Paris", "Berlin"],
            choices_method=sgl.token_length_normalized,
        )
    )

한 후보가 토큰이 많고, 앞 토큰이 확실하면 뒤 토큰도 높은 확신으로 예측되는 경우에 이 방식은 성능이 나빠질 수 있어요. 예를 들어 후보를 ["Paris", "Antidisestablishmentarianism"]으로 줬다면 강한 모델조차 위 예시를 틀려요. 토큰 수가 많은 긴 단어 후보가 평균을 깎아먹기 때문이에요.

탐욕 토큰 선택 (Greedy Token Selection)

탐욕 토큰 선택은 첫 토큰의 logprob이 가장 높은 후보를 그냥 골라요. 한 후보가 더 긴 후보의 부분집합처럼 겹치는 경우엔, 짧은 후보의 logprob을 자기 평균으로 연장해서 긴 후보와 비교해요.

사용 예:

@sgl.function
def example(s):
    s += sgl.user("What is the capital of France?")
    s += sgl.assistant(
        sgl.gen(
            "answer",
            choices=["London", "Paris", "Berlin"],
            choices_method=sgl.greedy_token_selection,
        )
    )

이 방식은 매력적인 첫 토큰 때문에 모델을 잘못된 길로 유인하는 후보가 있으면 틀려요. 예를 들어 다음 예시는 탐욕 선택으로는 잘못된 답이 나와요.

@sgl.function
def us_president_example(s):
    s += sgl.user("Name a US president.")
    s += sgl.assistant(
        sgl.gen(
            "answer",
            choices=["Donald Duck", "Millard Fillmore"],
            choices_method=sgl.greedy_token_selection,
        )
    )

"Donald Trump"를 기대하는 모델은 첫 토큰으로 "Donald"를 우선하게 되니 Donald Duck을 골라버리는 거죠.

무조건 우도 정규화 (Unconditional Likelihood Normalized)

무조건 우도 정규화는 EleutherAI 블로그에서 설명한 대로, 각 후보의 평균 토큰 logprob을 무조건 토큰 logprob으로 정규화한 뒤 가장 높은 후보를 골라요. 이 방식은 무조건 우도를 얻기 위해 LLM 호출을 한 번 더 해야 해요.

사용 예:

@sgl.function
def example(s):
    s += sgl.user("What is the capital of France?")
    s += sgl.assistant(
        sgl.gen(
            "answer",
            choices=["London", "Paris", "Berlin"],
            choices_method=sgl.unconditional_likelihood_normalized,
        )
    )

더 알아보기 (Learn more)