LLM은 매 스텝마다 다음 토큰의 확률 분포를 내놓는다. 그 분포에서 실제 토큰 하나를 뽑는 규칙이 샘플링 파라미터다. temperature와 top-p(nucleus)는 많이들 알지만, 실전에서 결과를 좌우하는 손잡이는 그 밖에도 있다. top-k, min-p, 그리고 반복을 억제하는 repetition/frequency/presence penalty까지. 이 노트는 이 덜 알려진 손잡이들을 언제 어떻게 돌려야 하는지에 대한 이야기다.
나는 한동안 temperature만 만지작거렸다. 그런데 "말은 되는데 자꾸 같은 표현을 반복"하거나 "가끔 뜬금없는 단어가 튀어나오는" 문제는 온도만으로 안 잡혔다. 범인은 따로 있었고, 그걸 알고 나서 출력 품질이 눈에 띄게 안정됐다.
먼저, 온도와 top-p 복습
temperature는 분포의 뾰족함을 조절한다. 낮으면(0에 가까우면) 가장 확률 높은 토큰에 쏠려 결정적·보수적이 되고, 높으면 분포가 평평해져 다양하고 과감해진다. top-p는 확률을 높은 순으로 더해 누적 p까지만 후보로 남기고 꼬리를 자른다. 상황에 따라 후보 개수가 유동적으로 변하는 게 특징이다.
top-k와 min-p — 꼬리 자르는 두 방식
top-k는 단순하다. 확률 상위 k개만 남기고 나머지는 버린다. 후보 수가 항상 고정 k개라는 게 장점이자 한계다. 분포가 아주 뾰족할 때도 억지로 k개를 남겨, 말도 안 되는 후보가 낄 수 있다.
그 약점을 보완한 게 min-p다. "가장 확률 높은 토큰의 p배" 미만인 후보를 전부 쳐낸다. 분포가 확신에 차 있으면(1등이 압도적이면) 후보가 저절로 좁아지고, 애매하면 넓어진다. 나는 창의적 생성에서 높은 온도를 쓰되 min-p로 엉뚱한 꼬리를 막는 조합을 즐겨 쓴다. 온도로 다양성을 열고, min-p로 하한선을 지키는 식이다.
| 파라미터 | 기준 | 후보 수 |
|---|---|---|
| top-k | 상위 k개 | 고정 |
| top-p | 누적 확률 p | 가변 |
| min-p | 최고 확률의 p배 | 가변(분포 반응) |
반복을 억제하는 페널티들
모델이 같은 구절을 앵무새처럼 되풀이하는 걸 막는 손잡이가 셋 있다. 이름이 헷갈리니 표로 정리한다.
| 페널티 | 작동 |
|---|---|
| presence | 한 번이라도 나온 토큰에 고정 감점 |
| frequency | 많이 나올수록 비례해 감점 |
| repetition | 기존 토큰 확률을 나눗셈식으로 억제 |
presence는 "새 주제로 넘어가라"는 압력, frequency는 "같은 단어 그만 써라"는 압력에 가깝다. 둘 다 과하게 주면 부작용이 생긴다. 나도 frequency penalty를 세게 걸었다가, 흔한 조사나 필수 단어까지 억눌려 문장이 어색해진 적이 있다. 반복은 잡혔는데 문법이 삐끗한 것이다.
# 대략적인 감각 (의사코드)
logits = model(ctx)
logits = logits / temperature # 뾰족함 조절
for tok in seen: # 이미 나온 토큰
logits[tok] -= presence_penalty
logits[tok] -= frequency_penalty * count[tok]
probs = softmax(logits)
probs = apply_min_p(probs, min_p) # 꼬리 컷
next_tok = sample(probs)
작업별 레시피
정답은 작업마다 다르다. 사실 조회·추출·코드처럼 정확성이 중요하면 온도를 낮게(또는 0에 가깝게) 두고 페널티도 최소로. 브레인스토밍·창작이면 온도를 올리고 min-p로 하한을 지키며, 반복이 거슬리면 frequency penalty를 아주 약하게부터 얹는다. 여러 손잡이를 동시에 세게 돌리면 서로 간섭해 원인 파악이 어려워지니, 한 번에 하나씩 움직이는 게 상책이다.
샘플링은 "정답 뽑기"가 아니라 "다양성과 안정성의 저울질"이다. 온도로 문을 열고, top-p·min-p로 위험한 꼬리를 자르고, 페널티로 반복을 다스린다.
자주 묻는 질문
temperature를 0으로 하면 완전히 똑같은 답이 나오나요?
대체로 가장 확률 높은 토큰만 고르는 그리디에 가까워져 결정적이 되지만, 완벽한 재현은 보장되지 않을 수 있다. 부동소수점 연산 순서, 배치 구성, 인프라 차이 등으로 미세한 변동이 생길 수 있기 때문이다. 재현성이 중요하면 시드 고정과 함께 실제 환경에서 확인하는 게 좋다.
top-p와 top-k, min-p를 동시에 써도 되나요?
엔진에 따라 함께 적용할 수 있지만, 여러 컷을 겹치면 효과가 서로 얽혀 조율이 어려워진다. 보통은 하나를 주력으로 고르는 편이 깔끔하다. 개인적으로는 min-p 하나로 꼬리를 다루는 게 분포 상태에 잘 반응해 편했다. 여러 개를 켤 거면 값을 보수적으로 잡는 게 안전하다.
반복이 심한데 frequency penalty를 얼마나 올려야 하나요?
아주 작은 값부터 조금씩 올리는 걸 권한다. 과하게 걸면 반복은 사라지지만 자주 쓰이는 필수 단어까지 눌려 문장이 어색해지고 의미가 흐트러진다. 반복의 원인이 프롬프트 구조나 컨텍스트에 있는 경우도 많으니, 페널티에만 의존하기보다 입력을 함께 점검하는 게 좋다.
구조화된 JSON 출력에도 온도를 올려야 하나요?
반대다. 형식이 정확해야 하는 출력은 온도를 낮게 두어 변동을 줄이는 편이 안전하다. 다양성은 여기서 미덕이 아니라 위험이다. 스키마를 강제하는 제약 디코딩이나 검증·재시도를 함께 쓰면 형식 안정성을 더 높일 수 있다.

댓글 0