OpenAI 생성 파라미터

Temperature, Top-P, Penalties 등 텍스트 생성 제어 메커니즘 심층 분석

OpenAI API의 핵심 생성 파라미터(Temperature, Top-P, Max Tokens, Frequency Penalty, Presence Penalty, Stop Sequences)의 수학적 원리와 실제 동작 방식을 상세히 설명한다. 각 파라미터가 확률 분포에 미치는 영향, 파라미터 간 상호작용, 실무 시나리오별 최적 설정값, 구체적 사용 예시를 통해 LLM 출력을 정밀하게 제어하는 방법을 제시한다.

Prompt Engineering
AI
Agent
저자

Kwangmin Kim

공개

2025년 01월 24일

0.1 기본 용어

0.1.1 토큰 (Token)

정의: 언어 모델이 처리하는 텍스트의 최소 단위

특징: - 영어: 평균 1단어 ≈ 1.3 토큰 (예: “ChatGPT” = 2토큰, “running” = 1토큰) - 한국어: 평균 1음절 ≈ 1-2 토큰 (예: “안녕하세요” = 5-10토큰) - 공백, 구두점도 토큰: ” hello” (공백 포함) vs “hello” (다른 토큰)

실용 예시:

# GPT-3.5/4의 경우
"Hello, world!" = ["Hello", ",", " world", "!"] = 4 토큰
"한글 테스트" = ["한", "글", " ", "테", "스", "트"] = 6토큰 (근사치)

중요성: - API 비용은 토큰 수로 계산 (GPT-4: $0.03/1K 입력 토큰) - 모델 컨텍스트 길이 제한 (GPT-4-turbo: 128K 토큰) - 프롬프트 최적화 필요 (불필요한 단어 제거로 비용 절감)

0.1.2 토크나이저 (Tokenizer)

역할: 텍스트 → 토큰 ID 변환 (모델이 이해할 수 있는 숫자)

OpenAI 토크나이저 종류: - cl100k_base: GPT-4, GPT-3.5-turbo - p50k_base: Codex, text-davinci-002/003 - r50k_base: GPT-3 (davinci, curie 등)

테스트 도구: OpenAI Tokenizer

1 OpenAI 생성 파라미터 상세

1.1 Temperature (온도)

1.1.1 수학적 원리

Temperature는 Softmax 함수의 확률 분포를 조정한다:

\[P(w_i) = \frac{e^{z_i / T}}{\sum_j e^{z_j / T}}\]

  • \(z_i\): 각 단어의 로짓(logit) 값
  • \(T\): Temperature (0 < T ≤ 2)
  • \(T = 1\): 원래 확률 분포
  • \(T → 0\): 가장 높은 확률에 집중 (거의 결정론적)
  • \(T > 1\): 확률 분포가 평탄화 (더 무작위)

1.1.2 값별 동작

Temperature 확률 분포 출력 특성 사용 사례
0.0-0.3 최고 확률에 극도 집중 일관성 높음, 예측 가능 코드 생성, 번역, 요약
0.4-0.7 상위 몇 개 선택 균형 잡힘 일반 대화, Q&A
0.8-1.0 상대적으로 고른 분포 창의적, 다양함 브레인스토밍, 스토리 생성
1.1-2.0 매우 평탄한 분포 무작위, 일관성 낮음 실험적 창작, 예술

1.1.3 구체적 예시

Temperature = 0.2 (일관성 우선)

프롬프트: "Python에서 리스트를 정렬하는 방법은?"

출력 1: "Python에서 리스트를 정렬하려면 sort() 메서드를 사용합니다..."
출력 2: "Python에서 리스트를 정렬하려면 sort() 메서드를 사용합니다..." (거의 동일)
출력 3: "Python에서 리스트를 정렬하려면 sort() 메서드를 사용합니다..."

Temperature = 1.0 (창의성 우선)

프롬프트: "새로운 스타트업 아이디어를 제안해줘"

출력 1: "반려동물 건강 관리 AI 플랫폼을 만들어보는 건 어떨까요?"
출력 2: "VR 기반 원격 협업 도구를 개발하면 좋을 것 같습니다."
출력 3: "음식물 쓰레기를 재활용하는 커뮤니티 플랫폼은 어떨까요?"

1.1.4 권장 설정

  • 사실 기반 작업 (코딩, 번역): 0.1-0.3
  • 일반 대화: 0.7
  • 창의적 작업: 0.9-1.2

1.2 Top-P (Nucleus Sampling)

1.2.1 핵심 개념

Temperature가 전체 확률 분포를 조정한다면, Top-P는 누적 확률이 P에 도달할 때까지의 토큰만 선택한다.

1.2.2 동작 원리

  1. 모든 토큰을 확률 순으로 정렬
  2. 누적 확률이 P를 초과할 때까지 토큰 선택
  3. 선택된 토큰 집합에서만 샘플링

예시 (Top-P = 0.9):

다음 단어 확률 분포:
"dog": 0.40
"cat": 0.30
"bird": 0.15
"fish": 0.10
"lion": 0.05

Top-P = 0.9 선택:
"dog" (0.40) + "cat" (0.30) + "bird" (0.15) = 0.85 < 0.9
"dog" (0.40) + "cat" (0.30) + "bird" (0.15) + "fish" (0.10) = 0.95 > 0.9

→ "dog", "cat", "bird", "fish" 중에서만 선택
→ "lion"은 제외됨

1.2.3 Temperature vs Top-P 비교

특성 Temperature Top-P
조정 대상 확률 분포 형태 고려 토큰 개수
효과 전체적 무작위성 동적 선택 범위
확률 분포 넓을 때 더 넓게 더 많은 토큰 선택
확률 분포 좁을 때 더 좁게 더 적은 토큰 선택

1.2.4 상황별 선택

확률 분포가 넓은 경우 (창의적 질문): - 프롬프트: “새로운 이야기를 만들어줘” - 다양한 단어들이 비슷한 확률로 가능 - Top-P = 0.9: 더 많은 선택지 → 다양성 ↑

확률 분포가 좁은 경우 (기술적 질문): - 프롬프트: “2 + 2는?” - “4”가 압도적으로 높은 확률 - Top-P = 0.9: “4”만 선택 → 정확성 유지

1.2.5 권장 설정

  • Top-P = 1.0: 모든 토큰 고려 (Temperature만 사용)
  • Top-P = 0.9: 일반적 권장값 (상위 90% 누적 확률)
  • Top-P = 0.5: 보수적 (가장 확실한 토큰만)

주의: Temperature와 Top-P를 동시에 낮게 설정하지 말 것 (과도하게 결정론적)

1.3 Max Tokens (최대 토큰 수)

1.3.1 정의

생성할 출력의 최대 토큰 수 (입력 토큰 제외)

1.3.2 동작 방식

# 예시
입력: "Python이란?" (5 토큰)
max_tokens: 100

가능한 출력: 최대 100 토큰까지 생성
전체 사용: 입력(5) + 출력(≤100) = 최대 105 토큰

1.3.3 중요 특징

  1. 생성 중단 조건:

    • Max tokens 도달
    • 자연스러운 종료 (문장 완성)
    • Stop sequence 만남
  2. 비용 계산:

    • 실제 생성된 토큰 수만큼만 과금
    • max_tokens=1000 설정해도 50 토큰만 생성되면 50 토큰 비용만 부과
  3. 컨텍스트 윈도우:

    GPT-4-turbo: 128,000 토큰 (입력 + 출력 합계)
    입력 100,000 토큰 → 출력 최대 28,000 토큰 가능

1.3.4 실용 가이드

작업 유형 권장 max_tokens 이유
짧은 답변 50-100 간결성 유지
일반 대화 150-300 자연스러운 응답
긴 설명 500-1000 충분한 상세 설명
코드 생성 1000-2000 완전한 함수/클래스
문서 작성 2000-4000 전체 문서

1.3.5 전략

# 적응적 max_tokens 설정
def adaptive_max_tokens(task_type):
    if task_type == "qa_short":
        return 100
    elif task_type == "explanation":
        return 500
    elif task_type == "code":
        return 1500
    else:
        return 1000

1.4 Frequency Penalty (빈도 페널티)

1.4.1 수학적 원리

이미 생성된 토큰의 출현 빈도에 비례하여 확률을 감소시킨다:

\[\text{logit}(w_i) = \text{logit}(w_i) - \alpha \times \text{count}(w_i)\]

  • \(\alpha\): Frequency penalty (0.0 ~ 2.0)
  • \(\text{count}(w_i)\): 토큰 \(w_i\)가 지금까지 출현한 횟수

1.4.2 값별 효과

Frequency Penalty 효과 사용 시나리오
0.0 페널티 없음 반복이 자연스러운 경우 (시, 노래)
0.3-0.5 약간 억제 일반 텍스트 생성
0.7-1.0 중간 억제 다양한 표현 필요 시
1.5-2.0 강력 억제 키워드 리스트, 브레인스토밍

1.4.3 구체적 예시

Frequency Penalty = 0.0 (페널티 없음)

프롬프트: "사과의 특징을 설명해줘"

출력: "사과는 빨간색이고, 사과는 달콤하며, 사과는 건강에 좋습니다. 
      사과는 비타민이 풍부하고, 사과는 아삭아삭한 식감을 가지고 있습니다."
      
→ "사과는" 5번 반복

Frequency Penalty = 1.0 (중간 억제)

프롬프트: "사과의 특징을 설명해줘"

출력: "사과는 빨간색이며 달콤한 맛을 지닙니다. 
      이 과일은 비타민이 풍부하고 아삭한 식감이 특징입니다.
      건강에 유익한 영양소를 많이 함유하고 있습니다."
      
→ 단어 반복 최소화, 다양한 표현 사용

1.4.4 실전 활용

키워드 리스트 생성 (높은 Frequency Penalty):

{
  "prompt": "AI 관련 키워드 20개를 나열해줘",
  "frequency_penalty": 1.5  # 중복 방지
}

출력: "머신러닝, 딥러닝, 신경망, 자연어처리, 컴퓨터비전, 
      강화학습, 트랜스포머, GPT, BERT, CNN, RNN..."

스토리텔링 (낮은 Frequency Penalty):

{
  "prompt": "짧은 이야기를 써줘",
  "frequency_penalty": 0.3  # 자연스러운 반복 허용
}

출력: "그는 문을 열었다. 문 너머에는 긴 복도가 있었다. 
      그는 복도를 걸어갔다. 복도 끝에는..."

1.5 Presence Penalty (존재 페널티)

1.5.1 Frequency Penalty와의 차이

항목 Frequency Penalty Presence Penalty
측정 대상 토큰 출현 횟수 토큰 출현 여부 (0 or 1)
페널티 계산 선형 증가 (횟수 비례) 일정 (출현했으면 동일 페널티)
효과 반복 억제 주제 다양화

1.5.2 수학적 원리

\[\text{logit}(w_i) = \text{logit}(w_i) - \beta \times \mathbb{1}(w_i \text{ appeared})\]

  • \(\beta\): Presence penalty (0.0 ~ 2.0)
  • \(\mathbb{1}(w_i \text{ appeared})\): 토큰이 한 번이라도 나타났으면 1, 아니면 0

1.5.3 값별 효과

Presence Penalty 효과 사용 시나리오
0.0 페널티 없음 주제 집중 필요 시
0.3-0.5 약간 다양화 일반 텍스트
0.7-1.0 중간 다양화 여러 관점 제시
1.5-2.0 강력 다양화 브레인스토밍, 다양한 아이디어

1.5.4 비교 예시

Frequency vs Presence 동작 차이:

생성 중인 텍스트: "사과는 맛있다. 사과는 건강하다."

Frequency Penalty = 1.0:
- "사과" 2번 출현 → logit("사과") -= 1.0 × 2 = -2.0
- 출현 횟수에 비례하여 점점 더 억제

Presence Penalty = 1.0:
- "사과" 출현 여부 = 1 → logit("사과") -= 1.0 × 1 = -1.0
- 한 번 나타난 이후 동일한 페널티 유지 (횟수 무관)

1.5.5 실전 활용

브레인스토밍 (높은 Presence Penalty):

{
  "prompt": "AI 비즈니스 아이디어를 10가지 제안해줘",
  "presence_penalty": 1.5  # 완전히 다른 아이디어들
}

출력:
1. AI 맞춤형 교육 플랫폼
2. 자율주행 배송 로봇
3. 의료 진단 보조 시스템
4. 개인화된 음악 생성 서비스
5. 실시간 언어 번역 이어폰
... (각각 완전히 다른 도메인)

주제 집중 (낮은 Presence Penalty):

{
  "prompt": "파이썬의 장점을 설명해줘",
  "presence_penalty": 0.2  # 관련 키워드 반복 허용
}

출력: "파이썬은 간결한 문법을 가지고 있습니다. 
      파이썬의 문법은 읽기 쉽고, 파이썬 커뮤니티는 활발합니다.
      파이썬 라이브러리는 풍부하며..." (파이썬 중심 설명)

1.5.6 Frequency + Presence 조합

# 리스트 생성: 중복 없이 다양한 항목
{
  "frequency_penalty": 1.2,   # 같은 단어 반복 억제
  "presence_penalty": 1.0     # 새로운 주제로 확장
}

# 자연스러운 문장: 적절한 반복 허용
{
  "frequency_penalty": 0.3,   # 약간의 반복 억제
  "presence_penalty": 0.5     # 적당한 주제 다양성
}

# 기술 문서: 일관된 용어 사용
{
  "frequency_penalty": 0.0,   # 반복 허용
  "presence_penalty": 0.0     # 페널티 없음
}

1.6 Stop Sequences (중지 시퀀스)

1.6.1 정의

특정 문자열이 생성되면 즉시 생성을 중단하는 트리거

1.6.2 동작 방식

{
  "prompt": "1부터 10까지 세어줘",
  "stop": ["\n\n", "10"]
}

출력: "1, 2, 3, 4, 5, 6, 7, 8, 9, 10"
"10" 생성 후 즉시 중단

1.6.3 주요 활용 사례

1.6.3.1 1. 대화 턴 제어

{
  "prompt": "User: 안녕?\nAssistant:",
  "stop": ["\nUser:", "\n\n"]
}

출력: "안녕하세요! 무엇을 도와드릴까요?"
"\nUser:"가 나타나면 중단 (다음 턴 방지)

1.6.3.2 2. 리스트 길이 제한

{
  "prompt": "프로그래밍 언어 목록:\n1.",
  "stop": ["6.", "\n\n"]
}

출력:
"1. Python
2. JavaScript
3. Java
4. C++
5. Go"
→ "6." 생성 전에 중단

1.6.3.3 3. JSON 생성 제어

{
  "prompt": "다음 JSON 객체를 생성해줘:\n{",
  "stop": ["\n}"]
}

출력:
'{
  "name": "John",
  "age": 30,
  "city": "Seoul"
}'
→ 닫는 괄호 후 중단

1.6.3.4 4. 코드 블록 추출

{
  "prompt": "Python 함수를 작성해줘:\n```python\n",
  "stop": ["```", "\n\n\n"]
}

출력:
"def hello():
    print('Hello, World!')
    return True"
→ 코드 블록 끝나면 중단

1.6.4 고급 패턴

1.6.4.1 다중 Stop Sequences

{
  "stop": ["END", "---", "\n\n\n", "Assistant:"]
}
4가지 중 하나라도 만나면 중단

1.6.4.2 구조화된 출력

{
  "prompt": "Q: 파이썬이란?\nA:",
  "stop": ["\n\nQ:", "\n\n"]
}
→ Q&A 형식 유지

1.6.5 주의사항

  1. 토큰 경계: Stop sequence는 정확히 일치해야 함

    stop: ["10"]  # "10" 전체가 하나의 토큰일 때만 작동
    # "1", "0" 두 토큰으로 분리되면 작동 안 함
  2. 최대 4개: OpenAI API는 최대 4개 stop sequence 지원

  3. 빈 문자열 불가: stop: [""] 는 오류

1.6.6 실전 조합 예시

# 뉴스 요약 생성
{
  "prompt": "다음 뉴스를 3문장으로 요약해줘:\n[뉴스 내용]\n\n요약:",
  "max_tokens": 150,
  "temperature": 0.3,
  "stop": ["\n\n", "---"]
}

# 코드 리뷰
{
  "prompt": "다음 코드를 리뷰해줘:\n```python\n[코드]\n```\n\n리뷰:",
  "max_tokens": 500,
  "temperature": 0.5,
  "stop": ["```", "\n\n\n"],
  "frequency_penalty": 0.5
}

# 창의적 글쓰기
{
  "prompt": "짧은 SF 소설을 써줘:",
  "max_tokens": 1000,
  "temperature": 1.0,
  "top_p": 0.95,
  "presence_penalty": 0.6,
  "stop": ["THE END", "끝."]
}

2 파라미터 조합 전략

2.1 시나리오별 최적 설정

2.1.1 코드 생성

{
  "temperature": 0.2,        # 정확성 우선
  "top_p": 0.95,            # 상위 선택지만
  "max_tokens": 2000,       # 충분한 코드 길이
  "frequency_penalty": 0.3,  # 반복 코드 약간 억제
  "presence_penalty": 0.0,   # 일관된 변수명 허용
  "stop": ["```", "\n\n\n"]
}

2.1.2 창의적 콘텐츠

{
  "temperature": 1.0,        # 높은 다양성
  "top_p": 0.9,             # 넓은 선택지
  "max_tokens": 1500,       
  "frequency_penalty": 0.5,  # 반복 방지
  "presence_penalty": 0.8,   # 주제 다양화
  "stop": None
}

2.1.3 사실 기반 Q&A

{
  "temperature": 0.1,        # 거의 결정론적
  "top_p": 1.0,             # Temperature만 사용
  "max_tokens": 300,        
  "frequency_penalty": 0.0,  # 핵심 용어 반복 허용
  "presence_penalty": 0.0,   
  "stop": ["\n\n"]
}

2.1.4 브레인스토밍

{
  "temperature": 0.9,        
  "top_p": 0.95,            
  "max_tokens": 1000,       
  "frequency_penalty": 1.5,  # 중복 아이디어 방지
  "presence_penalty": 1.2,   # 완전히 새로운 아이디어
  "stop": ["20.", "---"]    # 적당한 개수에서 중단
}

2.2 디버깅 가이드

2.2.1 출력이 너무 반복적일 때

# 문제
출력: "AI는 좋다. AI는 유용하다. AI는 중요하다. AI는..."

# 해결
frequency_penalty: 0.00.7  # 증가
presence_penalty: 0.00.5   # 증가

2.2.2 출력이 너무 무작위일 때

# 문제
출력: "AI는... 고양이... 파란 하늘... 우주..."

# 해결
temperature: 1.00.5  # 감소
top_p: 1.00.9       # 감소

2.2.3 출력이 너무 짧을 때

# 문제
출력: "네." (끝)

# 해결
max_tokens: 100500      # 증가
stop: ["\n\n"] → None      # 제거 또는 완화
temperature: 0.20.5     # 약간 증가 (더 많은 토큰 생성)

3 참고 자료

Subscribe

Enjoy this blog? Get notified of new posts by email: