从零开始大模型之实现GPT模型

从零开始大模型之从头实现GPT模型

  • 1.大语言模型整体架构
  • 2 大语言的Transformer模块
    • 2.1 层归一化
    • 2.2 GELU激活函数
    • 2.3 前馈神经网络
    • 2.4 快捷连接
  • 3 附录
    • 3.1 anaconda+python环境搭建

在这里插入图片描述
1.数据预处理:原始数据进行词元化,以及通过,依据词汇表生成ID编号,对ID编号随机生成嵌入向量,特别注意的是嵌入向量事实上也是一个权重,通过反向传播进行更新。

2.掩码多头注意力机制:增加掩码多头注意力机制,其中增加掩码机制是为了确定序列的输出的因果关系,多头注意力机制是为了对不同路径的来源数据进行上下文联系。

3.LLM架构transform块:进行层归一化,GELU激活函数,前馈神经网络,快捷连接。

1.大语言模型整体架构

在这里插入图片描述
数据预处理,掩码多头注意力机制已经学过了,接下来进行最重要的LLM架构的transform块的学习。
#1 Transform块总体概述
整个transform块包含以下内容,层归一化,GELU激活函数,前馈神经网络,快捷连接等等。
在这里插入图片描述

2 大语言的Transformer模块

2.1 层归一化

层归一化是为了调整神经网络的输出,让其均值为0,方差为1。目的是为了神经网络更加稳定。具体做法是依据以下的数学公式,对emb_dim维度上进行μ=x−μσ\mu=\frac{x-\mu}{\sigma}μ=σxμ,最终能够对该维度嵌入向量进行归一化,最后再加上动态可训练参数缩放和平移。

#%% 层归一化
import torch #导入torch包 类似于一个目录,包含了__init__.py以及其他模块的py文件或者其他子包
import torch.nn as nn # 导入torch包中的nn模块 一个模块就是一个.py文件,一个py文件下有函数以及类
torch.manual_seed(123) #固定随机种子
batch_example = torch.randn(2,5) #随机生成两行五列的张量,然后每行是均值为0,方差为1的正态分布
print("batch_example,随机生成的输入为:",batch_example)
layer = nn.Sequential(nn.Linear(5,6),nn.ReLU()) # 容器类装有神经网络类,并通过序列连接,输入连输出,输出也是一个神经网络模块
out = layer(batch_example)
print("自定义的神经网络结构的输出为:",out)
mean = out.mean(dim=-1,keepdim=True) #按照列的方向进行求均值,同时保持维度不变
var = out.var(dim=-1,keepdim=True) #按照行的方向进行求均值,同时保持维度不变
print("未归一化的输出的均值为:",mean,"未归一化的输出的方差为:",var)
#接下来进行归一化
out_norm = (out- mean)/torch.sqrt(var)
torch.set_printoptions(sci_mode=False)
print("归一化后的均值为:",out_norm.mean(dim=-1,keepdim=True))
print("归一化后的方差为:",out_norm.var(dim=-1,keepdim=True))

在这里插入图片描述
将上述归一化代码进行整合在一个类中:

class LayerNorm(nn.Module):def __init__(self, emb_dim):super().__init__()self.eps = 1e-5self.scale = nn.Parameter(torch.ones(emb_dim))self.shift = nn.Parameter(torch.zeros(emb_dim))def forward(self, x):mean = x.mean(dim=-1, keepdim=True)var = x.var(dim=-1, keepdim=True, unbiased=False)norm_x = (x - mean) / torch.sqrt(var + self.eps)return self.scale * norm_x + self.shift

最后测试用例:

#%% 归一化测试用例
import torch #导入torch包 类似于一个目录,包含了__init__.py以及其他模块的py文件或者其他子包
import torch.nn as nn # 导入torch包中的nn模块 一个模块就是一个.py文件,一个py文件下有函数以及类
torch.manual_seed(123) #固定随机种子
batch_example = torch.randn(2,5) #随机生成两行五列的张量,然后每行是均值为0,方差为1的正态分布
print("batch_example,随机生成的输入为:",batch_example)
class LayerNorm(nn.Module):def __init__(self, emb_dim):super().__init__()self.eps = 1e-5self.scale = nn.Parameter(torch.ones(emb_dim))self.shift = nn.Parameter(torch.zeros(emb_dim))def forward(self, x):mean = x.mean(dim=-1, keepdim=True)var = x.var(dim=-1, keepdim=True, unbiased=False)norm_x = (x - mean) / torch.sqrt(var + self.eps)return self.scale * norm_x + self.shift
ln = LayerNorm(emb_dim=5)
out_ln = ln(batch_example)
mean = out_ln.mean(dim=-1, keepdim=True)
var = out_ln.var(dim=-1, unbiased=False, keepdim=True)print("Mean:\n", mean)
print("Variance:\n", var)

2.2 GELU激活函数

精确的定义GELU(x)=x⋅ϕ(x)GELU(x)=x \cdot \phi{(x)}GELU(x)=xϕ(x),其中ϕ(x)\phi{(x)}ϕ(x)是标准高斯分布的累积分布函数,但是在实际操作中,我们会使用一种计算量较小的近似实现,可通过曲线拟合的方法近似得到,GELU(x)≈0.5⋅x⋅{1+tanh⁡[π2⋅(x+0.044715⋅x3)]}GELU(x) \approx 0.5 \cdot x \cdot \{1+\tanh[\sqrt{\frac{\pi}{2}} \cdot (x+0.044715 \cdot x^{3})]\}GELU(x)0.5x{1+tanh[2π(x+0.044715x3)]}

#%% GELU激活函数的前馈神经网络
#GELU激活类
import torch
import torch.nn as nn
import matplotlib.pyplot as plt
class GELU(nn.Module):def __init__(self):# 参数初始化super().__init__()def forward(self,x): #输入与输出return 0.5*x*(1+torch.tanh((torch.sqrt(torch.tensor(2/torch.pi)))*(x+0.044715 * torch.power(x,3))))
# GELU激活类与ReLU激活类的对比
gelu,relu = GELU(),nn.ReLU() #神经网络初始化
x = torch.linspace(-3,3,100)#生成-3到3之间的100个数
y_gelu = GELU(x)#前向传播
y_relu= nn.ReLU(x)#前向传播
plt.figure(figsize=(8,3))
for i,(label,y) in enumerate(zip(["ReLU","GELU"],[y_relu,y_gelu]),1):plt.subplot(1,2,i)plt.plot(x,y)plt.title(f"{label} activation function")plt.xlabel("x")plt.ylabel("{label}(x)")plt.grid(True)
plt.tight_layout()
plt.show()

在这里插入图片描述
RELU激活函数存在两个问题,第一个问题是当x=0的梯度不存在,第二个问题,输入小于零的输出部分直接被置为0,没有后续神经元的运算。从GELU激活函数与ReLU激活函数对比图可以看出,GELU在小于零部分梯度存在,同时在输入小于0的部分,输出接近于0,并没有置零,还能参与后续的运算。

2.3 前馈神经网络

前馈神经网络先放大输入的节点数,经过GELU激活函数,然后再缩小节点数到与原来的输入的节点数相同,通过这样一个过程,相当于去粗取精。
在这里插入图片描述

#%% 前馈神经网络
import torch
import torch.nn as nn
class FeedForward(nn.Module):#通过大模型进行层数的放大,然后再将层数缩小def __init__(self,cfg):#参数初始化,以及神经网络结构的定义super().__init__()self.layers = nn.Sequential(nn.Linear(cfg['emb_dim'],4*cfg['emb_dim']),nn.GELU(),nn.Linear(4*cfg['emb_dim'],cfg['emb_dim']))#用容器来装载神经网络结构def forward(self,x):#定义输入与输出的关系return self.layers(x)

2.4 快捷连接

残差连接实际上就是建立一个输入直接连接到输出,这样的话,下一层输入就变成了上一层的输出和上一层的输入的叠加。建立残差连接能够缓解梯度消失问题。
在这里插入图片描述

#%% 残差连接 shortcut
import torch
import torch.nn as nn
class ShortCutNn(nn.Module):def __init__(self,layer_sizes,use_shortcut):#参数初始化以及网络结构的定义super().__init__()self.use_shortcut = use_shortcutself.layers = nn.ModuleList([nn.Sequential(nn.Linear(layer_sizes[0],layer_sizes[1]),nn.GELU())#定义网络列表,nn.Sequential(nn.Linear(layer_sizes[1],layer_sizes[2]),nn.GELU()),nn.Sequential(nn.Linear(layer_sizes[2],layer_sizes[3]),nn.GELU()),nn.Sequential(nn.Linear(layer_sizes[3],layer_sizes[4]),nn.GELU()),nn.Sequential(nn.Linear(layer_sizes[4],layer_sizes[5]),nn.GELU())])def forward(self,x):for layer in self.layers:layer_out = layer(x)if self.use_shortcut and x.shape == layer_out.shape:x = x + layer_outelse:x = layer_outreturn x

3 附录

3.1 anaconda+python环境搭建

接下来进行代码准备,首先下载所有的requirements.txt中的所有依赖库,本次实验是在conda+pycharm环境下,推荐大家在conda+pycharm下进行:
首先创建conda下的环境LLM

conda create --p D:/.conda/envs/LLM 

在这里插入图片描述
然后激活conda下的LLM环境:

conda activate  D:/.conda/envs/LLM 
conda install requirements.txt

在这里插入图片描述

#%% 1 初始化信息查看
from importlib.metadata import version
print("matplotlib version:", version("matplotlib"))
print("torch version:", version("torch"))
print("tiktoken version:", version("tiktoken"))
#%% 2 配置GPT模型参数配置
GPT_CONFIG_124M = {"vocab_size": 50257,    # Vocabulary size 表示会被BPE分词器使用的由50257个单词的词汇表"context_length": 1024, # Context length  能够处理最大词元token的个数"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 qkv的偏置项开启与否,默认是关闭
}
nn用法
Embedding
Dropout
Sequential
Linear

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/93584.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/93584.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[1Prompt1Story] 滑动窗口机制 | 图像生成管线 | VAE变分自编码器 | UNet去噪神经网络

链接:https://github.com/byliutao/1Prompt1Story 这个项目是一个基于单个提示生成一致文本到图像的模型。它在ICLR 2025会议上获得了聚焦论文的地位。该项目提供了生成一致图像的代码、Gradio演示代码以及基准测试代码。 主要功能点: 使用单个提示生成一致的文本…

【GitHub开源AI精选】Sitcom-Crafter:北航联合港中文等高校打造的剧情驱动3D动作生成系统

系列篇章💥 No.文章1【GitHub开源AI精选】LLM 驱动的影视解说工具:Narrato AI 一站式高效创作实践2【GitHub开源AI精选】德国比勒费尔德大学TryOffDiff——高保真服装重建的虚拟试穿技术新突破3【GitHub开源AI精选】哈工大(深圳)…

智和信通全栈式运维平台落地深圳某学院,赋能运维管理提质提效

深圳某学院校园内信息化设备众多,网络环境复杂,使得网络管理工作面临着诸多难题与挑战。为保障校园网络能够稳定、高效地运行,学院亟须构建一套集高效、智能、协同于一体的网络运维平台。 对运维平台的期望包括: 实现校园内教学…

开疆智能Ethernet转ModbusTCP网关连接测联无纸记录仪配置案例

本案例是通过Ethernet转ModbusTCP网关将记录仪数据传送到欧姆龙PLC,具体操作过程如下。欧姆龙PLC配置首先打开主站组态软件“Sysmac Studio”并新建项目。设置PLC的IP地址点击工具-Ethernet/IP连接设置,在弹出的选个框内选择显示EDS库添加网关eds文件开始…

Eureka故障处理大汇总

#作者:Unstopabler 文章目录1. Eureka 服务启动故障处理1.1 端口占用导致启动失败1.2 配置文件错误导致启动失败1.3 依赖冲突与类加载错误2. 服务注册与发现异常2.1 服务无法注册到 Eureka2.2 Eureka 控制台看不到注册的服务2.3 服务注册后立即被剔除3. Eureka 集群…

基于Transformer的机器翻译——模型篇

1.模型结构 本案例整体采用transformer论文中提出的结构,部分设置做了调整。transformer网络结构介绍可参考博客——入门级别的Transformer模型介绍,这里着重介绍其代码实现。 模型的整体结构,包括词嵌入层,位置编码,…

上位机TCP/IP通信协议层常见问题汇总

以太网 TCP 通信是上位机开发中常用的通信方式,西门子 S7 通信、三菱 MC 通信以及 MQTT、OPC UA、Modbus TCP 等都是其典型应用。为帮助大家更好地理解 TCP 通信,我整理了一套常见问题汇总。一、OSI参考模型与TCP/IP参考模型基于TCP/IP的参考模型将协议分…

搭建ktg-mes

项目地址 该安装事项,基于当前最新版 2025年8月16日 之前的版本 下载地址: 后端JAVA 前端VUE 后端安装: 还原数据表 路径:根目录/sql/ry_20210908.sql、根目录/sql/quartz.sql、根目录/doc/实施文档/ktgmes-202505180846.sql.g…

uniapp纯前端绘制商品分享图

效果如图// useMpCustomShareImage.ts interface MpCustomShareImageData {canvasId: stringprice: stringlinePrice: stringgoodsSpecFirmName: stringimage: string }const CANVAS_WIDTH 500 const CANVAS_HEIGHT 400 const BG_IMAGE https://public-scjuchuang.oss-cn-ch…

醋酸镧:看不见的科技助力

虽然我们每天都在使用各种科技产品,但有些关键的化学物质却鲜为人知。醋酸镧,就是这样一种默默为科技进步贡献力量的“幕后英雄”。它不仅是稀土元素镧的一种化合物,还在许多高科技领域中发挥着重要作用。今天,让我们一起来了解这…

苍穹外卖日记

day 1 windows系统启动nginx报错: The system cannot find the path specified 在启动nginx的时候报错: /temp/client_body_temp" failed (3: The system cannot find the path specified) 解决办法: 1.检查nginx的目录是否存在中文 ,路…

楼宇自控系统赋能建筑全维度管理,实现环境、安全与能耗全面监管

随着城市化进程加速和绿色建筑理念普及,现代楼宇管理正经历从粗放式运营向精细化管控的转型。楼宇自控系统(BAS)作为建筑智能化的核心载体,通过物联网、大数据和人工智能技术的深度融合,正在重构建筑管理的全维度框架&…

【HarmonyOS】Window11家庭中文版开启鸿蒙模拟器失败提示未开启Hyoer-V

【HarmonyOS】Window11家庭中文版开启鸿蒙模拟器失败提示未开启Hyoer-V一、问题背景 当鸿蒙模拟器启动时,提示如下图所示:因为Hyper-V 仅在 Windows 11 专业版、企业版和教育版中作为预装功能提供,而家庭版(包括中文版&#xff09…

vscode远程服务器出现一直卡在正在打开远程和连接超时解决办法

项目场景: 使用ssh命令或者各种软件进行远程服务器之后,结果等到几分钟之后自动断开连接问题解决。vscode远程服务器一直卡在正在打开远程状态问题解决。问题描述 1.连接超时 2.vscode远程一直卡在正在打开远程...原因分析:需要修改设置超时断…

Maven下载和配置-IDEA使用

目录 一 MAVEN 二 三个仓库 1. 本地仓库(Local Repository) 2. 私有仓库(Private Repository,公司内部仓库) 3. 远程仓库(Remote Repository) 依赖查找流程(优先级&#xff09…

Dify实战应用指南(上传需求稿生成测试用例)

一、Dify平台简介 Dify是一款开源的大语言模型(LLM)应用开发平台,融合了“Define(定义) Modify(修改)”的设计理念,通过低代码/无代码的可视化界面降低技术门槛。其核心价值在于帮助…

学习日志35 python

1 Python 列表切片一、切片完整语法列表切片的基本格式: 列表[start:end:step]start:起始索引(包含该位置元素,可省略)end:结束索引(不包含该位置元素,可省略)step&#…

Linux -- 文件【下】

目录 一、EXT2文件系统 1、宏观认识 2、块组内部构成 2.1 Data Block 2.2 i节点表(Inode Table) 2.3 块位图(Block Bitmap) 2.4 inode位图(Inode Bitmap) 2.5 GDT(Group Descriptor Table) 2.6 超…

谷歌手机刷机和面具ROOT保姆级别教程

#比较常用的谷歌输入root面具教程,逆向工程师必修课程# 所需工具与材料清单 真机设备 推荐使用 Google Pixel 4 或其他兼容设备,确保硬件支持刷机操作。 ADB 环境配置 通过安装 Android Studio 自动配置 ADB 和 Fastboot 工具。安装完成后,需在系统环境…

平衡二叉搜索树 - 红黑树详解

文章目录一、红黑树概念引申问题二、红黑树操作一、红黑树概念 红黑树是一棵二叉搜索树,它在每个节点上增加了一个存储位用来表示节点颜色(红色或者黑色),红黑树通过约束颜色,可以保证最长路径不超过最短路径的两倍,因而近似平衡…