pos機(jī)出現(xiàn)代碼04,PyTorch 就可以復(fù)現(xiàn)代碼

 新聞資訊  |   2023-05-17 12:20  |  投稿人:pos機(jī)之家

網(wǎng)上有很多關(guān)于pos機(jī)出現(xiàn)代碼04,PyTorch 就可以復(fù)現(xiàn)代碼的知識,也有很多人為大家解答關(guān)于pos機(jī)出現(xiàn)代碼04的問題,今天pos機(jī)之家(www.rcqwhg.com)為大家整理了關(guān)于這方面的知識,讓我們一起來看下吧!

本文目錄一覽:

1、pos機(jī)出現(xiàn)代碼04

pos機(jī)出現(xiàn)代碼04

歡迎來到「帶注釋的 GPT-2」。

我讀過的最精彩、解釋最清楚的文章之一是「The Annotated Transformer」https://nlp.seas.harvard.edu/2018/04/03/attention.html。它引起了前所未有的關(guān)注,一個簡單的想法就是用一個文件注釋你所需要的代碼。

我在機(jī)器學(xué)習(xí)方面的經(jīng)驗讓我意識到,當(dāng)你將事情寫成代碼的時候,其實現(xiàn)和秘密會變得更清晰,而不再是魔法了。

魔法沒有什么神奇的。魔術(shù)師只是理解一些簡單的東西,而這些東西對未經(jīng)訓(xùn)練的觀眾來說似乎并不簡單。一旦你學(xué)會了操作魔術(shù)卡片,你也可以變魔術(shù)。

——Jeffrey Friedl 在《Mastering Regular Expressions》一書中寫道

GPT-2 一開始看起來像是魔術(shù),它的看起來太美麗了,但希望我能為你解釋魔術(shù),在你讀完這篇文章時揭示所有的技巧,這是我的目標(biāo)。使那些熱衷于理解 GPT-2 模型是如何工作的人更好理解。

注:幾乎所有代碼都是從Hugging Face(https://github.com/huggingface/transformers/blob/master/src/transformers/modeling_gpt2.py)的 GPT-2 實現(xiàn)中復(fù)制、啟發(fā)和引用的,只保留了簡單的基本要素。如果你想在并行 GPU 上訓(xùn)練 GPT-2 模型,在微調(diào)時保存檢查點,在多個 CPU 上運行推理任務(wù)等等,我建議你使用 Hugging Face API。最近,Hugging Face 發(fā)布了一個簡單的教程,它教你如何做到這一點:https://huggingface.co/blog/how-to-train。

在這篇文章中,我并不是在試圖重新發(fā)明輪子,而是僅僅把一系列已經(jīng)存在的優(yōu)秀資源放在一起,讓讀者更容易掌握 GPT-2。我讓讀者在他們所選擇的任何領(lǐng)域進(jìn)一步建立這些基礎(chǔ)。

你不能在弱小的基礎(chǔ)上建造一座偉大的建筑。如果你要有一個強(qiáng)大的上層建筑,你必須有堅實的基礎(chǔ)。

——Gordon B. Hinckley

學(xué)習(xí)本教程的先決條件

本文假設(shè)讀者對注意力機(jī)制和 tansformers 有著扎實的理解。GPT-2 采用 12 層的,僅有解碼器的 transformer 架構(gòu)。如果你想復(fù)習(xí)一下或了解注意力機(jī)制和 transformers,這里有一個很好的資源列表:

Jay Alammar 的 The illustrated Transformer:http://jalammar.github.io/illustrated-transformer/

哈佛大學(xué) The Annotated Transformer:https://nlp.seas.harvard.edu/2018/04/03/attention.html

Rachel Thomas 和 Jeremy Howard的 Introduction to the Transformer:https://www.youtube.com/watch?v=AFkGPmU16QA&list=PLtmWHNX-gukKocXQOkQjuVxglSDYWsSh9&index=18&t=0s

如果你剛剛開始你的 NLP 之旅,或者你是一個專家,我絕對會推薦 Rachel Thomas 和 Jeremy Howard 教授的 fast.ai NLP 課程(https://www.fast.ai/2019/07/08/fastai-nlp/)。本課程從基礎(chǔ)開始,包括使用樸素貝葉斯和 Logistic 回歸進(jìn)行語義分類,接著是 RNN,后面還討論了遷移學(xué)習(xí)、ULMFiT、Seq2Seq 翻譯和 transformers 等。它是 fast.ai 團(tuán)隊免費提供的優(yōu)秀資源。

另一個關(guān)于 GPT-2 本身的優(yōu)秀資源,是 Jay Alammar 的 The Illustrated GPT-2(http://jalammar.github.io/illustrated-gpt2/)。本文從語言模型的基本介紹開始,以一種非常容易理解的方式逐步解釋 GPT-2 模型。我強(qiáng)烈建議讀者閱讀這篇文章。

哈佛大學(xué) The Annotated Transformer 使用 PyTorch 實現(xiàn)了完整的 transformer 架構(gòu),是深入理解 transformer 的好方法。

然后,讓我們在這些優(yōu)秀的現(xiàn)有資源的基礎(chǔ)上,用代碼實現(xiàn) GPT-2 吧~

摘要

自然語言處理任務(wù),如問答、機(jī)器翻譯、閱讀理解等,通常是在特定任務(wù)的數(shù)據(jù)集上進(jìn)行有監(jiān)督的學(xué)習(xí)。我們證明,當(dāng)語言模型在一個名為 WebText 的數(shù)百萬網(wǎng)頁的新數(shù)據(jù)集上訓(xùn)練時,它開始學(xué)習(xí)這些任務(wù),而不需要任何明確的監(jiān)督。我們最大的模型,GPT-2,是一個 1.5B 參數(shù)的 transformer,它可以獲得最先進(jìn)的語言建模成果,但仍然不適合 WebText。模型中的示例反映了這些改進(jìn),并包含連貫的文本段落。這些發(fā)現(xiàn)為構(gòu)建語言處理系統(tǒng)提供了一條有希望的途徑,該系統(tǒng)可以從自然發(fā)生的演示中學(xué)習(xí)執(zhí)行任務(wù)。

Zero-shot 設(shè)置是不微調(diào)語言模型并直接在目標(biāo)數(shù)據(jù)集上運行推理的設(shè)置。例如,在 WebText 上預(yù)覽一個 LM,并直接嘗試預(yù)測 Amazon 影評數(shù)據(jù)集的下一個單詞。

模型架構(gòu)(GPT-2)

我們的 LM 使用基于 transformer 的架構(gòu)。該模型主要遵循 OpenAI GPT 模型的細(xì)節(jié),并進(jìn)行了一些修改。層規(guī)范化被移動到每個子塊的輸入,類似于預(yù)激活剩余網(wǎng)絡(luò),并且在最終的自關(guān)注塊之后添加了額外的層規(guī)范化。我們在初始化時將剩余層的權(quán)重按 1/√N(yùn) 的因子進(jìn)行縮放,其中 N 是剩余層的數(shù)量。詞匯量擴(kuò)大到 50257 個單詞。我們還將上下文大小從 512 增加到 1024 個,并使用更大的批大小——512。

模型規(guī)格(GPT)

我們的模型基本上遵循了最初 transformer 的工作原理。我們訓(xùn)練了一個 12 層的只解碼的 transformer,它有隱藏的自注意力頭(768 維狀態(tài)和 12 個注意力頭)。對于位置前饋網(wǎng)絡(luò),我們使用了 3072 維的內(nèi)部狀態(tài)。我們使用 Adam 優(yōu)化方案,最大學(xué)習(xí)速率為 2.5e-4。學(xué)習(xí)速率在前 2000 次更新中從零線性增加,并使用余弦調(diào)度將其退火為 0。我們在 64 個隨機(jī)抽樣的小批量、512 個令牌的連續(xù)序列上訓(xùn)練了 100 個階段。由于 layernorm 在整個模型中廣泛使用,簡單的 N(0,0.02)權(quán)重初始化就足夠了。我們使用了一個 bytepair 編碼(BPE)詞匯表。我們還采用了在中提出的 L2 正則化的改進(jìn)版本,在所有非偏倚或增益權(quán)重上的 w=0.01。對于激活函數(shù),我們使用高斯誤差線性單位(GELU)。

導(dǎo)入

import torch

import copy

import torch.nn as nn

import torch.nn.functional as F

from torch.nn.modules import ModuleList

from torch.nn.modules.normalization import LayerNorm

import numpy as np

import os

from tqdm import tqdm_notebook, trange

import logging

logging.basicConfig(level = logging.INFO)

logger = logging.getLogger

GPT-2 內(nèi)部的 transformer 解碼器

要重用用于描述 transformer 的術(shù)語,注意是一個查詢(Q)和一組鍵(K)和值(V)對的函數(shù)。為了處理更長的序列,我們修改了 transformer 的多頭自注意力機(jī)制,通過限制 Q 和 K 之間的點積來減少內(nèi)存使用:

注意力是查詢、鍵和值的組合

class Conv1D(nn.Module):

def __init__(self, nx, nf): super.__init__

self.nf = nf

w = torch.empty(nx, nf)

nn.init.normal_(w, std=0.02)

self.weight = nn.Parameter(w)

self.bias = nn.Parameter(torch.zeros(nf))

def forward(self, x):

size_out = x.size[:-1] + (self.nf,)

x = torch.addmm(self.bias, x.view(-1, x.size(-1)), self.weight)

x = x.view(*size_out)

return x

CONV1D 層解釋

CONV1D 層本身可以看作是一個線性層。本質(zhì)上,它是投射一個初始張量 x(最終尺寸為 x.size(-1))并傳遞給它,最終尺寸為 self.nf。

下面是相同的輸出示例:

d_model = 768

conv1d = Conv1D(d_model, d_model*3)

x = torch.rand(1,4,d_model) #represents a sequence of batch_size=1, seq_len=4 and embedding_sz=768, something like "Hello how are you"

x = conv1d(x)

x.shape

>> torch.Size([1, 4, 2304])

如上例所示,CONV1D 返回的張量的最終維數(shù)是初始大小的 3 倍。我們這樣做是為了能夠?qū)⑤斎朕D(zhuǎn)換為查詢、鍵和值矩陣。

然后可以檢索查詢、鍵和值矩陣,如下所示:

query, key, value = x.split(d_model, dim=-1)

query.shape, key.shape, value.shape

>> (torch.Size([1, 4, 768]), torch.Size([1, 4, 768]), torch.Size([1, 4, 768]))

將輸入轉(zhuǎn)換為 Q、K 和 V 矩陣的另一種方法是必須有單獨的 Wq、Wk 和 Wv 矩陣。我已經(jīng)在這篇文章底部的附加部分解釋了這一點。我發(fā)現(xiàn)這種方法更直觀、更具相關(guān)性,但在本文中我們使用了 CONV1D 層,因為我們重用了 Hugging Face 的 CONV1D 預(yù)訓(xùn)練權(quán)重。

前向?qū)咏忉?/strong>

class FeedForward(nn.Module):

def __init__(self, dropout, d_model=768, nx=768*4):

super.__init__

self.c_fc = Conv1D(d_model, nx)

self.c_proj = Conv1D(nx, d_model)

self.act = F.gelu

self.dropout = nn.Dropout(dropout)

def forward(self, x):

return self.dropout(self.c_proj(self.act(self.c_fc(x))))

在 Jay Alammar 的文章中有一個很好的解釋,也就是上面提到的,輸入是如何先經(jīng)過注意力層,然后再進(jìn)入前向?qū)拥摹G梆伨W(wǎng)絡(luò)是一個正常的網(wǎng)絡(luò),它接受來自注意力層(768)的輸出,將其投射到 nx(768×4)維,添加一個激活函數(shù) self.act(GELU),將其投射回 d_model (768) 并添加 dropout(0.1)。

注意力層解釋

下面的摘錄是從論文上摘取的:https://arxiv.org/abs/1706.03762。

標(biāo)度點產(chǎn)品注意力

我們稱我們的注意力為「標(biāo)度點產(chǎn)品注意力」。輸入包括維度 dk 的查詢和鍵以及維度 dv 的值。我們使用所有鍵計算查詢的點積,用√dk除以每個鍵,然后應(yīng)用 softmax 函數(shù)獲得值的權(quán)重。

在實際應(yīng)用中,我們同時計算一組查詢的注意力函數(shù),將它們組合成一個矩陣 Q,并將鍵和值組合成矩陣 K 和 V。我們將輸出矩陣計算為:

輸出矩陣為 Q、K 和 V 的組合

最常用的兩個注意力函數(shù)是加性注意力函數(shù)和點積(乘法)力函數(shù)注意。除了比例因子 1/√dk 外,點積注意力與我們的算法相同。附加注意力使用具有單個隱藏層的前饋網(wǎng)絡(luò)計算兼容性函數(shù)。雖然二者在理論復(fù)雜度上相似,但在實際應(yīng)用中,點積注意力速度更快,空間效率更高,因為它可以使用高度優(yōu)化的矩陣乘法碼來實現(xiàn)。當(dāng) dk 值較小時,兩種機(jī)制的表現(xiàn)相似,但在 dk 值較大時,加性注意力優(yōu)于點積注意力。我們懷疑,對于 dk 的較大值,點積在數(shù)量上增長較大,將 softmax 函數(shù)推入具有極小梯度的區(qū)域。為了抵消這一影響,我們將網(wǎng)點產(chǎn)品縮放至 1/√dk。

為了在代碼中實現(xiàn)注意力層,我們首先利用 CONV1D 層,得到前面解釋的 Q、K 和 V 矩陣。

一旦我們有了 Q、K 和 V 矩陣,我們就可以使用函數(shù) _attn 來執(zhí)行注意力。此函數(shù)復(fù)制了上述注意力點積公式。

class Attention(nn.Module):

def __init__(self, d_model=768, n_head=12, n_ctx=1024, d_head=64, bias=True, scale=False):

super.__init__

self.n_head = n_head

self.d_model = d_model

self.c_attn = Conv1D(d_model, d_model*3)

self.scale = scale

self.softmax = nn.Softmax(dim=-1)

self.register_buffer("bias", torch.tril(torch.ones(n_ctx, n_ctx)).view(1, 1, n_ctx, n_ctx))

self.dropout = nn.Dropout(0.1)

self.c_proj = Conv1D(d_model, d_model)

def split_heads(self, x):

"return shape [`batch`, `head`, `sequence`, `features`]"

new_shape = x.size[:-1] + (self.n_head, x.size(-1)//self.n_head)

x = x.view(*new_shape)

return x.permute(0, 2, 1, 3)

def _attn(self, q, k, v, attn_mask=None):

scores = torch.matmul(q, k.transpose(-2, -1))

if self.scale: scores = scores/math.sqrt(v.size(-1))

nd, ns = scores.size(-2), scores.size(-1)

if attn_mask is not None: scores = scores + attn_mask

scores = self.softmax(scores)

scores = self.dropout(scores)

outputs = torch.matmul(scores, v)

return outputs

def merge_heads(self, x):

x = x.permute(0, 2, 1, 3).contiguous

new_shape = x.size[:-2] + (x.size(-2)*x.size(-1),)

return x.view(*new_shape)

def forward(self, x):

x = self.c_attn(x) #new `x` shape - `[1,3,2304]`

q, k, v = x.split(self.d_model, dim=2)

q, k, v = self.split_heads(q), self.split_heads(k), self.split_heads(v)

out = self._attn(q, k, v)

out = self.merge_heads(out)

out = self.c_proj(out)

return out

另一種實現(xiàn)注意力的方法在本博客底部的附加部分進(jìn)行了說明。我發(fā)現(xiàn)它更直觀,更容易與研究論文進(jìn)行比較。它利用線性層而不是 CONV1D 將輸入轉(zhuǎn)換為 Q、K 和 V 矩陣。我們之所以沒有使用它,是因為我們使用了預(yù)訓(xùn)練的權(quán)重,從 Hugging Face 轉(zhuǎn)換為一維層。

多頭注意力

下面一段是從論文「Attention is all you need」上摘取的。

我們發(fā)現(xiàn),使用不同的、學(xué)習(xí)到的線性映射將查詢、鍵和值分別線性映射到 dk、dk 和 dv 維度更好。然后,在這些查詢、鍵和值的隱射版本中,我們并行地執(zhí)行注意力函數(shù),生成 dv 維輸出值。這些值被連接起來,然后再次進(jìn)行映射,得到最終值,如下圖所示:

多頭注意力機(jī)制允許模型在不同的位置共同關(guān)注來自不同表示子空間的信息。

多頭注意力等式

在這項工作中,我們使用了 h=8 個平行的注意力層,或者說頭。其中,我們使用的都是 dk=dv=dmodel/h=64。由于每個頭的維數(shù)減少,總的計算成本與全維度的單頭部注意的計算成本相似。

不要被這個弄糊涂了,本質(zhì)上,我們所做的就是給 Q,K 和 V 矩陣增加一個維數(shù)。也就是說,如果這些矩陣之前的大小是 [1, 4, 768],表示 [bs, seq_len, d_model],則這些矩陣被投影到[bs, n_head, seq_len, d_model//n_head],大小為 [1, 12, 4, 64]。GPT-2 使用 12 個平行頭。我們將 Q,K,V 矩陣分解到 split_heads 函數(shù)中。最后,當(dāng)我們通過應(yīng)用并行注意力得到一個輸出時,我們將它連接到合并頭中,返回到維度矩陣 [bs,seq_len,d_model]。

代碼中的 GPT-2 模型體系結(jié)構(gòu)

到目前為止,我們已經(jīng)實現(xiàn)了多頭注意和前饋層。如上圖所示,這兩層構(gòu)成 transformer 解碼器塊的構(gòu)建塊。GPT-2 由 12 個 transformer 組組成。

這在 Jay Alammar 的文章中顯示如下:

由 12 個解碼塊組成的 GPT 體系結(jié)構(gòu)

transformer 解碼器塊說明

class TransformerBlock(nn.Module):

def __init__(self, d_model=768, n_head=12, dropout=0.1):

super(TransformerBlock, self).__init__

self.attn = Attention(d_model=768, n_head=12, d_head=64, n_ctx=1024, bias=True, scale=False)

self.feedforward = FeedForward(dropout=0.1, d_model=768, nx=768*4)

self.ln_1 = LayerNorm(d_model)

self.ln_2 = LayerNorm(d_model)

def forward(self, x):

x = x + self.attn(self.ln_1(x))

x = x + self.feedforward(self.ln_2(x))

return x

transformer 組由注意力層和前饋層組成,如 GPT-2 架構(gòu)模型規(guī)范所述:層規(guī)范化被移動到每個子塊的輸入,這里的子塊是注意力和前饋。

因此,在 transformer 解碼器塊中,我們首先將輸入傳遞給一個 LayerNorm,然后是第一個子注意力塊。接下來,我們將這個子塊的輸出再次傳遞給 LayerNorm,最后傳遞給前饋層。

GPT-2架構(gòu)說明

如 GPT 論文所述:我們訓(xùn)練了一個 12 層的只解碼的 transformer,它有隱藏的自注意力頭(768 個維度和 12 個注意力頭)。

因此,完整的 GPT-2 體系結(jié)構(gòu)是經(jīng)過 12 次復(fù)制的 TransformerBlock。

def _get_clones(module, n): return ModuleList([copy.deepcopy(module) for i in range(n)])

class GPT2(nn.Module):

def __init__(self, nlayers=12, n_ctx=1024, d_model=768, vcb_sz=50257):

super(GPT2, self).__init__

self.nlayers = nlayers

block = TransformerBlock(d_model=768, n_head=12, dropout=0.1)

self.h = _get_clones(block, 12)

self.wte = nn.Embedding(vcb_sz, d_model)

self.wpe = nn.Embedding(n_ctx, d_model)

self.drop = nn.Dropout(0.1)

self.ln_f = LayerNorm(d_model)

self.out = nn.Linear(d_model, vcb_sz, bias=False)

self.loss_fn = nn.CrossEntropyLoss

self.init_weights

def init_weights(self):

self.out.weight = self.wte.weight

self.apply(self._init_weights)

def _init_weights(self, module):

if isinstance(module, (nn.Linear, nn.Embedding, Conv1D)):

module.weight.data.normal_(mean=0.0, std=0.02)

if isinstance(module, (nn.Linear, Conv1D)) and module.bias is not None:

module.bias.data.zero_

elif isinstance(module, nn.LayerNorm):

module.bias.data.zero_

module.weight.data.fill_(1.0)

def forward(self, src, labels=None, pos_ids=None):

if pos_ids is None: pos_ids = torch.arange(0, src.size(-1)).unsqueeze(0)

inp = self.drop((self.wte(src)+self.wpe(pos_ids)))

for i in range(self.nlayers): inp = self.h[i](inp)

inp = self.ln_f(inp)

logits = self.out(inp)

outputs = (logits,) + (inp,)

if labels is not None:

shift_logits = logits[..., :-1, :].contiguous

shift_labels = labels[..., 1:].contiguous

loss = self.loss_fn(shift_logits.view(-1, shift_logits.size(-1)), shift_labels.view(-1))

outputs = (loss,) + outputs

return outputs

return logits

我還沒有提到的是位置編碼和標(biāo)記嵌入。因為,我們不能將諸如「hey」或「hello」之類的詞直接傳遞給模型,所以我們首先將輸入標(biāo)記化。接下來,我們使用嵌入將標(biāo)記表示為數(shù)字。Jay Alammar 的這篇文章(http://jalammar.github.io/illustrated-word2vec/)很好地解釋了嵌入。

此外,與按順序傳遞輸入詞的 RNN 不同,transformer 并行地接受輸入矩陣,從而失去了被輸入詞的位置感。為了彌補(bǔ)這一損失,在將標(biāo)記嵌入處理到模型之前,我們添加了 Positional Encoding——一種指示序列中單詞順序的信號。如前所述,由于 GPT-2 的上下文大小是 1024,因此位置編碼的維度是 [1024, 768]。

從[The Illustrated GPT-2]引用的位置編碼(http://jalammar.github.io/Illustrated-gpt2/)

因此,GPT-2 體系結(jié)構(gòu)的輸入是通過一個 Dropout 的標(biāo)記嵌入和位置編碼的總和。一旦我們有了輸入矩陣,我們就讓其通過 GPT-2 架構(gòu)的 12 層中的每一層,其中每一層都是一個由兩個子層組成的 transformer 譯碼器塊——注意力和前饋網(wǎng)絡(luò)。

語言建?;蚍诸?

當(dāng)使用 GPT-2 作為語言模型時,我們將輸入傳遞到最終層形式,并通過最終大小為[768, vocab_sz](50257)的線性層,得到大小為[1,4,50257]的輸出。這個輸出表示下一個詞匯輸入,我們現(xiàn)在可以很容易地通過一個 softmax 層,并使用 argmax 以最大的概率獲得單詞在詞匯表中的位置。

對于分類任務(wù),我們可以通過大小為 [768, n] 的線性層來傳遞從 GPT-2 架構(gòu)接收到的輸出,以獲得每個類別的概率(其中 n 表示類別的數(shù)量),然后通過 softmax 傳遞,得到最高的預(yù)測類別,并使用 CrossEntropyLoss 來訓(xùn)練架構(gòu)進(jìn)行分類。

這就是 GPT-2 背后的全部魔法。它是一種基于解碼器的 transformer 式結(jié)構(gòu),與 RNN 不同,它采用與位置編碼并行的輸入,通過 12 個 transformer 解碼器層(由多頭注意力和前饋網(wǎng)絡(luò)組成)中的每一層來返回最終輸出。

讓我們在語言模型任務(wù)中看看這個模型的實際作用。

使用 Hugging Face 預(yù)訓(xùn)練權(quán)重生成示例文本

首先,讓我們用 Hugging Face 提供的預(yù)訓(xùn)練權(quán)重初始化模型。

model = GPT2

# load pretrained_weights from hugging face

# download file https://s3.amazonaws.com/models.huggingface.co/bert/gpt2-pytorch_model.bin to `.`

model_dict = model.state_dict #currently with random initializationstate_dict = torch.load("./gpt2-pytorch_model.bin") #pretrained weights

old_keys =

new_keys =

for key in state_dict.keys:

if "mlp" in key: #The hugging face state dict references the feedforward network as mlp, need to replace to `feedforward` be able to reuse these weights

new_key = key.replace("mlp", "feedforward")

new_keys.append(new_key)

old_keys.append(key)

for old_key, new_key in zip(old_keys, new_keys): state_dict[new_key]=state_dict.pop(old_key)

pretrained_dict = {k: v for k, v in state_dict.items if k in model_dict}

model_dict.update(pretrained_dict)

model.load_state_dict(model_dict)

model.eval #model in inference mode as it\'s now initialized with pretrained weights

現(xiàn)在讓我們生成文本。我們將使用 Hugging Face 的預(yù)訓(xùn)練標(biāo)記器將單詞轉(zhuǎn)換為輸入嵌入。

from transformers import GPT2Tokenizer

tokenizer = GPT2Tokenizer.from_pretrained("gpt2")

context = torch.tensor([tokenizer.encode("The planet earth")])

def generate(context, ntok=20):

for _ in range(ntok):

out = model(context)

logits = out[:, -1, :]

indices_to_remove = logits logits[indices_to_remove] = np.NINF

next_tok = torch.multinomial(F.softmax(logits, dim=-1), num_samples=1).squeeze(1)

context = torch.cat([context, next_tok.unsqueeze(-1)], dim=-1)

return context

out = generate(context, ntok=20)tokenizer.decode(out[0])

>> \'The planet earth is the source of all of all the light," says the study that the government will\'

附加內(nèi)容

另一種實現(xiàn)注意力的方法,在 fast.ai 的 NLP 課程(https://github.com/fastai/course-nlp/blob/master/8-translation-transformer.ipynb)中有,我發(fā)現(xiàn)更直觀的方法如下:

class Attention_FASTAI(nn.Module):

def __init__(self, d_model=768, n_head=12, d_head=64, n_ctx=1024, bias=True, scale=False):

super.__init__

self.n_head = n_head

self.d_head = d_head

self.softmax = nn.Softmax(dim=-1)

self.scale = scale

self.atn_drop = nn.Dropout(0.1)

self.wq, self.wk, self.wv = [nn.Linear(d_model, n_head*d_head,

bias=bias) for o in range(3)]

def split_heads(self, x, layer, bs):

x = layer(x)

return x.view(bs, x.size(1), self.n_head, self.d_head).permute(0,2,1,3)

def _attn(self, q, k, v, attn_mask=None):

scores = torch.matmul(q, k.transpose(-2, -1))

if self.scale: scores = scores/math.sqrt(v.size(-1))

if attn_mask is not None:

scores = scores.float.masked_fill(attn_mask, -float(\'inf\')).type_as(scores)

attn_prob = self.atn_drop(self.softmax(scores))

attn_vec = attn_prob @ v

return attn_vec

def merge_heads(self, x, bs, seq_len):

x = x.permute(0, 2, 1, 3).contiguous

return x.view(bs, seq_len, -1)

def forward(self, q, k, v, mask=None):

bs, seq_len = q.size(0), q.size(1)

wq, wk, wv = map(lambda o:self.split_heads(*o, bs),

zip((q,k,v), (self.wq, self.wk, self.wv)))

attn_vec = self._attn(wq, wk, wv)

attn_vec = self.merge_heads(attn_vec, bs, seq_len)

return attn_vec

上面的實現(xiàn)與我們采用的實現(xiàn)方法的關(guān)鍵區(qū)別在于,這個實現(xiàn)沒有使用 CONV1D,而是先將輸入 x 傳遞給 self.wq、self.wk 和 self.wv 線性層,得到 wq、wk 和 wv 矩陣,然后接下來和前面一樣。

寫在最后

特別感謝 Hugging Face 創(chuàng)建了一個開源的 NLP 庫,并提供了許多可使用的預(yù)訓(xùn)練模型。如前所述,本文中的代碼直接來自 Hugging Face 庫。The Illustrated GPT-2(http://jalammar.github.io/illustrated-gpt2/)是關(guān)于 GPT-2 知識最全的博客之一。最后,Harvard NLP 的 The Annotated Transformer(https://nlp.seas.harvard.edu/2018/04/03/attention.html)完成了一個很棒且易于學(xué)習(xí)的 PyTorch 中 Transformers 的實現(xiàn)。

via:https://amaarora.github.io/2020/02/18/annotatedGPT2.html

雷鋒網(wǎng)雷鋒網(wǎng)雷鋒網(wǎng)

以上就是關(guān)于pos機(jī)出現(xiàn)代碼04,PyTorch 就可以復(fù)現(xiàn)代碼的知識,后面我們會繼續(xù)為大家整理關(guān)于pos機(jī)出現(xiàn)代碼04的知識,希望能夠幫助到大家!

轉(zhuǎn)發(fā)請帶上網(wǎng)址:http://www.rcqwhg.com/news/46970.html

你可能會喜歡:

版權(quán)聲明:本文內(nèi)容由互聯(lián)網(wǎng)用戶自發(fā)貢獻(xiàn),該文觀點僅代表作者本人。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如發(fā)現(xiàn)本站有涉嫌抄襲侵權(quán)/違法違規(guī)的內(nèi)容, 請發(fā)送郵件至 babsan@163.com 舉報,一經(jīng)查實,本站將立刻刪除。