Top-p 핵 샘플링
Top-p가 샘플링 대상을 확률이 가장 높은 토큰 집합으로 제한하는 방식을 알아봅니다.
Top-p 핵 샘플링은(는) CoddyKit의 무료 AI Prompt Engineering 강의입니다. 이것은 4개 중 2번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 AI Prompt Engineering 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. AI Prompt Engineering 강의에는 총 4개의 강의가 포함되어 있습니다.
상위 p 샘플링이란?
상위 p 샘플링(핵 샘플링이라고도 함)은 어휘에서 동적으로 선택한 부분집합으로 샘플링을 제한하는 기법입니다. 모든 토큰에서 샘플링하는 대신, 모델은 누적 확률이 최소한 p 이상이 되는 가장 작은 토큰 집합만 고려합니다.
이 방법은 ‘신경망 텍스트 퇴화의 기묘한 사례’라는 논문(Holtzman 외, 2019)에서 제안되었으며, 다양하면서도 일관된 생성을 위해 단순한 온도 조정보다 뛰어난 성능을 보입니다.
상위 p 작동 방식 단계별 설명
알고리즘:
- 전체 어휘에 대해 softmax 확률을 계산합니다
- 확률에 따라 토큰을 정렬합니다(높은 확률부터)
- 정렬된 목록을 따라가며 확률을 누적하고, 누적 합이 p에 도달할 때까지 계속합니다
- 이 토큰 집합이 핵입니다
- 핵에서만 샘플링합니다(확률을 다시 정규화하여 합이 1이 되게 합니다)
import numpy as np
def top_p_sample(logits, p=0.9):
probs = softmax(logits, temperature=1.0)
# Sort by probability descending
sorted_indices = np.argsort(probs)[::-1]
sorted_probs = probs[sorted_indices]
# Find nucleus: smallest set with cumulative prob >= p
cumulative = np.cumsum(sorted_probs)
nucleus_size = np.searchsorted(cumulative, p) + 1
nucleus_indices = sorted_indices[:nucleus_size]
nucleus_probs = sorted_probs[:nucleus_size]
# Renormalize
nucleus_probs = nucleus_probs / nucleus_probs.sum()
# Sample
chosen = np.random.choice(nucleus_indices, p=nucleus_probs)
return chosen
token = top_p_sample(logits, p=0.9)동적 핵
상위 p의 핵심 통찰은 핵의 크기가 동적이라는 점입니다. 모델이 매우 확신하는 경우(한 토큰이 0.95의 확률로 우세한 경우) 핵에는 토큰 하나만 포함됩니다. 모델이 불확실한 경우(많은 토큰의 확률이 비슷한 경우) 핵은 더 많은 토큰을 포함하도록 확장됩니다.
이 방식은 모델의 확신 정도에 맞춰 자동으로 조정됩니다 — 확신이 높음 → 작은 어휘 크기 → 집중된 출력. 확신이 낮음 → 큰 어휘 → 더 많은 탐색.
# High-confidence situation: model strongly prefers 'the'
high_confidence_logits = np.array([5.0, 1.0, 0.5, 0.1, -0.5])
hc_probs = softmax(high_confidence_logits)
print('High confidence probs:', np.round(hc_probs, 3))
# [0.974, 0.018, 0.011, 0.007, 0.004]
# Top-p=0.9 nucleus: just 1 token (cumulative after token 0 = 97.4% > 90%)
# Low-confidence situation: model unsure
low_confidence_logits = np.array([1.1, 1.0, 0.9, 0.8, 0.7])
lc_probs = softmax(low_confidence_logits)
print('Low confidence probs:', np.round(lc_probs, 3))
# [0.218, 0.208, 0.199, 0.190, 0.181]
# Top-p=0.9 nucleus: all 5 tokens (need all to reach 90%)OpenAI API에서의 상위 p
API 호출에서 top_p를 설정하십시오. 유효한 범위는 0.0–1.0입니다. 기본값은 1.0입니다(전체 어휘를 사용하며 핵 제한이 없습니다).
OpenAI의 권장 사항은 다음과 같습니다. 상위 p를 변경할 경우 온도는 1.0으로 유지하고, 그 반대의 경우도 마찬가지입니다. 두 값을 동시에 조정하면 실제 샘플링 동작을 예측하기 어려워집니다.
import openai
client = openai.OpenAI(api_key='sk-...')
# Nucleus sampling: top 90% of probability mass
resp = client.chat.completions.create(
model='gpt-4o',
messages=[{'role': 'user', 'content': 'Tell me an interesting fact about the ocean.'}],
temperature=1.0, # leave temperature at default
top_p=0.9 # sample from top 90% nucleus
)
print(resp.choices[0].message.content)p=1.0: 제한 없는 샘플링
top_p=1.0이면 핵에 모든 토큰, 즉 전체 어휘가 포함됩니다. 이는 상위 p 제한이 없는 순수 온도 샘플링과 같습니다. 아무리 가능성이 낮은 토큰이라도 선택될 확률이 0이 아닙니다.
최대한의 다양성을 원할 때 p=1.0을 사용하십시오. p=1.0에서는 온도만 분포의 형태를 제어합니다.
# p=1.0: all tokens in nucleus
resp_full = client.chat.completions.create(
model='gpt-4o',
messages=[{'role': 'user', 'content': 'Generate a creative story opening.'}],
temperature=1.0,
top_p=1.0 # no nucleus restriction
)
# p=0.5: very focused nucleus
resp_focused = client.chat.completions.create(
model='gpt-4o',
messages=[{'role': 'user', 'content': 'Generate a creative story opening.'}],
temperature=1.0,
top_p=0.5 # only top 50% probability mass
)절충: 상위 p 대 온도
두 매개변수 모두 출력의 다양성을 제어하지만 방식은 서로 다릅니다:
- 온도는 전체 분포의 형태를 바꿉니다 — 모든 다른 토큰에 대한 토큰의 상대적 확률이 달라집니다
- 상위 p는 분포를 잘라 냅니다 — 토큰이 핵의 범위를 벗어나면 상대적 확률과 관계없이 단순히 제외됩니다
상위 p는 ‘꼬리 샘플링’ 문제를 방지합니다. 높은 온도에서는 확률이 극히 낮은 토큰(무의미한 문자열이나 관련 없는 단어)이 가끔 샘플링될 수 있습니다. 상위 p는 이러한 토큰을 고려 대상에서 완전히 제거합니다.
# The tail problem with temperature alone
high_temp_logits = np.array([3.0, 2.0, 1.0, 0.0, -1.0, -5.0, -10.0])
probs_high_temp = softmax(high_temp_logits, temperature=2.0)
print('High temp probs:', np.round(probs_high_temp, 4))
# The last token (logit=-10) still has a small probability
# With many tokens in a real vocab, these rare tokens accumulate
# and occasionally get sampled, producing incoherent output
# Top-p=0.9 cuts these off entirely
# ensuring only tokens contributing to the top 90% are considered온도와 상위 p 결합
두 매개변수를 결합할 때는 먼저 온도를 적용하여 분포의 형태를 바꾼 다음, 그 결과로 나온 확률에 상위 p를 적용하여 핵으로 잘라 냅니다.
일반적인 운영 환경 설정:
- 창작 글쓰기: 온도=1.0, 상위 p=0.95
- 채팅: 온도=0.8, 상위 p=0.9
- 코드: 온도=0.2, 상위 p=1.0(낮은 온도에서는 상위 p가 제한적으로 작용하지 않음)
def combined_sample(logits, temperature=1.0, top_p=0.9):
# Step 1: apply temperature
probs = softmax(logits, temperature=temperature)
# Step 2: apply top-p nucleus
sorted_idx = np.argsort(probs)[::-1]
sorted_probs = probs[sorted_idx]
cumulative = np.cumsum(sorted_probs)
nucleus_size = np.searchsorted(cumulative, top_p) + 1
nucleus_idx = sorted_idx[:nucleus_size]
nucleus_probs = probs[nucleus_idx]
nucleus_probs = nucleus_probs / nucleus_probs.sum()
return np.random.choice(nucleus_idx, p=nucleus_probs)상위 p와 반복
상위 p 값이 낮으면 반복이 발생할 수 있습니다. 핵이 매우 작을 때(예: p=0.5) 모델은 아주 작은 토큰 집합에서 반복적으로 샘플링합니다. 그 결과 출력이 반복적이고 예측 가능해지며, 이는 의도한 창작 효과와는 반대입니다.
과제에 비해 상위 p가 너무 낮게 설정되었다는 신호로 반복을 관찰하십시오. 유용한 진단 방법은 다음과 같습니다. 모델이 같은 구절을 반복한다면 상위 p 또는 온도를 높이십시오.
def detect_repetition(text, window=20):
words = text.split()
if len(words) < window * 2:
return False
# Check if any window of words repeats within the text
for i in range(len(words) - window):
phrase = ' '.join(words[i:i + window])
rest = ' '.join(words[i + window:])
if phrase in rest:
return True
return False
response = call_llm(prompt)
if detect_repetition(response):
print('Warning: repetition detected — consider increasing top_p or temperature')상위 p와 상위 k: 미리 보기
상위 p와 상위 k는 모두 샘플링 전에 어휘를 잘라 내지만 방식은 서로 다릅니다:
- 상위 p: 동적인 핵 크기 — 모델이 불확실할 때 확장되고 확신할 때 축소됩니다
- 상위 k: 고정된 핵 크기 — 확신 정도와 관계없이 항상 정확히 k개의 토큰을 고려합니다
상위 p는 모델의 확신 정도에 맞춰 조정되므로 일반적으로 선호됩니다. 상위 k는 다음 수업에서 자세히 다룹니다.
# Top-k equivalent for comparison
def top_k_sample(logits, k=50):
probs = softmax(logits)
# Keep only top-k tokens
top_k_indices = np.argsort(probs)[::-1][:k]
top_k_probs = probs[top_k_indices]
top_k_probs = top_k_probs / top_k_probs.sum()
return np.random.choice(top_k_indices, p=top_k_probs)
# Key difference: k is always 50, regardless of model confidence
# Top-p nucleus size varies from 1 to thousands depending on confidence기본값과 변경할 시점
API 기본값: 상위 p = 1.0(핵 제한 없음). 언제 변경해야 할까요?
- 상위 p 낮추기(0.7–0.9): 출력이 일관되지 않거나 무의미한 단어가 포함될 때 — 꼬리 샘플링이 너무 많다는 뜻입니다
- 1.0으로 유지: 온도가 이미 낮을 때 — 낮은 온도에서는 분포가 이미 뾰족하므로 상위 p가 어차피 제한적으로 작용하지 않습니다
- 0.5 미만으로 낮추지 않기: 반복과 다양성의 손실을 유발합니다
# Guidance: what to adjust based on symptoms
TROUBLESHOOTING = {
'output is incoherent or contains random words': {
'fix': 'lower top_p to 0.9 or 0.85',
'or': 'lower temperature'
},
'output is repetitive and looping': {
'fix': 'increase top_p or temperature',
'also': 'try adding frequency_penalty or presence_penalty'
},
'output is too predictable and boring': {
'fix': 'increase temperature to 0.9-1.2',
'keep': 'top_p at 0.95'
},
'output needs to be deterministic': {
'fix': 'set temperature=0, top_p=1.0'
}
}Anthropic Claude에서의 상위 p
Anthropic의 Claude API도 top_p를 매개변수로 제공합니다. 동작 방식은 동일합니다. 모델은 누적 확률이 임계값 p 이상이 되는 가장 작은 토큰 집합으로 핵을 만든 다음, 해당 핵에서 샘플링합니다.
세밀하게 제어하려면 온도와 함께 사용하십시오. 온도로 분포의 형태를 조정하고, 상위 p로 해당 분포에서 선택할 수 있는 토큰을 제한하십시오.
import anthropic
claude = anthropic.Anthropic(api_key='sk-ant-...')
# Creative writing with nucleus sampling
message = claude.messages.create(
model='claude-opus-4-5',
max_tokens=256,
temperature=1.0,
top_p=0.95,
messages=[{
'role': 'user',
'content': 'Write a short poem about the ocean.'
}]
)
print(message.content[0].text)지식 확인
상위 p(핵) 샘플링이 상위 k 샘플링보다 갖는 핵심적인 장점은 무엇입니까?
복습: 상위 p 핵 샘플링
상위 p 샘플링은 전체 확률의 p 이상을 포함하는 가장 작은 토큰 집합인 동적 핵을 만듭니다:
- p=1.0: 전체 어휘, 제한 없음
- p=0.9: 확률 질량의 상위 90% — 일반적인 창작 설정
- p=0.5: 매우 집중됨 — 반복 위험
모델이 불확실할 때 핵은 확장되고 확신할 때 축소됩니다. 이를 통해 꼬리 샘플링(확률이 낮은 토큰에서 무의미한 문자열이 생성되는 현상)을 방지하면서도 다양성을 유지합니다. 다음 수업: 상위 k 샘플링과 상위 p와의 차이
AI 튜터와 함께 AI Prompt Engineering을(를) 배우세요 — 무료
브라우저에서 실제 코드를 작성하고 실행하며, 24/7 AI 튜터로부터 즉각적인 도움을 받고, 웹이나 앱에서 중단한 부분부터 계속 학습하세요.
- 코스
- 53
- 레슨
- 199
자주 묻는 질문
“Top-p 핵 샘플링” 강의는 무료인가요?
네 — “Top-p 핵 샘플링” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 AI Prompt Engineering 강의 전체를 잠금 해제할 수 있습니다. AI Prompt Engineering 강의에는 총 4개의 강의가 포함되어 있습니다.
“Top-p 핵 샘플링”에서 뭘 배우나요?
Top-p가 샘플링 대상을 확률이 가장 높은 토큰 집합으로 제한하는 방식을 알아봅니다. 브라우저에서 직접 실행하는 실습 코드로 AI Prompt Engineering을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
AI Prompt Engineering을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 AI Prompt Engineering은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 2번째 강의입니다.
“Top-p 핵 샘플링” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 AI Prompt Engineering 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 AI Prompt Engineering 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.