← Go Back
Artificial intelligence/LLM AILLM

How LLMs Work Internally

회사 업무, 개인 프로젝트, 문서 정리, 기술 공부 등 모든 일상에 LLM을 활용하고, 더 좋은 답변, 정확한 답변을 얻기 위한 다양한 기술들이 발전하고 있습니다. 프롬프트 엔지니어링, 하네스 엔지니어링, 이제는 멀티 에이전트까지 등장하며 프롬프트마저 LLM이 자체 생성하고 있습니다. 이러한 기술의 발전은 LLM의 어떤 부분을 타깃으로 튜닝되는지를 고민해보며 LLM의 내부 동작 원리를 정리하게 되었습니다.

LLM 내부 동작 원리 6단계

1. Tokenization - 모델은 글자를 모른다

사용자의 프롬프트를 LLM이 이해할 수 있는 최소 단위인 토큰(Token)으로 분리하고, 각 토큰에 고유한 ID를 매핑하는 단계

토큰화는 LLM이 문장을 이해하기 위해 의미 있는 최소 단위로 분리하는 과정입니다. 마치 우리가 문장을 읽을 때 단어 단위로 끊어 읽는 것과 비슷한데, LLM은 인식하지 못하는 새로운 단어가 등장하면 그 단어를 더 작은 단위로 쪼개어 해석합니다.

토큰화는 다음과 같은 과정으로 진행합니다.

  • “LLM의 내부 동작 원리”라는 문장은 [‘LLM’, ‘의’, ‘내부’, ‘동작’, ‘원리’, ’.’] 처럼 의미 있는 단위로 나뉩니다.
  • 각 토큰은 고유한 정수 ID에 매핑됩니다. (ex: [73, 12, 36, 63, 96, 91])

Gemini 모델은 토큰화를 위해 SentencePiece라는 토크나이저를 사용합니다. SentencePiece는 다음과 같은 특징이 있습니다.

  • 언어 중립적: 공백을 기준으로 단어를 나누지 않고, 문장을 유니코드 문자들의 연속으로 보고, 자주 함께 등장하는 글자들을 통계적으로 묶어 하나의 토큰으로 만듭니다.
  • 서브워드(Subword) 기반: 어휘 사전에 없는 새로운 단어나 긴 단어가 등장하면, 이를 더 작은 의미 단위(Subword)로 분해합니다.
    • 단어 단위로 자르면 오타, 신조어, 띄어쓰기 단어 등을 처리하지 못하고, 글자 단위로 자르면 시퀀스가 너무 길어집니다. CS229에서는 서브워드를 어휘 사전 크기와 시퀀스 길이의 타협점이라 정의합니다.
import sentencepiece as spm

# 훈련 데이터 준비
training_data = """제미나이는 구글이 개발한 인공지능 언어 모델입니다.
LLM 내부 동작 원리가 궁금하지 않나요?
LLM 내부 동작 원리를 함께 알아보아요
"""

with open("sample-data.txt", "w", encoding="utf-8") as f:
	f.write(training_data)
	
# 1. 토크나이저 모델 훈련
# SentencePiece 토크나이저 모델 훈련
# 'sample_tokenizer.model', 'sample_tokenizer.vocab' 파일이 생성
spm.SentencePieceTrainer.train(
    '--input=sample-data.txt '   # 훈련시킬 데이터 파일
    '--model_prefix=sample_tokenizer '   # 생성될 토크나이저 모델 파일의 이름
    '--vocab_size=133 '   # 단어 집합의 크기 (어휘의 총 개수)
    '--model_type=bpe'   # 토크나이저 모델 타입 (bpe, unigram ..)
)

# 2. 훈련된 토크나이저 모델로 토큰화 실행
sp = spm.SentencePieceProcessor()

# 훈련된 토크나이저 모델 파일 로드
sp.load('sample_tokenizer.model')

# 테스트할 문장
sentence1 = "나는 LLM 내부 동작 원리를 공부한다."

# 문장을 토큰으로 분리
# _(언더바) 기호는 띄어쓰기(공백)를 의미
tokens1 = sp.encode_as_pieces(sentence1)
print(tokens1)   # ['▁', '나', '는', '▁LLM', '▁내부', '▁동작', '▁원리를', '▁', '공', '부', '한', '다', '.']

# 문장을 정수 ID로 변환
ids1 = sp.encode_as_ids(sentence1)
print(ids1)   # [89, 93, 113, 11, 8, 9, 44, 89, 107, 97, 131, 116, 91]

# 정수 ID를 다시 문장으로 복원
decoded_sentence = sp.decode_ids(ids1)
print(decoded_sentence)   # 나는 LLM 내부 동작 원리를 공부한다.

SentencePieceTrainer.train() 함수는 훈련 데이터 파일을 통계적으로 분석해, 어떤 글자들을 하나의 토큰으로 묶을지 결정합니다. 이렇게 만들어진 규칙은 토크나이저 모델(.model)에 저장되며, 어휘 사전(.vocab)에는 생성된 토큰 목록과 각 토큰의 점수가 함께 기록됩니다.

  • 어휘 사전의 토큰 점수는 토크나이저 훈련 과정에서 빈도(해당 토큰이 얼마나 자주 등장하는지) 또는 우선순위(모델링 과정에서 해당 토큰이 얼마나 중요한지)를 기준으로 매겨집니다.
  • 여기서의 점수로그 확률(어떤 토큰이 등장할 확률을 로그 함수로 변환한 값) 또는 비용(토큰을 선택하는데 드는 비용)을 의미하고, 토크나이저가 텍스트를 분할할 때, 어떤 토큰 조합이 더 적합한지 판단하는 기준(가장 낮은 비용 (=가장 높은 확률))으로 사용합니다.
...
개발	-49
구글	-50
궁금	-51
내부	-52
동작	-53
리가	-54
리를	-55
...

그럼 LLM은 매 요청마다 사용자 입력을 토크나이저 훈련에 사용할까?

LLM의 토크나이저는 실시간으로 요청이 들어올 때마다 사용자 입력을 추가로 훈련시키지 않고, 훈련(Training)과 추론(Inference)이라는 두 단계로 명확하게 구분하여 동작합니다.

✅ Training Phase
  • 인공지능 언어 모델 개발사(Google, OpenAI 등)가 모델 생성 초기에 단 한 번, 대규모 데이터로 토크나이저를 학습시키는 단계
  • 이 과정에서 수십 테라바이트에 달하는 방대한 텍스트 데이터를 활용해 토크나이저를 학습시키고, 결과적으로 토크나이저 모델(.model) 과 어휘 사전(.vocab) 파일을 생성
✅ Inference Phase
  • 사용자가 질문을 할 때마다 일어나는 단계
  • LLM은 이미 만들어진 토크나이저를 단순히 메모리에 로드해서 사용하며, 사용자의 문장을 이 규칙에 따라 즉시 토큰으로 변환하고 응답을 생성

토크나이저 모델의 알고리즘

알고리즘특징대표적으로 사용되는 모델
BPE(Byte Pair Encoding)- 빈도수가 높은 문자 쌍을 점진적으로 병합
- Bottom-Up 방식
- 텍스트를 더 적은 수의 토큰으로 압축
- 영어와 같이 단어 경계가 명확한 언어에서 효율적
- 높은 압축 효율로 널리 사용
GPT, LLaMA, Gemini 등
ULM(Unigram Language Model)- 매우 큰 초기 어휘 집합에서 시작
- Top-Down 방식
중요도가 낮은 서브워드를 점차 제거
Google T5, mBART
BPE 기본 원리
  • 텍스트 내 모든 개별 문자를 초기 어휘로 설정
  • 현재 어휘로 구성된 텍스트에서 가장 자주 함께 등장하는 문자 쌍 찾기
  • 가장 빈번한 문자 쌍을 하나의 새로운 서브워드 토큰으로 병합 (ex: “l o w”에서 ‘o’와 ‘w’가 자주 나타나면 ‘ow’로 병합)
  • 새로운 토큰을 어휘에 추가하고, 미리 정의한 어휘 크기에 도달하거나 더 이상 병합할 유의미한 쌍이 없을때까지 이 과정을 반복

BPE는 이처럼 자주 쓰이는 단어는 긴 토큰으로 만들고, 희귀하거나 새로운 단어는 여러 짧은 토큰으로 분리합니다.

ULM 기본 원리
  • 매우 큰 초기 어휘 집합을 생성
  • 각 서브워드 토큰이 텍스트에 나타날 확률을 계산(해당 서브워드의 빈도수 기반)
  • 주어진 단어를 여러 서브워드로 분절할 수 있는 모든 가능한 경우의 수를 고려
    • 예를 들어, “unigram”이라는 단어가 있을 때, un + igram, uni + gram, u + ni + gram 등 다양한 분절이 가능한데, 이 중에서 가장 높은 확률을 가지는 분절 조합을 선택
  • 어휘 집합의 크기를 줄여나가는 과정에서는 전체 확률 분포에 미치는 영향이 가장 작은 서브워드를 제거하며, 미리 정해둔 vocab_size에 도달할 때까지 반복

ULM은 이처럼 확률을 기반으로 다양한 분절 조합을 평가해 최적의 토큰 분할을 찾습니다.

2. Embedding - 숫자에 의미 심기

토큰화된 정수 ID를 의미를 가진 다차원 공간의 좌표(벡터)로 변환하는 단계

임베딩은 단순히 숫자를 다른 숫자로 바꾸는 것이 아니라, 단어의 의미와 뉘앙스를 수치적으로 표현하는 핵심 과정입니다.

임베딩 결과, 각 토큰 ID(정수 ID)와 그에 대응하는 임베딩 벡터를 저장한 Embedding Table이라는 사전이 생성됩니다.

  • 예를 들어, ‘Jeans’라는 단어는 토큰화 과정을 거져 1423이라는 토큰 ID를 부여받고, 이 토큰 ID는 768차원의 좌표 [-0.2416, -0.0663, 0.4457, ...]로 저장됩니다.
  • 이러한 좌표값들은 방대한 데이터를 학습하는 과정에서 모델이 얻어낸 결과물입니다.

벡터 간의 거리는 의미론적 근접성(Semantic Proximity) 이라는 성질을 통해 단어들 사이의 관계를 수학적으로 이해하고 추론할 수 있게 해줍니다.

이 공간에서는 벡터 사이의 거리가 곧 의미의 거리가 됩니다. 자동차와 자전거는 ‘탈 것’이라는 공통점 때문에 가깝고, 자동차와 행복은 멀리 떨어져 있습니다. 코사인 유사도로 측정하면 대략 이런 값이 나옵니다.

'자동차' vs '자전거' → 0.8315   # 의미가 가까움
'자동차' vs '행복' → 0.1854   # 관련성 없음

하지만 임베딩 결과로 얻어지는 수백 차원의 벡터 공간은 우리가 직접 눈으로 확인하거나 직관적으로 상상하기 어렵습니다.

  • 이때 PCA(Principal Component Analysis, 주성분 분석) 와 같은 차원 축소 기술을 활용하면, 데이터의 가장 중요한 특징(주성분)만 남기고 수백 개의 차원을 2개의 숫자(x, y 좌표)로 압축할 수 있습니다.

3. Positional Encoding - 순서 알려주기

LLM의 핵심인 Attention 메커니즘(문장 속에서 어떤 단어가 다른 단어에 얼마나 영향을 미치는지 수치화하여 문맥을 정확하게 파악)은 문장 내 단어들의 관계를 파악하는데 매우 뛰어납니다.

  • 예시로, “나는 사과(과일)를 먹었다.” 문장과 “나는 너에게 사과(용서)했다.” 문장의 문맥을 파악할 수 있습니다.

하지만 어떤 단어가 먼저 나왔는지, 즉 순서를 알지 못한다는 단점이 있습니다. 이 때문에 “고양이가 강아지를 이겼다”“강아지가 고양이를 이겼다”를 구분하지 못하는 문제가 발생합니다.

Positional Encoding은 이 문제를 해결하기 위해 각 단어의 순서 정보를 담은 고유한 벡터를 만들어 단어의 임베딩 벡터에 더해주는 단계입니다.

최종 입력 벡터 = Word Embedding Vector(의미 벡터; 2단계 임베딩 결과)+ Positional Encoding Vector(순서 벡터)

✅ 위치마다 고유한 벡터를 만드는 법

원 논문의 고전적 방식은 sin/cos 함수를 사용합니다.

PE(pos, 2i)   = sin(pos / 10000^(2i / d_model))   # 짝수 차원
PE(pos, 2i+1) = cos(pos / 10000^(2i / d_model))   # 홀수 차원

d_model : 임베딩 벡터의 총 차원 수
pos     : 시퀀스 내 위치
i       : 차원 인덱스

위치마다 서로 다른 주파수의 파형이 생기므로, 각 위치가 고유한 지문을 갖게 되는 구조입니다

고양이가 소파 위에서 잠을 잡니다.

   [0.6525 0.266 0.5645 0.7149 0.6867 ...] ('고양이' 의미 벡터)
+  [0 1 0 1 0 ...] (0번째 위치 벡터)
----------------------------------------------------------------
   [0.6525 1.266 0.5645 1.7149 0.6867 ...] ('고양이'의 최종 임베딩)

   [0.8779 0.2883 0.0404 0.0478 0.6339 ...] ('잠을' 의미 벡터)
+  [-0.7568 -0.6536 -0.6572 -0.7537 -0.5486 ...] (3번째 위치 벡터)
----------------------------------------------------------------
   [ 0.1211 -0.3653 -0.6168 -0.7059 0.0853 ...] ('잠을'의 최종 임베딩)

최신 모델은 조금 다릅니다. 요즘 모델(Llama, Gemini 계열 등)은 절대 위치를 더하는 대신 RoPE(Rotary Positional Embedding) 처럼 벡터를 회전시켜 상대적 위치 관계를 인코딩하는 방식을 씁니다. 학습 때보다 긴 문맥으로 확장하기 유리하기 때문이며, 컨텍스트 윈도우가 계속 늘어나는 이유 중 하나입니다.

4. Transformer & Attention - 문맥 이해하기

Transformer는 데이터를 어떻게 처리할지 정의하는 신경망 구조이고, Attention은 그 안에서 문맥을 파악하는 메커니즘입니다.

Transformer
  • 훈련 단계에서 이 구조를 사용해 대규모 데이터로 모델을 학습
  • 문장 전체의 단어들을 한 번에 병렬로 처리하여 빠른 학습이 가능
Attention

문장 속에서 어떤 토큰이 다른 토큰에 얼마나 영향을 미치는지를 수치화 하는 단계

  • 문장 내 모든 단어들 간의 관련도에 집중함으로서, 복잡하 문맥과 다의어를 더 정확하게 이해
  • 문장이 길어져도 멀리 떨어진 단어들 사이의 관계를 효과적으로 파악 (Q, K, V)

영어를 한국어로 번역하는 것에서 예시를 들면, “나는 그녀를 사랑한다” - “I love her” 예시에서, ‘나는’이라는 주체가 Query, 연관성을 찾는 대상인 I, love, her이 Key, Q와 K 의 유사도 값인 Value가 생깁니다. Q, K, V는 단순한 스칼라가 아니라 벡터이고, 출력도 마찬가지로 벡터입니다.

Attention의 수식은 다음과 같습니다.

Attention(Q,K,V)=softmax(QKTdk)VAttention(Q,K,V) = softmax\left(\frac{QK^T}{\sqrt{d_k}}\right)V

Attention Is All You Need 논문에서 Transformer는 인코더디코더라는 두 가지 주요 블록으로 구성되어 있으며, 각 블록 안에는 핵심 구성 요소인 셀프 어텐션(Self-Attention) 메커니즘피드 포워드 신경망(Feed-Forward Neural Network, FFN)이 반복적으로 나타납니다.

인코더 레이어

입력 텍스트를 모델이 이해할 수 있는 내부 표현으로 변환하는 역할을 합니다.

입력 단계
  • Input Embedding 벡터와 Positional Encoding 벡터를 더해 최종 입력 벡터를 생성합니다.
인코딩
  • Multi-Head Attention: 입력 문장 내의 모든 단어(토큰)가 서로에게 얼마나 집중해야 하는지, 즉 서로 간의 관계를 계산

    • “나는 사과를 먹었다” vs “나는 너에게 사과했다” → 주변 토큰과의 관계를 통해 다의어를 구분 / “그가 물을 마셨다” → 가 마셨다물을에 더 집중해야 함을 학습
    • Multi-Head란, 여러 개의 독립적인 헤드(Attention 구조)가 동시에 다양한 관점에서 관계(주어-동사, 명사-형용사 등)를 파악하고, 그 결과를 결합하는 것
  • Feed-Forward Neural Network: 어텐션 레이어를 통과한 벡터(문맥 정보가 반영된 단어 표현)를 받아, 각 단어의 벡터를 독립적이고 비선형적으로 변환하여 더 풍부하고 복잡한 특징 표현을 생성 합니다.

디코더 레이어

인코더에서 변환된 정보를 바탕으로 새로운 텍스트를 생성하는 역할을 합니다.

입력 단계
  • Outputs: 생성될 문장의 시작을 알리는 특수 토큰(BOS (beginning of sequence))과 이미 생성된 단어들(이전에 디코더가 생성한 단어)을 입력으로 삽입합니다.

    • ex) ‘나는’을 이미 생성했다면, 다음 단어를 예측할 때 “[BOS]나는”을 입력으로 사용
  • shifted right: 훈련 시 정답 시퀀스를 한 칸 뒤로 밀어 넣어, 현재 시점의 단어를 예측할 때 미래의 단어를 볼 수 없도록 하는 방식

    • ex) 정답 시퀀스가 [A, B, C]라면 디코더의 입력은 [시작토큰, A, B]가 되고, 디코더는 각 시점에서 다음 단어[B, C, 종료토큰]를 예측
    • 모델이 지금까지 생성된 단어만 보고 다음 단어를 예측하도록 훈련
디코딩
  • Masked Multi-Head Attention: 디코더는 단어를 생성하는 역할을 하므로, 현재 단어를 예측할 때 아직 생성되지 않은 미래의 단어를 참조할 수 없도록 해야합니다.

    • 여기서 Masked는 미래 단어에 대한 Attention 점수를 0으로 만들어 참조하지 못하게 하는 것을 의미합니다. (치팅 방지)
    • 이 외의 작동 방식은 인코더의 Multi-Head Attention과 유사
  • Multi-Head Attention: 인코더의 출력디코더의 Masked Attention의 출력을 동시을 동시에 참조합니다.

  • Feed-Forward Neural Network: 앞선 두 어텐션 레이어의 출력을 받아 각 단어별 특징을 강화합니다.

출력 단계
  • Linear: 디코더 레이어의 최종 출력(각 토큰별로 의미와 문맥이 반영된 고차원 벡터)을 모델의 전체 단어 개수(어휘 사전 크기)만큼의 차원을 가진 벡터로 변환합니다.

    • 디코더의 최종 출력이 [10, 768] 형태(10개 토큰, 768차원 벡터)라면, Linear 레이어를 거쳐 [10, 50000] 처럼 모델 전체 단어 개수만큼의 차원으로 변환
    • 디코더가 생성한 각 단어의 특징 벡터를 모델이 알고 있는 모든 단어 각각에 대해 다음 단어로 등장할 가능성 점수(Logits) 계산
  • Softmax: Linear 단계에서 계산된 점수를 확률(Output Probabilities)로 변환합니다.

    • 가장 높은 확률을 가진 단어가 최종 출력으로 선택
+ Add & Norm
  • Add(잔차 연결): 이전 레이어의 입력 값을 현재 레이어의 출력 값에 더하는 방식
    • 신경망이 여러 층을 거치면서 정보가 소실되거나 왜곡되는 문제를 감소
    • 중요한 정보가 다음 단계로 잘 전달됨. 성능 및 학습 안정성 향상
  • Norm(레이어 정규화): 신경망의 각 레이어 출력값을 평균 0, 분산 1로 맞추어 데이터 분포를 정규화하는 기법
    • 값이 너무 크거나 작아지는 현상을 방지하고, 모든 레이어가 비슷한 분포의 데이터를 처리할 수 있어 학습이 더 안정적이고 빠르게 진행
    • 즉, 신경망이 각 레이어에서 일관된 데이터 분포를 유지하도록 도와주는 단계

요약하면, Transformer는 기본적으로 Self-Attention 메커니즘으로 문맥 관계를 파악하고, Feed-Forward Neural Network로 각 단어의 표현을 정제하고 강화하는 과정을 반복하며 텍스트를 이해하고 생성합니다.

5. Prediction - 다음 단어 예측

문맥을 파악한 최종 벡터를 바탕으로 다음에 올 확률이 가장 높은 단어(토큰)을 예측하는 단계

위의 4단계를 거쳐 문맥이 반영된 최종 벡터가 준비되면, 모델은 “그래서 다음에 올 단어는?”에 답하게 됩니다. 이 단계가 확률 계산샘플링 두 부분으로 나뉩니다.

확률 계산

LLM은 자신이 알고 있는 수만 개의 모든 단어(토큰)를 후보로 올려놓고, 다음에 등장할 확률을 각각 계산합니다. 이 과정은 Transformer에서 설명한 디코더 레이어의 출력 단계(Linear → Softmax)를 거쳐 나온 결과입니다.

  • Linear: 최종 벡터를 어휘 사전 크기만큼의 차원으로 변환합니다. 이 값이 Logits, 즉 각 토큰이 다음에 올 가능성 점수입니다.
  • Softmax: Logits를 확률(%)로 변환하며, 모든 단어의 확률을 합하면 1(100%)이 됩니다.

이제 모델은 “다음에 ‘매우’가 올 확률은 15%(0.15), ‘복잡’이 올 확률은 12%(0.12)…” 와 같은 확률 분포표를 갖게 됩니다.

이렇게 모델이 각 토큰의 확률을 계산한 뒤, Temperature로 확률 분포를 조절하고, 변화된 확률 분포를 기반으로 샘플링 전략을 사용해 최종적으로 토큰을 선택하게 됩니다.

Temperature

  • Softmax를 적용하기 전에 Logits를 온도 T로 나누어 분포 자체를 조절합니다.
T = 1

Temperature 매개변수가 적용되지 않았기에 원래 점수와 동일합니다.

T > 1

높은 Temperature 매개변수가 적용되면, 가장 높은 확률을 가진 단어의 확률은 낮아지고, 다른 단어들의 확률은 상대적으로 높아지면서, 모델이 다양하고 예측 불가능한 단어를 선택할 가능성이 높아져 창의적인 출력을 생성합니다.

반면, Temperature 가 너무 높으면 문맥과 관련 없는 단어가 선택되어 텍스트의 일관성이 떨어질 수 있습니다.

T < 1

낮은 Temperature 매개변수가 적용되면, 가장 높은 확률을 가진 단어의 확률은 더 높아지고, 다른 단어들의 확률은 더 낮아지면서, 모델이 가장 확실한 선택을 하도록 유도하여 보수적이고 반복적인 출력을 생성할 가능성이 높아집니다.

Sampling

가장 확률이 높은 단어만 계속 선택하면 매우 예측 가능하고 지루한 문장이 생성되므로, LLM은 더 창의적인 문장을 만들기 위해 다양한 샘플링 전략을 사용합니다.

무조건 확률 1등 단어만 선택

Top-K Sampling

확률 순위가 높은 상위 K개(ex: 3개)의 단어들 중 확률에 따라 선택

전체 어휘가 아닌, 확률이 가장 높은 K개의 단어 중에서만 샘플링하므로 다양성을 어느 정도 유지하면서도 엉뚱한 단어가 나오는 것을 방지합니다.

K값 설정에 따라 출력 품질이 크게 변화되고, K값이 너무 작으면 선택 가능한 단어의 폭이 좁아져 특정 구절이나 단어가 반복될 수 있습니다.

Top-P Sampling

누적 확률이 P(ex: 70%)가 될 때까지 상위권 단어들을 후보로 올리고, 후보에 올라온 단어들 중 확률에 따라 선택

문맥에 따라 동적으로 선택할 단어의 수를 조절하고, 누적 확률을 기준으로 단어를 선택하기 때문에, 다양한 단어가 나올 수 있는 확률의 핵심 영역에 집중하여 더 자연스러운 다양성을 보장합니다.

최적의 P값을 찾는 것이 어려울 수 있으며, P값이 너무 높으면 Top-K와 마찬가지로 관련성 없는 단어가 선택되어 일관성이 떨어질 가능성이 있습니다.

6. Loop & Decoding - 생성 반복

예측된 토큰을 다시 입력값에 추가한 뒤, 4~6단계를 반복하여 다음 단어를 계속 생성합니다.

이 과정을 자동 회귀(Autoregressive)라고 하며, 이 반복을 통해 최종적으로 완성된 문장을 사용자에게 반환합니다.

Loop
  1. 예측(Predict): 현재까지의 문장을 보고 다음 단어 하나를 예측 (5단계 과정)
    • LLM의 내부 동작 원리는 → 매우
  2. 추가(Append): 예측된 단어를 원래 문장 끝에 이어 붙여 새로운 입력 값을 생성
    • 새로운 입력: LLM의 내부 동작 원리는 매우
  3. 반복(Loop): 길어진 문장을 가지고 다시 1번으로 돌아가 다음 단어를 예측
    • LLM의 내부 동작 원리는 매우 → 복잡
    • 새로운 입력: LLM의 내부 동작 원리는 매우 복잡
    • LLM의 내부 동작 원리는 매우 복잡 → 하지만

‘Predict-Append-Loop’ 루프는 다음 두 가지 조건 중 하나를 만족할 때까지 반복됩니다.

  • [EOS] 토큰 등장: 모델이 문장의 끝을 의미하는 특수 토큰(End-Of-Sentence)을 생성할 때
  • 최대 길이 도달: 미리 설정한 최대 단어 개수(예: 100개)에 도달할 때
Decoding

루프가 모두 끝나고 최종적으로 생성된 정수 ID들의 배열 [3141, 912, 114, ...]을 사람이 읽을 수 있는 하나의 완성된 텍스트로 다시 변환하는 과정입니다.

참고로, 지금까지의 예시는 이해를 위해 한글로 설명했지만, 실제 내부 동작에서는 2~6단계의 디코딩 직전까지 모든 과정이 정수 ID(토큰 ID)를 기반으로 처리됩니다.

LLM 내부 동작원리 활용 프롬프팅 최적화

위의 동작원리를 위해하면, LLM을 프로그래밍 가능한 언어 인터페이스로 활용할 수 있습니다.

1. 풍부하고 구체적인 컨텍스트 제공

“코드에 에러가 나” 보다는 “Spring Boot 3.1.5 버전에서 JPA를 사용 중인데, NullPointerException이 발생했습니다. 아래는 관련 코드와 에러 로그입니다.” 처럼 구체적인 정보를 제공하면 Attention 효율을 높일 수 있습니다.

2. 예시를 통한 출력 유도

원하는 결과물의 예시를 한 두 개 보여주면, LLM이 출력 형식을 더 정확하게 학습합니다. 이는 모델 전체를 재학습시키는 것이 아니라, 특정 요청에 대한 Attention 가중치를 효과적으로 유도하는 방법입니다.

3. 명확한 역할과 형식 지정

프롬프트 시작에 “당신은 10년 차 백엔드 개발자입니다. Kotlin Spring 코드로 답변해 주세요.” 와 같이 역할을 부여하면, Prediction 단계에서 모델이 선택할 단어의 범위를 효과적으로 좁혀줍니다.

4. 복잡한 작업은 단계별로 분해

하나의 거대한 프롬프트는 정밀도가 떨어집니다. “A 데이터를 분석해서, 그래프를 그리고, 보고서를 써줘” 보다는, 1. A 데이터를 분석해줘 → 피드백 → 2. 분석 결과를 바탕으로 막대그래프를 그리는 Python 코드를 작성해줘 → 피드백 → 3. 위 내용을 종합해서 보고서 초안을 작성해줘 식으로 작업을 나누어 요청하는 것이 훨씬 효과적입니다.

5. 부정문 대신 긍정문을로 지시

“Json 형식 외에는 출력하지 마” 보다는 “반드시 RFC 8259 표준을 준수하는 JSON 형식으로만 출력해줘” 처럼 긍정적이고 명확한 지시가 완성도 높은 결과를 만듭니다.

6. 결과를 비판적으로 검토하고 피드백

4번 내용과 같이, 대화 사이사이에 답변에 대한 피드백을 주며 이어나가면 Loop 과정을 사용자가 직접 제어하며 원하는 결과로 유도하는 효과를 만들 수 있습니다.

LLM 내부 동작 6단계 요약

단계핵심 동작
1단계: Tokenization입력 문장을 의미 있는 최소 단위로 분리하고, 각 토큰에 고유한 정수 ID를 할당
2단계: Embedding토큰 ID를 의미와 문맥을 담은 고차원 벡터로 변환
3단계: Positional Encoding각 단어의 순서 정보를 벡터에 더해 위치를 인식
4단계: Transformer & Attention문맥을 파악하고, 각 단어의 표현을 정교하게 다듬기
5단계: Prediction다음에 올 토큰의 확률을 계산하고, 최적의 토큰을 선택
6단계: Loop & Decoding예측된 토큰을 반복적으로 입력에 추가해 문장을 완성

결론

그래서 처음 했던 고민(“이러한 기술의 발전은 LLM의 어떤 부분을 타깃으로 튜닝되는가”)에 대한 답이 뭐냐면, Transformer 자체의 Self-Attention 구조를 코드 레벨에서 바꿀 수 없다 보니, 어텐션 메커니즘이 가장 선명하고 정확한 정보만 바라보도록 렌즈를 맞춰주는 작업(Prompt/RAG)과 어텐션의 한 번의 계산으로 부족한 부분을 여러 번 나누어 처리하도록 궤적을 만들어주는 작업(Multi-Agent)으로 최적화가 이루어지고 있다고 합니다.

Reference

Comments

Loading comments…

← Go Back