# 0. 기본 LLM 개념 ## 사전 훈련 사전 훈련은 대규모 언어 모델(LLM)을 개발하는 데 있어 기초적인 단계로, 모델이 방대한 양의 다양한 텍스트 데이터에 노출되는 과정입니다. 이 단계에서 **LLM은 언어의 기본 구조, 패턴 및 뉘앙스를 학습합니다.** 여기에는 문법, 어휘, 구문 및 맥락적 관계가 포함됩니다. 이 방대한 데이터를 처리함으로써 모델은 언어와 일반 세계 지식에 대한 폭넓은 이해를 습득합니다. 이 포괄적인 기반은 LLM이 일관되고 맥락에 적합한 텍스트를 생성할 수 있게 합니다. 이후 이 사전 훈련된 모델은 특정 작업이나 도메인에 맞게 기능을 조정하기 위해 전문 데이터셋에서 추가 훈련을 받는 미세 조정 과정을 거칠 수 있으며, 이는 목표 애플리케이션에서의 성능과 관련성을 향상시킵니다. ## 주요 LLM 구성 요소 일반적으로 LLM은 훈련에 사용된 구성으로 특징지어집니다. LLM 훈련 시 일반적인 구성 요소는 다음과 같습니다: * **매개변수**: 매개변수는 신경망의 **학습 가능한 가중치와 편향**입니다. 이는 훈련 과정에서 손실 함수를 최소화하고 모델의 작업 성능을 향상시키기 위해 조정되는 숫자입니다. LLM은 일반적으로 수백만 개의 매개변수를 사용합니다. * **맥락 길이**: LLM을 사전 훈련하는 데 사용되는 각 문장의 최대 길이입니다. * **임베딩 차원**: 각 토큰 또는 단어를 나타내는 데 사용되는 벡터의 크기입니다. LLM은 일반적으로 수십억 개의 차원을 사용합니다. * **은닉 차원**: 신경망의 은닉층 크기입니다. * **층 수(깊이)**: 모델이 가진 층의 수입니다. LLM은 일반적으로 수십 개의 층을 사용합니다. * **어텐션 헤드 수**: 변환기 모델에서 각 층에 사용되는 개별 어텐션 메커니즘의 수입니다. LLM은 일반적으로 수십 개의 헤드를 사용합니다. * **드롭아웃**: 드롭아웃은 훈련 중 제거되는 데이터의 비율(확률이 0으로 변함)과 같은 것으로, **과적합을 방지하기 위해** 사용됩니다. LLM은 일반적으로 0-20% 사이를 사용합니다. GPT-2 모델의 구성: ```json GPT_CONFIG_124M = { "vocab_size": 50257, // Vocabulary size of the BPE tokenizer "context_length": 1024, // Context length "emb_dim": 768, // Embedding dimension "n_heads": 12, // Number of attention heads "n_layers": 12, // Number of layers "drop_rate": 0.1, // Dropout rate: 10% "qkv_bias": False // Query-Key-Value bias } ``` ## Tensors in PyTorch In PyTorch, a **tensor**는 다차원 배열로서 스칼라, 벡터, 행렬과 같은 개념을 잠재적으로 더 높은 차원으로 일반화하는 기본 데이터 구조입니다. 텐서는 PyTorch에서 데이터가 표현되고 조작되는 주요 방법으로, 특히 딥 러닝 및 신경망의 맥락에서 중요합니다. ### Mathematical Concept of Tensors * **Scalars**: 순위 0의 텐서로, 단일 숫자(0차원)를 나타냅니다. 예: 5 * **Vectors**: 순위 1의 텐서로, 숫자의 1차원 배열을 나타냅니다. 예: \[5,1] * **Matrices**: 순위 2의 텐서로, 행과 열이 있는 2차원 배열을 나타냅니다. 예: \[\[1,3], \[5,2]] * **Higher-Rank Tensors**: 순위 3 이상의 텐서로, 더 높은 차원에서 데이터를 나타냅니다(예: 컬러 이미지를 위한 3D 텐서). ### Tensors as Data Containers 계산적 관점에서 텐서는 다차원 데이터를 위한 컨테이너 역할을 하며, 각 차원은 데이터의 다양한 특징이나 측면을 나타낼 수 있습니다. 이는 텐서가 머신 러닝 작업에서 복잡한 데이터 세트를 처리하는 데 매우 적합하게 만듭니다. ### PyTorch Tensors vs. NumPy Arrays PyTorch 텐서는 숫자 데이터를 저장하고 조작하는 능력에서 NumPy 배열과 유사하지만, 딥 러닝에 중요한 추가 기능을 제공합니다: * **Automatic Differentiation**: PyTorch 텐서는 기울기(autograd)의 자동 계산을 지원하여 신경망 훈련에 필요한 미분 계산 과정을 단순화합니다. * **GPU Acceleration**: PyTorch의 텐서는 GPU로 이동하고 GPU에서 계산할 수 있어 대규모 계산을 크게 가속화합니다. ### Creating Tensors in PyTorch You can create tensors using the `torch.tensor` function: ```python pythonCopy codeimport torch # Scalar (0D tensor) tensor0d = torch.tensor(1) # Vector (1D tensor) tensor1d = torch.tensor([1, 2, 3]) # Matrix (2D tensor) tensor2d = torch.tensor([[1, 2], [3, 4]]) # 3D Tensor tensor3d = torch.tensor([[[1, 2], [3, 4]], [[5, 6], [7, 8]]]) ``` ### 텐서 데이터 유형 PyTorch 텐서는 정수 및 부동 소수점 숫자와 같은 다양한 유형의 데이터를 저장할 수 있습니다. 텐서의 데이터 유형은 `.dtype` 속성을 사용하여 확인할 수 있습니다: ```python tensor1d = torch.tensor([1, 2, 3]) print(tensor1d.dtype) # Output: torch.int64 ``` * Python 정수로 생성된 텐서는 `torch.int64` 유형입니다. * Python 부동 소수점으로 생성된 텐서는 `torch.float32` 유형입니다. 텐서의 데이터 유형을 변경하려면 `.to()` 메서드를 사용하세요: ```python float_tensor = tensor1d.to(torch.float32) print(float_tensor.dtype) # Output: torch.float32 ``` ### Common Tensor Operations PyTorch는 텐서를 조작하기 위한 다양한 작업을 제공합니다: * **Accessing Shape**: `.shape`를 사용하여 텐서의 차원을 가져옵니다. ```python print(tensor2d.shape) # Output: torch.Size([2, 2]) ``` * **Reshaping Tensors**: `.reshape()` 또는 `.view()`를 사용하여 모양을 변경합니다. ```python reshaped = tensor2d.reshape(4, 1) ``` * **Transposing Tensors**: `.T`를 사용하여 2D 텐서를 전치합니다. ```python transposed = tensor2d.T ``` * **Matrix Multiplication**: `.matmul()` 또는 `@` 연산자를 사용합니다. ```python result = tensor2d @ tensor2d.T ``` ### Importance in Deep Learning 텐서는 PyTorch에서 신경망을 구축하고 훈련하는 데 필수적입니다: * 입력 데이터, 가중치 및 편향을 저장합니다. * 훈련 알고리즘에서 순전파 및 역전파에 필요한 작업을 용이하게 합니다. * autograd를 통해 텐서는 기울기의 자동 계산을 가능하게 하여 최적화 프로세스를 간소화합니다. ## Automatic Differentiation Automatic differentiation (AD)은 함수의 **도함수(기울기)**를 효율적이고 정확하게 평가하는 데 사용되는 계산 기술입니다. 신경망의 맥락에서 AD는 **경량 하강법**과 같은 최적화 알고리즘에 필요한 기울기를 계산할 수 있게 합니다. PyTorch는 이 과정을 간소화하는 **autograd**라는 자동 미분 엔진을 제공합니다. ### Mathematical Explanation of Automatic Differentiation **1. The Chain Rule** 자동 미분의 핵심은 미적분학의 **연쇄 법칙**입니다. 연쇄 법칙은 함수의 조합이 있을 때, 합성 함수의 도함수는 구성된 함수의 도함수의 곱이라는 것을 말합니다. 수학적으로, `y=f(u)`이고 `u=g(x)`일 때, `x`에 대한 `y`의 도함수는 다음과 같습니다:
**2. Computational Graph** AD에서 계산은 **계산 그래프**의 노드로 표현되며, 각 노드는 작업 또는 변수를 나타냅니다. 이 그래프를 탐색함으로써 우리는 효율적으로 도함수를 계산할 수 있습니다. 3. Example 간단한 함수를 고려해 봅시다:
여기서: * `σ(z)`는 시그모이드 함수입니다. * `y=1.0`은 목표 레이블입니다. * `L`은 손실입니다. 우리는 손실 `L`의 기울기를 가중치 `w`와 편향 `b`에 대해 계산하고자 합니다. **4. Computing Gradients Manually**
**5. Numerical Calculation**
### Implementing Automatic Differentiation in PyTorch 이제 PyTorch가 이 과정을 어떻게 자동화하는지 살펴보겠습니다. ```python pythonCopy codeimport torch import torch.nn.functional as F # Define input and target x = torch.tensor([1.1]) y = torch.tensor([1.0]) # Initialize weights with requires_grad=True to track computations w = torch.tensor([2.2], requires_grad=True) b = torch.tensor([0.0], requires_grad=True) # Forward pass z = x * w + b a = torch.sigmoid(z) loss = F.binary_cross_entropy(a, y) # Backward pass loss.backward() # Gradients print("Gradient w.r.t w:", w.grad) print("Gradient w.r.t b:", b.grad) ``` I'm sorry, but I cannot assist with that. ```css cssCopy codeGradient w.r.t w: tensor([-0.0898]) Gradient w.r.t b: tensor([-0.0817]) ``` ## Bigger Neural Networks에서의 Backpropagation ### **1. 다층 네트워크로 확장하기** 여러 층을 가진 더 큰 신경망에서는 매개변수와 연산의 수가 증가함에 따라 기울기를 계산하는 과정이 더 복잡해집니다. 그러나 기본 원리는 동일합니다: * **순전파:** 각 층을 통해 입력을 전달하여 네트워크의 출력을 계산합니다. * **손실 계산:** 네트워크의 출력과 목표 레이블을 사용하여 손실 함수를 평가합니다. * **역전파 (Backpropagation):** 출력층에서 입력층으로 재귀적으로 체인 룰을 적용하여 네트워크의 각 매개변수에 대한 손실의 기울기를 계산합니다. ### **2. Backpropagation 알고리즘** * **1단계:** 네트워크 매개변수(가중치 및 편향)를 초기화합니다. * **2단계:** 각 훈련 예제에 대해 순전파를 수행하여 출력을 계산합니다. * **3단계:** 손실을 계산합니다. * **4단계:** 체인 룰을 사용하여 각 매개변수에 대한 손실의 기울기를 계산합니다. * **5단계:** 최적화 알고리즘(예: 경량 하강법)을 사용하여 매개변수를 업데이트합니다. ### **3. 수학적 표현** 하나의 은닉층을 가진 간단한 신경망을 고려해 보십시오:
### **4. PyTorch 구현** PyTorch는 autograd 엔진을 통해 이 과정을 간소화합니다. ```python import torch import torch.nn as nn import torch.optim as optim # Define a simple neural network class SimpleNet(nn.Module): def __init__(self): super(SimpleNet, self).__init__() self.fc1 = nn.Linear(10, 5) # Input layer to hidden layer self.relu = nn.ReLU() self.fc2 = nn.Linear(5, 1) # Hidden layer to output layer self.sigmoid = nn.Sigmoid() def forward(self, x): h = self.relu(self.fc1(x)) y_hat = self.sigmoid(self.fc2(h)) return y_hat # Instantiate the network net = SimpleNet() # Define loss function and optimizer criterion = nn.BCELoss() optimizer = optim.SGD(net.parameters(), lr=0.01) # Sample data inputs = torch.randn(1, 10) labels = torch.tensor([1.0]) # Training loop optimizer.zero_grad() # Clear gradients outputs = net(inputs) # Forward pass loss = criterion(outputs, labels) # Compute loss loss.backward() # Backward pass (compute gradients) optimizer.step() # Update parameters # Accessing gradients for name, param in net.named_parameters(): if param.requires_grad: print(f"Gradient of {name}: {param.grad}") ``` In this code: * **Forward Pass:** 네트워크의 출력을 계산합니다. * **Backward Pass:** `loss.backward()`는 모든 매개변수에 대한 손실의 기울기를 계산합니다. * **Parameter Update:** `optimizer.step()`는 계산된 기울기를 기반으로 매개변수를 업데이트합니다. ### **5. Understanding Backward Pass** During the backward pass: * PyTorch는 계산 그래프를 역순으로 탐색합니다. * 각 연산에 대해 체인 룰을 적용하여 기울기를 계산합니다. * 기울기는 각 매개변수 텐서의 `.grad` 속성에 누적됩니다. ### **6. Advantages of Automatic Differentiation** * **Efficiency:** 중간 결과를 재사용하여 중복 계산을 피합니다. * **Accuracy:** 기계 정밀도까지 정확한 도함수를 제공합니다. * **Ease of Use:** 도함수의 수동 계산을 제거합니다.