
도서: 생성 AI 디자인 패턴 독서 메모-01
요약
생성형 AI 모델의 출력 스타일을 제어하기 위한 디자인 패턴 중 로짓 마스킹(Logit Masking)의 원리와 구현 과정을 다룹니다. 토크나이저부터 로짓 변형, 샘플링에 이르는 파이프라인을 통해 특정 규칙을 준수하는 텍스트 생성을 강제하는 방법을 설명합니다.
핵심 포인트
- 로짓 마스킹을 통해 특정 토큰의 생성 확률을 제어 가능
- 규칙에 어긋나는 토큰의 로짓 값을 음의 무한대로 설정하여 배제
- 토크나이저, LLM 추론, 로짓 변형, 샘플링으로 이어지는 파이프라인 이해
- 모델의 확률적 응답을 애플리케이션 수준에서 구조적으로 제어
기초 지식 등의 이유로 일단 생략. 향후 막히는 부분이 생기면 다시 읽고 기재할 것.
전체 32개 패턴을 이제부터 배운다.
기반 모델(Foundation Model)에 의해 생성되는 콘텐츠의 스타일을 제어하는 것에 대하여.
모델의 응답은 확률적이므로, 애플리케이션에서 응답의 스타일을 제어할 필요가 있다.
- 패턴 1: 로짓 마스킹 (Logit Masking)
- 패턴 2: 그래머 (Grammar)
일련의 규칙을 준수하는 텍스트 생성을 모델에 강제한다.
-
로짓 (Logit)
-
딥러닝 (Deep Learning)이나 통계학에서, "확률(0~1)로 변환되기 전, 모델이 계산한 가공되지 않은 출력값(Score)"을 의미함
-
텐서 (Tensor)
-
머신러닝 (Machine Learning)이나 딥러닝 (Deep Learning)에서, 데이터를 관리·계산하기 위한 "다차원 배열 (Multi-dimensional Array)"이라는 데이터 구조
LLM을 사용하여 텍스트 생성을 수행할 때, 특정 스타일 규칙을 따르도록 생성시키고 싶을 때 (브랜드 전략, 정확성, 스타일 등)
콘텐츠 생성 후, 관련 규칙에 따른 평가를 수행하여 기각 또는 재생성하는 방법.
이는 시행착오가 거의 필수적이며, 수렴하지 않을 가능성도 있음.
기반 모델은 계속되는 시퀀스의 후보로부터 샘플링(Sampling)하여 텍스트를 생성한다 (빔 서치 (Beam Search))
이 샘플링 단계에서 생성을 가로채는 이미지.
로짓 마스킹 (Logit Masking)의 기능
- 완전한 콘텐츠가 생성될 때까지 기다리지 않고, 각 중간 지점에서 후보가 되는 계속될 텍스트 세트를 취득
- 규칙을 만족하지 않는 계속될 텍스트 후보의 확률을 0으로 만듦
- 규칙을 만족하는 계속될 텍스트가 하나라도 있으면 생성을 계속
- 규칙을 만족하는 계속될 텍스트가 없어지거나 막다른 길임을 알게 되면 한 단계 후퇴하여 생성을 다시 시도
- 최대 시도 횟수를 초과한 경우, 규칙을 만족하는 콘텐츠를 생성할 수 없음을 사용자에게 전달
이하에 처리 흐름, 내부 기구의 포인트, 그리고 데이터 플로우(Data Flow)를 기술.
본 구현에서의 처리는 토크나이저 (Tokenizer)에 의한 ID 변환부터 시작하여, LLM의 추론, 로짓의 변형, 그리고 샘플링에 이르는 일련의 파이프라인으로 구성된다.
Input: 사용자가 입력한 문자열 (프롬프트 (Prompt)) -
처리: 토크나이저 (Tokenizer)에 의해, 문자열이 어휘 사전 (Vocabulary)에 대응하는 토큰 ID의 시퀀스 (텐서 (Tensor))로 변환 -
Output: 토큰 ID 배열 (형태: [1, sequence_length])
Input: 토큰 ID 배열 -
처리: 토큰 ID 배열이 LLM의 층을 순전파 (Forward Pass)합니다. 모델의 최종 선형층 (LM Head)에 의해, 다음 토큰 예측을 위한 미정규화된 로그 확률 (로짓 (Logit))이 계산됨 -
Output: 가공되지 않은 로짓 텐서 (형태: [1, vocabulary_size])
Input: 가공되지 않은 로짓 텐서, 및 허용(또는 금지)할 토큰 ID 리스트 -
처리:
- 어휘 수 (
vocabulary_size)와 동일한 크기의 마스크용 텐서를 초기화 - 생성을 허용하고 싶은 토큰 ID의 인덱스에 대해서는 변경을 가하지 않고, 배제하고 싶은 토큰 ID의 인덱스에 대해서는 음의 무한대 (통상적으로-float('inf')또는-1e9등과 같은 극단적으로 작은 음수 값)를 대입 - 가공되지 않은 로짓 텐서와 마스크용 텐서를 가산 (또는 요소별 요소 치환)
Output: 마스크 처리된 로짓 텐서 (형태: [1, vocabulary_size])
Input: 마스크 처리된 로짓 텐서 -
처리:
- 로짓 텐서에 대해 소프트맥스 (Softmax) 함수를 적용하여 확률 분포로 변환. 이때,
-inf가 대입된 인덱스의 확률은 수학적으로 $0$ ($e^{-\inf} = 0$)이 됨 - 확률이 $0$이 된 토큰은 샘플링 후보에서 완전히 배제되며, 남은 후보의 확률 총합이 $1$이 되도록 재정규화 - 변형된 확률 분포에 기반하여 다음 토큰 ID를 샘플링
Output: 결정된 다음 토큰 ID (형태: [1, 1])
Notebook에서의 기술적 요점
로짓에 직접 0을 곱하는 것이 아니라, -inf를 가산하는 접근 방식을 취합니다. 소프트맥스 (Softmax) 함수의 정의는 다음과 같습니다.
$$P(x_i) = \frac{e^{z_i}}{\sum_{j} e^{z_j}}$$
특정 인덱스 $i$의 로짓 (Logit) $z_i$를 $-\inf$로 설정함으로써, $e^{-\inf} = 0$이 되어 분자가 $0$이 되므로, 해당 토큰이 선택될 확률을 엄격하게 $0$으로 제어할 수 있다.
Notebook 내에서는 Hugging Face의 transformers 라이브러리가 제공하는 LogitsProcessor 클래스를 상속하여 커스텀 마스크 (Custom Mask)를 구현하고 있다.
__call__ 메서드 내에서 현재의 입력 ID (input_ids)와 생 로짓 (scores)을 받아, 인플레이스 (In-place) 또는 새로운 텐서 (Tensor)로서 마스크 처리된 로짓을 반환하는 구조로 되어 있으며, 이를 통해 model.generate()의 루프 처리 내부를 인터셉트 (Intercept) 하는 형태로 로짓 제어가 삽입된다.
# 시스템 프롬프트 (System Prompt)
당신은 영양 보충제 마케팅 담당자이다.
고객을 끌어들이는 제품 설명과, 검색 엔진 최적화(SEO) 및
...
게재가 금지될 가능성이 있는 단어가 생성 내용에 포함됨으로써, 비즈니스상의 리스크를 내포한 내용이 출력될 가능성이 있다.
이에 대해 로짓 마스킹 (Logit Masking)을 통해, 바람직한 특징을 가진 시퀀스 (Sequence)를 계속 채택함으로써 규칙을 만족하는 아웃풋 (Output)을 얻는다.
- 금지된 선택지를 제외하는 검열을 구현할 때 유용
- 대안
- 프롬프트 엔지니어링 (Prompt Engineering)을 통한 회피
- 기타 패턴의 적용
AI 자동 생성 콘텐츠
본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기