首页 > 其他分享 >常见大模型——LLama系列

常见大模型——LLama系列

时间:2024-10-31 16:15:36浏览次数:3  
标签:系列 LLama 模型 torch freqs GQA LLaMA theta

LLaMA简介

LLaMA(Large Language Model Meta AI)是由Meta开发的一种大规模语言模型,旨在提高自然语言处理任务的性能。LLaMA基于Transformer机构,并经过大规模数据训练,以便在多种语言任务中表现出色。
LLaMA所采用的Transformer结构和细节,与标准的Transformer结构不同的地方是包括了采用前置层归一化(Pre-normalization)并使用RMSNorm归一化函数(Normalizing Function)、激活函数更换为了SwiGLU,并使用了旋转位置嵌入(RoPE),整体Transformer架构与GPT-2类似。
在这里插入图片描述

RMSNorm归一化函数

为了使得模型训练的过程更加稳定,GPT-2相较于GPT就引入了前置层归一化方法,将第一个归一化移动到了多头注意力层之前,第二个归一化也移动到了全连接层之前,同时残差链接的位置也调整到了多头注意力层与全连接层之后。归一化中也采用了RMSNorm归一化函数。针对输入向量RNSNorm函数的计算公式如下:
在这里插入图片描述
代码实现如下:

class LLaMARMSNorm(nn.Module):
	def __init__(self,hidden_size,eps=1e-6):
		super().__init__()
		self.weight=nn.Parameter(torch.ones(hidden_size))
		self.variance_epsilon=eps
	def forward(self,hidden_states):
		input_dtype=hidden_states.dtype
		variance=hidden_states.to(torch.float32).pow(2).mean(-1,keepdim=True)
		hidden_states=hidden_states*torch.rsqrt(variance+self.variance_epsilon)
		return (self.weight*hidden_states).to(input_dtype)

SwiGLU激活函数

SwiGLU激活函数是相较于ReLU函数在大部分测评中都有不少的提升。在LLaMA中全连接层使用带有SwiGLU激活函数的FFN(Position-wise Feef-Forward Network)计算公式如下:
在这里插入图片描述
其中Swish函数是Sigmoid函数。当取不同的β时,激活函数的图像如下图所示。当β趋近于0时,Swish函数趋近于线性函数y=x;当β趋近于无穷大时,Swish函数趋近于ReLU函数。
在这里插入图片描述
LLaMA中直接将FFN中的ReLU替换为SwiGLU,并将维度放缩为(2/3)*4d
在这里插入图片描述

旋转位置嵌入(RoPE)

在位置编码上,使用旋转位置嵌(Rotary Positional Embeddings, RoPE)入代替原来的绝对位置编码。RoPE 借助了 复数的思想,出发点是通过绝对位置编码的方式实现相对位置编码。其目标是通过q,k添加绝对位置信息:
在这里插入图片描述
在这里插入图片描述

import torch

def precompute_freqs_cis(dim: int, end: int, constant: float = 10000.0):
    '''
    计算cos和sin的值,cos值在实部,sin值在虚部,类似于 cosx+j*sinx
    :param dim: q,k,v的最后一维,一般为emb_dim/head_num
    :param end: 句长length
    :param constant: 这里指10000
    :return:
    复数计算 torch.polar(a, t)输出, a*(cos(t)+j*sin(t))
    '''
    # freqs: 计算 1/(10000^(2i/d) ),将结果作为参数theta
    # 形式化为 [theta_0, theta_1, ..., theta_(d/2-1)]
    freqs = 1.0 / (constant ** (torch.arange(0, dim, 2)[: (dim // 2)].float() / dim)) # [d/2]

    # 计算m
    t = torch.arange(end, device=freqs.device)  # [length]
    # 计算m*theta
    freqs = torch.outer(t, freqs).float()  # [length, d/2]
    # freqs形式化为 [m*theta_0, m*theta_1, ..., m*theta_(d/2-1)],其中 m=0,1,...,length-1

    # 计算cos(m*theta)+j*sin(m*theta)
    freqs_cis = torch.polar(torch.ones_like(freqs), freqs)  # complex64
    # freqs_cis: [cos(m*theta_0)+j*sin(m*theta_0),  cos(m*theta_1)+j*sin(m*theta_1),), ..., cos(m*theta_(d/2-1))+j*sin(m*theta_(d/2-1))]
    # 其中j为虚数单位, m=0,1,...,length-1
    return freqs_cis # [length, d/2]

def reshape_for_broadcast(freqs_cis: torch.Tensor, x: torch.Tensor):
    ndim = x.ndim
    assert 0 <= 1 < ndim
    assert freqs_cis.shape == (x.shape[1], x.shape[-1])
    shape = [d if i == 1 or i == ndim - 1 else 1 for i, d in enumerate(x.shape)] # (1, length, 1, d/2)
    return freqs_cis.view(*shape) # [1, length, 1, d/2]

def apply_rotary_emb(xq: torch.Tensor, xk: torch.Tensor, freqs_cis: torch.Tensor,):
    # 先将xq维度变为[bs, length, head,  d/2, 2], 利用torch.view_as_complex转变为复数
    # xq:[q0, q1, .., q(d-1)] 转变为 xq_: [q0+j*q1, q2+j*q3, ..., q(d-2)+j*q(d-1)]
    xq_ = torch.view_as_complex(xq.float().reshape(*xq.shape[:-1], -1, 2)) # [bs, length, head, d/2]
    # 同样的,xk_:[k0+j*k1, k2+j*k3, ..., k(d-2)+j*k(d-1)]
    xk_ = torch.view_as_complex(xk.float().reshape(*xk.shape[:-1], -1, 2))

    freqs_cis = reshape_for_broadcast(freqs_cis, xq_) # [1, length, 1, d/2]
    # 下式xq_ * freqs_cis形式化输出,以第一个为例, 如下
    # (q0+j*q1)(cos(m*theta_0)+j*sin(m*theta_0)) = q0*cos(m*theta_0)-q1*sin(m*theta_0) + j*(q1*cos(m*theta_0)+q0*sin(m*theta_0))
    # 上式的实部为q0*cos(m*theta_0)-q1*sin(m*theta_0),虚部为q1*cos(m*theta_0)+q0*sin(m*theta_0)
    # 然后通过torch.view_as_real函数,取出实部和虚部,维度由[bs, length, head, d/2]变为[bs, length, head, d/2, 2],最后一维放实部与虚部
    # 最后经flatten函数将维度拉平,即[bs, length, head, d]
    # 此时xq_out形式化为 [实部0,虚部0,实部1,虚部1,..., 实部(d/2-1), 虚部(d/2-1)]
    xq_out = torch.view_as_real(xq_ * freqs_cis).flatten(3) # [bs, length, head, d]
    # 即为新生成的q

    xk_out = torch.view_as_real(xk_ * freqs_cis).flatten(3)
    return xq_out.type_as(xq), xk_out.type_as(xk)

if __name__=='__main__':
    # (bs, length, head, d)
    q = torch.randn((2, 10, 12, 32))  # q=[q0, q1, .., qd-1]
    k = torch.randn((2, 10, 12, 32))
    v = torch.randn((2, 10, 12, 32))
    freqs_cis= precompute_freqs_cis(dim=32, end=10, constant= 10000.0)
    # print(freqs_cis.detach().numpy())

    q_new, k_new = apply_rotary_emb(xq=q, xk=k, freqs_cis=freqs_cis)
    print()

Alpace

Alpaca是在LLaMA基础上使用52K指令数据精调的预训练模型;

微调

第一步:构造175条self-instruct种子示例任务;
第二步:基于上述种子任务,利用text-davinci-003爬取指令数据;
第三步:使用爬取下来的52k指令数据在LLaMA 进行精调,最终得到Alpaca;
在这里插入图片描述

Self-instruct数据构造

{
	"id":"000000",
	"name":"nnnnnn",
	"instruction": "Find the four smallest perfect numbers.", 
	"instances": [{ "input": "", "output": "6, 28, 496, and 8128”}], 
	"is_classification": false
}

指令数据格式

  • instruction:描述模型需要执行的指令内容;
  • input:任务上下文或输入信息,例如当指令是“对文章进行总结”,则input是文章内容;
  • output:由text-davinci-003生成的针对指令的回复;
    在这里插入图片描述

LLaMA-2

2023年7月,meta推出了LLaMA-2开源大模型,并推出了LLaMA-2-chat对话模型;

与上一代LLaMA主要区别体现在更多的训练数据、更长的上下文窗口、GQA技术等;
在这里插入图片描述
结构上的变动主要体现在GQA和FFN缩放上:

  • MHA改成GQA:整体参数量会有减少;
  • FFN模块矩阵维度由扩充:增强泛化能力,整体参数量增加;
  • 上下文长度时是LLaMA两倍:训练语料增加约40%,体现在1.4T->2.0T的okens llama2-34B和llama2-70B使用了GQA,加速模型训练和推理速度;

GQA

GQA和MQA都是注意力的变体,其中多个查询头关注相同的键和值头,以减少推理过程中 KV 缓存的大小,并可以显著提高推理吞吐量。

MHA、GQA、MQA的区别和联系,具体的优点如下:

  • Mutil-Head Attention 因为自回归模型生成回答时,需要前面生成的KV缓存起来,来加速计算。
  • Multi-Query Attention 多个头之间可以共享KV对,因此速度上非常有优势,实验验证大约减少30-40%吞吐。
  • Group Query Attention 没有像MQA那么极端,将query分组,组内共享KV,效果接近MQA,速度上与MQA可比较。
    在这里插入图片描述
    Llama-2中使用了8个KV映射,即GQA-8,GQA在多数任务上与MHA效果相当,且平均效果优于MQA;GQA和MQA均比MHA有更好的吞吐量;

总结

LLaMA

  • 开源大模型繁荣发展的开端,一系列相关工作均基于LLaMA开展;
  • 模型规模7B、13B、33B、65B满足了开发者和研究者的不同需求;

Alpaca:通过少量的指令精调赋予LLaMA指令理解与执行的能力

Llama-2

  • LLaMA的二代模型,相关模型性能进一步提升,模型可商用
  • 推出官方对⻬的Chat版本模型,采用了完整的RLHF链条;

Code Llama:专注于代码能力的LLaMA模型,最好的模型代码能力接近GPT-4效果,模型可商用

标签:系列,LLama,模型,torch,freqs,GQA,LLaMA,theta
From: https://blog.csdn.net/cancer_s/article/details/143401453

相关文章

  • Python工具箱系列:Pandas 数据清洗与预处理详解
    目录一、数据清洗与预处理的重要性二、Pandas简介三、Pandas数据清洗与预处理技巧1.读取数据2.查看数据3.处理缺失值4.处理重复值5.处理异常值6.处理数据类型不一致7.处理数据格式不一致8.数据标准化和归一化9.数据编码四、案例:使用Pandas进行数据清......
  • 科普文:软件架构数据库系列之【MySQL:InnoDB预读Ahead-read(线性预读linear read-ahead和
    概叙操作系统文件预读(Prefetching)科普文:软件架构Linux系列之【Linux的文件预读readahead】-CSDN博客前面文章我们从操作系统角度解释了文件预读readahead,指Linux系统内核将指定文件的某区域预读进页(OSpagecache)缓存起来,便于接下来对该区域进行读取时,不会因缺页(pagefault)......
  • 从零开始认识大模型,小白入行必看!
    前言什么是ChatGPT?什么是GPT-4?Bard和PaLM又是什么?它们有什么关系?它们对我们有什么影响?AI技术第一次这么密集地冲击着非从业者们,身处变革之中的我们或许会迷茫,但这本来就是工业革命之后的常态,我们要做的就是像九十年代学习计算机一样拥抱未来。在ChatGPT刚出的时候,我对未......
  • 从零到精通大模型!超详细入门知识点汇总,一篇在手,学习无忧!
    采用提问方式,从个人知识盲点开始,渐进式掌握大模型入门知识点。‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍1、大模型中7b、70B代表什么在讨论人工智能领域特别是大型语言模型(LLMs)时,“7b”和“70B”均用来表示模型所包含的参数数量。这里的“b”是英文“Billion”......
  • 大模型训练优化方法_大模型调优
    写在前面在训练模型尤其是大模型的时候,如何加快训练速度以及优化显存利用率是一个很关键的问题。本文主要参考HF上的一篇文章:https://huggingface.co/docs/transformers/perf_train_gpu_one,以及笔者在实际训练中的一些经验,给出一些比较实用的方法。先看一个总览的表:方法......
  • 揭秘”大模型加速器”如何助力大模型应用
    文章目录一、大模型发展面临的问题二、“大模型加速器”助力突破困难2.1现场效果展示2.1.1大模型加速器——文档解析引擎2.2.2图表数据提取三、TextIn智能文档处理平台3.1在线免费体验3.1.1数学公式提取3.1.2表格数据提取四、acge文本向量化模型4.1介绍4.2......
  • 哥伦比亚大学杨立昆演讲:大模型只是AI发展阶段性成果,但下一步AI革命制胜关键不会依赖于
    在昨天哥伦比亚大学最新一期的AI讲座上,Meta首席科学家YannLeCun(杨立昆)分享了他对人工智能未来的深刻见解。作为深度学习领域的先驱者和2018年图灵奖得主,LeCun的观点引发了广泛关注。这位法国计算机科学家的学术之路充满传奇。从1987年在索邦大学提出开创性的反向传播算法,到1989......
  • 大模型导论
    为什么大模型相比中小模型,有更突出的性能和泛化能力,也许大多数人并没有想过这个问题,业内一般从函数曲线拟合的角度,来理解模型为什么能解决现实中的问题。1、模型为什么越大,性能和泛化越好?在AI领域,对需要解决的业务问题,将其视为满足一定条件的数据分布,先通过特征工程的方式,从......
  • BitNet.cpp:革新性的1比特LLM推理框架,让CPU也能驾驭百亿参数大模型!
    ......
  • Taro 鸿蒙技术内幕系列(二):如何让 W3C 标准的 CSS跑在鸿蒙上
    作者:京东零售马银涛 基于Taro打造的京东鸿蒙APP已跟随鸿蒙Next系统公测,本系列文章将深入解析Taro如何实现使用React开发高性能鸿蒙应用的技术内幕背景HarmonyOS采用自研的ArkUI框架作为原生UI开发方案,这套方案有完善的布局系统和样式控制,但是他的标准与W3C......