4.2.3 파멸의 형용사: Frequency Penalty와 Presence Penalty가 응답 구조 반복성 및 결정론에 미치는 악영향

4.2.3 파멸의 형용사: Frequency Penalty와 Presence Penalty가 응답 구조 반복성 및 결정론에 미치는 악영향

오토레그레시브(Auto-regressive) 기반의 거대 언어 모델(LLM)이 이전 텍스트 맥락(Context)을 바탕으로 다음 토큰을 숨 가쁘게 생성할 때, 이 확률 기계가 태생적으로 앓고 있는 고질적이고 치명적인 부작용 중 하나는 바로 **‘동일한 단어나 구문의 무한 반복 굴레(Infinite Repetition Loop)’**에 빠지는 것이다.
B2C 챗봇이나 소설 작성 AI를 개발하는 엔지니어들은 이 지루하고 바보 같은 앵무새 현상을 제어하기 위해, API 파이프라인 단에서 Frequency Penalty(빈도 벌점)와 Presence Penalty(존재 벌점)라는 두 가지 강력한 패널티(Penalty) 조절 매커니즘 다이얼을 습관적으로 돌려 제공한다.

이 두 파라미터는 모델의 출력 레이어(Output Layer)인 소프트맥스(Softmax) 로짓(Logit) 계산 과정에 인위적으로 음수(-)의 가중치를 더하여, 특정 토큰이 다음 타자로 등장할 최종 확률을 강제로 깎아내리는(Discounting) 역할을 무자비하게 수행한다. 그 억제 공식은 수학적으로 일반적으로 다음과 매우 유사한 형태를 띤다.

Modified\_Logit = Original\_Logit - (\alpha \times Count) - (\beta \times I(Count > 0))
(여기서 \alpha는 Frequency Penalty, \beta는 Presence Penalty, Count는 해당 토큰이 앞서 텍스트에서 등장한 횟수다.)

이 두 가지 패널티 다이얼은 B2C 모델의 문장 창의력(Creativity)을 억지로 쥐어짜 내고 인간의 대화처럼 출력을 화려하고 다채롭게 만들지만, 반대로 우리가 피땀 흘려 구축한 MLOps 파이프라인의 ’결정론적인 소프트웨어 동작성(Deterministic Software Behavior)’을 가장 심각하게, 그리고 치명적으로 훼손하고 박괴하므로 오라클 설계자는 이 다이얼에 극도의 주의를 기울이고 절대 건드려서는 안 된다.

1. Frequency Penalty: 등장 횟수에 비례한 선형적 억제 (Linear Repetition Blocker)

Frequency Penalty(자주 등장할수록 더 무거운 벌점)는 특정 토큰이 지금까지 생성된 텍스트 컨텍스트 내에서 ‘얼마나 자주(빈도수, Frequency)’ 등장했는지를 카운팅하여 그 누적 횟수에 정확히 비례하는 혹독한 벌점을 부여한다. 단어가 한 번 등장할 때마다 그 다음 번 등장 확률의 로짓이 계속해서 깎여 나가므로, 디코딩(Decoding) 중인 모델은 갈수록 고통을 느끼며 어떻게든 기존 단어를 피해 다른 낯선 유의어(Synonym)를 찾거나 완전히 새로운 뚱딴지같은 화제 토큰으로 탈출하려는 강한 확률적 압력을 받게 된다.

소프트웨어 품질 보증(QA) 및 JSON 구조 출력 시나리오에서 이 파라미터에 0.0보다 단 0.1이라도 큰 양수 값을 부여하면 끔찍하고 치명적인 데이터 붕괴 결과가 발생한다.

  • 만약 시스템 프롬프트가 정규식 파서를 위해 특정한 Key 문자열을 일관되게 반복적으로 나열하도록 지시했다고 가정해 보자.
  • 정상적인 로드 밸런서 로그 분석이라면: {"에러코드": 500}, {"에러코드": 404}, {"에러코드": 503}과 같이 수백 번의 기계적인 Key 배열 반복 출력이 필수적인 상황이다.
  • 하지만 Frequency Penalty의 독약이 주입되어 있다면, 모델은 "에러코드"라는 단어를 불과 두세 번 출력한 직후부터 강제로 부과되는 음수 가중치의 압박을 견디지 못하고 환각을 일으킨다. 그리고 돌연 "발생오류번호":, "장애식별ID":, "서버크래시코드": 따위로 스키마(Schema) 구문을 임의로, 그리고 치명적으로 틀어버리게 된다.
  • 이는 결과적으로 백엔드 서버에서 기다리고 있던 정규표현식(Regex) 기반의 파서나 엄격한 Pydantic 구조화 스키마 검증기(Validator)를 완전히 에러의 늪으로 붕괴(Crash)시켜버리는 최악의 대참사다.

2. Presence Penalty: 출현 유무에 따른 존재론적 억제 (Existential Pushing)

Presence Penalty(한 번이라도 등장하면 즉각 벌점)는 앞선 빈도수 카운팅과 무관하게, 특정 토큰 덩어리가 생성 텍스트 내에 단 ‘한 번이라도’ 존재(Present)했다면 즉시 일괄적인 고정 벌점 타격을 부과하는 냉혹한 방식이다. 즉, 패널티 공식의 I(Count > 0) 항이 말하듯, 모델의 등짝을 때리며 *“이미 앞 문단에서 썼던 말은 다시 입 밖으로 꺼내지 말고, 신속하게 새로운 화제나 다른 단상으로 화제를 전환하라”*고 강제하는 로직이다.

이 역시 결정론성과 팩트 체크(Fact-checking) 달성에는 거대한 적이자 트로이 목마와 같다. 특정 도메인의 코드(Code)나 리버스 엔지니어링 룰셋에서는 특정 함수명(calculate_tax), 클래스명(UserAccount), 혹은 법적으로 규정된 도메인 명사(Domain Jargon)를 수백 줄의 맥락 안에서 계속해서 앵무새처럼 토씨 하나 틀리지 않고 동일하게 지칭해야만 한다.
기술 문서 번역이나 엄격한 RAG(Retrieval-Augmented Generation) 요약 작업에 이 Presence Penalty의 변위가 조금이라도 개입하게 되면, 모델은 소프트웨어 코드의 명명 규칙(Naming Convention) 일관성을 스스로 깨뜨리거나 문서의 핵심 키워드를 자의적으로 유의어로 변조해버리는 심각한 의미론적 할루시네이션(Semantic Hallucination) 지옥에 빠지게 된다.

3. 오라클 아키텍트의 행동 강령: 0.0으로 못 박힌 다이얼 (Hardcoded Rule)

결론적으로, 무결점의 ’결정론적 정답지(Deterministic Ground Truth)’를 안전하게 설계하고, 제어하기 힘든 AI 에이전트를 엔터프라이즈 자동화 파이프라인의 백엔드 톱니바퀴로 완전히 편입시키기 위해서는 이 두 가지 유혹적인 다이얼, Frequency PenaltyPresence Penalty 파라미터 값은 그레디언트 디센트나 튜닝의 여지 없이 무조건, 절대적으로 기본값인 0.0으로 스크립트 상에 고정(Hardcode)해버려야만 한다.

API 응답을 받은 AI의 대답이 챗봇처럼 유려하지 않고, 로봇처럼 지루하고 단조로우며 무식하게 반복적인 문맥 테이프가 되는 것은 이 엔지니어링 맥락에서는 전혀 단점이 아니다. 오히려 그것이야말로 백엔드의 구문 파서(Parser)와 엄격한 유닛 테스트 스위트(Unit Test Suite)가 가장 환영하고 박수 치는 **‘완벽한 구조적 멱등성(Structural Idempotency)’**의 숭고한 증거다.
파이프라인 안의 모델이 가장 재미없고 지루한 대답의 패턴을 끝없이 반복하도록 안전하게 내버려 두어라. 그것이 오류율 0%의 예측 가능한 소프트웨어 인프라로 가는 가장 빠르고 확고한 지름길이다.