LLM 동작 원리 알아보기
0. 왜?
LLM의 동작 원리를 이해하면, 단순 사용을 넘어서 원하는 결과가 잘 나오지 않는 원인을 분석하거나, 특정 목적에 맞게 커스터마이징할 기준을 세울 수 있는 실질적인 역량을 키울 수 있다.
1. 개요
대규모 언어 모델(LLM, Large Language Model)은 딥러닝 기술을 기반으로 방대한 텍스트 데이터를 통해 언어의 의미와 맥락을 학습하여 자연어 처리(NLP) 작업을 수행하는 인공지능 모델이다.
초기의 NLP 연구는 기계 번역(Machine Translation)과 같은 특정 작업을 수행하기 위해 발전하였다. 특히 2010년대 초반에는 RNN(Recurrent Neural Network)을 활용한 번역 모델이 개발되었고, 이는 문맥 파악 능력을 기반으로 기계 번역의 품질을 획기적으로 개선하였다.
이후 Transformer 모델이 2017년 구글의 “Attention is All You Need” 논문에서 제안되면서, 자연어 처리 성능과 효율성이 크게 향상되었다. Transformer 기반 모델은 초기 번역 목적으로 개발되었으나, 텍스트 분류, 문장 생성, 질의응답 등 다양한 분야에 적용 가능성을 보이며 점차 범용성을 확보하게 되었다.
최근에는 GPT 시리즈(GPT-3, GPT-4)와 같은 모델이 등장하여 언어 이해와 생성 능력이 더욱 정교해졌으며, 광범위한 응용 분야에 걸쳐 활용되고 있다.
2. LLM 모델별 활용과 특성
주요 모델 비교
- RNN (Recurrent Neural Network): 시간적 순서가 있는 데이터를 순차적으로 처리하며, 이전 단계의 출력을 현재 입력의 일부로 활용
- CNN (Convolutional Neural Network): 주로 이미지와 같은 공간적 데이터를 처리할 때 사용되며, 필터를 통해 지역적(local) 특징을 추출
- Transformer: Self-attention 메커니즘을 이용해 데이터를 병렬로 처리
| 분류 | 활용 분야 | 장점 | 단점 |
|---|---|---|---|
| RNN | 순차 데이터 처리 | • 순차 데이터 처리 용이 • 간단한 구조 | • 장기 의존성 문제 • 병렬 처리 어려움 |
| CNN | 이미지, 공간적 데이터 처리 | • 공간적 정보 활용 우수 • 병렬 처리 가능 | • 순차 데이터 모델링에 제한적 |
| Transformer | 병렬처리, 장거리 의존성 모델링 | • 장거리 의존성 포착 우수 • 병렬 처리로 효율적 학습 가능 | • 계산량 및 메모리 사용량 많음 |
RNN의 처리 방법 예시
예시 문장: “I am a student”
RNN은 단어를 시퀀스 순서대로 처리하여 이전 단어의 정보를 다음 단어 처리 시 참조한다.
입력 단계
각 단어는 단어 임베딩(Embedding)을 통해 숫자 벡터 형태로 변환된다.
처리 단계
- “I” → RNN 셀은 입력 “I”의 임베딩 벡터를 처리하여 은닉 상태(Hidden state)를 출력한다.
- “am” → 이전 단계의 은닉 상태를 입력으로 받아 “am”의 임베딩 벡터와 함께 처리하여 새로운 은닉 상태를 출력한다.
- “a” → 이전 은닉 상태를 이어받아 처리한다.
- “student” → 마지막으로 이전 은닉 상태와 함께 처리한다.
출력 단계
최종적으로 생성된 은닉 상태는 문장의 의미를 요약한 벡터 표현(Sentence embedding)으로 활용된다.
CNN의 처리 방법 예시
예시 문장: “I am a student”
CNN은 문장을 공간적인 데이터로 간주하여 필터를 통해 지역적인 패턴을 추출하는 방식으로 처리한다.
입력 단계
문장을 단어 임베딩을 통해 숫자 벡터로 변환한 후, 행렬 형태로 표현한다. 예를 들어, 4개의 단어가 있고 각 단어를 5차원 임베딩으로 나타낸다면, 문장은 (4 × 5)의 행렬이 된다.
처리 단계
- 필터(filter)가 단어들을 순차적으로 윈도우(window) 크기만큼 슬라이딩하면서 문장의 일부를 추출한다. (예: “I am”, “am a”, “a student”)
- 각 부분의 특징(feature)을 뽑기 위해 필터와 해당 단어 벡터들의 내적(dot product)을 수행한다.
- 여러 개의 필터를 사용해 다양한 특징을 추출한다.
출력 단계
특징들을 풀링(pooling)하여 최종적으로 문장의 요약된 특징 벡터를 얻는다.
Transformer의 처리 방법 예시
예시 문장: “I am a student”
Transformer는 RNN과 달리 각 단어를 순차적으로 처리하지 않고, 전체 문장을 한 번에 입력하여 Self-Attention을 통해 단어 간 상호 연관성을 계산한다.
입력 단계
- 각 단어는 임베딩을 통해 벡터로 변환되고, 위치 임베딩(Positional embedding)을 추가하여 단어의 위치 정보를 포함시킨다.
- 예: “I”, “am”, “a”, “student” 각각은 고유한 벡터로 표현되며, 각 벡터에 위치 정보를 더해 입력 행렬로 표현한다.
처리 단계
- Self-attention 계산
- Multi-head Attention
- Feed-forward network
- 정규화
출력 단계
최종적으로 얻어진 각 단어의 표현은 전체 문장에 대한 맥락적 의미를 담고 있으며, 문장 분류, 번역, 문장 생성 등에 사용된다.
3. Transformer 모델의 구조와 동작 원리 이해하기
Transformer는 Encoder-Decoder 구조로 이루어져 있으며, 두 부분은 각각 여러 개의 블록(layer)로 구성됩니다.
입력 문장 → [Encoder] → 문맥 정보 → [Decoder] → 출력 문장
3.1 문장을 숫자로 변환하는 단계 (Tokenization & Embedding)
목표: 텍스트 데이터를 모델이 이해할 수 있는 숫자(벡터)로 바꿈
동작:
- “나는 피자를 좋아해” → [‘나’, ‘는’, ‘피자’, ‘를’, ‘좋아해’]
- 각 단어를 고정 길이의 Embedding Vector로 변환
- 출력: Tensor of shape (seq_len, embedding_dim)
Embedding Vector
Embedding Vector는 단어나 문장 등의 개체를 고차원 공간의 실수 벡터로 표현한 것입니다. 벡터들 간의 내적(dot product)을 계산하면, 의미적으로 관련 있는 것들일수록 값이 커지는 경향이 있습니다.
Embedding Vector의 각 요소에 대한 의미
다음은 설명을 위한 단순화된 예시입니다.
예시 단어: “King”, “Queen”, “Man”, “Woman”
| 단어 | Embedding Vector (5차원 예시) |
|---|---|
| king | [0.8, 0.2, 0.9, 0.1, 0.7] |
| queen | [0.8, 0.2, 0.9, 0.1, 0.3] |
| man | [0.6, 0.1, 0.8, 0.2, 0.9] |
| woman | [0.6, 0.1, 0.8, 0.2, 0.2] |
이 벡터에서 각 차원이 다음과 같은 의미를 잠재적으로 갖고 있다고 가정해볼 수 있습니다:
| 차원 번호 | 의미 |
|---|---|
| 1 | 사회적 지위 정도 |
| 2 | 연령대 성향 |
| 3 | 리더십/권한의 정도 |
| 4 | 감정 표현 강도 |
| 5 | 성별 (남성: 1.0, 여성: 0.0 가깝게) |
“king”과 “queen”은 대부분의 차원에서 유사하지만, 5번 차원(성별 관련 가정된 요소)에서 차이를 보입니다.
“man”과 “woman”도 동일한 패턴을 보입니다.
이 구조는 king - man + woman ≈ queen 과 같은 의미 추론이 가능한 이유를 보여줍니다.
Tensor
Tensor는 스칼라(0차원), 벡터(1차원), 행렬(2차원), 고차원 배열(3차원 이상)을 일반화한 데이터와 파라미터를 표현하는 기본 단위입니다.
Tensor의 주요 요소
| 요소 | 설명 | 예시 | 중요도 | 관련 키워드 |
|---|---|---|---|---|
| Rank | 텐서가 몇 차원을 가지는지 나타냄 | 2 (e.g. [batch, hidden]) | 높음 | shape, 차원 |
| Shape | 각 차원에서의 크기를 나타냄 | (32, 128, 512) | 매우 높음 | batch size, seq length |
| Data Type | 텐서의 데이터 타입 | float32, float16, bfloat16 | 중간 | precision, memory |
| Device | 텐서가 저장/연산되는 장치 | cpu, cuda:0 | 높음 | GPU, acceleration |
| Requires Grad | 역전파 시 gradient 계산이 필요한지 여부 | True, False | 높음 | 학습, backpropagation |
| Storage Format | 메모리에 저장되는 방식 (희소/밀집 등) | Dense, Sparse | 낮음 | 희소 행렬, 효율적 메모리 사용 |
| Broadcast 가능여부 | 다른 텐서와 shape이 달라도 연산이 가능한지 여부 | 예: (1, 128, 512) + (32, 128, 512) | 중간 | 연산 호환성, 어텐션 연산 |
Tensor의 성질들은 Transformer의 다양한 연산을 정확하게 수행하는데 필수적인 요소들입니다. Tensor가 어떻게 구성되고 처리되는지를 이해하는 것이 모델의 디버깅, 최적화, 커스터마이징에 큰 도움이 되기 때문에, Tensor의 기본 성질을 알아두면 좋습니다.
3.2 단어의 순서를 알려주는 단계 (Positional Encoding)
문제: Transformer는 순서를 모름 (RNN과 달리 구조적으로 순서가 없음)
해결: 입력 벡터에 위치 정보를 더함 (“순서 감각” 부여)
동작:
- 각 단어에 위치에 따른 고유한 벡터를 더함
- 사인(sin), 코사인(cos) 함수로 계산된 값 사용
- “피자를”이 “나는”보다 뒤에 있다는 정보 포함됨
Positional Encoding이 필요한 이유
트랜스포머는 모든 단어를 동시에(병렬로) 처리하기 때문에 단어의 순서 정보가 모델에 자연스럽게 전달되지 않습니다. 이를 해결하기 위해 Positional Encoding을 사용합니다.
수식
\[PE_{(pos, 2i)} = \sin\left(\frac{pos}{10000^{\frac{2i}{d}}}\right)\] \[PE_{(pos, 2i+1)} = \cos\left(\frac{pos}{10000^{\frac{2i}{d}}}\right)\]pos: 단어의 위치 (0부터 시작)i: 임베딩 차원의 인덱스d: 전체 임베딩 벡터의 차원
짝수 인덱스에는 sin, 홀수 인덱스에는 cos 함수가 적용되어 위치마다 고유한 벡터가 생성됩니다.
수식 예시
pos = 0,d = 4일 경우
pos = 1,d = 4일 경우
대략적으로 계산하면,
\[PE_{(1)} \approx [\sin(1),\, \cos(1),\, \sin(0.01),\, \cos(0.01)] \approx [0.841,\, 0.540,\, 0.010,\, 0.999]\]Positional Encoding의 패턴 시각화
각 행은 하나의 벡터에 대한 positional encoding에 해당합니다. 그러므로 첫 번째 행은 우리가 입력 문장의 첫 번째 단어의 embedding 벡터에 더할 positional encoding 벡터입니다. 각 행은 사이즈 512인 즉 512개의 셀을 가진 벡터이며 각 셀의 값은 1과 -1 사이를 가집니다. 다음 그림에서는 이 셀들의 값들에 대해 색깔을 다르게 나타내어 positional encoding 벡터들이 가지는 패턴을 볼 수 있도록 시각화한 모습입니다.
3.3 서로의 관계를 파악하는 단계 (Self-Attention)
핵심: 문장 내 단어들이 서로를 얼마나 참고해야 하는지 결정
동작:
- 각 단어에서 Query, Key, Value 생성
- Query와 다른 단어들의 Key와 내적 → 유사도 측정
- softmax → 가중치 계산 → Value와 Weighted Sum
- 예: “좋아해”가 “피자”를 더 많이 참고하게 됨
내적(dot product)으로 유사도 계산하기
내적(dot product)은 두 벡터가 얼마나 같은 방향을 향하는지(유사도)를 나타냅니다.
단어 시퀀스: “I like pizza.”
Transformer에서 각 단어는 임베딩 및 선형 변환을 통해 Query (Q)와 Key (K) 벡터로 변환됩니다.
| 단어 | Query Vector (Q) | Key Vector (K) |
|---|---|---|
| “like” | [1.0, 0.5, 0.0] | - |
| “I” | - | [0.9, 0.4, 0.1] |
| “pizza” | - | [0.2, 0.1, 0.7] |
이제 “like”이 다른 단어(“I”, “pizza”)와 얼마나 관련 있는지를 Q·K^T 내적으로 계산합니다:
1. like vs I:
1
(1.0 × 0.9) + (0.5 × 0.4) + (0.0 × 0.1) = 0.9 + 0.2 + 0.0 = 1.1
2. like vs pizza:
1
(1.0 × 0.2) + (0.5 × 0.1) + (0.0 × 0.7) = 0.2 + 0.05 + 0.0 = 0.25
해석:
- “like”는 문장 내에서 “I”와 더 밀접한 관계를 가지므로 내적 값 1.1이 더 큽니다.
- “pizza”와는 관련은 있지만 상대적으로 약해 내적 값이 작게(0.25) 나옵니다.
결과:
- 유사할수록(관련될수록) 내적 값이 커지며, 해당 단어가 문맥에 더 중요한 정보로 반영됩니다.
Softmax
Softmax는 벡터의 값을 확률처럼 0~1 사이로 정규화해주는 함수로, 출력값의 총합이 1이 되도록 만듭니다.
Softmax 상세 내용
주어진 벡터 z=[z1, z2, …, zn]에 대해 Softmax는 다음과 같이 계산됩니다.
\[\text{softmax}(z_i) = \frac{e^{z_i}}{\sum_{j=1}^{n} e^{z_j}}\]- Exponential 함수를 사용해 값을 양수로 만들고
- 전체 합이 1이 되도록 정규화하여
- 각 원소를 확률 분포처럼 해석 가능하게 만듭니다.
| 특성 | 설명 |
|---|---|
| 출력값은 모두 0~1 사이 | 확률처럼 해석 가능함 |
| 출력값의 총합은 항상 1 | 분포의 개념으로 표현됨 |
| 큰 입력값은 더 강조됨 | 지수함수 때문에 차이가 확대됨 |
| 입력값에 상대적인 차이가 중요 | 값 자체보다는 값들 사이의 상대 차이가 가중치 결정 |
예시 계산:
내적 계산:
- like vs I: Q * K^T = 1.1
- like vs pizza: Q * K^T = 0.25
Softmax 함수를 통해 이 두 값을 정규화하면 각 단어에 대해 얼마나 “주의(attention)”할지를 알 수 있습니다.
- 지수함수 적용: e^1.1 ≈ 3.004, e^0.25 ≈ 1.284
- 분모 계산: sum = 3.004 + 1.284 = 4.288
- Softmax 결과 계산:
- like vs I: Softmax(1.1) = 3.004 / 4.288 ≈ 0.701
- like vs pizza: Softmax(0.25) = 1.284 / 4.288 ≈ 0.299
결과: “like”는 “I”에 약 70.1%의 Attention을 주고, “pizza”에는 약 29.9%의 Attention을 줍니다.
Self-Attention 메커니즘
Self-Attention은 입력 시퀀스 내의 각 토큰이 다른 모든 토큰을 참고하여 문맥을 반영하는 표현을 만드는 메커니즘입니다. Transformer에서 핵심 역할을 하며, 단어들 간의 관계(의미/문법/위치 등)를 내적 기반의 유사도 계산을 통해 파악합니다.
핵심 아이디어
기존 RNN은 단어를 순차적으로 처리했지만, Self-Attention은 모든 단어를 동시에 비교하고 연관된 정보를 종합할 수 있습니다.
계산 단계 (단일 head 기준):
입력: 각 단어의 임베딩 → [x₁, x₂, ..., xₙ]
1. 선형 변환으로 Q, K, V 생성
\[Q = XW_Q, \quad K = XW_K, \quad V = XW_V\]| 항목 | 내용 |
|---|---|
| Q (Query) | “내가 주목하려는 기준” |
| K (Key) | “다른 단어들의 정보” |
| V (Value) | “실제 전달할 정보” |
2. Query와 Key의 내적 → 유사도(Attention Score) 계산
\[\text{score}_{i,j} = Q_i \cdot K_j^T\]- i번째 단어가 j번째 단어를 얼마나 참고할지 결정
- 결과:
[seq_len, seq_len]의 score 행렬
3. 정규화 (softmax)
\[\alpha_{i,j} = \text{softmax}(\text{score}_{i,j})\]- i번째 단어가 j번째 단어에 얼마나 집중할지 가중치 (attention weight)로 변환
4. Weighted Sum (가중합)
\[\text{output}_i = \sum_{j=1}^{n} \alpha_{i,j} V_j\]- 각 단어가 참고한 정보를 비율에 따라 종합
- 출력: 문맥 반영된 표현 벡터
Self-Attention의 특징:
| 특징 | 설명 |
|---|---|
| 병렬 계산 가능 | 모든 단어 간 관계를 동시에 계산 가능 (GPU 최적화) |
| 문맥 정보 동시 반영 | 한 단어가 전체 문장을 동시에 바라볼 수 있음 |
| 위치 정보는 따로 인코딩 필요 | 위치 순서 개념이 없기 때문에 Positional Encoding이 필수 |
수식 요약:
\[\text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V\]각 요소가 평균: 0, 분산: 1인 분포를 따른다고 할 때, 내적 결과는 평균: 0, 분산 dk가 됩니다. 따라서, 계산된 Attention Score에 √dk 값으로 나눠서 분산을 1로 만들어, 정규화를 해줍니다.
Weighted Sum (가중합)
Weighted Sum은 가중치의 비율에 따라 정보를 강조하거나 줄이는 방식입니다. 기존 정보들을 버리지 않고 중요도에 따라 반영합니다.
정보 유지의 이유: Weighted Sum은 단순히 정보를 삭제하지 않고, 모든 벡터의 선형 결합을 만듭니다. 따라서 입력 벡터의 정보를 비율 조정만 해서 보존합니다.
\[y = \sum_{i=1}^{n} \alpha_i x_i\]여기서 x_i는 벡터 또는 Tensor 요소, α_i는 그에 대응되는 가중치입니다.
예시 문장: “I like pizza.”
| 단어 | 벡터 | 가중치 |
|---|---|---|
| “I” | [0.1, 0.3, 0.5] | 0.2 |
| “like” | [0.4, 0.6, 0.8] | 0.5 |
| “pizza” | [0.7, 0.9, 0.2] | 0.3 |
Weighted Sum 결과:
1
2
3
0.2·"I" + 0.5·"like" + 0.3·"pizza"
= 0.2 · [0.1, 0.3, 0.5] + 0.5 · [0.4, 0.6, 0.8] + 0.3 · [0.7, 0.9, 0.2]
= [0.43, 0.63, 0.56]
3.4 병렬로 여러 관점에서 보는 단계 (Multi-Head Attention)
이유: 단어 관계를 다양한 관점에서 분석 (예: 의미, 문법 등)
동작:
- 여러 개의 Attention Head 사용 → 다양한 정보 추출
- 다시 합쳐서 통합 정보 생성
Attention Head
하나의 Attention Head는 Query, Key, Value 벡터를 입력받아 Self-Attention 연산을 수행합니다. 이 Head는 자체적인 선형 변환 행렬(W_q, W_k, W_v)을 가지므로, 입력 정보를 다른 방식으로 해석합니다. 즉, 한 개의 Attention Head는 단일 시야(viewpoint)로 단어 간 관계를 본다고 생각하면 됩니다.
Multi-Head Attention Head의 예시
하나의 head는 특정 관계(예: 문법적 연결)만 잘 학습할 수 있습니다. 여러 head를 사용하면, 각 head가 다른 의미적/구문적 관계를 집중적으로 학습 가능합니다.
| Head No. | 의미적/구문적 관계 |
|---|---|
| Head 1 | 동사-목적어 관계 |
| Head 2 | 주어-동사 일치 |
| Head 3 | 명사 간 유사성 |
일반적으로 8개 또는 12개의 head를 사용하며, 각 head는 같은 입력을 받지만 서로 다른 W_q, W_k, W_v로 연산합니다. 각 head의 출력을 Concat(연결) → 선형 변환하여 최종 출력을 생성합니다.
3.5 정보를 조정하고 다음 단계로 넘기는 단계 (Feed-Forward & Residual Connection)
Feed-Forward Network (FFN)
역할: Attention 결과를 비선형 연산으로 가공
동작:
- Dense layer → ReLU → Dense layer
- Residual connection으로 안정적인 학습 지원
- Layer Normalization을 통해 정보 정리
Attention을 통해 얻은 문맥 벡터를 비선형 함수로 가공해, 더 복잡한 표현을 학습하게 합니다. 각 토큰에 독립적으로 적용됩니다 (즉, 위치 간 상호작용은 없음).
FFN의 구조:
두 개의 선형 계층과 활성화 함수로 구성:
\[\text{FFN}(x) = \text{Linear}_2(\text{ReLU}(\text{Linear}_1(x)))\]- Linear_1: hidden dim → FFN dim (예: 512 → 2048)
- ReLU: 비선형성 추가
- Linear_2: FFN dim → hidden dim (예: 2048 → 512)
각 토큰 벡터에 독립적으로 적용되므로, 병렬 연산이 가능합니다. Attention이 관계를 파악했다면, FFN은 정보를 정제하는 역할을 합니다.
Residual Connection
입력을 그대로 더해줌 → 정보 손실 방지, 깊은 네트워크에서도 기울기 소실(gradient vanishing)을 완화
\[\text{Output} = x + \text{SubLayer}(x)\]여기서 SubLayer(x)는 Attention 또는 FFN 같은 블록입니다.
Layer Normalization
위의 결과에 정규화를 적용하여 학습 안정화
\[\text{LayerNorm}(x) = \frac{x - \mu}{\sigma} \cdot \gamma + \beta\]- μ: 벡터의 평균
- σ: 벡터의 표준편차
- γ, β: 학습 가능한 스케일 및 시프트 파라미터
Layer Normalization을 수행하는 이유:
- 스케일 차이 보정: 입력 벡터의 값 분포를 정규화해, 훈련 시 안정적인 그래디언트 흐름 보장
- 배치 크기에 독립적: LayerNorm은 배치 전체가 아니라 각 토큰 벡터 단위로 정규화하므로, 작은 배치에서도 잘 작동
- 모델 수렴 속도 향상: 학습이 더 빠르고 일관되게 진행됨
3.6 입력 문장을 이해하는 파트 (Encoder)
역할:
- 입력 문장 내 모든 단어들의 의미를 파악하고, 전체 문맥 정보를 추출
- Decoder가 참고할 수 있도록 context representation을 생성
구성 요소:
- Self-Attention: 입력 문장 내 단어들 간 관계를 계산 (예: “나는 피자를 좋아해”에서 “피자”와 “좋아해”의 관계)
- Feed Forward Network (FFN): Attention 결과를 더 풍부하게 가공
- Residual + Layer Norm: 정보 손실 방지 및 학습 안정화
출력: 각 입력 토큰에 대해 문맥을 반영한 임베딩 벡터 (shape: [batch_size, seq_len, hidden_dim])
3.7 문장을 생성하는 파트 (Decoder)
역할:
- Encoder의 문맥 정보를 참고하며, 출력 문장을 왼쪽부터 한 단어씩 생성
- 예: 번역 시, 영어 문장을 하나씩 만들어냄 (“I like pizza”)
구성 요소:
- Masked Self-Attention: 현재까지 생성된 단어들만 보면서 다음 단어 예측 (자기 자신보다 미래 단어는 못 봄 → auto-regressive)
- Encoder-Decoder Attention: Encoder의 출력(context)을 참고
- Query는 Decoder에서 생성한 벡터
- Key와 Value는 Encoder의 출력에서 생성한 벡터
- Feed Forward Network
- Residual + Layer Norm
출력: 각 위치에서 생성할 다음 단어에 대한 확률 분포. Softmax를 통해 가장 확률 높은 단어 선택 → 반복하며 문장 생성
3.8 최종 출력 (단어 생성)
과정: Decoder가 softmax를 통해 다음 단어 확률 예측
동작:
- 확률이 가장 높은 단어 선택 → 문장 생성
- 반복해서 전체 문장 생성


















