面向长文本处理的键值缓存压缩技术:智能压缩,无损性能,免微调

news2025/1/16 15:44:48

随着输入长度的增加,大型语言模型(LLMs)中的键值(KV)缓存需要存储更多的上下文信息以维持性能,这导致内存消耗和计算时间急剧上升。KV缓存的增长对内存和时间效率的挑战主要表现在两个方面:一是在处理长文本时,模型需要更多的内存资源来存储KV缓存,这不仅增加了硬件成本,还可能因内存限制而影响模型规模的扩展;二是在生成文本时,模型需要对KV缓存中的每个键值对进行注意力计算,随着缓存的增大,这个过程变得更加耗时,从而降低了模型的解码速度。

在深入分析大型语言模型(LLMs)的注意力机制时,研究者发现了一些关键模式,这些模式对于优化KV缓存至关重要。某些键在令牌生成期间始终吸引着模型的注意力,无论上下文的长度如何,这些“活跃”的键展现出稳定的高注意力权重。在长摘要和问答任务中,问题的位置(无论是在提示的开头还是结尾)对模型的注意力分配模式影响不大,显示出模型在处理长文本时的鲁棒性。研究者还发现注意力模式高度依赖于上下文,与用户的具体指令密切相关,这意味着不同的指令会引导模型关注不同的信息。

在超过 3k 的平均输入长度下,重要位置在生成过程中的逐层平均命中率。它显示了在多轮对话中,观察窗口中识别出的关键特征在随后的标记生成中保持了显著的一致性

这些观察结果促成了SnapKV的开发,它是一种创新的KV缓存压缩方法。SnapKV的创新之处在于它提出了一种无需微调的压缩方法,通过观察模型在生成过程中的注意力分配模式,自动识别并压缩KV缓存中的关键信息。SnapKV通过“投票”机制选出每个注意力头关注的关键KV位置,并通过聚类算法保留这些关键特征周围的信息,从而在不牺牲准确性的前提下显著减少KV缓存的大小。这种方法不仅减少了计算开销,还提高了内存效率,使得模型在处理长文本时更为高效。SnapKV在解码速度上实现了3.6倍的提升,在内存效率上实现了8.2倍的提升,同时在多个长序列数据集上保持了与基线模型相当的性能。SnapKV还能够与现有的深度学习框架轻松集成,仅需少量代码调整,为长文本处理提供了一种实用的解决方案。

 SnapKV 的简化工作流程。橙色区域表示 SnapKV 为每个注意力头选择的每头一组位置的聚类。这些聚类特征随后与观察窗口中的标记一起形成新的键值对,与观察窗口(标记为 "Window")连接。所选的前缀和观察窗口共同构成了用于生成的新 KV 缓存

SnapKV 的核心思想是在生成过程中保持提示(prompt)的 KV 缓存数量恒定,从而显著减少长上下文 LLMs 的服务时间。这是通过识别和选择每个注意力头(attention head)最关键的注意力特征(attention features)来实现的,以此创建一个新的、更小的 KV 缓存。

实现步骤

SnapKV 的实现分为两个主要阶段:

  1. 投票选择重要特征(Voting for Important Previous Features):

    • 利用定义好的投票过程(如公式1所示),基于观察窗口(observation window)——即提示的最后部分——来选择重要的特征。
    • 通过分析发现,这些特征在整个序列生成过程中表现出显著的一致性,表明它们对后续生成至关重要。
    • 此外,实施聚类算法以保留选定特征周围的特征,这有助于保留信息的完整性并避免丢失上下文。
  2. 更新和存储截断的键和值(Update and Store Truncated Key and Value):

    • 将选定的特征与观察窗口的特征连接起来,这些特征包含了所有提示信息。
    • 将连接后的 KV 缓存存储起来,以供后续生成使用,同时节省内存使用。

代码示例

def snap_kv(query_states, key_states, value_states, window_size, max_capacity_prompt, kernel_size):
    bsz, num_heads, q_len, head_dim = query_states.shape
    # 确保当前是处理提示阶段
    assert key_states.shape[-2] == query_states.shape[-2]
    if q_len < max_capacity_prompt:
        return key_states, value_states
    else:
        # 计算观察窗口的查询和前缀上下文的键的注意力权重
        attn_weights = compute_attn(query_states[..., -window_size:, :], key_states, attention_mask)
        # 沿着查询维度对权重求和
        attn_weights_sum = attn_weights[..., -window_size:, :-window_size].sum(dim=-2)
        # 应用1D池化进行聚类
        attn_cache = pool1d(attn_weights_sum, kernel_size=kernel_size, padding=kernel_size // 2, stride=1)
        # 基于池化后的权重选择每个头的top-k索引,以识别重要位置
        indices = attn_cache.topk(max_capacity_prompt - window_size, dim=-1).indices
        # 扩展索引以匹配头维度进行聚集
        indices = indices.unsqueeze(-1).expand(-1, -1, -1, head_dim)
        # 根据选定的索引聚集压缩的过去键和值状态
        k_past_compress = key_states[..., :-window_size, :].gather(dim=2, index=indices)
        v_past_compress = value_states[..., :-window_size, :].gather(dim=2, index=indices)
        k_obs = key_states[..., -window_size:, :]
        v_obs = value_states[..., -window_size:, :]
        # 将压缩后的过去键和观察窗口的键拼接在一起
        key_states = torch.cat([k_past_compress, k_obs], dim=2)
        # 将压缩后的过去值和观察窗口的值拼接在一起
        value_states = torch.cat([v_past_compress, v_obs], dim=2)
    return key_states, value_states
  • snap_kv 函数接受查询状态 query_states、键状态 key_states、值状态 value_states,以及其他参数如窗口大小 window_size、最大提示容量 max_capacity_prompt 和池化核大小 kernel_size
  • 首先,检查是否处于处理提示的阶段,如果不是,则直接返回原始的键和值状态。
  • 然后,计算观察窗口内查询和前缀上下文键之间的注意力权重 attn_weights
  • 对这些权重进行求和 attn_weights_sum,然后应用一维池化 pool1d 来聚类,以便选择重要的特征。
  • 使用 topk 方法根据池化后的权重选择每个头的重要位置 indices
  • 根据这些索引聚集压缩后的键和值状态 k_past_compress 和 v_past_compress
  • 最后,将压缩的键和值状态与观察窗口的键和值状态拼接起来,形成新的键和值状态,这些状态将用于后续的生成过程。

SnapKV方法论包含两个主要阶段:首先是通过一个称为“投票”的过程来识别重要的先前特征,其次是更新并存储截断的键和值。

在第一阶段,SnapKV利用了一个观察窗口,这个窗口位于提示的末端,它的作用是捕捉模型在生成过程中所关注的关键特征。通过计算观察窗口中每个查询的注意力权重,并在所有注意力头上聚合这些权重,SnapKV能够突出显示被认为是最重要的前缀位置。这个过程称为投票,它帮助系统识别出那些在生成文本时需要特别关注的KV位置。

第二阶段中,SnapKV将这些选出的重要特征与观察窗口中的特征结合起来,形成一个新的键值对。这个新的键值对随后被用于生成过程,同时通过仅保留这些关键特征,系统能够显著减少所需的内存和计算资源。此外,为了保持信息的完整性并避免因过度压缩而导致的细节丢失,SnapKV采用了一种基于池化的聚类算法。这个算法通过池化层对信息进行细粒度的压缩,确保了在压缩KV缓存的同时,依然能够保留足够的上下文信息,从而维持模型的准确性。

SnapKV的实现是高效的,因为它只需要对现有的深度学习框架进行少量的代码调整。这意味着它可以轻松地集成到现有的系统中,而无需进行大规模的重构。在实验中,SnapKV显示出了卓越的性能,它不仅在解码速度上实现了显著的提升,还在内存效率上达到了大幅度的增强。这些改进使得SnapKV成为一个在处理长文本方面极具潜力的解决方案,特别是在需要处理大量输入序列的应用场景中,如聊天机器人、代理服务、文档处理等。SnapKV通过其创新的方法论,为长文本处理中的内存和时间效率问题提供了一个有效的解决方案。

在对SnapKV进行的实验中,研究团队采取了一系列严谨的测试,旨在评估该方法在不同模型和长文本数据集上的性能。实验的目的是验证SnapKV在减少计算和内存负担的同时,是否能够保持或甚至提升模型的生成质量和效率。

实验首先在LWM-Text-Chat-1M模型上进行了压力测试,这是当时最先进的模型之一,能够处理长达一百万个令牌的上下文。测试中,SnapKV展现了其算法效率,特别是在硬件优化方面。通过“Needle-in-a-Haystack”测试,即在长达380K令牌的文档中准确检索特定句子的能力,SnapKV证明了其在极端条件下处理长文本的能力,即便在极高的压缩比下也能保持精确性。

在单 A100-80GB GPU 上,使用 SnapKV 优化的模型与原始实现在 "Needle-in-a-Haystack" 测试中的性能比较。图表显示了 SnapKV 在处理极长输入上下文时准确管理细节的潜力

实验通过不同的批处理大小对LWM-Text-Chat-1M模型进行了解码速度和内存限制的基准测试。结果表明,SnapKV优化的模型在解码速度上保持了稳定,与输入序列长度的增加无关,这与基线实现形成了鲜明对比,后者的解码速度随输入长度的增加而指数级增长。SnapKV显著提高了模型处理长序列的能力,显著减少了内存消耗。

在不同批量大小设置下,基线实现与 SnapKV 优化模型在解码速度和输入序列长度方面的比较。图表显示了 SnapKV 在保持解码速度恒定方面的优势

为了进一步验证SnapKV的有效性,研究团队还对Mistral-7B-Instruct-v0.2模型进行了消融研究,以理解池化技术对模型信息检索性能的影响。消融研究结果表明,通过池化增强了检索准确性,这可能是因为强大的注意力机制倾向于关注令牌序列的初始部分。

池化技术在 LongEval-Lines 测试中对检索准确性的影响。结果表明,使用池化的模型在压缩 KV 缓存时的性能显著优于不使用池化的模型

最后,实验使用了LongBench,这是一个多任务基准测试,旨在全面评估长文本理解能力。SnapKV在多个不同设置下进行了测试,包括压缩KV缓存到1024、2048和4096个令牌,并使用最大池化和观察窗口。测试结果显示,即使在压缩率高达92%的情况下,SnapKV与原始实现相比,在16个不同数据集上的性能下降可以忽略不计,某些情况下甚至超过了基线模型。

 SnapKV 和 H2O 在 LongBench 数据集上不同 LLMs 的性能比较。表格显示了 SnapKV 在压缩提示 KV 缓存时的性能与原始实现相比几乎没有下降

实验结果,SnapKV证明了其作为一种有效的KV缓存压缩方法,在保持大型语言模型处理长文本的能力的同时,显著提升了效率和减少了资源消耗。这些发现不仅证实了SnapKV的实用性,还为未来的研究和应用提供了有价值的见解。

SnapKV代码可在https://github.com/FasterDecoding/SnapKV上找到

论文链接:https://arxiv.org/abs/2404.14469

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

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

相关文章

【数据库初阶】SQL--DCL

文章目录 DCL1. 基本介绍2. 用户管理2.1 查询用户2.2 创建用户2.3 修改用户密码2.4 删除用户 3. 权限控制3.1 查询权限3.2 授予权限3.3 撤销权限 4. DCL总结 DCL 更多数据库MySQL系统内容就在以下专栏&#xff1a; 专栏链接&#xff1a;数据库MySQL 1. 基本介绍 DCL英文全称是…

推荐系统学习 二

双塔模型的结构 用户的特征&#xff0c;我们知道用户ID还能从用户填写的资料和用户行为中获取很多特征&#xff0c;包括离散特征和连续特征。所有这些特征不能直接输入神经网络&#xff0c;而是要先做一些处理&#xff0c;比如用embedding层把用户ID映射到一个向量 跟之前我们…

【每日刷题】Day56

【每日刷题】Day56 &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;每日刷题&#x1f34d; &#x1f33c;文章目录&#x1f33c; 1. 292. Nim 游戏 - 力扣&#xff08;LeetCode&#xff09; 2. 129. 求根节点到叶节点数字之和 - 力扣…

QT案例 记录解决在管理员权限下QFrame控件获取拖拽到控件上的文件路径

参考知乎问答 Qt管理员权限如何支持拖放操作&#xff1f; 的回答和代码示例。 解决在管理员权限运行下&#xff0c;通过窗体的QFrame子控件获取到拖拽的内容。 目录标题 导读解决方案详解示例详细 【管理员权限】在QFrame控件中获取拖拽内容 【管理员权限】继承 IDropTarget 类…

[SaaS] AI+数据,tiktok选品,找达人,看广告数据

TK观察专访丨前阿里“鲁班”创始人用AIGC赋能TikTok获千万融资用AI数据做TikTokhttps://mp.weixin.qq.com/s/xp5UM3ROo48DK4jS9UBMuQ主要还是爬虫做数据的。 商家做内容&#xff1a;1.找达人拍内容&#xff0c;2.商家自己做原生自制内容&#xff0c;3.广告内容。 短视频&…

俞敏洪一句“乱七八糟”,让东方甄选跌了40亿

“虽然直播的特点就是能说会道&#xff0c;但是网上那种买买买的嚎叫&#xff0c;我是完全看不起的”&#xff0c;俞敏洪在2023亚布力论坛上颇为自豪地说。 在他看来&#xff0c;“直播带货”本质上也是教育的一种&#xff0c;对产品进行知识性讲解才是最核心的一环。而知识传…

Centos 7部署NTP

介绍 NTP是Network Time Protocol&#xff08;网络时间协议&#xff09;的简称&#xff0c;它是用来通过互联网或局域网将计算机时钟同步到世界协调时间&#xff08;UTC&#xff09;的协议。 安装 # yum安装 yum install -y ntp# 离线安装 #下载地址&#xff1a;https://mir…

Meta Llama 3 残差结构

Meta Llama 3 残差结构 flyfish 在Transformer架构中&#xff0c;残差结构&#xff08;Residual Connections&#xff09;是一个关键组件&#xff0c;它在模型的性能和训练稳定性上起到了重要作用。残差结构最早由He et al.在ResNet中提出&#xff0c;并被广泛应用于各种深度…

【python】爬虫记录每小时金价

数据来源&#xff1a; https://www.cngold.org/img_date/ 因为这个网站是数据随时变动的&#xff0c;用requests、BeautifulSoup的方式解析html的话&#xff0c;数据的位置显示的是“--”&#xff0c;并不能取到数据。 所以采用webdriver访问网站&#xff0c;然后从界面上获取…

3389远程连接器,3389远程连接器如何进行远程连接

3389远程连接器是一款专业的远程桌面连接工具&#xff0c;它允许用户通过网络远程访问和控制另一台计算机&#xff0c;实现远程办公、技术支持、文件传输等多种功能。下面将详细介绍如何使用3389远程连接器进行远程连接。 首先&#xff0c;确保被连接的计算机已经开启了远程桌面…

TCP的核心属性

TCP的核心属性 一: TCP的核心属性1.1: 确认应答:1.2 : 超时重传1.3 : 连接管理1.3.1 三次握手1.3.2 四次挥手 1.4 滑动窗口1.5: 流量控制:1.6 拥塞控制1.7 延时应答1.8 :捎带应答1.9: 面向字节流1.10 : 异常情况 一: TCP的核心属性 1.1: 确认应答: 保证可靠性最核心的机制 1…

二刷算法训练营Day22 | 二叉树(8/9)

目录 详细布置&#xff1a; 1. 235. 二叉搜索树的最近公共祖先 2. 701. 二叉搜索树中的插入操作 3. 450. 删除二叉搜索树中的节点 详细布置&#xff1a; 1. 235. 二叉搜索树的最近公共祖先 给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共…

二叉树的算法题目

二叉树的遍历题目 二叉树遍历一般包含三种分别为&#xff1a;根左右、左根右、左右根&#xff08;又称为前序遍历、中序遍历、后序遍历&#xff09; 方法一&#xff1a;使用递归遍历 方法二&#xff1a;使用迭代使用栈 我们以左根右&#xff08;中序遍历&…

修复Windows上“发生意外错误”问题的5种方法,总有一种适合你

在尝试启动网络适配器的设置菜单时,是否收到“发生意外错误”消息?不用担心,因为在大多数情况下解决这个问题很容易。我们将向你展示在Windows 11或Windows 10计算机上解决此问题的多种方法。 为什么我收到“发生意外错误”的消息 当网络适配器出现问题时,Windows会显示一…

MariaDB数据导入与导出操作演示

文章目录 整个数据库导出导入先删除库然后再导入 参考这里&#xff1a; MariaDB数据库导出导入. 整个数据库 该部分演示&#xff1a;导出数据库&#xff0c;然后重建数据库&#xff0c;并导入数据的整个过程。 导出 Win R &#xff0c;打开运行输入cmd并回车&#xff0c;然…

【docker】docker的安装

如果之前安装了旧版本的docker我们需要进行卸载&#xff1a; 卸载之前的旧版本 卸载 # 卸载旧版本 sudo apt-get remove docker docker-engine docker.io containerd runc # 卸载历史版本 apt-get purge docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker…

如何在Weblogic环境中启动认证方式对接Zabbix监控

在WebLogic Server中&#xff0c;启动认证可用于确保只有经过授权的用户和系统能够访问WebLogic Server及其应用程序&#xff0c;通过合理配置认证提供者和安全领域&#xff0c;管理员可以有效管理和控制用户访问。 本文将详细介绍如何在Weblogic环境中配置启动认证并对接Zabb…

植物大战僵尸杂交版2.0.88最新版+防闪退工具V2+修改工具+高清工具

植物大战僵尸杂交版&#xff0c;不仅继承原作的经典玩法&#xff0c;而且引入了全新的植物融合玩法&#xff0c;将各式各样的植物进行巧妙的杂交&#xff0c;孕育出前所未有、功能各异的全新植物。 创新的杂交合成系统 游戏引入了创新的杂交合成系统&#xff0c;让玩家可以将不…

Swift 中的Getter 和 Setter

目录 前言 1. 什么是Getter和Setter 1.定义 2.作用 2.属性 1.存储属性 2.计算属性 3.属性观察者 3. 使用 Getter 和 Setter 的场景 1.数据转换 2.懒加载 3.数据验证和限制 4.触发相关操作 4.自定义Getter 和 Setter 5. 参考资料 前言 属性是 Swift 编程中的基本…

Ubuntu中PDF阅读器和编辑器

1. 福昕PDF编辑器 1.1. 下载地址 PDF阅读器下载_PDF编辑器下载_PDF软件官方下载_福昕软件官网 1.2. 安装 sudo dpkg -i signed_com.foxit.foxitpdfeditor_xxx_amd64_UOS.deb 2. WPS DPF 2.1. 下载地址 WPS Office 2019 for Linux-支持多版本下载_WPS官方网站 2.2. 使用 …