hacktricks/src/AI/AI-llm-architecture/0.-basic-llm-concepts.md

286 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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
在 PyTorch 中,**tensor** 是一种基本数据结构,作为多维数组,推广了标量、向量和矩阵等概念到更高的维度。张量是数据在 PyTorch 中表示和操作的主要方式,特别是在深度学习和神经网络的背景下。
### Mathematical Concept of Tensors
- **Scalars**: 秩为 0 的张量表示一个单一的数字零维。例如5
- **Vectors**: 秩为 1 的张量,表示一维数字数组。例如:\[5,1]
- **Matrices**: 秩为 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 上进行计算,显著加快大规模计算的速度。
### Creating Tensors in PyTorch
您可以使用 `torch.tensor` 函数创建张量:
```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]]])
```
### Tensor 数据类型
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
```
### 常见的张量操作
PyTorch 提供了多种操作来处理张量:
- **访问形状**:使用 `.shape` 获取张量的维度。
```python
print(tensor2d.shape) # 输出: torch.Size([2, 2])
```
- **重塑张量**:使用 `.reshape()``.view()` 改变形状。
```python
reshaped = tensor2d.reshape(4, 1)
```
- **转置张量**:使用 `.T` 转置 2D 张量。
```python
transposed = tensor2d.T
```
- **矩阵乘法**:使用 `.matmul()``@` 运算符。
```python
result = tensor2d @ tensor2d.T
```
### 在深度学习中的重要性
张量在 PyTorch 中对于构建和训练神经网络至关重要:
- 它们存储输入数据、权重和偏差。
- 它们促进训练算法中前向和后向传播所需的操作。
- 通过 autograd张量能够自动计算梯度从而简化优化过程。
## 自动微分
自动微分AD是一种计算技术用于**高效且准确地评估函数的导数(梯度)**。在神经网络的上下文中AD 使得计算**优化算法如梯度下降**所需的梯度成为可能。PyTorch 提供了一个名为 **autograd** 的自动微分引擎,简化了这个过程。
### 自动微分的数学解释
**1. 链式法则**
自动微分的核心是微积分中的 **链式法则**。链式法则指出,如果你有一个函数的复合,复合函数的导数是组成函数导数的乘积。
在数学上,如果 `y=f(u)``u=g(x)`,那么 `y``x` 的导数为:
<figure><img src="../../images/image (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
**2. 计算图**
在 AD 中,计算被表示为 **计算图** 中的节点,每个节点对应一个操作或变量。通过遍历这个图,我们可以高效地计算导数。
3. 示例
让我们考虑一个简单的函数:
<figure><img src="../../images/image (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
其中:
- `σ(z)` 是 sigmoid 函数。
- `y=1.0` 是目标标签。
- `L` 是损失。
我们想要计算损失 `L` 对权重 `w` 和偏差 `b` 的梯度。
**4. 手动计算梯度**
<figure><img src="../../images/image (2) (1) (1).png" alt=""><figcaption></figcaption></figure>
**5. 数值计算**
<figure><img src="../../images/image (3) (1) (1).png" alt=""><figcaption></figcaption></figure>
### 在 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)
```
请提供需要翻译的具体内容。
```css
cssCopy codeGradient w.r.t w: tensor([-0.0898])
Gradient w.r.t b: tensor([-0.0817])
```
## Backpropagation in Bigger Neural Networks
### **1.Extending to Multilayer Networks**
在具有多个层的大型神经网络中,由于参数和操作数量的增加,计算梯度的过程变得更加复杂。然而,基本原理保持不变:
- **Forward Pass:** 通过将输入传递通过每一层来计算网络的输出。
- **Compute Loss:** 使用网络的输出和目标标签评估损失函数。
- **Backward Pass (Backpropagation):** 通过从输出层递归应用链式法则到输入层,计算损失相对于网络中每个参数的梯度。
### **2. Backpropagation Algorithm**
- **Step 1:** 初始化网络参数(权重和偏置)。
- **Step 2:** 对于每个训练示例,执行前向传播以计算输出。
- **Step 3:** 计算损失。
- **Step 4:** 使用链式法则计算损失相对于每个参数的梯度。
- **Step 5:** 使用优化算法(例如,梯度下降)更新参数。
### **3. Mathematical Representation**
考虑一个具有一个隐藏层的简单神经网络:
<figure><img src="../../images/image (5) (1).png" alt=""><figcaption></figcaption></figure>
### **4. PyTorch Implementation**
PyTorch通过其自动求导引擎简化了这个过程。
```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}")
```
在这段代码中:
- **前向传播:** 计算网络的输出。
- **反向传播:** `loss.backward()` 计算损失相对于所有参数的梯度。
- **参数更新:** `optimizer.step()` 根据计算出的梯度更新参数。
### **5. 理解反向传播**
在反向传播过程中:
- PyTorch 以相反的顺序遍历计算图。
- 对于每个操作,它应用链式法则来计算梯度。
- 梯度被累积在每个参数张量的 `.grad` 属性中。
### **6. 自动微分的优点**
- **效率:** 通过重用中间结果避免冗余计算。
- **准确性:** 提供精确的导数,达到机器精度。
- **易用性:** 消除了手动计算导数的需要。