Llama模型结构解析(源码阅读)
目录
- 1. LlamaModel整体结构流程图
- 2. LlamaRMSNorm
- 3. LlamaMLP
- 4. LlamaRotaryEmbedding
- 参考资料:
https://zhuanlan.zhihu.com/p/636784644
https://spaces.ac.cn/archives/8265 ——《Transformer升级之路:2、博采众长的旋转式位置编码》
前言:本次阅读代码位置,在transformers库底下的modeling_llama.py,具体位置在:transformers/models/llama/modeling_llama.py,如下图所示:
1. LlamaModel整体结构流程图

2. LlamaRMSNorm
- 代码如下
class LlamaRMSNorm(nn.Module):def __init__(self, hidden_size, eps=1e-6):"""LlamaRMSNorm is equivalent to T5LayerNorm"""super().__init__()self.weight = nn.Parameter(torch.ones(hidden_size))self.variance_epsilon = epsdef forward(self, hidden_states):input_dtype = hidden_states.dtypevariance = 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)
-
RMSNorm的公式如下所示:
x i 1 n ∑ i = 1 n x i 2 + e p s ∗ w e i g h t i \frac{x_i}{\sqrt{\frac{1}{n}\sum\limits_{i=1}^{n}{x_i}^2 + eps}} * weight_i n1i=1∑nxi2+epsxi∗weighti- 其中,公式与代码的对应关系如下:

- 其中,公式与代码的对应关系如下:
3. LlamaMLP
- 代码如下:
class LlamaMLP(nn.Module):def __init__(self,hidden_size: int,intermediate_size: int,hidden_act: str,):super().__init__()self.gate_proj = nn.Linear(hidden_size, intermediate_size, bias=False)self.down_proj = nn.Linear(intermediate_size, hidden_size, bias=False)self.up_proj = nn.Linear(hidden_size, intermediate_size, bias=False)self.act_fn = ACT2FN[hidden_act]def forward(self, x):return self.down_proj(self.act_fn(self.gate_proj(x)) * self.up_proj(x))
-
流程图:

-
其中输入为x,输出为y
-
代码中intermediate_size一般比hidden_size大,我们通过在jupyter notebook中打印Llama-13B的模型,可以看到如下所示:

-
总结:MLP模块就是几个nn.Linear的组合
4. LlamaRotaryEmbedding
- 代码如下
class LlamaRotaryEmbedding(torch.nn.Module):def __init__(self, dim, max_position_embeddings=2048, base=10000, device=None):super().__init__()inv_freq = 1.0 / (base ** (torch.arange(0, dim, 2).float().to(device) / dim))self.register_buffer("inv_freq", inv_freq)# Build here to make `torch.jit.trace` work.self.max_seq_len_cached = max_position_embeddingst = torch.arange(self.max_seq_len_cached, device=self.inv_freq.device, dtype=self.inv_freq.dtype)freqs = torch.einsum("i,j->ij", t, self.inv_freq)# Different from paper, but it uses a different permutation in order to obtain the same calculationemb = torch.cat((freqs, freqs), dim=-1)self.register_buffer("cos_cached", emb.cos()[None, None, :, :], persistent=False)self.register_buffer("sin_cached", emb.sin()[None, None, :, :], persistent=False)def forward(self, x, seq_len=None):# x: [bs, num_attention_heads, seq_len, head_size]# This `if` block is unlikely to be run after we build sin/cos in `__init__`. Keep the logic here just in case.if seq_len > self.max_seq_len_cached:self.max_seq_len_cached = seq_lent = torch.arange(self.max_seq_len_cached, device=x.device, dtype=self.inv_freq.dtype)freqs = torch.einsum("i,j->ij", t, self.inv_freq)# Different from paper, but it uses a different permutation in order to obtain the same calculationemb = torch.cat((freqs, freqs), dim=-1).to(x.device)self.register_buffer("cos_cached", emb.cos()[None, None, :, :], persistent=False)self.register_buffer("sin_cached", emb.sin()[None, None, :, :], persistent=False)return (self.cos_cached[:, :, :seq_len, ...].to(dtype=x.dtype),self.sin_cached[:, :, :seq_len, ...].to(dtype=x.dtype),)
- 具体的使用,还调用了另外两个函数,如下所示:
def rotate_half(x):"""Rotates half the hidden dims of the input."""x1 = x[..., : x.shape[-1] // 2]x2 = x[..., x.shape[-1] // 2 :]return torch.cat((-x2, x1), dim=-1)def apply_rotary_pos_emb(q, k, cos, sin, position_ids):# The first two dimensions of cos and sin are always 1, so we can `squeeze` them.cos = cos.squeeze(1).squeeze(0) # [seq_len, dim]sin = sin.squeeze(1).squeeze(0) # [seq_len, dim]cos = cos[position_ids].unsqueeze(1) # [bs, 1, seq_len, dim]sin = sin[position_ids].unsqueeze(1) # [bs, 1, seq_len, dim]q_embed = (q * cos) + (rotate_half(q) * sin)k_embed = (k * cos) + (rotate_half(k) * sin)return q_embed, k_embed
-
注意这里的实现跟原始推导有点区别,这里实现的方式如下图所示:

-
原始推导如下图所示:

具体可以查看作者的博客:👉戳我👈 -
总结:RoPE就是在attention计算时,K跟Q做内积之前,先给各自注入位置信息。
结束。
相关文章:
Llama模型结构解析(源码阅读)
目录 1. LlamaModel整体结构流程图2. LlamaRMSNorm3. LlamaMLP4. LlamaRotaryEmbedding 参考资料: https://zhuanlan.zhihu.com/p/636784644 https://spaces.ac.cn/archives/8265 ——《Transformer升级之路:2、博采众长的旋转式位置编码》 前言&#x…...
基于XML实现SpringIoC配置
目录 SpringIoc创建与使用的大致步骤 一.基于xml配置SpringIoc 二.基于xml配置DI 三.创建IoC容器并获取组件 SpringIoc创建与使用的大致步骤 SpringIoC的创建与使用过程分为3步 1.编写配置信息(编写XML,注解、Java类) 2.创建IoC容器&…...
Kaniko在containerd中无特权快速构建并推送容器镜像
目录 一、kaniko是什么 二、kaniko工作原理 三、kanijo工作在Containerd上 基于serverless的考虑,我们选择了kaniko作为镜像打包工具,它是google提供了一种不需要特权就可以构建的docker镜像构建工具。 一、kaniko是什么 kaniko 是一种在容器或 Kube…...
分享5款不会被打入冷宫的神器软件
检查一下你最近安装的软件,他们是不是都一样无法避免最终被你打入冷宫的命运?我们明明很懂“在精不在多”的道理,却依然让我们的电脑塞满了形形色色无用的软件。你需要知道的是,如何找到一款适合自己且真正实用的电脑软件。 自…...
Windows如何部署Redis
一、简介 Redis (Remote Dictionary Server) 是一个由意大利人 Salvatore Sanfilippo 开发的 key-value 存储系统,具有极高的读写性能,读的速度可达 110000 次/s,写的速度可达 81000 次/s 。 二、下载 访问 https://github.com/tporadows…...
VUE数据双向绑定原理解析
VUE数据双向绑定原理解析 在Vue.js中,数据双向绑定是一项非常强大的功能。它使开发者能够轻松地将模板与数据进行动态关联,实现了页面和数据之间的实时同步更新。本文将深入探讨VUE中数据双向绑定的原理,并通过代码示例演示其工作机制。 1.…...
SSM商城项目实战:订单管理
SSM商城项目实战:订单管理 在SSM商城项目中,订单管理是一个非常重要的功能模块。本文将详细介绍订单管理的实现思路和步骤代码。 实现SSM商城项目中订单管理功能的思路如下: 设计数据库表结构:根据订单管理的需求,设计…...
SELinux 入门 pt.2
哈喽大家好,我是咸鱼 在《SELinux 入门 pt.1》中,咸鱼向各位小伙伴介绍了 SELinux 所使用的 MAC 模型、以及几个重要的概念(主体、目标、策略、安全上下文) 我们还讲到: 对于受 SELinux 管制的进程,会先…...
函数(个人学习笔记黑马学习)
1、函数定义 #include <iostream> using namespace std;int add(int num1, int num2) {int sum num1 num2;return sum; }int main() {system("pause");return 0; } 2、函数的调用 #include <iostream> using namespace std;int add(int num1, int num2…...
《Flink学习笔记》——第五章 DataStream API
一个Flink程序,其实就是对DataStream的各种转换,代码基本可以由以下几部分构成: 获取执行环境读取数据源定义对DataStream的转换操作输出触发程序执行 获取执行环境和触发程序执行都属于对执行环境的操作,那么其构成可以用下图表示…...
Vue3.0 新特性以及使用变更总结
Vue3.0 在2020年9月正式发布了,也有许多小伙伴都热情的拥抱Vue3.0。去年年底我们新项目使用Vue3.0来开发,这篇文章就是在使用后的一个总结, 包含Vue3新特性的使用以及一些用法上的变更。 图片.png 为什么要升级Vue3 使用Vue2.x的小伙伴都熟悉…...
ToBeWritten之VSOC安全运营
也许每个人出生的时候都以为这世界都是为他一个人而存在的,当他发现自己错的时候,他便开始长大 少走了弯路,也就错过了风景,无论如何,感谢经历 转移发布平台通知:将不再在CSDN博客发布新文章,敬…...
2023爱分析·一站式通信解决方案市场厂商评估报告:牛信云
[图片] 01 中国企业出海发展背景及阶段 出海背景:出海,对中国企业而言,并不陌生。从最初的贸易型出海,到制造业崛起,再到互联网、移动互联网产业腾飞,中国企业在出海道路上走的越发稳健。行业也从最初的家电…...
微信小程序消防知识每天学平台设计与实现
摘 要 消防是当下一个人都需要在日常生活中所高度重视的事项。消防安全关系到居民的日常生活的安全,通过学习消防知识能够提升人们在日常生活中对于灾难的防范。通过对当下的大学生进行调查研究后发现,现在的年轻人在消防意识上比较的单薄,对…...
Oracle跨库访问DBLINK
1. DBLINK的介绍 Oracle在进行跨库访问时,可以创建DBLINK实现,比如要将UAT的表数据灌入开发环境,则可以使用UAT库为数据源,通过DBLINK实现将查出的数据灌入开发库。 简而言之就是在当前数据库中访问另一个数据库中的表中的数据 2…...
【vue3.0 组合式API与选项式API是什么,有什么区别】
vue3.0 组合式API与选项式API是什么 Vue3.0中引入了组合式API(Composition API),同时保留了选项式API(Options API)。两种 API 风格都能够覆盖大部分的应用场景。它们只是同一个底层系统所提供的两套不同的接口。实际…...
React配置代理的5种方法
React配置代理的五种方法的介绍 使用create-react-app的代理配置: 使用场景:适用于使用create-react-app创建的React项目,特别是小型项目或快速原型开发。优点:配置简单,无需额外安装依赖,适合快速开发和简…...
皮卡丘靶场搭建遇到的问题大全
该博客记录我在安装皮卡丘靶场中遇到的一些问题。 1、 phpstudy_pro启动Mysql失败 自己电脑开启了mysql服务,使用winr,services.msc,找到自己的mysql服务,关闭。再次尝试使用phpstudy_pro启动mysql,成功解决。 2、皮…...
【C++】C++11的新特性(上)
引入 C11作为C标准的一个重要版本,引入了许多令人振奋的新特性,极大地丰富了这门编程语言的功能和表达能力。本章将为您介绍C11的一些主要变化和改进,为接下来的章节铺垫。 文章目录 引入 一、列表初始化 1、1 {} 初始化 1、2 std::initiali…...
ubuntu学习(四)----文件写入操作编程
1、write函数的详解 ssize_t write(int fd,const void*buf,size_t count); 参数说明: fd:是文件描述符(write所对应的是写,即就是1) buf:通常是一个字符串,需要写入的字符串 count:是每次写入的字节数…...
变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析
一、变量声明设计:let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性,这种设计体现了语言的核心哲学。以下是深度解析: 1.1 设计理念剖析 安全优先原则:默认不可变强制开发者明确声明意图 let x 5; …...
使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...
【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...
Opencv中的addweighted函数
一.addweighted函数作用 addweighted()是OpenCV库中用于图像处理的函数,主要功能是将两个输入图像(尺寸和类型相同)按照指定的权重进行加权叠加(图像融合),并添加一个标量值&#x…...
vue3 字体颜色设置的多种方式
在Vue 3中设置字体颜色可以通过多种方式实现,这取决于你是想在组件内部直接设置,还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法: 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...
P3 QT项目----记事本(3.8)
3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...
Cinnamon修改面板小工具图标
Cinnamon开始菜单-CSDN博客 设置模块都是做好的,比GNOME简单得多! 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...
什么是EULA和DPA
文章目录 EULA(End User License Agreement)DPA(Data Protection Agreement)一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA(End User License Agreement) 定义: EULA即…...
【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)
要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况,可以通过以下几种方式模拟或触发: 1. 增加CPU负载 运行大量计算密集型任务,例如: 使用多线程循环执行复杂计算(如数学运算、加密解密等)。运行图…...
保姆级教程:在无网络无显卡的Windows电脑的vscode本地部署deepseek
文章目录 1 前言2 部署流程2.1 准备工作2.2 Ollama2.2.1 使用有网络的电脑下载Ollama2.2.2 安装Ollama(有网络的电脑)2.2.3 安装Ollama(无网络的电脑)2.2.4 安装验证2.2.5 修改大模型安装位置2.2.6 下载Deepseek模型 2.3 将deepse…...
