当前位置: 首页 > news >正文

聊聊拉长LLaMA的一些经验

Sequence Length是指LLM能够处理的文本的最大长度,越长,自然越有优势:

  1. 更强的记忆性。更多轮的历史对话被拼接到对话中,减少出现遗忘现象

  2. 长文本场景下体验更佳。比如文档问答、小说续写等

当今开源LLM中的当红炸子鸡——LLaMA,第一版上下文长度是2048,第二版长度是4096。相比之下ChatGPT、GPT4已经支持到16k,Claude甚至支持到了100k。足以见得将LLaMA拉长是如此的任重而道远。本文将会介绍三种在旋转位置编码(RoPE)基础上扩充上下文的高性价比方案,在文末会介绍我的实践经验。

线性插值法

Kaiokendev的博客[1]中提到了方法,和Meta的一篇工作[2]不谋而合,其思想主要是将目标长度压缩到原始长度。如下图所示,LLaMA-1预训练的长度为2048,如果我们想把它拉长到4096:

  • 方法一:推理时直接拉长到4096。这考虑位置编码的外推性(即在短文本上训练,长文本上推理的能力[2]),而RoPE的外推性则是相当一般[2]。由于训练时长度都是小于2048的,超过2048部分Attention分数会飙升,导致困惑度急剧上升。

  • 方法二:在原始模型基础上做长度为4096的继续训练。这里先岔开介绍另一款模型——MPT-30B的做法,根据官方博客[3]的介绍:

    As mentioned earlier, MPT-30B was trained with a long context window of 8k tokens (vs. 2k for LLaMa and Falcon) and can handle arbitrarily long context windows via ALiBi or with fine-tuning. To build 8k support into MPT-30B efficiently, we first pre-trained on 1T tokens using sequences that were 2k tokens long, and continued training for an additional 50B tokens using sequences that were 8k tokens long.

    MPT-30B采用ALiBi位置编码(外推性优于RoPE),在2k的长度进行1T token的训练,然后在8k长度上进行50B token的预训练——这是在外推性强于RoPE的ALiBi上的情况。LLaMA-1预训练的token数是1T以上,想要在长度为4096样本上效果不下降,那需要训练足够多的token数才行,这就需要较大的成本了。

  • 方法三:另一种思路则是将4096的位置编码通过线性插值法压缩到2048内,这样只需要在少量的长度为4096的数据上进行继续预训练,便可达到不错的效果。

来自论文[2]

来自论文[2]

代码实现

线性插值法的实现代码相当的简单,这需要在原始RoPE上进行微小的改动,即加上下图的scale参数。

来自[7],scaled_rope/LlamaLinearScaledRotaryEmbedding.py

来自[7],scaled_rope/LlamaLinearScaledRotaryEmbedding.py

效果

Meta的工作[2]中进行了充足实验和公式推导证明,如果想看具体的代码,建议看lmsys.org(Vicuna的出品方)的一篇工作[4]:How Long Can Open-Source LLMs Truly Promise on Context Length? 他们对比了商用模型、号称支持长文本的开源模型和“Vicuna+线性插值法”的效果,并给出了几个结论:

  1. 商用模型在长文本的效果上很能打!而那些号称支持长文本的开源模型,在长文本上则表现不佳。

  2. 随着文本长度的增加,越接近边界,Vicuna+线性插值法的效果降低越明显。这可能是因为训练数据存在短文本的情况。

来自[4]

来自[4]

来自[4]

来自[4]

写这篇文章的同时,ChatGLM团队更新了ChatGLM2-6B-32K,也是使用了插值法。同时推出了长文本的中英评测集LongBench,在这个评测集上ChatGLM2-6B-32K展示了强大的实力,但值得注意的是,该评测集的评测方式是使用ChatGLM2-6B来进行评估的。

NTK插值法

NTK插值法的提出于一篇Reddit帖子[5],它提出使用Neural Tangent Kernel (NTK)来解决这个问题。

if you apply Neural Tangent Kernel (NTK) theory to this problem, it becomes clear that simply interpolating the RoPE's fourier space "linearly" is very sub-optimal, as it prevents the network to distinguish the order and positions of tokens that are very close by. Borrowing from NTK literature, scaling down the fourier features too much will eventually even prevent succesful finetunes (this is corroborated by the recent paper by Meta that suggests an upper bound of ~600x)

Instead of the simple linear interpolation scheme, I've tried to design a nonlinear interpolation scheme using tools from NTK literature. Basically this interpolation scheme changes the base of the RoPE instead of the scale, which intuitively changes the "spinning" speed which each of the RoPE's dimension vectors compared to the next. Because it does not scale the fourier features directly, all the positions are perfectly distinguishable from eachother, even when taken to the extreme (eg. streched 1million times, which is effectively a context size of 2 Billion)

帖子中作者还用了时钟的例子来解释线性插值和NTK插值的异同:

RoPE behaves like a clock. Your 12 hours wall clock is basically a RoPE of dimension 3 with a base of 60. So for each second, the minute hand turns 1/60th of a minute, and for each minute, the hour hand turns 1/60th.

Now if you slowed down time by a factor of 4x, that is a linear RoPE scaling used in SuperHOT. Unfortunately now it is really really hard to distinguish each second, because now the seconds hand barely moves each second. So if someone gave you two different times, which is only different by a single second, you won't be able to distinguish them from afar (let's say the NNs have myopia because that's basically what NTK predicts)

Now NTK-Aware RoPE scaling does not slow down the seconds. One second is still one second, but it slows down minutes by a factor of let's say 1.5, and the hours by a factor of 2. This way you can fit 90 minutes in a hour, and fit 24 hours in half a day. So now you basically have a clock that can measure 129.6k seconds instead of 43.2k seconds.

Because you don't need a precise measurement of the hour hand when looking at the time, scaling the hours more compared to seconds is crucial. You don't want to lose the precision of the seconds hand, but you can afford to lose precision on the minutes hand and even more on the hours hand.

Then, it's just a matter of deriving the base change formula in order to obtain such a scaling. (where less precise dimensions are scaled more and more)

代码实现

NTK的实现则更加简单了,根据超参数alpha,对应修改base变量即可:

来自[7],scaled-rope/scaled_rope/LlamaNTKScaledRotaryEmbedding.py

来自[7],scaled-rope/scaled_rope/LlamaNTKScaledRotaryEmbedding.py

效果

在效果上,帖子中也给出了NTK插值法和线性插值法的PPL比较,可以看到,在二者都不做Finetune的情况下,NTK插值法具备更低的PPL。

来自[5]

来自[5]

动态插值法

动态插值法同样出自于一篇Reddit帖子[6],它的出发点很简单:

My idea was to use the exact position values for the first 2k context (after all, why mess with a good thing?) and then re-calculate the position vector for every new sequence length as the model generates token by token.

这种做法可以和先前的两种方法相结合,[7]中也给出了详细的代码实现。

效果

作者和前两种方法做了对比,展示了动态插值法在PPL下降上的优势。

实践经验

我在实践的过程中,评估效果主要使用longChat[4]中使用的评估方式,以下是一些takeaway tips,欢迎大家一起交流。

  1. 线性插值法具备完整的理论支持和大量的实验证明,在我的实践中,“线性插值法+Finetune”取得了最佳效果。

  2. NTK插值法的实验中,对比的是不做Finetune的情况,在我的实践中,“NTK插值+Finetune”效果会明显优于单独的“NTK插值”,但它的收敛速度会慢于“线性插值法+Finetune”。

  3. 动态插值法的实验同样是在不做Finetune的情况对比的,目前为止我并没有尝试过这种方法。在Reddit的评论区有人提出一个很好的问题:如果采取这种方法,逐token推理时,文本的长度是在变化的,则导致无法使用kv-cache,这会对性能产生很大的影响。

最后,拉长LLaMA的方案可以不从RoPE入手(如:LongLLaMA[8]),但“线性插值法+Finetune”无疑是一种性价比很高的方案,推荐大家尝试!

——2023.07.31

Reference

[1] Extending Context is Hard…but not Impossible†

[2] EXTENDING CONTEXT WINDOW OF LARGE LANGUAGE MODELS VIA POSITION INTERPOLATION

[3] MPT-30B: Raising the bar for open-source foundation models

[4] How Long Can Open-Source LLMs Truly Promise on Context Length?

[5] NTK-Aware Scaled RoPE allows LLaMA models to have extended (8k+) context size without any fine-tuning and minimal perplexity degradation.

[6] Dynamically Scaled RoPE further increases performance of long context LLaMA with zero fine-tuning

[7] GitHub - jquesnelle/scaled-rope

[8] Focused Transformer: Contrastive Training for Context Scaling

相关文章:

聊聊拉长LLaMA的一些经验

Sequence Length是指LLM能够处理的文本的最大长度,越长,自然越有优势: 更强的记忆性。更多轮的历史对话被拼接到对话中,减少出现遗忘现象 长文本场景下体验更佳。比如文档问答、小说续写等 当今开源LLM中的当红炸子鸡——LLaMA…...

线程池的使用详解

一 使用线程池的好处 池化技术相比大家已经屡见不鲜了,线程池、数据库连接池、Http 连接池等等都是对这个思想的应用。池化技术的思想主要是为了减少每次获取资源的消耗,提高对资源的利用率。 线程池提供了一种限制和管理资源(包括执行一个任…...

刷题笔记 day4

力扣 611 有效三角形的个数 首先需要知道如何判断 三个数是否能构成三角形。 假如 存在三个数 a < b < c&#xff0c;如果要构成三角形&#xff0c;需要满足&#xff1a; ab > c ; a c > b ; b c > a ; 任意两个数大于第三个数就可构成三角形。 其实不难…...

Python 2.x 中如何使用flask模块进行Web开发

Python 2.x 中如何使用 Flask 模块进行 Web 开发 引言: 随着互联网的快速发展&#xff0c;Web开发成为了互联网行业中一项非常重要的技术。而在 Python 的Web开发中&#xff0c;Flask框架是一种非常流行的选择。它简单轻巧&#xff0c;灵活易用&#xff0c;适合中小型项目的快…...

spring websocket 调用受权限保护的方法失败

版本 spring-security 5.6.10 spring-websocket 5.3.27 现象 通过AbstractWebSocketHandler实现websocket端点处理器 调用使用PreAuthorize注解的方法报错&#xff0c;无法在SecurityContext中找到认证信息 org.springframework.security.authentication.AuthenticationCred…...

Vue.js2+Cesium 四、模型对比

Vue.js2Cesium 四、模型对比 Cesium 版本 1.103.0&#xff0c;低版本 Cesium 不支持 Compare 对比功能。 Demo 同一区域的两套模型&#xff0c;实现对比功能 <template><div style"width: 100%; height: 100%;"><divid"cesium-container"…...

Linux 之 Vi 编辑器

文章目录 1. vi/vim介绍2. vi/vim使用详解2.1 vi/vim的特点2.2 vi/vim三种编辑模式2.3 文本编辑方式 1. vi/vim介绍 vi编辑器是linux和unix上最基本的文本编辑器&#xff0c;工作在字符模式下。由于不需要图形界面&#xff0c;vi是效率很高的文本编辑器。尽管在linux上也有很多…...

Python超实用!批量重命名文件/文件夹,只需1行代码

大家好&#xff0c;这里是程序员晚枫&#xff0c;之前在小破站给大家分享了一个视频&#xff1a;批量重命名文件。 最近在程序员晚枫的读者群里&#xff0c;发现很多朋友对这个功能很感兴趣&#xff0c;尤其是对下一步的优化&#xff1a;批量重命名文件夹。 这周我利用下班时…...

sqoop

一、bg 可以在关系型数据库和hdfs、hive、hbase之间导数 导入&#xff1a;从RDBMS到hdfs、hive、hbase 导出&#xff1a;相反 sqoop1 和sqoop2 (1.99.x)不兼容&#xff0c;sqoop2 并没有生产的稳定版本&#xff0c; Sqoop1 import原理(导入) 从传统数据库获取元数据信息&…...

PySpark 数据操作(综合案例)

搜索引擎日志分析 要求&#xff1a; 读取文件转换成RDD&#xff0c;并完成&#xff1a; 打印输出&#xff1a;热门搜索时间段&#xff08;小时精度&#xff09;Top3打印输出&#xff1a;热门搜索词Top3打印输出&#xff1a;统计黑马程序员关键字在哪个时段被搜索最多将数据转…...

产品经理如何平衡用户体验与商业价值?

近期负责前端产品设计工作的小李忍不住抱怨&#xff1a;公司总是要求客户第一&#xff0c;实现客户良好体验&#xff0c;但在实际操作过程中&#xff0c;面向用户 体验提升的需求&#xff0c;研发资源计划几乎很难排上&#xff0c;资源都放在公司根据业务价值排序的需求…...

【PostgreSQL】系列之 一 CentOS 7安装PGSQL15版本(一)

目录 一、何为PostgreSQL&#xff1f; 二、PostgreSQL安装 2.1安装依赖 2.2 执行安装 2.3 数据库初始化 2.4 配置环境变量 2.5 创建数据库 2.6 配置远程 2.7 测试远程 三、常用命令 四、用户创建和数据库权限 一、何为PostgreSQL&#xff1f; PostgreSQL是以加州大学…...

Nginx解决文件服务器文件名显示不全的问题

Nginx可以搭建Http文件服务器&#xff0c;但默认的搭建会长文件名显示不全&#xff0c;比如如下&#xff1a; 问题&#xff1a;显示不全&#xff0c;出现...&#xff0c;需要进行解决 这里使用重新编绎nginx的方式&#xff0c;见此文&#xff1a; https://unix.stackexchange…...

IO进程线程第四天(8.1)

作业1&#xff1a; 从终端获取一个文件的路径以及名字。 若该文件是目录文件&#xff0c;则将该文件下的所有文件的属性显示到终端&#xff0c;类似ls -l该文件夹 若该文件不是目录文件&#xff0c;则显示该文件的属性到终端上&#xff0c;类似ls -l这单个文件 #include<…...

WAF绕过-权限控制篇-后门免杀

WAF绕过主要集中在信息收集&#xff0c;漏洞发现&#xff0c;漏洞利用&#xff0c;权限控制四个阶段。 1、什么是WAF&#xff1f; Web Application Firewall&#xff08;web应用防火墙&#xff09;&#xff0c;一种公认的说法是“web应用防火墙通过执行一系列针对HTTP/HTTPS的安…...

LED灯的驱动,GPIO子系统,添加按键的中断处理

1.应用程序发送指令控制LED亮灭 2.按键1 按下&#xff0c;led1电位反转 按键2按下&#xff0c;led2电位反转 按键3 按下&#xff0c;led3电位反转 驱动程序&#xff1a; #include <linux/init.h> #include <linux/module.h> #include<linux/of.h> #include…...

Gradle和Maven的区别

Gradle和Maven 当涉及到构建和管理项目时&#xff0c;Gradle和Maven是两个非常流行的选项。本文将讨论Gradle和Maven之间的区别以及它们的配置信息差异。 1. Gradle和Maven的区别 1.1 构建脚本语言 Maven使用XML作为构建脚本语言&#xff0c;而Gradle使用基于Groovy的DSL&…...

C#中 使用yield return 优化大数组或集合的访问

概要 我们在开发过程中&#xff0c;经常需要在一个很大的数组或集合中搜索元素&#xff0c;以满足业务需求。 本文主要介绍通过使用yield return的方式&#xff0c;避免将大量数据全部加载进入内存&#xff0c;再进行处理。从而提高程序的性能。 设计和实现 基本业务场景&a…...

ROS实现导航中止(pub命令版+C++代码版)

pub命令 rostopic pub /move_base/cancel actionlib_msgs/GoalID -- {}C代码&#xff1a; stop_navigation.cpp #include <ros/ros.h> #include <geometry_msgs/Twist.h> #include <nav_msgs/Odometry.h> #include <sys/time.h> #include <unistd…...

【VTK】读取一个 STL 文件,并使用 Qt 显示出来,在 Windows 上使用 Visual Studio 配合 Qt 构建 VTK

知识不是单独的&#xff0c;一定是成体系的。更多我的个人总结和相关经验可查阅这个专栏&#xff1a;Visual Studio。 文章目录 A.hA.cppRef. 直接先把效果放出来&#xff0c;有需要就往下看。 A.h // A.h #pragma once#include <QtWidgets/QMainWindow> #include "…...

深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录

ASP.NET Core 是一个跨平台的开源框架&#xff0c;用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录&#xff0c;以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...

相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解

【关注我&#xff0c;后续持续新增专题博文&#xff0c;谢谢&#xff01;&#xff01;&#xff01;】 上一篇我们讲了&#xff1a; 这一篇我们开始讲&#xff1a; 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下&#xff1a; 一、场景操作步骤 操作步…...

生成 Git SSH 证书

&#x1f511; 1. ​​生成 SSH 密钥对​​ 在终端&#xff08;Windows 使用 Git Bash&#xff0c;Mac/Linux 使用 Terminal&#xff09;执行命令&#xff1a; ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" ​​参数说明​​&#xff1a; -t rsa&#x…...

linux 下常用变更-8

1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行&#xff0c;YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID&#xff1a; YW3…...

JDK 17 新特性

#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持&#xff0c;不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的&#xff…...

JS设计模式(4):观察者模式

JS设计模式(4):观察者模式 一、引入 在开发中&#xff0c;我们经常会遇到这样的场景&#xff1a;一个对象的状态变化需要自动通知其他对象&#xff0c;比如&#xff1a; 电商平台中&#xff0c;商品库存变化时需要通知所有订阅该商品的用户&#xff1b;新闻网站中&#xff0…...

C++.OpenGL (20/64)混合(Blending)

混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...

站群服务器的应用场景都有哪些?

站群服务器主要是为了多个网站的托管和管理所设计的&#xff0c;可以通过集中管理和高效资源的分配&#xff0c;来支持多个独立的网站同时运行&#xff0c;让每一个网站都可以分配到独立的IP地址&#xff0c;避免出现IP关联的风险&#xff0c;用户还可以通过控制面板进行管理功…...

省略号和可变参数模板

本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…...

DBLP数据库是什么?

DBLP&#xff08;Digital Bibliography & Library Project&#xff09;Computer Science Bibliography是全球著名的计算机科学出版物的开放书目数据库。DBLP所收录的期刊和会议论文质量较高&#xff0c;数据库文献更新速度很快&#xff0c;很好地反映了国际计算机科学学术研…...