大模型入门-day13-14:小规模训练(小规模教学)
ztj100 2025-06-09 07:26 27 浏览 0 评论
小规模训练 内容基于 Hugging Face 的 datasets 库加载 WikiText-2 数据集,训练简单 Transformer 模型,并观察 Perplexity 下降。
第 13-14 天:小规模训练(6-10 小时)
学习目标
- 理解 Transformer 原理:掌握 Self-Attention 等核心概念。
- 加载数据:用 Hugging Face 的 datasets 库加载 WikiText-2。
- 构建模型:用 PyTorch 搭建简单 Transformer。
- 训练与评估:训练模型,观察 Perplexity 下降。
- 成果:能解释 Transformer,手写简单代码。
时间安排
- 总计:6-10 小时
- 第 13 天:3-5 小时(原理、数据加载、模型搭建)
- 第 14 天:3-5 小时(训练、评估、总结)
第 13 天:准备与搭建
任务 1:理解 Transformer 原理
时间:1-2 小时
内容:
- Transformer 核心:通过 Self-Attention 关注句子中的重要词,用编码器和解码器处理输入和生成输出。
- 关键组件:
- Self-Attention:让模型关注每个词与其他词的关系。
- Multi-Head Attention:多角度理解句子。
- Positional Encoding:给词加上位置信息。
- 资源:
- The Illustrated Transformer
- Attention is All You Need(可选)
练习:用自己的话说:“Transformer 怎么预测下一个词?”
任务 2:加载数据集和分词
时间:1 小时
内容:用 datasets 库加载 WikiText-2 数据集,并用分词器处理文本。
代码:
python
# 导入库
from datasets import load_dataset # 加载数据集
from transformers import AutoTokenizer # 加载分词器
# 加载 WikiText-2 数据集
dataset = load_dataset("wikitext", "wikitext-2-v1")
# 解释:从 Hugging Face 下载 WikiText-2,包含 train、valid、test 三部分。
# 加载分词器
tokenizer = AutoTokenizer.from_pretrained("bert-base-uncased")
# 解释:用 BERT 的分词器,把文本转为数字 token。
# 分词函数
def tokenize_function(examples):
return tokenizer(examples["text"], truncation=True, padding="max_length", max_length=512)
# 解释:对文本分词,截断或填充到 512 个 token。
# 分词整个数据集
tokenized_dataset = dataset.map(tokenize_function, batched=True)
# 解释:批量处理数据集,分词后返回新数据集。
输出示例:
- 检查 tokenized_dataset["train"][0]["input_ids"],会看到一串数字(如 [101, 1996, 4937, ...])。
任务 3:数据预处理
时间:1 小时
内容:将分词数据转为 PyTorch 张量,创建 DataLoader。
代码:
python
# 导入库
from torch.utils.data import DataLoader # 创建 DataLoader
from torch.nn.utils.rnn import pad_sequence # 填充序列
# 自定义批处理函数
def collate_fn(batch):
input_ids = [torch.tensor(item["input_ids"]) for item in batch]
# 解释:从每个样本中提取 input_ids,转为张量。
input_ids = pad_sequence(input_ids, batch_first=True, padding_value=tokenizer.pad_token_id)
# 解释:填充序列到相同长度,用 pad_token_id(如 0)填充。
return {"input_ids": input_ids}
# 解释:返回字典,包含填充后的 input_ids。
# 创建 DataLoader
train_dataloader = DataLoader(
tokenized_dataset["train"], # 训练集
batch_size=8, # 每批 8 个样本
shuffle=True, # 随机打乱
collate_fn=collate_fn # 用自定义函数处理批次
)
# 解释:DataLoader 批量加载数据,方便训练。
输出示例:
- next(iter(train_dataloader))["input_ids"] 输出形状:(8, 512)。
任务 4:构建简单 Transformer 模型
时间:2-3 小时
内容:用 PyTorch 搭建一个简单 Transformer。
代码:
python
# 导入库
import torch
import torch.nn as nn # 神经网络模块
# 定义模型
class SimpleTransformer(nn.Module):
def __init__(self, vocab_size, d_model, nhead, num_encoder_layers, dim_feedforward, max_seq_length, dropout=0.1):
super(SimpleTransformer, self).__init__()
# 解释:初始化父类 nn.Module。
self.embedding = nn.Embedding(vocab_size, d_model)
# 解释:将词索引转为 d_model 维的向量。
self.positional_encoding = nn.Parameter(torch.zeros(1, max_seq_length, d_model))
# 解释:可学习的位置编码,记录词的位置。
encoder_layer = nn.TransformerEncoderLayer(
d_model=d_model, nhead=nhead, dim_feedforward=dim_feedforward, dropout=dropout, batch_first=True
)
# 解释:定义单层编码器,包含注意力机制和前馈网络。
self.transformer_encoder = nn.TransformerEncoder(encoder_layer, num_encoder_layers)
# 解释:堆叠多层编码器。
self.fc_out = nn.Linear(d_model, vocab_size)
# 解释:将编码器输出映射到词汇表大小。
def forward(self, src):
seq_length = src.size(1)
# 解释:获取输入序列长度。
src = self.embedding(src) + self.positional_encoding[:, :seq_length, :]
# 解释:词嵌入加上位置编码。
output = self.transformer_encoder(src)
# 解释:通过 Transformer 编码器处理。
return self.fc_out(output)
# 解释:输出预测结果。
# 初始化模型
vocab_size = tokenizer.vocab_size # 词汇表大小(如 30522)
model = SimpleTransformer(
vocab_size=vocab_size, d_model=512, nhead=8, num_encoder_layers=6,
dim_feedforward=2048, max_seq_length=512, dropout=0.1
)
# 解释:创建模型实例,设置超参数。
参数说明:
- d_model:词嵌入维度(512)。
- nhead:注意力头数(8)。
- num_encoder_layers:编码器层数(6)。
第 14 天:训练与评估
任务 5:训练模型
时间:2-3 小时
内容:编写训练循环,训练模型。
代码:
python
# 导入库
import torch.optim as optim # 优化器
# 设置设备和损失函数
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model.to(device)
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.0001)
# 训练函数
def train(model, dataloader, epochs=3): # 减少 epoch 以节省时间
model.train()
for epoch in range(epochs):
total_loss = 0
for batch in dataloader:
input_ids = batch["input_ids"].to(device)
# 解释:将输入移到 GPU/CPU。
labels = input_ids # 语言模型用输入预测下一个词
optimizer.zero_grad()
# 解释:清空上一次梯度。
output = model(input_ids)
# 解释:模型前向传播。
loss = criterion(output.view(-1, vocab_size), labels.view(-1))
# 解释:计算损失,view(-1) 展平张量。
loss.backward()
# 解释:反向传播计算梯度。
optimizer.step()
# 解释:更新模型参数。
total_loss += loss.item()
avg_loss = total_loss / len(dataloader)
print(f"Epoch {epoch+1}, Avg Loss: {avg_loss:.3f}")
# 开始训练
train(model, train_dataloader)
输出示例:
Epoch 1, Avg Loss: 7.500
Epoch 2, Avg Loss: 6.800
Epoch 3, Avg Loss: 6.200
任务 6:评估模型
时间:1 小时
内容:计算 Perplexity,观察下降趋势。
代码:
python
import math
def calculate_perplexity(model, dataloader):
model.eval()
total_loss = 0
with torch.no_grad(): # 不计算梯度
for batch in dataloader:
input_ids = batch["input_ids"].to(device)
labels = input_ids
output = model(input_ids)
loss = criterion(output.view(-1, vocab_size), labels.view(-1))
total_loss += loss.item()
avg_loss = total_loss / len(dataloader)
perplexity = math.exp(avg_loss) # Perplexity = e^loss
return perplexity
# 计算并打印
perplexity = calculate_perplexity(model, train_dataloader)
print(f"Perplexity: {perplexity:.3f}")
输出示例:
Perplexity: 500.000
任务 7:总结与反思
时间:1 小时
内容:回顾学习成果,回答问题:
- Perplexity 是否下降? 如果没有,可能是学习率太高(调小 lr)或数据问题。
- Self-Attention 怎么工作? 试着解释:“它让模型关注句子中重要的词,比如‘猫’和‘坐’的关系。”
- 改进建议:调整 lr(如 0.001)、增加 epochs、减少 batch_size。
成果验收
- 原理:能用简单语言解释 Transformer。
- 数据:成功加载并分词 WikiText-2。
- 模型:手写并运行 Transformer 代码。
- 评估:观察到 Perplexity 下降(比如从 1800 到 500)。
小 Tips
- 硬件:没 GPU 用 CPU,调小 batch_size(如 4)。
- 调试:报错告诉我,我帮你调。
- 扩展:试试用 valid_dataloader 评估验证集。
完成任务后,告诉我 Perplexity 结果和你的 Transformer 解释,我帮你确认!动手开始吧!
相关推荐
- 这个 JavaScript Api 已被废弃!请慎用!
-
在开发过程中,我们可能会不自觉地使用一些已经被标记为废弃的JavaScriptAPI。这些...
- JavaScript中10个“过时”的API,你的代码里还在用吗?
-
JavaScript作为一门不断发展的语言,其API也在持续进化。新的、更安全、更高效的API不断涌现,而一些旧的API则因为各种原因(如安全问题、性能瓶颈、设计缺陷或有了更好的替代品)被标记为“废...
- 几大开源免费的 JavaScript 富文本编辑器测评
-
MarkDown编辑器用的时间长了,发现发现富文本编辑器用起来是真的舒服。...
- 比较好的网页里面的 html 编辑器 推荐
-
如果您正在寻找嵌入到网页中的HTML编辑器,以便用户可以直接在网页上编辑HTML内容,以下是几个备受推荐的:CKEditor:CKEditor是一个功能强大的、开源的富文本编辑器,可以嵌入到...
- Luckysheet 实现excel多人在线协同编辑
-
前言前些天看到Luckysheet支持协同编辑Excel,正符合我们协同项目的一部分,故而想进一步完善协同文章,但是遇到了一下困难,特此做声明哈,若侵权,请联系我删除文章!若侵犯版权、个人隐私,请联系...
- 从 Element UI 源码的构建流程来看前端 UI 库设计
-
作者:前端森林转发链接:https://mp.weixin.qq.com/s/ziDMLDJcvx07aM6xoEyWHQ引言...
- 手把手教你如何用 Decorator 装饰你的 Typescript?「实践」
-
作者:Nealyang转发连接:https://mp.weixin.qq.com/s/PFgc8xD7gT40-9qXNTpk7A...
- 推荐五个优秀的富文本编辑器
-
富文本编辑器是一种可嵌入浏览器网页中,所见即所得的文本编辑器。对于许多从事前端开发的小伙伴来说并不算陌生,它的应用场景非常广泛,平时发个评论、写篇博客文章等都能见到它的身影。...
- 基于vue + element的后台管理系统解决方案
-
作者:林鑫转发链接:https://github.com/lin-xin前言该方案作为一套多功能的后台框架模板,适用于绝大部分的后台管理系统(WebManagementSystem)开发。基于v...
- 开源富文本编辑器Quill 2.0重磅发布
-
开源富文本编辑器Quill正式发布2.0版本。官方TypeScript声明...
- Python之Web开发框架学习 Django-表单处理
-
在Django中创建表单实际上类似于创建模型。同样,我们只需要从Django类继承,则类属性将是表单字段。让我们在myapp文件夹中添加一个forms.py文件以包含我们的应用程序表单。我们将创建一个...
- Django测试入门:打造坚实代码基础的钥匙
-
这一篇说一下django框架的自动化测试,...
- Django ORM vs SQLAlchemy:到底谁更香?从入门到上头的选择指南
-
阅读文章前辛苦您点下“关注”,方便讨论和分享,为了回馈您的支持,我将每日更新优质内容。...
- 超详细的Django 框架介绍,它来了!
-
时光荏苒,一晃小编的Tornado框架系列也结束了。这个框架虽然没有之前的FastAPI高流量,但是,它也是小编的心血呀。总共16篇博文,从入门到进阶,包含了框架的方方面面。虽然小编有些方面介绍得不是...
- 20《Nginx 入门教程》使用 Nginx 部署 Python 项目
-
今天的目标是完成一个PythonWeb项目的线上部署,我们使用最新的Django项目搭建一个简易的Web工程,然后基于Nginx服务部署该PythonWeb项目。1.前期准备...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- idea eval reset (50)
- vue dispatch (70)
- update canceled (42)
- order by asc (53)
- spring gateway (67)
- 简单代码编程 贪吃蛇 (40)
- transforms.resize (33)
- redisson trylock (35)
- 卸载node (35)
- np.reshape (33)
- torch.arange (34)
- npm 源 (35)
- vue3 deep (35)
- win10 ssh (35)
- vue foreach (34)
- idea设置编码为utf8 (35)
- vue 数组添加元素 (34)
- std find (34)
- tablefield注解用途 (35)
- python str转json (34)
- java websocket客户端 (34)
- tensor.view (34)
- java jackson (34)
- vmware17pro最新密钥 (34)
- mysql单表最大数据量 (35)