從頭構建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.pswp.cn/news/716571.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/716571.shtml
英文地址,請注明出處:http://en.pswp.cn/news/716571.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

CSS 自測題

盒模型的寬度計算 默認為標準盒模型 box-sizing:content-box; offsetWidth (內容寬度內邊距 邊框),無外邊距 答案 122px通過 box-sizing: border-box; 可切換為 IE盒模型 offsetWidth width 即 100px margin 縱向重疊 相鄰元素的 margin-top 和 margin-bottom 會發…

leetcode-簡單

448. 找到所有數組中消失的數字 硬解 時間O(n)&#xff0c;空間O(n) class Solution { public:vector<int> findDisappearedNumbers(vector<int>& nums) {vector<int> result;vector<int> tem(nums.size()1, 0);for(int i: nums){tem[i] 1;}for…

Benchmark學習筆記

小記一篇Benchmark的學習筆記 1.什么是benchmark 在維基百科中&#xff0c;是這樣子講的 “As computer architecture advanced, it became more difficult to compare the performance of various computer systems simply by looking at their specifications.Therefore, te…

python標識符、變量和常量

一、保留字與標識符 1.1保留字 保留字是指python中被賦予特定意義的單詞&#xff0c;在開發程序時&#xff0c;不可以把這些保留字作為變量、函數、類、模塊和其它對象的名稱來使用。 比如&#xff1a;and、as、def、if、import、class、finally、with等 查詢這些關鍵字的方…

【LeetCode】升級打怪之路 Day 11 加餐:單調隊列

今日題目&#xff1a; 239. 滑動窗口最大值 | LeetCode 今天學習了單調隊列這種特殊的數據結構&#xff0c;思路很新穎&#xff0c;值得學習。 Problem&#xff1a;單調隊列 【必會】 與單調棧類似&#xff0c;單調隊列也是一種特殊的數據結構&#xff0c;它相比與普通的 que…

【NR 定位】3GPP NR Positioning 5G定位標準解讀(一)

目錄 前言 1. 3GPP規劃下的5G技術演進 2. 5G NR定位技術的發展 2.1 Rel-16首次對基于5G的定位技術進行標準化 2.2 Rel-17進一步提升5G定位技術的性能 3. Rel-18 關于5G定位技術的新方向、新進展 3.1 Sidelink高精度定位功能 3.2 針對上述不同用例&#xff0c;3GPP考慮按…

自動駕駛---Motion Planning之Speed Boundary(上)

1 背景 在上篇博客《自動駕駛---Motion Planning之Path Boundary》中,筆者主要介紹了path boundary的一些內容,通過將道路中感興趣區域的動靜態障礙物投影到車道坐標系中,用于確定L或者S的邊界,并利用道路信息再確定Speed的邊界,最后結合粗糙的速度曲線和路徑曲線,即可使…

Go-知識簡短變量聲明

Go-知識簡短變量聲明 1. 簡短變量聲明符2. 簡短變量賦值可能會重新聲明3. 簡短變量賦值不能用于函數外部4. 簡短變量賦值作用域問題5. 總結 githuio地址&#xff1a;https://a18792721831.github.io/ 1. 簡短變量聲明符 在Go語言中&#xff0c;可以使用關鍵字var或直接使用簡短…

【STK】手把手教你利用STK進行仿真-STK軟件基礎02 STK系統的軟件界面01 STK的界面窗口組成

STK系統是Windows窗口類型的桌面應用軟件,功能非常強大。在一個桌面應用軟件中集成了仿真對象管理、仿真對象屬性參數、設置、空間場景二三維可視化、場景顯示控制欲操作、仿真結果報表定制與分析、對象數據管理、仿真過程控制、外部接口連接和系統集成編程等復雜的功能。 STK…

SpringBoot之Actuator的兩種監控模式

SpringBoot之Actuator的兩種監控模式 springboot提供了很多的檢測端點(Endpoint),但是默認值開啟了shutdown的Endpoint&#xff0c;其他默認都是關閉的,可根據需要自行開啟 文章目錄 SpringBoot之Actuator的兩種監控模式1. pom.xml2. 監控模式1. HTTP2. JMX 1. pom.xml <de…

力扣 第 125 場雙周賽 解題報告 | 珂學家 | 樹形DP + 組合數學

前言 整體評價 T4感覺有簡單的方法&#xff0c;無奈樹形DP一條路上走到黑了&#xff0c;這場還是有難度的。 T1. 超過閾值的最少操作數 I 思路: 模擬 class Solution {public int minOperations(int[] nums, int k) {return (int)Arrays.stream(nums).filter(x -> x <…

VM虛擬機無法傳輸文件(更新時間24/3/3)

出現這個問題一般是未安裝VMware Tools 以下為手動安裝教程及可能出現的問題的解決方法&#xff1a; 1. 準備安裝 2.用cmd手動啟動安裝 3. 安裝過程默認即可&#xff0c;直接一直下一步 4.安裝完成后會自動重啟虛擬機&#xff08;沒有的話手動重啟即可&#xff09; 5.重啟以后…

Web應用安全威脅與防護措施

本文已收錄至《全國計算機等級考試——信息 安全技術》專欄 由于極其容易出現漏洞、并引發安全事故&#xff0c;因此數據隱私的保護是目前絕大多數企業不可繞過的運維環節。不過&#xff0c;許多中小型企業往往會錯誤地認為只有大型企業才會成為黑客的目標。而實際統計數字卻截…

StarCoder2模型,釋放你的大模型編碼潛能

每周跟蹤AI熱點新聞動向和震撼發展 想要探索生成式人工智能的前沿進展嗎&#xff1f;訂閱我們的簡報&#xff0c;深入解析最新的技術突破、實際應用案例和未來的趨勢。與全球數同行一同&#xff0c;從行業內部的深度分析和實用指南中受益。不要錯過這個機會&#xff0c;成為AI領…

DeepSpeed-Chat RLHF 階段代碼解讀(0) —— 原始 PPO 代碼解讀

為了理解 DeepSpeed-Chat RLHF 的 RLHF 全部過程&#xff0c;這個系列會分三篇文章分別介紹&#xff1a; 原始 PPO 代碼解讀RLHF 獎勵函數代碼解讀RLHF PPO 代碼解讀 這是系列的第一篇文章&#xff0c;我們來一步一步的看 PPO 算法的代碼實現&#xff0c;對于 PPO 算法原理不太…

部署若依前后端分離項目,連接數據庫失敗

部署若依前后端分離項目&#xff0c;連接數據庫失敗&#xff0c;異常如下&#xff1a; 解決方案&#xff1a;application配置文件里&#xff0c;連接數據庫的參數useSSL的值改為false

leetcode 長度最小的子數組

在本題中&#xff0c;我們可以知道&#xff0c;是要求數組中組成和為target的最小子數組的長度。所以&#xff0c;我們肯定可以想到用兩層for循環進行遍歷&#xff0c;然后枚舉所有的結果進行挑選&#xff0c;但這樣時間復雜度過高。 我們可以采用滑動窗口&#xff0c;其實就是…

編寫dockerfile掛載卷、數據容器卷

編寫dockerfile掛載卷 編寫dockerfile文件 [rootwq docker-test-volume]# vim dockerfile1 [rootwq docker-test-volume]# cat dockerfile1 FROM centosVOLUME ["volume01","volume02"]CMD echo "------end------" CMD /bin/bash [rootwq dock…

2024 年廣東省職業院校技能大賽(高職組)“云計算應用”賽項樣題 2

#需要資源或有問題的&#xff0c;可私博主&#xff01;&#xff01;&#xff01; #需要資源或有問題的&#xff0c;可私博主&#xff01;&#xff01;&#xff01; #需要資源或有問題的&#xff0c;可私博主&#xff01;&#xff01;&#xff01; 某企業根據自身業務需求&#…

每日OJ題_牛客_合法括號序列判斷

目錄 合法括號序列判斷 解析代碼 合法括號序列判斷 合法括號序列判斷__牛客網 解析代碼 class Parenthesis {public:bool chkParenthesis(string A, int n){if (n & 1) // 如果n是奇數return false;stack<char> st;for (int i 0; i < n; i) {if (A[i] () {s…