您现在的位置是:首页 > 正文

逐行对比LLaMA2和LLaMA模型源代码

2024-02-01 06:40:49阅读 3

几个小时前(2023年7月18日),Meta发布了允许商用的开源模型LLaMA2。笔者逐行对比了LLaMA2模型源代码,和LLaMA相比,几乎没有改动,细节如下:

是否改动 LLaMA2 LLaMA
模型整体构架 Transformer Transformer
规范化函数 均方根规范化(RMSNorm) 均方根规范化(RMSNorm)
位置编码 复数形式的旋转位置编码(RoPE) 复数形式的旋转位置编码(RoPE)
激活函数 SiLU SiLU
注意力机制 略有改动 分组查询多头注意力机制 多头注意力机制
前馈函数 逐元素前馈函数 逐元素前馈函数
连接 残差连接 残差连接
掩码 因果掩码 因果掩码
推理 略有改动 自回归推理 自回归推理

第二版的模型代码,增加了一个repeat_kv函数如下:

def repeat_kv(x: torch.Tensor, n_rep: int) -> torch.Tensor:
    """torch.repeat_interleave(x, dim=2, repeats=n_rep)"""
    bs, slen, n_kv_heads, head_dim = x.shape
    if n_rep == 1:
        return x
    return (
        x[:, :, :, None, :]
        .expand(bs, slen, n_kv_heads, n_rep, head_dim)
        .reshape(bs, slen, n_kv_heads * n_rep, head_dim)
    )

这个函数在多头注意力机制的前馈函数中使用。

在前馈函数应用位置编码之后,应用查询之前调用:

        # repeat k/v heads if n_kv_heads < n_heads
        keys = repeat_kv(keys, self.n_rep)  # (bs, seqlen, n_local_heads, head_dim)
        values = repeat_kv(values, self.n_rep)  # (bs, seqlen, n_local_heads, head_dim)

这个函数主要作用是当键(key)和值(value)的头数小于查询(query)的头数时,将键和值的头数复制至与查询头数相同。

这个函数的功能并不奇怪,在模型编写的过程中,矩阵变换和匹配是常见的操作。比较奇怪的是代码的写法有点反直觉,这种写法并不象预先设计的,更象是一个补丁。

笔者先叠个甲,在并未做实验的基础上做如下猜测:

支持LLaMA论文提出的分组查询注意力机制(Grouped-Query Attention)。但为什么不能预分配键值的数量而是在位置变换后再单独用一个函数来处理呢?也可以这样解释:为了减少计算负担或存储需求。这是因为键和值的数量直接影响了注意力矩阵和值矩阵的大小,如果序列长度非常大,这些矩阵的存储和计算可能会变得非常昂贵。通过减少键和值的头数,可以有效地减少存储和计算的需求。在这种情况下,需要在计算注意力权重前,将键和值的头数通过复制的方式扩展到与查询头数一样多,才能进行查询和键的点积操作。

在推理函数中,第一版的输出:

output(h[:, -1, :]).float()

不论输入序列的长度为多少,只输出最后一个时间步的词的概率

而第二版的输出,改成:

output(h).float()

对于输入序列中的每个位置,该函数都会输出一个词汇表大小的向量,表示每个词的概率。

如果只是拿来生成下一个词,比如ChatGPT的典型续写应用,这两者没有区别。

网站文章

  • fork源码分析

    文章目录

    2024-02-01 06:40:24
  • 计算机语言bus代表什么,计算机中bus指什么

    大家好,我是时间财富网智能客服时间君,上述问题将由我为大家进行解答。计算机中bus是指总线,总线的作用就是在计算机各部件之间传递信息,由数据总线,地址总线和控制总线组成。总线(Bus)是计算机各种功能...

    2024-02-01 06:40:17
  • 【漏洞复现】JDWP远程命令执行漏洞

    【漏洞复现】JDWP远程命令执行漏洞

    0x01 漏洞描述JPDA(Java Platform Debugger Architecture):即Java平台调试体系架构。Java虚拟机设计的专门的API接口供调试和监控虚拟机使用JPDA按照...

    2024-02-01 06:40:09
  • Node.js模块加载机制

    I. 使用require()加载自定义模块是,必须以./或者…/开头的路径标识符。在加载自定义模块时,如果没有指定./或者…/这样的路径标识符,则node会把它当作内置模块或者第三方模块进行加载。II...

    2024-02-01 06:39:41
  • 从源码分析:Java中的SPI是怎样工作的

    spi介绍提到api,大家或多或少地都接触或者使用过,但是如果说到spi呢,可能了解的人就要少一些。Java SPI的全...

    2024-02-01 06:39:33
  • 家用 文件服务器,家用文件服务器

    家用 文件服务器,家用文件服务器

    家用文件服务器 内容精选换一换远程桌面协议(Remote Desktop Protocol,RDP),是微软提供的多通道的远程登录协议。本节为您介绍如何使用RDP文件远程登录Windows弹性云服务器...

    2024-02-01 06:39:25
  • SpringCloud-向Eureka注册中心注册微服务(微服务的搭建)

    SpringCloud-向Eureka注册中心注册微服务(微服务的搭建)

    Eureka注册中心注册微服务 注明:此项目为本人学习尚硅谷老师的教学视频然后整理核心的配置文件,所有的项目均在以下地址下载。https://github.com/xwbGithub/microservicecloud下载, 本章讲解请参考microservicecloud-provider-dept-8001,首先微服务的服务中心...

    2024-02-01 06:38:54
  • spring实现aop的步骤

    spring实现aop的步骤

    首先注意导入一个jar包! 在applicationContext.xml中配置扫包 :开启aop的自动代理 切面类 @Component//spri

    2024-02-01 06:38:47
  • 爬虫技术原来可以做这么多牛逼哄哄的事情!

    爬虫技术原来可以做这么多牛逼哄哄的事情!

    对于很多对于不懂编程语言的GGMM来说,爬虫技术高深莫测。但是对于IT工程师来说,爬虫技术可以说信手拈来。虽然熟知爬虫技术,你是否知道它竟然可以做这么多这么牛逼哄哄的事情! 1.利用爬虫技术抓取公司用户信息 公司有15k员工,办公系统的hr模块,只要有部门级的管理人员权限就可以看自己部门的几百名员工资料,包括历年历月的工资条和具体个人信息。关键是,网页地址上有员工编号,如果改一下编号...

    2024-02-01 06:38:41
  • 构建工具webpack与babel使用

    构建工具webpack与babel使用

    Babel入门 一、Bable是什么 Babel是一个广泛使用的转码器,可以将ES6代码转为ES5代码,从而在现有环境执行。 这意味着,你可以现在就用 ES6 编写程序,而不用担心现有环境是否支持。下...

    2024-02-01 06:38:34