首页 > 其他分享 >Pytorch根据论文手搓CoPE

Pytorch根据论文手搓CoPE

时间:2024-06-03 16:32:17浏览次数:9  
标签:CoPE self 论文 value states Pytorch num key attn

根据论文《Contextual Position Encoding: Learning to Count What’s Important》编写的CoPE代码。具备多头计算能力,本人水平不高,个人代码未经验证,有问题和建议欢迎指出。

CoPE代码为代替Llama Model中的RoPE而设计,因此函数名称类似于LlamaModel的RoPE,但实际功能略有不同,有待商榷,使用猴子补丁动态替换LlamaAttention中的forward来达到使用CoPE的目的。

1. llama attention init函数

def llama_attn_init(self, config: LlamaConfig):
    super(LlamaAttention, self).__init__()
    self.config = config
    self.hidden_size = config.hidden_size
    self.num_heads = config.num_attention_heads
    self.head_dim = self.hidden_size // self.num_heads
    self.num_key_value_heads = config.num_key_value_heads
    self.num_key_value_groups = self.num_heads // self.num_key_value_heads
    self.max_position_embeddings = config.max_position_embeddings

    if (self.head_dim * self.num_heads) != self.hidden_size:
        raise ValueError(
            f"hidden_size must be divisible by num_heads (got `hidden_size`: {self.hidden_size}"
            f" and `num_heads`: {self.num_heads})."
        )
    self.q_proj = nn.Linear(self.hidden_size, self.num_heads * self.head_dim, bias=False)
    self.k_proj = nn.Linear(self.hidden_size, self.num_key_value_heads * self.head_dim, bias=False)
    self.v_proj = nn.Linear(self.hidden_size, self.num_key_value_heads * self.head_dim, bias=False)
    self.o_proj = nn.Linear(self.num_heads * self.head_dim, self.hidden_size, bias=False)
    self._init_cope()

2. init cope函数

def _init_cope(self):
    self.max_cope_position = self.config.max_cope_position
    self.cope_embeddings = nn.Parameter(
        torch.randn(self.num_heads, self.max_cope_position, self.hidden_size // self.num_heads))

3. llama attention forward函数

def llama_attn_forward(
        self,
        hidden_states: torch.Tensor,
        attention_mask: Optional[torch.Tensor] = None,
        position_ids: Optional[torch.LongTensor] = None,
        past_key_value: Optional[Tuple[torch.Tensor]] = None,
        output_attentions: bool = False,
        use_cache: bool = False,
) -> Tuple[torch.Tensor, Optional[torch.Tensor], Optional[Tuple[torch.Tensor]]]:
    bsz, q_len, _ = hidden_states.size()
    print("modified llama_attn_forward")

    if self.config.pretraining_tp > 1:
        key_value_slicing = (self.num_key_value_heads * self.head_dim) // self.config.pretraining_tp
        query_slices = self.q_proj.weight.split(
            (self.num_heads * self.head_dim) // self.config.pretraining_tp, dim=0
        )
        key_slices = self.k_proj.weight.split(key_value_slicing, dim=0)
        value_slices = self.v_proj.weight.split(key_value_slicing, dim=0)

        query_states = [F.linear(hidden_states, query_slices[i]) for i in range(self.config.pretraining_tp)]
        query_states = torch.cat(query_states, dim=-1)

        key_states = [F.linear(hidden_states, key_slices[i]) for i in range(self.config.pretraining_tp)]
        key_states = torch.cat(key_states, dim=-1)

        value_states = [F.linear(hidden_states, value_slices[i]) for i in range(self.config.pretraining_tp)]
        value_states = torch.cat(value_states, dim=-1)

    else:
        query_states = self.q_proj(hidden_states)
        key_states = self.k_proj(hidden_states)
        value_states = self.v_proj(hidden_states)

    query_states = query_states.view(bsz, q_len, self.num_heads, self.head_dim).transpose(1, 2)
    key_states = key_states.view(bsz, q_len, self.num_key_value_heads, self.head_dim).transpose(1, 2)
    value_states = value_states.view(bsz, q_len, self.num_key_value_heads, self.head_dim).transpose(1, 2)

    kv_seq_len = key_states.shape[-2]
    if past_key_value is not None:
        kv_seq_len += past_key_value[0].shape[-2]
    position_weight = apply_cope_emb(query_states, key_states, self.cope_embeddings, self.max_cope_position)

    if past_key_value is not None:
        # reuse k, v, self_attention
        key_states = torch.cat([past_key_value[0], key_states], dim=2)
        value_states = torch.cat([past_key_value[1], value_states], dim=2)

    past_key_value = (key_states, value_states) if use_cache else None

    # repeat k/v heads if n_kv_heads < n_heads
    key_states = repeat_kv(key_states, self.num_key_value_groups)
    value_states = repeat_kv(value_states, self.num_key_value_groups)

    attn_weights = torch.matmul(query_states, key_states.transpose(2, 3)) / math.sqrt(self.head_dim)
    attn_weights = attn_weights + position_weight

    if attn_weights.size() != (bsz, self.num_heads, q_len, kv_seq_len):
        raise ValueError(
            f"Attention weights should be of size {(bsz, self.num_heads, q_len, kv_seq_len)}, but is"
            f" {attn_weights.size()}"
        )

    if attention_mask is not None:
        if attention_mask.size() != (bsz, 1, q_len, kv_seq_len):
            raise ValueError(
                f"Attention mask should be of size {(bsz, 1, q_len, kv_seq_len)}, but is {attention_mask.size()}"
            )
        attn_weights = attn_weights + attention_mask

    # upcast attention to fp32
    attn_weights = nn.functional.softmax(attn_weights, dim=-1, dtype=torch.float32).to(query_states.dtype)
    attn_output = torch.matmul(attn_weights, value_states)

    if attn_output.size() != (bsz, self.num_heads, q_len, self.head_dim):
        raise ValueError(
            f"`attn_output` should be of size {(bsz, self.num_heads, q_len, self.head_dim)}, but is"
            f" {attn_output.size()}"
        )

    attn_output = attn_output.transpose(1, 2).contiguous()
    attn_output = attn_output.reshape(bsz, q_len, self.hidden_size)

    if self.config.pretraining_tp > 1:
        attn_output = attn_output.split(self.hidden_size // self.config.pretraining_tp, dim=2)
        o_proj_slices = self.o_proj.weight.split(self.hidden_size // self.config.pretraining_tp, dim=1)
        attn_output = sum([F.linear(attn_output[i], o_proj_slices[i]) for i in range(self.config.pretraining_tp)])
    else:
        attn_output = self.o_proj(attn_output)

    if not output_attentions:
        attn_weights = None

    return attn_output, attn_weights, past_key_value

4. 使用示例

LlamaAttention._init_cope = _init_cope
LlamaAttention.__init__ = llama_attn_init
LlamaAttention.forward = llama_attn_forward
config = LlamaConfig(num_layers=3, num_heads=2, hidden_size=128, intermediate_size=256, hidden_act="gelu",
                     max_cope_position=128)  # add an extra new parameter max_cope_position
model = LlamaModel(config)
print(model)
inputs_embeds = torch.randn(1, 5, 128)
output = model(inputs_embeds=inputs_embeds)

 

标签:CoPE,self,论文,value,states,Pytorch,num,key,attn
From: https://www.cnblogs.com/myendless/p/18229166

相关文章

  • AI降重神器:笔灵AI降重如何让论文查重率大幅下降?
    论文降重一直是困扰各界毕业生的“拦路虎”,还不容易熬过修改的苦,又要迎来降重的痛。其实想要给论文降重达标,我有一些独家秘诀。话不多说直接上干货!1、同义词改写(针对整段整句重复)这是最靠谱也是比较费精力的办法,就是在保证同义的情况下改写内容,幅度要大。往往需要整段改写,一......
  • 论文AI率太高怎么办?ai降重工具能解决吗?
    如何有效降低AIGC论文的重复率,也就是我们说的aigc如何降重?AIGC疑似度过高确实是个比较愁人的问题。如果你用AI帮忙写了论文,就一定要在交稿之前做一下AIGC降重的检查。一般来说,如果论文的AIGC超过30%,很可能会被判定为AI代写,从而无法参加答辩,影响毕业。那么如何降低AIGC的疑似度......
  • AI降重工具笔灵AI:如何帮助学生快速通过论文查重?
    论文降重一直是困扰各界毕业生的“拦路虎”,还不容易熬过修改的苦,又要迎来降重的痛。其实想要给论文降重达标,我有一些独家秘诀。话不多说直接上干货!1、同义词改写(针对整段整句重复)这是最靠谱也是比较费精力的办法,就是在保证同义的情况下改写内容,幅度要大。往往需要整段改写,一......
  • AI降重工具:如何使用它们有效降低论文AI率?
    如何有效降低AIGC论文的重复率,也就是我们说的aigc如何降重?AIGC疑似度过高确实是个比较愁人的问题。如果你用AI帮忙写了论文,就一定要在交稿之前做一下AIGC降重的检查。一般来说,如果论文的AIGC超过30%,很可能会被判定为AI代写,从而无法参加答辩,影响毕业。那么如何降低AIGC的疑似度......
  • 论文降重新策略:笔灵AI降重如何提高论文质量?
    论文降重一直是困扰各界毕业生的“拦路虎”,还不容易熬过修改的苦,又要迎来降重的痛。其实想要给论文降重达标,我有一些独家秘诀。话不多说直接上干货!1、同义词改写(针对整段整句重复)这是最靠谱也是比较费精力的办法,就是在保证同义的情况下改写内容,幅度要大。往往需要整段改写,一......
  • 论文降重:笔灵AIGC去痕工具是如何帮助降低AI率的?
    如何有效降低AIGC论文的重复率,也就是我们说的aigc如何降重?AIGC疑似度过高确实是个比较愁人的问题。如果你用AI帮忙写了论文,就一定要在交稿之前做一下AIGC降重的检查。一般来说,如果论文的AIGC超过30%,很可能会被判定为AI代写,从而无法参加答辩,影响毕业。那么如何降低AIGC的疑似度......
  • 论文降重不再难:AI降重工具笔灵AI降重的使用方法是什么?
    论文降重一直是困扰各界毕业生的“拦路虎”,还不容易熬过修改的苦,又要迎来降重的痛。其实想要给论文降重达标,我有一些独家秘诀。话不多说直接上干货!1、同义词改写(针对整段整句重复)这是最靠谱也是比较费精力的办法,就是在保证同义的情况下改写内容,幅度要大。往往需要整段改写,一......
  • 如何避免AIGC论文被判定为AI代写?论文降重技巧
    如何有效降低AIGC论文的重复率,也就是我们说的aigc如何降重?AIGC疑似度过高确实是个比较愁人的问题。如果你用AI帮忙写了论文,就一定要在交稿之前做一下AIGC降重的检查。一般来说,如果论文的AIGC超过30%,很可能会被判定为AI代写,从而无法参加答辩,影响毕业。那么如何降低AIGC的疑似度......
  • 论文降重技巧:AI工具如何助力论文原创性提升?
    论文降重一直是困扰各界毕业生的“拦路虎”,还不容易熬过修改的苦,又要迎来降重的痛。其实想要给论文降重达标,我有一些独家秘诀。话不多说直接上干货!1、同义词改写(针对整段整句重复)这是最靠谱也是比较费精力的办法,就是在保证同义的情况下改写内容,幅度要大。往往需要整段改写,一......
  • 论文AI率太高怎么办?AI降重方法大揭秘
    如何有效降低AIGC论文的重复率,也就是我们说的aigc如何降重?AIGC疑似度过高确实是个比较愁人的问题。如果你用AI帮忙写了论文,就一定要在交稿之前做一下AIGC降重的检查。一般来说,如果论文的AIGC超过30%,很可能会被判定为AI代写,从而无法参加答辩,影响毕业。那么如何降低AIGC的疑似度......