从头构建gpt2 基于Transformer

从头构建gpt2 基于Transformer

VX关注{晓理紫|小李子},获取技术推送信息,如感兴趣,请转发给有需要的同学,谢谢支持!!

如果你感觉对你有所帮助,请关注我。

源码获取 VX关注晓理紫并回复“chatgpt-0”

在这里插入图片描述

  • 头文件以及超参数
import torch
import torch.nn as nn
from torch.nn import functional as F
# 加入为了扩大网络进行修改 head ,注意力、前向网络添加了dropout和设置蹭数目
#超参数
batch_size = 64
block_size = 34 #块大小 现在有34个上下文字符来预测
max_iters = 5000
eval_interval = 500
learning_rate=3e-4
device = 'cuda' if torch.cuda.is_available() else 'cpu'
eval_iters = 200
n_embd = 384  #嵌入维度
n_head = 6    #有6个头,每个头有284/6维
n_layer = 6   # 6层
dropout = 0.2torch.manual_seed(1337)
  • 数据处理

with open('input.txt','r',encoding='utf-8') as f:text = f.read()chars = sorted(list(set(text)))
vocab_size = len(chars)stoi = {ch:i for i,ch in enumerate(chars)}itos = {i:ch for i,ch in enumerate(chars)}encode = lambda s : [stoi[c] for c in s]
decode = lambda l: ''.join([itos[i] for i in l])data = torch.tensor(encode(text),dtype=torch.long)n = int(0.9*len(data))
train_data = data[:n]
val_data = data[n:]def get_batch(split):data = train_data if split=="train" else val_dataix = torch.randint(len(data)-batch_size,(batch_size,))x = torch.stack([data[i:i+block_size] for i in ix])y = torch.stack([data[i+1:i+block_size+1] for i in ix])x,y = x.to(device),y.to(device)return x,y
  • 估计损失
@torch.no_grad()
def estimate_loos(model):out={}model.eval()for split in ['train','val']:losses = torch.zeros(eval_iters)for k in range(eval_iters):x,y = get_batch(split)logits,loss = model(x,y)losses[k] = loss.mean()out[split] = losses.mean()model.train()return out
  • 单头注意力
class Head(nn.Module):"""one head of self-attention"""def __init__(self, head_size):super(Head,self).__init__()self.key = nn.Linear(n_embd,head_size,bias=False)self.query = nn.Linear(n_embd,head_size,bias=False)self.value= nn.Linear(n_embd,head_size,bias=False)self.register_buffer('tril',torch.tril(torch.ones(block_size,block_size)))self.dropout = nn.Dropout(dropout)def forward(self,x):B,T,C = x.shapek = self.key(x) #(B,T,C)q = self.query(x) #(B,T,C)wei = q@k.transpose(-2,-1)*C**-0.5  #(B,T,C) @ (B,C,T)-->(B,T,T)wei = wei.masked_fill(self.tril[:T,:T]==0,float('-inf'))#(B,T,T)wei = F.softmax(wei,dim=-1) #(B,T,T)wei = self.dropout(wei)v= self.value(x)out = wei@vreturn out
  • 多头注意力

在这里插入图片描述

class MultiHeadAttention(nn.Module):"""multiple heads of self-attention in parallel"""def __init__(self, num_heads,head_size) -> None:super(MultiHeadAttention,self).__init__()self.heads = nn.ModuleList([Head(head_size) for _ in range(num_heads)])self.proj = nn.Linear(n_embd,n_embd) #投影,为了方便使用惨差跳连self.dropout = nn.Dropout(dropout)def forward(self,x):out = torch.cat([h(x) for h in self.heads],dim=-1)out = self.dropout(self.proj(out))return out
  • 前馈网络

在这里插入图片描述

class FeedFoward(nn.Module):"""a simple linear layer followed by a non-linearity"""def __init__(self,n_embd):super().__init__()self.net = nn.Sequential(nn.Linear(n_embd,4*n_embd), #从512变成2048nn.ReLU(),nn.Linear(4*n_embd,n_embd), #从2048变成512nn.Dropout(dropout),  #Dropout 是可以在惨差链接之前加的东西)def forward(self,x):out = self.net(x)return out

在这里插入图片描述

class Block(nn.Module):"""Transformer block:communication followed by computation"""def __init__(self, n_embd,n_head) -> None:#n_embd 需要嵌入维度中的嵌入数量#n_head 头部数量super().__init__()head_size = n_embd//n_headself.sa = MultiHeadAttention(n_head,head_size) #通过多头注意力进行计算self.ffwd = FeedFoward(n_embd) # 对注意力计算的结果进行提要完成self.ln1 = nn.LayerNorm(n_embd) #层规范  对于优化深层网络很重要 论文Layer Normalizationself.ln2 = nn.LayerNorm(n_embd) #层规范def forward(self,x):# 通过使用残差网络的跳连进行x = x + self.sa(self.ln1(x)) x = x + self.ffwd(self.ln2(x))return x
  • 整个语言模型
class BigramLangeNodel(nn.Module):def __init__(self):super(BigramLangeNodel,self).__init__()self.token_embedding_table = nn.Embedding(vocab_size,n_embd) #令牌嵌入表,对标记的身份进行编码self.position_embedding_table = nn.Embedding(block_size,n_embd) #位置嵌入表,对标记的位置进行编码。从0到block_size大小减一的每个位置将获得自己的嵌入向量self.blocks = nn.Sequential(*[Block(n_embd,n_head=n_head) for _ in range(n_layer)]) #通过n_layer设置构建的曾数self.ln_f = nn.LayerNorm(n_embd)self.lm_head = nn.Linear(n_embd,vocab_size)  #进行令牌嵌入到logits的转换,这是语言头def forward(self,idx,targets=None):B,T = idx.shapetok_emb= self.token_embedding_table(idx) #(B,T,C) C是嵌入大小    根据idx内的令牌的身份进行编码pos_emb = self.position_embedding_table(torch.arange(T,device=device)) #(T,C) 从0到T减一的整数都嵌入到表中x = tok_emb+pos_emb #(B,T,C) 标记的身份嵌入与位置嵌入相加。x保存了身份以及身份出现的位置# x = self.sa_head(x)  #(B,T,C)x = self.blocks(x)x = self.ln_f(x)logits = self.lm_head(x) #(B,T,vocab_size)if targets is None:loss = Noneelse:B,T,C = logits.shapelogits = logits.view(B*T,C)targets = targets.view(B*T)loss = F.cross_entropy(logits,targets)return logits,lossdef generate(self,idx,max_new_tokens):for _ in range(max_new_tokens):idx_cond = idx[:,-block_size] logits,loss= self(idx_cond)logits = logits[:,-1,:]# becomes (B,C)probs = F.softmax(logits,dim=-1)idx_next = torch.multinomial(probs,num_samples=1)idx = torch.cat((idx,idx_next),dim=1) #(B,T+1)return idx
  • 训练
model = BigramLangeNodel()
m  = model.to(device)optimizer = torch.optim.AdamW(model.parameters(),lr = learning_rate)for iter in range(max_iters):if iter % eval_interval==0:losses = estimate_loos(model)print(f"step {iter}:train loss {losses['train']:.4f},val loss{losses['val']:.4f}")xb,yb = get_batch('train')logits,loss = model(xb,yb)optimizer.zero_grad(set_to_none=True)loss.backward()optimizer.step()context = torch.zeros((1,1),dtype=torch.long,device=device)
print(decode(m.generate(context,max_new_tokens=500)[0].tolist()))
  • 训练损失
step 0:train loss 4.3975,val loss4.3983
step 500:train loss 1.8497,val loss1.9600
step 1000:train loss 1.6500,val loss1.8210
step 1500:train loss 1.5530,val loss1.7376
step 2000:train loss 1.5034,val loss1.6891
step 2500:train loss 1.4665,val loss1.6638
step 3000:train loss 1.4431,val loss1.6457
step 3500:train loss 1.4156,val loss1.6209
step 4000:train loss 1.3958,val loss1.6025
step 4500:train loss 1.3855,val loss1.5988

简单实现自注意力

VX 关注{晓理紫|小李子},获取技术推送信息,如感兴趣,请转发给有需要的同学,谢谢支持!!

如果你感觉对你有所帮助,请关注我。

源码获取 VX关注晓理紫并回复“chatgpt-0”
在这里插入图片描述

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

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

相关文章

消息中间件之RocketMQ源码分析(二十九)

延迟消息投递机制 RocketMQ在存储延迟消息时,将其保存在一个系统的Topic中,在创建ConsumeQueue时,tagCode字段中保存着延迟消息需要被投递的时间,通过这个存储实现的思路,我们可以总结出延迟消息的投递过程:通过定时服…

C++入门07 数组、指针与字符串

图源:文心一言 听课笔记简单整理,供小伙伴们参考~🥝🥝 第1版:听课的记录代码~🧩🧩 编辑:梅头脑🌸 审核:文心一言 目录 🐳课程来源 &#x1…

逆序遍历字符串(不改变内存地址)

题目:逆序遍历字符串"ABCDEFG" 实现思路: 使用StringBuilder创建对象,因为String字符串是不可变的,而StringBuilder内部的方法没有被final关键字修饰,所以将s1的字符串内容传给StringBuilder创建的对象ret…

模拟算法题练习(一)(扫雷,灌溉,回文日期)

目录 模拟算法介绍: (一、扫雷) (二、灌溉) (三、回文日期) 有一说一这题大佬的题解是真的强 模拟算法介绍: 模拟算法通过模拟实际情况来解决问题,一般容易理解但是实…

c语言游戏实战(10):坤坤的篮球回避秀

前言: 这款简易版的球球大作战是博主耗时两天半完成的,玩家需要控制坤坤在游戏界面上移动,来躲避游戏界面上方不断掉下来的篮球。本游戏使用C语言和easyx图形库编写,旨在帮助初学者了解游戏开发的基本概念和技巧。 在开始编写代…

SpringMVC01、回顾MVC

1、回顾MVC 1.1、什么是MVC MVC是模型(Model)、视图(View)、控制器(Controller)的简写,是一种软件设计规范。是将业务逻辑、数据、显示分离的方法来组织代码。MVC主要作用是降低了视图与业务逻辑间的双向偶合。MVC不是一种设计模式,MVC是一种架构模式。…

Node.js中的并发和多线程处理

在Node.js中,处理并发和多线程是一个非常重要的话题。由于Node.js是单线程的,这意味着它在任何给定时间内只能执行一个任务。然而,Node.js的事件驱动和非阻塞I/O模型使得处理并发和多线程变得更加高效和简单。在本文中,我们将探讨…

恋爱话术小程序源码支持多种流量主模式

源码介绍 这就是一款恋爱话术小程序,该款小程序相对来说还是挺强大的 这款小程序基本分段都是和外面几千块几百块的分段是一样的,基本就是从开场-情绪-聊天-升级-邀约-约会等几大分类开始 然后每一大分类下面都有N个小分类来做识别 另外也支持输入对方的话或关键词获取相关的话…

Container killed on request. Exit code is 143

Bug信息 WARN YarnAllocator: Container marked as failed: container_e33_1480922439133_0845_02_000002 on host: hdp4. Exit status: 143. Diagnostics: Container killed on request. Exit code is 143 Container exited with a non-zero exit code 143 Killed by externa…

大数据技术(一)

大数据技术概述 大数据技术层面及其功能 数据采集与预处理 利用ETL(extract-transform-load)工具将分布的、异构数据源中的数据,如关系数据、平面数据文件等,抽取到临时中间层后进行清洗、转换、集成,最后加载到数据仓库或数据集市中&…

机器人 标准DH与改进DH

文章目录 1 建立机器人坐标系1.1 连杆编号1.2 关节编号1.3 坐标系方向2 标准DH(STD)2.1 确定X轴方向2.2 建模步骤2.3 变换顺序2.4 变换矩阵3 改进DH(MDH)3.1 确定X轴方向3.2 建模步骤3.3 变换顺序3.4 变换矩阵4 标准DH与改进DH区别5 Matlab示例参考链接1 建立机器人坐标系 1.1…

【Python】变量的引用

🚩 WRITE IN FRONT 🚩 🔎 介绍:"謓泽"正在路上朝着"攻城狮"方向"前进四" 🔎🏅 荣誉:2021|2022年度博客之星物联网与嵌入式开发TOP5|TOP4、2021|2222年获评…

微服务day04-基于Feign的远程调用

一.Feign的认识 是http客户端,因为使用RestTemplate存在一些问题:代码可读性差,参数配置费事,不够优雅… String url"http://userservice/user/"order.getUserId(); User userrestTemplate.getForObject(url,User.cla…

【AIGC】如何提高Prompt准确度

前言 随着人工智能的迅猛进展,AIGC(通用人工智能聊天工具)已成为多个行业中不可或缺的自然语言处理技术。Prompt作为AIGC系统的一项关键功能,在工具的有效运作中发挥了举足轻重的作用。本篇文章将深入探讨Prompt与AIGC之间的紧密…

OpenLayers线性渐变和中心渐变(径向渐变)

目录 1.前言2.添加一个面要素3.线性渐变3.1 第一个注意点3.2 第二个注意点 4.中心渐变(径向渐变)5.总结 1.前言 OpenLayers官网有整个图层的渐变示例,但是没有单个要素的渐变示例,我们这里来补充一下。OpenLayers中的渐变是通过fi…

PostgreSQL restartpoint 原理详解

背景 大部分人对 PG 的 checkpoint 机制会熟悉一点,但是对 restartpoint 却不太熟悉,网上介绍这方面的文章也比较少。因此,本文将以 PG 14.7 的社区代码为基础,介绍 PG 中的 restartpoint 机制。 原理介绍 什么是 restartpoint…

Docker的基础知识与应用技巧

文章目录 一.docekr简介二.docekr安装三.docker命令 一.docekr简介 Docker是一个开源的应用容器引擎,它可以让开发者打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的Linux或Windows操作系统的机器上。Docker基于轻量级虚拟化技术&a…

2024022701-信息安全(二)——密码学

密码学的基本概念 密码学(Cryptology): 研究信息系统安全保密的科学。 密码编码学(Cryptography): 研究对信息进行编码,实现对信息的隐蔽。 密码分析学(Cryptanalytics) : 研究加密消息的破译或消息的伪造。 消息被称为明文(Plaintext)。 用…

【CSS】(浮动定位)易忘知识点汇总

浮动特性 加了浮动之后的元素,会具有很多特性,需要我们掌握的. 1、浮动元素会脱离标准流(脱标:浮动的盒子不再保留原先的位置) 2、浮动的元素会一行内显示并且元素顶部对齐 注意: 浮动的元素是互相贴靠在一起的(不会有缝隙)&…

用于游戏开发的顶级 PYTHON 框架

一、说明 我们试图用python开发游戏,一旦产生这个念头,就伴随这样一个问题:当今用于构建游戏的领先 Python 框架有哪些?python下,支持游戏开发平台有哪些优势?我们在这篇博文中告诉你。 二、高级游戏平台简…