如何修改大模型的位置编码 --以LLama为例

这篇具有很好参考价值的文章主要介绍了如何修改大模型的位置编码 --以LLama为例。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

最近在看RoPE相关内容,一些方法通过简单修改位置编码就可以无需训练支持更长的文本内容。由于一些模型,已经训练好了,但是怎么修改已经训练好的模型位置编码。查了以下相关代码,记录一下。原理这里就不细讲了,贴几个相关博客。
十分钟读懂旋转编码(RoPE)
Transformer升级之路:11、将β进制位置进行到底
Transformer升级之路:10、RoPE是一种β进制编码

NTK

下图为NTK的原理证明:截取自Transformer升级之路:10、RoPE是一种β进制编码
修改大模型代码,llama
修改大模型代码,llama

看了上面的公式,我在考虑为什么需要建立 λ \lambda λ和k之间的关系?

因为我们要修改 β \beta β进制为 β λ \beta\lambda βλ,由于k我们是可以知道的比如我们需要把位置编码缩小为10倍,直接设置k为10,但是采用NTK的方式,维度缩小为10倍,那么我们就不确定, λ \lambda λ怎么设置了。所以需要简历 λ \lambda λ和k之间的关系,从上图可知, λ = k 2 / ( d − 2 ) \lambda=k^{2/(d-2)} λ=k2/(d2)
下面开始理解如何修改RoPE为NTK的形式:
以下为LLama的RoPE代码实现

class LlamaRotaryEmbedding(nn.Module):
    def __init__(self, dim, max_position_embeddings=2048, base=10000, device=None, scaling_factor=1.0):
        super().__init__()
        self.scaling_factor = scaling_factor
        self.dim = dim
        self.max_position_embeddings = max_position_embeddings
        self.base = base
        inv_freq = 1.0 / (self.base ** (torch.arange(0, self.dim, 2, dtype=torch.int64).float().to(device) / self.dim))
        self.register_buffer("inv_freq", inv_freq, persistent=False)
        # For BC we register cos and sin cached
        self.max_seq_len_cached = max_position_embeddings
        t = torch.arange(self.max_seq_len_cached, device=device, dtype=torch.int64).type_as(self.inv_freq)
        t = t / self.scaling_factor
        freqs = torch.outer(t, self.inv_freq)
        # Different from paper, but it uses a different permutation in order to obtain the same calculation
        emb = torch.cat((freqs, freqs), dim=-1)
        self.register_buffer("_cos_cached", emb.cos().to(torch.get_default_dtype()), persistent=False)
        self.register_buffer("_sin_cached", emb.sin().to(torch.get_default_dtype()), persistent=False)

    @property
    def sin_cached(self):
        logger.warning_once(
            "The sin_cached attribute will be removed in 4.39. Bear in mind that its contents changed in v4.38. Use "
            "the forward method of RoPE from now on instead. It is not used in the `LlamaAttention` class"
        )
        return self._sin_cached

    @property
    def cos_cached(self):
        logger.warning_once(
            "The cos_cached attribute will be removed in 4.39. Bear in mind that its contents changed in v4.38. Use "
            "the forward method of RoPE from now on instead. It is not used in the `LlamaAttention` class"
        )
        return self._cos_cached

    @torch.no_grad()
    def forward(self, x, position_ids):
        # x: [bs, num_attention_heads, seq_len, head_size]
        inv_freq_expanded = self.inv_freq[None, :, None].float().expand(position_ids.shape[0], -1, 1)
        position_ids_expanded = position_ids[:, None, :].float()
        # Force float32 since bfloat16 loses precision on long contexts
        # See https://github.com/huggingface/transformers/pull/29285
        device_type = x.device.type
        device_type = device_type if isinstance(device_type, str) and device_type != "mps" else "cpu"
        with torch.autocast(device_type=device_type, enabled=False):
            freqs = (inv_freq_expanded.float() @ position_ids_expanded.float()).transpose(1, 2)
            emb = torch.cat((freqs, freqs), dim=-1)
            cos = emb.cos()
            sin = emb.sin()
        return cos.to(dtype=x.dtype), sin.to(dtype=x.dtype)

λ \lambda λ和k之间的关系,那么代码怎么实现呢,我们只需要修改 β λ \beta\lambda βλ的结果即可,其中 β \beta β 1000 0 2 / d 10000^{2/d} 100002/d
参考代码为:点击

import transformers

old_init = transformers.models.llama.modeling_llama.LlamaRotaryEmbedding.__init__
def ntk_scaled_init(self, dim, max_position_embeddings=2048, base=10000, device=None):

    #The method is just these three lines
    max_position_embeddings = 16384
    k = 8 #Alpha value
    base = base * k ** (dim / (dim-2)) #Base change formula

    old_init(self, dim, max_position_embeddings, base, device)
transformers.models.llama.modeling_llama.LlamaRotaryEmbedding.__init__ = ntk_scaled_init

为什么采用base = base * k ** (dim / (dim-2)),原始的base为10000, 而 β \beta β 1000 0 2 / d 10000^{2/d} 100002/d,发现在代码里面修改的仅仅是base的结果, β \beta β= b a s e 2 / d base^{2/d} base2/d,而 λ = k 2 / ( d − 2 ) \lambda=k^{2/(d-2)} λ=k2/(d2),我们需要把k和base进行融合,修改成,base*k的形式形成新的base, λ \lambda λ等于k的指数 2 / ( d − 2 ) ∗ d / 2 ∗ 2 / d = d / ( d − 2 ) ∗ 2 / d 2/(d-2)*d/2*2/d=d/(d-2)*2/d 2/(d2)d/22/d=d/(d2)2/d λ = ( k d / ( d − 2 ) ) 2 / d \lambda=(k^{d/(d-2)})^{2/d} λ=(kd/(d2))2/d,因为2/d在RoPE的代码里面已经计算过了:

inv_freq = 1.0 / (self.base ** (torch.arange(0, self.dim, 2, dtype=torch.int64).float().to(device) / self.dim)

所以我们则赋值新的base为base * k ** (dim / (dim-2))。

Dynamic NTK

Dynamic在NTK的基础上进行简单的修改,采用NTK的时候更加灵活。
截图源于:RoPE到底是何方神圣(数学推理+优化方法)
修改大模型代码,llama
代码实现:文章来源地址https://www.toymoban.com/news/detail-851913.html

class LlamaDynamicNTKScalingRotaryEmbedding(LlamaRotaryEmbedding):
    """LlamaRotaryEmbedding extended with Dynamic NTK scaling. Credits to the Reddit users /u/bloc97 and /u/emozilla"""

    def forward(self, x, position_ids):
        # difference to the original RoPE: inv_freq is recomputed when the sequence length > original length
        seq_len = torch.max(position_ids) + 1
        if seq_len > self.max_position_embeddings:#只有长度超过了预训练的阈值,进行NTK
            base = self.base * (
                (self.scaling_factor * seq_len / self.max_position_embeddings) - (self.scaling_factor - 1)
            ) ** (self.dim / (self.dim - 2))
            inv_freq = 1.0 / (
                base ** (torch.arange(0, self.dim, 2, dtype=torch.int64).float().to(x.device) / self.dim)
            )
            self.register_buffer("inv_freq", inv_freq, persistent=False)  # TODO joao: this may break with compilation

        cos, sin = super().forward(x, position_ids)
        return cos, sin

到了这里,关于如何修改大模型的位置编码 --以LLama为例的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 以Llama-2为例,在生成模型中使用自定义LogitsProcessor

    在上一篇文章 以Llama-2为例,在生成模型中使用自定义StoppingCriteria中,介绍了怎样在生成的过程中,使用 stopping criteria 来控制生成过程的结束,本文将继续这一话题,结合具体的场景,介绍如何实现自定义的 logits processor ,并以此来控制生成的过程。 场景延续上篇介绍stop

    2024年02月14日
    浏览(23)
  • 以Llama-2为例,在生成模型中使用自定义StoppingCriteria

    在之前的文章中,介绍了使用transformers模块创建的模型,其generate方法的详细原理和使用方法,文章链接: 以beam search为例,详解transformers中generate方法(上) 以beam search为例,详解transformers中generate方法(下) 其中提到了用户参与生成过程的两个关键组件, logits_processor 和

    2024年02月14日
    浏览(35)
  • 【Python】科研代码学习:十五 configuration,tokenization 的代码细节:Llama 为例

    对于 HF 的 Transformers 库的经典 API 以及大致架构我们都从前面已经学习的差不多了 【动机】那还剩下几个小问题,就是: Tokenizer 和 Specific Model 的运作原理是什么? 我如何查看与修改模型的架构?前向与反向传播过程?损失计算?激活函数? 这些模型层面的内容,如何学习

    2024年03月22日
    浏览(27)
  • [玩转AIGC]如何训练LLaMA2(模型训练、推理、代码讲解,并附可直接运行的kaggle连接)

    Llama 2,基于优化的 Transformer 架构,是Meta AI正式发布的最新一代开源大模型,一系列模型(7b、13b、70b)均开源可商用,效果直逼gpt3.5。 下面我们来介绍如何使用Llama 2来训练一个故事生成模型。 如果迫不及待想爽一把先,请直接跳到这里,可直接运行:llama2-c, 学习不就是

    2024年02月12日
    浏览(31)
  • 中文LLaMa和Alpaca大语言模型开源方案 | 扩充中文词表 & 针对中文语料进行高效编码

    欢迎关注『CVHub』官方微信公众号! Title: Efficient and Effective Text Encoding for Chinese Llama and Alpaca PDF: https://arxiv.org/pdf/2304.08177v1.pdf Code: https://github.com/ymcui/Chinese-LLaMA-Alpaca 大型语言模型 LLM ,如ChatGPT和GPT-4,已经彻底改变了自然语言处理研究。然而, LLMs 的昂贵训练和部署对于透明

    2024年02月09日
    浏览(41)
  • 逐行对比LLaMA2和LLaMA模型源代码

    几个小时前(2023年7月18日),Meta发布了允许商用的开源模型LLaMA2。笔者逐行对比了LLaMA2模型源代码,和LLaMA相比,几乎没有改动,细节如下: 是否改动 LLaMA2 LLaMA 模型整体构架 无 Transformer Transformer 规范化函数 无 均方根规范化(RMSNorm) 均方根规范化(RMSNorm) 位置编码 无

    2024年02月16日
    浏览(35)
  • Meta语言模型LLaMA解读:模型的下载部署与运行代码

    Meta最新语言模型LLaMA解读,LLaMA是Facebook AI Research团队于2023年发布的一种语言模型,这是一个基础语言模型的集合。 体验地址 模型下载地址 下载步骤 准备工作 先注册登录 授权,需要一段时间, 需要使用gls 什么是Git LFS git是程序员开发程序不可或缺的工具,有效的使用git能

    2024年02月08日
    浏览(37)
  • [玩转AIGC]LLaMA2之如何微调模型

    首先我们从github上下载Llama 2的微调代码:GitHub - facebookresearch/llama-recipes: Examples and recipes for Llama 2 model 执行命令: 下载完成之后,安装对应环境,执行命令: 在这里我补充一下模型下载权限的申请 需先在Meta上申请权限(国家选中国不行,要选其他国家) https://ai.meta.com/re

    2024年02月03日
    浏览(35)
  • LLMs之llama_7b_qlora:源代码解读export_hf_checkpoint.py(模型权重合并文件)将LORA模型的权重合并回原始模型的权重(hf_llama_model+llama_

    LLMs之llama_7b_qlora:源码解读export_hf_checkpoint.py模型权重合并文件)将LORA模型的权重合并回原始模型的权重(hf_llama_model+llama_7b_qlora),并保存到指定的检查点文件中 目录

    2024年02月15日
    浏览(53)
  • LLM各层参数详细分析(以LLaMA为例)

    网上大多分析LLM参数的文章都比较粗粒度,对于LLM的精确部署不太友好,在这里记录一下分析LLM参数的过程。 首先看QKV。先上transformer原文 也就是说,当h(heads) = 1时,在默认情况下, W i Q W_i^Q W i Q ​ 、 W i K W_i^K W i K ​ 、 W i V W_i^V W i V ​ 都是2维方阵,方阵维度是 d m o

    2024年02月07日
    浏览(28)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包