大模型入门3:理解LLAMA

  • LLama在transformers库中的代码,以及各部分原理
  • Llama3.1技术报告
  • LLama 33b 微调尝试

Model

  • a stack of DecoderBlocks(SelfAttention, FeedForward, and RMSNorm)
    在这里插入图片描述
    decoder block 整体结构:最大的区别在pre-norm

x -> norm(x) -> attention() -> residual connect -> norm() -> ffn -> residual connect

class DecoderBlock(nn.Module):def __init__(self, config):super().__init__()self.n_heads = config['n_heads']self.dim = config['embed_dim']self.head_dim = self.dim // self.n_headsself.attention = SelfAttention(config)self.feed_forward = FeedForward(config)# rms before attention blockself.attention_norm = RMSNorm(self.dim, eps=config['norm_eps'])# rms before  feed forward blockself.ffn_norm = RMSNorm(self.dim, eps=config['norm_eps'])def forward(self, x, start_pos, freqs_complex):# (m, seq_len, dim)h = x + self.attention.forward(self.attention_norm(x), start_pos, freqs_complex)# (m, seq_len, dim)out = h + self.feed_forward.forward(self.ffn_norm(h))return outclass Transformer(nn.Module):def __init__(self, config):super().__init__()self.vocab_size = config['vocab_size']self.n_layers = config['n_layers']self.tok_embeddings = nn.Embedding(self.vocab_size, config['embed_dim'])self.head_dim = config['embed_dim'] // config['n_heads']self.layers = nn.ModuleList()for layer_id in range(config['n_layers']):self.layers.append(DecoderBlock(config))self.norm = RMSNorm(config['embed_dim'], eps=config['norm_eps'])self.output = nn.Linear(config['embed_dim'], self.vocab_size, bias=False)self.freqs_complex = precompute_theta_pos_frequencies(self.head_dim, config['max_seq_len'] * 2, device=(config['device']))def forward(self, tokens, start_pos):# (m, seq_len)batch_size, seq_len = tokens.shape# (m, seq_len) -> (m, seq_len, embed_dim)h = self.tok_embeddings(tokens)# (seq_len, (embed_dim/n_heads)/2]freqs_complex = self.freqs_complex[start_pos:start_pos + seq_len]# Consecutively apply all the encoder layers# (m, seq_len, dim)for layer in self.layers:h = layer(h, start_pos, freqs_complex)h = self.norm(h)# (m, seq_len, vocab_size)output = self.output(h).float()return outputmodel = Transformer(config).to(config['device'])
res = model.forward(test_set['input_ids'].to(config['device']), 0)
print(res.size())

RoPE

在这里插入图片描述

def precompute_theta_pos_frequencies(head_dim, seq_len, device, theta=10000.0):# theta_i = 10000^(-2(i-1)/dim) for i = [1, 2, ... dim/2]# (head_dim / 2)theta_numerator = torch.arange(0, head_dim, 2).float()theta = 1.0 / (theta ** (theta_numerator / head_dim)).to(device)# (seq_len)m = torch.arange(seq_len, device=device)# (seq_len, head_dim / 2)freqs = torch.outer(m, theta).float()# complex numbers in polar, c = R * exp(m * theta), where R = 1:# (seq_len, head_dim/2)freqs_complex = torch.polar(torch.ones_like(freqs), freqs)return freqs_complexdef apply_rotary_embeddings(x, freqs_complex, device):# last dimension pairs of two values represent real and imaginary# two consecutive values will become a single complex number# (m, seq_len, num_heads, head_dim/2, 2)x = x.float().reshape(*x.shape[:-1], -1, 2)# (m, seq_len, num_heads, head_dim/2)x_complex = torch.view_as_complex(x)# (seq_len, head_dim/2) --> (1, seq_len, 1, head_dim/2)freqs_complex = freqs_complex.unsqueeze(0).unsqueeze(2)# multiply each complex number# (m, seq_len, n_heads, head_dim/2)x_rotated = x_complex * freqs_complex# convert back to the real number# (m, seq_len, n_heads, head_dim/2, 2)x_out = torch.view_as_real(x_rotated)# (m, seq_len, n_heads, head_dim)x_out = x_out.reshape(*x.shape)return x_out.type_as(x).to(device)

RMS norm

class RMSNorm(nn.Module):def __init__(self, dim, eps=1e-6):super().__init__()self.eps = epsself.weight = nn.Parameter(torch.ones(dim))def _norm(self, x: torch.Tensor):# (m, seq_len, dim) * (m, seq_len, 1) = (m, seq_len, dim)# rsqrt: 1 / sqrt(x)return x * torch.rsqrt(x.pow(2).mean(-1, keepdim=True) + self.eps)def forward(self, x: torch.Tensor):# weight is a gain parameter used to re-scale the standardized summed inputs# (dim) * (m, seq_len, dim) = (m, seq_Len, dim)return self.weight * self._norm(x.float()).type_as(x)

KV Caching

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

class KVCache:def __init__(self, max_batch_size, max_seq_len, n_kv_heads, head_dim, device):self.cache_k = torch.zeros((max_batch_size, max_seq_len, n_kv_heads, head_dim)).to(device)self.cache_v = torch.zeros((max_batch_size, max_seq_len, n_kv_heads, head_dim)).to(device)def update(self, batch_size, start_pos, xk, xv):self.cache_k[:batch_size, start_pos :start_pos + xk.size(1)] = xkself.cache_v[:batch_size, start_pos :start_pos + xv.size(1)] = xvdef get(self, batch_size, start_pos, seq_len):keys = self.cache_k[:batch_size,  :start_pos + seq_len]values = self.cache_v[:batch_size, :start_pos + seq_len]return keys, values

Grouped Query Attention

在这里插入图片描述

def repeat_kv(x, n_rep):batch_size, seq_len, n_kv_heads, head_dim = x.shapeif n_rep == 1:return xelse:# (m, seq_len, n_kv_heads, 1, head_dim)# --> (m, seq_len, n_kv_heads, n_rep, head_dim)# --> (m, seq_len, n_kv_heads * n_rep, head_dim)return (x[:, :, :, None, :].expand(batch_size, seq_len, n_kv_heads, n_rep, head_dim).reshape(batch_size, seq_len, n_kv_heads * n_rep, head_dim))class SelfAttention(nn.Module):def __init__(self, config):super().__init__()self.n_heads = config['n_heads']self.n_kv_heads = config['n_kv_heads']self.dim = config['embed_dim']self.n_kv_heads = self.n_heads if self.n_kv_heads is None else self.n_kv_headsself.n_heads_q = self.n_headsself.n_rep = self.n_heads_q // self.n_kv_headsself.head_dim = self.dim // self.n_headsself.wq = nn.Linear(self.dim, self.n_heads * self.head_dim, bias=False)self.wk = nn.Linear(self.dim, self.n_kv_heads * self.head_dim, bias=False)self.wv = nn.Linear(self.dim, self.n_kv_heads * self.head_dim, bias=False)self.wo = nn.Linear(self.n_heads * self.head_dim, self.dim, bias=False)self.cache = KVCache(max_batch_size=config['max_batch_size'],max_seq_len=config['max_seq_len'],n_kv_heads=self.n_kv_heads,head_dim=self.head_dim,device=config['device'])def forward(self, x, start_pos, freqs_complex):# seq_len is always 1 during inferencebatch_size, seq_len, _ = x.shape# (m, seq_len, dim)xq = self.wq(x)# (m, seq_len, h_kv * head_dim)xk = self.wk(x)xv = self.wv(x)# (m, seq_len, n_heads, head_dim)xq = xq.view(batch_size, seq_len, self.n_heads_q, self.head_dim)# (m, seq_len, h_kv, head_dim)xk = xk.view(batch_size, seq_len, self.n_kv_heads, self.head_dim)xv = xv.view(batch_size, seq_len, self.n_kv_heads, self.head_dim)# (m, seq_len, num_head, head_dim)xq = apply_rotary_embeddings(xq, freqs_complex, device=x.device)# (m, seq_len, h_kv, head_dim)xk = apply_rotary_embeddings(xk, freqs_complex, device=x.device)# replace the entry in the cacheself.cache.update(batch_size, start_pos, xk, xv)# (m, seq_len, h_kv, head_dim)keys, values = self.cache.get(batch_size, start_pos, seq_len)# (m, seq_len, h_kv, head_dim) --> (m, seq_len, n_heads, head_dim)keys = repeat_kv(keys, self.n_rep)values = repeat_kv(values, self.n_rep)# (m, n_heads, seq_len, head_dim)# seq_len is 1 for xq during inferencexq = xq.transpose(1, 2)# (m, n_heads, seq_len, head_dim)keys = keys.transpose(1, 2)values = values.transpose(1, 2)# (m, n_heads, seq_len_q, head_dim) @ (m, n_heads, head_dim, seq_len) -> (m, n_heads, seq_len_q, seq_len)scores = torch.matmul(xq, keys.transpose(2, 3)) / math.sqrt(self.head_dim)# (m, n_heads, seq_len_q, seq_len)scores = F.softmax(scores.float(), dim=-1).type_as(xq)# (m, n_heads, seq_len_q, seq_len) @ (m, n_heads, seq_len, head_dim) -> (m, n_heads, seq_len_q, head_dim)output = torch.matmul(scores, values)# ((m, n_heads, seq_len_q, head_dim) -> (m, seq_len_q, dim)output = (output.transpose(1, 2).contiguous().view(batch_size, seq_len, -1))# (m, seq_len_q, dim)return self.wo(output)

SwiGlu

def sigmoid(x, beta=1):return 1 / (1 + torch.exp(-x * beta))def swiglu(x, beta=1):return x * sigmoid(x, beta)
class FeedForward(nn.Module):def __init__(self, config):super().__init__()hidden_dim = 4 * config['embed_dim']hidden_dim = int(2 * hidden_dim / 3)if config['ffn_dim_multiplier'] is not None:hidden_dim = int(config['ffn_dim_multiplier'] * hidden_dim)# Round the hidden_dim to the nearest multiple of the multiple_of parameterhidden_dim = config['multiple_of'] * ((hidden_dim + config['multiple_of'] - 1) // config['multiple_of'])self.w1 = nn.Linear(config['embed_dim'], hidden_dim, bias=False)self.w2 = nn.Linear(config['embed_dim'], hidden_dim, bias=False)self.w3 = nn.Linear(hidden_dim, config['embed_dim'], bias=False)def forward(self, x: torch.Tensor):# (m, seq_len, dim) --> (m, seq_len, hidden_dim)swish = swiglu(self.w1(x))# (m, seq_len, dim) --> (m, seq_len, hidden_dim)x_V = self.w2(x)# (m, seq_len, hidden_dim)x = swish * x_V# (m, seq_len, hidden_dim) --> (m, seq_len, dim)return self.w3(x)

小结

  • padding 方式

reference

  • llama tech report
  • 源码:transformers
  • 参数量计算: https://zhuanlan.zhihu.com/p/676113501
  • 基于 MLX 的 LLAMA2-13B 的详细分析 - 亚东的文章 - 知乎 https://zhuanlan.zhihu.com/p/677125915
  • 2023年你最喜欢的MLSys相关的工作是什么? - Lin Zhang的回答 - 知乎
  • https://ai.plainenglish.io/understanding-llama2-kv-cache-grouped-query-attention-rotary-embedding-and-more-c17e5f49a6d7
  • https://github.com/wdndev/llama3-from-scratch-zh/blob/main/llama3/model.py

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/53002.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

什么是上拉,下拉?

上拉就是将引脚通过一个电阻连接到电源,作用:1.使IO口的不确定电平稳定在高点平,2、为了增加IO口拉电流的能力。 下拉就是将引脚通过一个电阻与GND相连,作用:1.从器件输出电流 2.当IO口为输入状态时,引脚的…

【爱给网-注册安全分析报告-无验证方式导致安全隐患】

前言 由于网站注册入口容易被黑客攻击,存在如下安全问题: 1. 暴力破解密码,造成用户信息泄露 2. 短信盗刷的安全问题,影响业务及导致用户投诉 3. 带来经济损失,尤其是后付费客户,风险巨大,造…

Flet全平台开发:软件开发界勇士为Python语言补短板的一次极具挑战性的尝试、冲刺和华丽亮相

一、Flet创始人和开发者介绍、开发Flet的背景介绍 Flet 的创始人和开发者 Feodor Fitsner 是俄罗斯人,就职于微软。 Flet 的第一个版本于 2022 年 6 月发布。这是一个相对较新的库,它基于 Flutter 框架,首先支持的是用 Python 语言开发软件…

速通汇编(五)认识段地址与偏移地址,CS、IP寄存器和jmp指令,DS寄存器

一,地址的概念 通常所说的地址指的是某内存单元在整个机器内存中的物理地址,把整个机器内存比作一个酒店,内存单元就是这个酒店的各个房间,给这些房间编的门牌号,类比回来就是内存单元的物理地址 在第一篇介绍debug的…

文心智能体应用:美国旅游助手的诞生

创造灵感 在如今的数字化时代,旅行体验越来越依赖于智能技术的辅助。从机票预订到行程安排,再到当地美食推荐,智能助手在旅行中的作用愈发重要。尤其在美国这样一个广袤且多样化的国家,拥有一个智能旅行助手能够极大地提升游客的…

C++3D迷宫

目录 开头程序程序的流程图程序游玩的效果下一篇博客要说的东西 开头 大家好&#xff0c;我叫这是我58。 程序 #include <iostream> using namespace std; void printmaze(char strmaze[5][5][5]) {cout << "-----" << endl;int i 0;int ia 0…

react18基础教程系列--安装环境及packagejson文件分析

一个React项目中&#xff0c;默认会安装: react:React框架的核心react-dom:React 视图渲染的核心「基于React构建WebApp(HTML页面)J—>react-native:构建和渲染App的react-scripts: 脚手架为了让项目目录看起来干净一些&#xff0c;把webpack打包的规则及相关的插件/LOADER…

《OpenCV计算机视觉》—— 图像金字塔

文章目录 什么是图像金字塔&#xff1f;一、定义与基本原理二、主要类型三、构建过程四、应用领域 图像金字塔中的下采样和上采样一、下采样&#xff08;Downsampling&#xff09;二、上采样&#xff08;Upsampling&#xff09;三、总结 代码实现 什么是图像金字塔&#xff1f;…

YOLOv8目标检测模型——遥感小目标检测经验分享

小目标检测——YOLOV8 一、引言 背景介绍 &#xff08;1&#xff09;目标检测的重要性 目标检测在许多领域都具有极其重要的作用。在自动驾驶中&#xff0c;目标检测能够识别道路上的障碍物和行人&#xff0c;确保行车安全。在视频监控中&#xff0c;目标检测能够实时发现异…

从登录到免登录:JSP与Servlet结合Cookie的基本实现

前言 JSP中应用Cookie解析&#xff1a; 用户登录成功后&#xff0c;将用户信息保存到Cookie中&#xff0c;在页面读取Cookie并显示&#xff0c;不需要再次登录可以直接进入页面 第一步&#xff1a;创建JavaWeb项目&#xff0c;配置pom.xml文件 创建maven项目&#xff0c;项目名…

DB-GPT部署和试用

前言 DB-GPT是一个开源的AI原生数据应用开发框架(AI Native Data App Development framework with AWEL(Agentic Workflow Expression Language) and Agents)。 目的是构建大模型领域的基础设施&#xff0c;通过开发多模型管理(SMMF)、Text2SQL效果优化、RAG框架以及优化、Mu…

Element UI入门笔记(个人向)

Element UI入门笔记 将页面分割为一级菜单、二级菜单、导航栏三个部分&#xff1b;使用npm下载安装&#xff0c;使用语句npm i element-ui -s; 布局组件 el-form 用于创建和管理表单&#xff1b;从属性上看&#xff1a; :model&#xff1a;用于双向数据绑定&#xff0c;将表单…

打造古风炫酷个人网页:用HTML和CSS3传递笔墨韵味

需要用到的背景大家可以自己找喜欢的风格!!! 当然俺把俺用的背景放到文章最后了哦&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 感谢关注和支持 长期更新哦~~~ 1. 简洁的页面布局&#xff1a;保持优雅和对称 在古风设计中&#xff0c;布局的对称性非常重要…

Linux - 探秘/proc/sys/net/ipv4/ip_local_port_range

文章目录 Pre概述默认值及其意义评估需求如何调整临时修改永久修改测试和验证 修改的潜在影响 Pre Linux - 探秘 Linux 的 /proc/sys/vm 常见核心配置 计划&#xff1a; 简要解释 /proc/sys/net/ipv4/ip_local_port_range 文件的功能和作用。介绍该文件的默认值及其影响。说明…

螺丝、螺母、垫片等紧固件常用类型详细介绍

螺钉、螺母、垫片等紧固件介绍 螺钉 杯头内六角 首先介绍一下杯头内六角&#xff0c;杯头内六角是我们用的最常见的一种螺钉&#xff0c;如果你对选择螺钉没有什么想法&#xff0c;可以直接无脑选杯头内六角去使用。 比如说我们有一个零件加工了通孔&#xff0c;另一个零件加…

Vue3.0组合式API:setup()函数

1、什么是组合式API Vue 3.0 中新增了组合式 API 的功能&#xff0c;它是一组附加的、基于函数的 API&#xff0c;可以更加灵活地组织组件代码。通过组合式 API 可以使用函数而不是声明选项的方式来编写 Vue 组件。因此&#xff0c;使用组合式 API 可以将组件代码编写为多个函…

CPU 和 GPU:为什么GPU更适合深度学习?

目录 什么是 CPU &#xff1f; 什么是 GPU &#xff1f; GPU vs CPU 差异性对比分析 GPU 是如何工作的 &#xff1f; GPU 与 CPU 是如何协同工作的 &#xff1f; GPU vs CPU 类型解析 GPU 应用于深度学习 什么是 CPU &#xff1f; CPU&#xff08;中央处理器&#xff09;…

git push : RPC failed; HTTP 400 curl 22 The requested URL returned error: 400

git push 出现RPC failed; HTTP 400 curl 22 The requested URL returned error: 400 问题 git push Enumerating objects: 11, done. Counting objects: 100% (11/11), done. Delta compression using up to 8 threads Compressing objects: 100% (10/10), done. error: RPC …

对中文进行文本分类的常用方法

一&#xff1a;关键词分类和基于规则的分类 关键词分类和基于规则的分类是两种常见的文本分类方法&#xff0c;它们可以应用于中文文本的分类。下面我将详细介绍这两种方法&#xff1a; 关键词分类 原理&#xff1a;这种方法通过识别文本中出现的特定关键词或短语来确定文本的…

STM32常用数据采集滤波算法

例如&#xff0c;STM32进行滤波处理时&#xff0c;主要目的是处理数据采集过程中可能产生的噪声和尖刺信号。这些噪声可能来自电源干扰、传感器自身的不稳定性或其他外部因素。 1.一阶互补滤波 方法&#xff1a;取a0~1,本次滤波结果&#xff08;1-a&#xff09;本次采样值a上…