深度学习_GPT2Block详解(casual attention)

一、GTP2Block 整体结构

1.1 block准备

import torch 
from torch import nn
from transformers import GPT2Model, GPT2Config
from transformers.models.gpt2.modeling_gpt2 import GPT2Block

cfg = GPT2Config()
print(cfg.add_cross_attention)
blk = GPT2Block(cfg, layer_idx=0)
hidden_states = torch.randn(10, 1024, 768)

1.2 block架构

经典的preNorm TFDecoder架构

GPT2Block(
  (ln_1): LayerNorm((768,), eps=1e-05, elementwise_affine=True)
  (attn): GPT2Attention(
    (c_attn): Conv1D()
    (c_proj): Conv1D()
    (attn_dropout): Dropout(p=0.1, inplace=False)
    (resid_dropout): Dropout(p=0.1, inplace=False)
  )
  (ln_2): LayerNorm((768,), eps=1e-05, elementwise_affine=True)
  (mlp): GPT2MLP(
    (c_fc): Conv1D()
    (c_proj): Conv1D()
    (act): NewGELUActivation()
    (dropout): Dropout(p=0.1, inplace=False)
  )
)

1.3 forward-preNorm

y = attn(ln_1(x)) + x
O = mlp(ln_2(y)) + y

在这里插入图片描述
在这里插入图片描述

二、GPT2Attention

  1. hidden 拆分成 q k v: query, key, value = gpt2_att.c_attn(hidden_states).split(split_size, dim=2)
  2. q k v 拆分成多头
query = gpt2_att._split_heads(query, gpt2_att.num_heads, gpt2_att.head_dim)
key = gpt2_att._split_heads(key, gpt2_att.num_heads, gpt2_att.head_dim)
value = gpt2_att._split_heads(value, gpt2_att.num_heads, gpt2_att.head_dim)
print(f'{query.shape=}') # [batch, n_head, len, head_emb] 
  1. 计算attention
    1. A ^ = Q K T K d i m \hat{A}=\frac{QK^T}{\sqrt{K_{dim}}} A^=Kdim QKT 代码中用的是 V d i m \sqrt{V_{dim}} Vdim
    2. casual attention: 对原始attn进行mask
    3. 计算mask后的attention: A = s o f t m a x ( A ^ , d i m = − 1 ) A=softmax(\hat{A}, dim=-1) A=softmax(A^,dim=1)
    4. O = A V O=AV O=AV
# 3- attention 
#  3.1 A = QK^T
attn_weights = torch.matmul(query, key.transpose(-1, -2)) / torch.full([], value.size(-1) ** 0.5)
#  3.2 mask 
max_positions = 1024
causal_mask = torch.tril(
    torch.ones((max_positions, max_positions), dtype=torch.bool)
).view(1, 1, max_positions, max_positions)
mask_value = torch.finfo(attn_weights.dtype).min
mask_value = torch.full([], mask_value, dtype=attn_weights.dtype).to(attn_weights.device)
# where mask
attn_weights = torch.where(causal_mask, attn_weights.to(attn_weights.dtype), mask_value)
#  3.3 A = softmax(A)
attn_weights = nn.functional.softmax(attn_weights, dim=-1) # [batch, n_head, len, len] 
#  3.4  O = AV
attn_output = torch.matmul(attn_weights, value)            # [batch, n_head, len, head_emb] 
# 4- q k v -> merge head -> attn_out # [batch, len, head_emb*n_head] 
attn_output = gpt2_att._merge_heads(attn_output, gpt2_att.num_heads, gpt2_att.head_dim)
  1. 多头合并 [batch, n_head, len, head_emb] =>> [batch, len, head_emb*n_head]
    1. attn_output = gpt2_att._merge_heads(attn_output, gpt2_att.num_heads, gpt2_att.head_dim)

pic-attn_weights mask前后

三、GPT2MLP

结构比较简单 O = d r o p O u t ( σ ( X W 1 ) W 2 ) O=dropOut(\sigma (XW_1)W_2) O=dropOut(σ(XW1)W2),主要是激活函数 NewGELU

GPT2MLP(
  (c_fc): Conv1D()
  (c_proj): Conv1D()
  (act): NewGELUActivation()
  (dropout): Dropout(p=0.1, inplace=False)
)

class NewGELUActivation(nn.Module):
    """
    Implementation of the GELU activation function currently in Google BERT repo (identical to OpenAI GPT). Also see
    the Gaussian Error Linear Units paper: https://arxiv.org/abs/1606.08415
    """

    def forward(self, input: Tensor) -> Tensor:
        return 0.5 * input * (1.0 + torch.tanh(math.sqrt(2.0 / math.pi) * (input + 0.044715 * torch.pow(input, 3.0))))

在这里插入图片描述

NewGELUActivation 它是高斯误差线性单元(Gaussian Error Linear Unit,简称 GELU)的一种变体。GELU 激活函数在近年来的深度学习模型中越来越受欢迎,尤其是在自然语言处理(NLP)领域,如 BERT 和 GPT 等模型中。

GELU 激活函数的数学定义是输入值 x 乘以标准正态分布的累积分布函数(CDF)在该点的值。具体来说,GELU 的表达式为:
G E L U ( x ) = x Φ ( x ) GELU(x)=x \Phi(x) GELU(x)=xΦ(x)

其中 Φ ( x ) \Phi(x) Φ(x) 是标准正态分布的 CDF,可以通过误差函数(error function,记为 erf)来计算:
Φ ( x ) = 1 2 ( 1 + e r f ( x 2 ) ) \Phi(x)=\frac{1}{2}(1+erf(\frac{x}{\sqrt 2})) Φ(x)=21(1+erf(2 x))
GPT2中用了近似公式:
σ ( x ) = 0.5 x [ 1 + t a n h ( 2 π ( x + 0.044715 x 3 ) ) ] \sigma(x) = 0.5x [1+ tanh(\sqrt{\frac{2}{\pi}} (x + 0.044715 x^3))] σ(x)=0.5x[1+tanh(π2 (x+0.044715x3))]

GELU 激活函数的优点包括:

  • 平滑性:GELU 在整个实数域上都是平滑的,这有助于梯度的传播,减少了梯度消失或爆炸的问题
  • 非单调性:GELU 函数是非单调的,这意味着它能够捕捉数据中的更复杂模式
  • 改善性能:在某些任务中,使用 GELU 激活函数的模型性能优于使用传统的 ReLU 或其他激活函数的模型。
### 回答1: 在transformers模块中,没有名为modeling_gpt2的属性。 我们知道,transformers库是一个用于自然语言处理(NLP)任务的常用工具包,它包含了各种预训练模型和训练模型的工具函数。 在这个错误中,出现了"module transformers has no attribute modeling_gpt2"的错误提示。这意味着我们在transformers模块中尝试访问modeling_gpt2属性,但是并没有找到这个属性。 可能的原因是我们导入了transformers模块,但是没有正确引入所需的模型或模型类。 对于GPT-2模型,我们应该使用"from transformers import GPT2Model"来导入GPT-2模型类,而不是modeling_gpt2属性。 请确保您在代码中正确导入了所需的模型类或属性,并使用适当的名称进行访问。如果您正在尝试访问的模型或属性不存在,您需要检查transformers库的版本和更新情况,或者查看文档以了解如何正确使用该库。 ### 回答2: 在transformers模块中没有名为modeling_gpt2的属性。这是因为最新版本的transformers库已经重新组织了其内部结构和命名规则。以前版本的transformers库中,GPT-2模型相关的代码被命名为modeling_gpt2,但在最新版本中已经进行了重构和重命名。 现在,GPT-2模型相关的代码在transformers模块中被命名为GPT2Model。如果您想使用GPT-2模型,可以通过以下代码来实例化一个GPT2Model对象: ```python from transformers import GPT2Model model = GPT2Model.from_pretrained('gpt2') ``` 注意,为了使用GPT-2模型,您需要先安装transformers库,并且通过`pip install transformers`命令来安装它的相应版本。 总结一下,"module transformers has no attribute modeling_gpt2"的错误信息是因为您正在引用一个过时的命名。在最新版本的transformers库中,GPT-2模型的代码被命名为GPT2Model,而不再是modeling_gpt2。 ### 回答3: 在transformers模块中找不到属性modeling_gpt2的原因可能有以下几种情况: 1. 版本不匹配:可能您使用的transformers版本过低,缺少了modeling_gpt2这个属性。建议您升级transformers到最新版本,并且检查是否安装了正确的版本。 2. 模型名称错误:modeling_gpt2是指GPT2模型的具体实现,因此如果您在代码中使用模型时,错误地使用了别的模型名称,就会报错找不到modeling_gpt2属性。请确保在代码中正确地引用了GPT2模型。 3. 错误导入:可能您导入transformers模块时出现错误,导致没有正确地加载modeling_gpt2属性。请检查您导入transformers的代码,确保正确地导入了模块。 如果以上三种情况都检查过了,仍然找不到modeling_gpt2属性,建议查阅transformers库的官方文档,了解该属性是否在您使用的版本中可用。另外,您还可以尝试搜索相关的解决方案或者咨询transformers社区来获取更多帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Scc_hy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值