探索和构建 LLaMA 3 架构:深入探讨组件、编码和推理技术(三)KV缓存

本文主要是介绍探索和构建 LLaMA 3 架构:深入探讨组件、编码和推理技术(三)KV缓存,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

探索和构建 LLaMA 3 架构:深入探讨组件、编码和推理技术(三)

KV缓存

在推理的每一步中,只对模型输出的最后一个标记感兴趣,因为已经有了之前的标记。然而,模型需要访问所有先前的标记来决定输出哪个标记,因为它们构成了它的上下文(或“提示”)。
这是一种使模型在推理过程中对已经看到的标记进行更少计算的方法。解决办法就是KV缓存!

在Transformer的推理过程中, 增量且顺序地获取查询向量。将其乘以 Key 向量即可得到每个 token 与先前生成的 token 及其自身的注意力矩阵。然后,在取softmax之后, 乘以值向量以获得自注意力分数。最后有另一个输出投影矩阵,用于转换下一组多头注意力层的注意力分数。这个计算重复多次,然后得到词汇表中所有单词的概率分布
在这里插入图片描述
在上图中, 可以看到Transformer的推论。标记 TOKEN 1 到 TOKEN 4 按顺序出现,因为注意力计算 TOKEN 4 取决于所有先前的标记。

  • 在紫色矩阵中, 可以看到 Q 和 K 矩阵乘法随着注意力矩阵一起增长,但 K 和 V 值矩阵对于所有先前的标记保持相同。另外,如图所示, 不需要已经计算出的注意力分数(需要注意的是, 可能需要波束搜索来获得它们,但这里 只考虑贪婪采样),所以 可以扔掉它们。深紫色矩阵实际上为零,因为它是因果矩阵,因此第一个标记从不关注第四个标记,并且它们被屏蔽。

  • 因此 可以缓存 K 和 V 矩阵,因为它们不会改变。但是, 无法缓存 Q 矩阵。这是因为 Q 矩阵随着每个新标记而变化。查询矩阵是标记正在查找的内容,键矩阵是标记包含的内容,值矩阵是当前标记和前一个标记是否对词汇表中的标记感兴趣。

  • 此外,可以借助电影数据库来理解查询(query)、键(key)和值(value)的概念。假设你想看一部能让你发笑,并且最后有一个“谁是凶手”环节的电影(这是查询)。那么首先,我们会在数据库中查询一部能让我们发笑的电影,这将是一部喜剧片(这是键)。然后,我们会得到一系列喜剧电影的推荐(这是值)。在那之后,电影数据库会获取到电影应该是“谁是凶手”类型或属于惊悚片类型的信息。然后,电影数据库将寻找喜剧和惊悚类型的电影(这是更新后的键),并且借助之前缓存的喜剧电影推荐,我们可以搜索那些同时也是惊悚片的电影(值)。
    因此, 可以缓存喜剧类型和所有喜剧电影推荐,以便当新信息出现(惊悚类型)时, 可以缩小搜索范围并提高效率。

KV 缓存对于高效推理至关重要,因为 增量存储键和值矩阵并缓存它们,以便可以更快地计算未来的注意力分数。

def repeat_kv(x: torch.Tensor, n_rep: int)-> torch.Tensor:batch_size, seq_len, n_kv_heads, head_dim = x.shapeif n_rep == 1:return xelse:return (# (B, seq_len, n_kv_heads, 1, head_dim)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))

KV 缓存的一些问题

KV缓存一般存储在连续的内存中。如果有多个并行请求,那么它们需要单独存储,这会浪费内存,并可能导致 OOM(内存不足)错误。而且,每个请求的提示几乎相同(特别是像“你是一个有用的助手…”这样的系统提示),因此一次又一次地将它们存储在连续的内存中效率很低。
在这里插入图片描述

  • 静态模型权重消耗了近 65% 的 VRAM 内存,而 KV 缓存则消耗了近 30%,因为它会因多个请求而增大且内存使用效率低下。并且,如果将 KV 缓存存储在连续的内存中,那么在一些服务之后需要将其取消分配以适应最近的 KV 缓存

  • 如果想要生成具有一些初始响应的并行多个响应,那么需要为每个生成的响应单独存储它们在连续的内存中,这会浪费很多空间。此外,使用诸如束搜索(beam search)这样的高级技术时,会根据生成的的未来累积概率来选择最有可能的。在这里,需要回溯并关闭一些路径,因此对于束搜索中的每个方向,如果分配了一个新的连续内存,那么它将消耗大量内存,效率很低。

  • GPU在矩阵乘法方面已经变得非常擅长,但这些系统的记忆仍然有限,因此受内存限制。KV缓存可以帮助,因为它可以帮助更快地获取键和值矩阵以进行计算。但在内存有限的情况下,需要提出更好的内存管理方法。

系列博客

探索和构建 LLaMA 3 架构:深入探讨组件、编码和推理技术(一)
https://duanzhihua.blog.csdn.net/article/details/138208650
探索和构建 LLaMA 3 架构:深入探讨组件、编码和推理技术(二)
https://duanzhihua.blog.csdn.net/article/details/138212328

在这里插入图片描述

在这里插入图片描述

这篇关于探索和构建 LLaMA 3 架构:深入探讨组件、编码和推理技术(三)KV缓存的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/939473

相关文章

Java实现字节字符转bcd编码

《Java实现字节字符转bcd编码》BCD是一种将十进制数字编码为二进制的表示方式,常用于数字显示和存储,本文将介绍如何在Java中实现字节字符转BCD码的过程,需要的小伙伴可以了解下... 目录前言BCD码是什么Java实现字节转bcd编码方法补充总结前言BCD码(Binary-Coded Decima

Vue和React受控组件的区别小结

《Vue和React受控组件的区别小结》本文主要介绍了Vue和React受控组件的区别小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学... 目录背景React 的实现vue3 的实现写法一:直接修改事件参数写法二:通过ref引用 DOMVu

Three.js构建一个 3D 商品展示空间完整实战项目

《Three.js构建一个3D商品展示空间完整实战项目》Three.js是一个强大的JavaScript库,专用于在Web浏览器中创建3D图形,:本文主要介绍Three.js构建一个3D商品展... 目录引言项目核心技术1. 项目架构与资源组织2. 多模型切换、交互热点绑定3. 移动端适配与帧率优化4. 可

使用Spring Cache本地缓存示例代码

《使用SpringCache本地缓存示例代码》缓存是提高应用程序性能的重要手段,通过将频繁访问的数据存储在内存中,可以减少数据库访问次数,从而加速数据读取,:本文主要介绍使用SpringCac... 目录一、Spring Cache简介核心特点:二、基础配置1. 添加依赖2. 启用缓存3. 缓存配置方案方案

Python利用PySpark和Kafka实现流处理引擎构建指南

《Python利用PySpark和Kafka实现流处理引擎构建指南》本文将深入解剖基于Python的实时处理黄金组合:Kafka(分布式消息队列)与PySpark(分布式计算引擎)的化学反应,并构建一... 目录引言:数据洪流时代的生存法则第一章 Kafka:数据世界的中央神经系统消息引擎核心设计哲学高吞吐

Springboot项目构建时各种依赖详细介绍与依赖关系说明详解

《Springboot项目构建时各种依赖详细介绍与依赖关系说明详解》SpringBoot通过spring-boot-dependencies统一依赖版本管理,spring-boot-starter-w... 目录一、spring-boot-dependencies1.简介2. 内容概览3.核心内容结构4.

Java实现本地缓存的四种方法实现与对比

《Java实现本地缓存的四种方法实现与对比》本地缓存的优点就是速度非常快,没有网络消耗,本地缓存比如caffine,guavacache这些都是比较常用的,下面我们来看看这四种缓存的具体实现吧... 目录1、HashMap2、Guava Cache3、Caffeine4、Encache本地缓存比如 caff

Java 中编码与解码的具体实现方法

《Java中编码与解码的具体实现方法》在Java中,字符编码与解码是处理数据的重要组成部分,正确的编码和解码可以确保字符数据在存储、传输、读取时不会出现乱码,本文将详细介绍Java中字符编码与解码的... 目录Java 中编码与解码的实现详解1. 什么是字符编码与解码?1.1 字符编码(Encoding)1

Python中高级文本模式匹配与查找技术指南

《Python中高级文本模式匹配与查找技术指南》文本处理是编程世界的永恒主题,而模式匹配则是文本处理的基石,本文将深度剖析PythonCookbook中的核心匹配技术,并结合实际工程案例展示其应用,希... 目录引言一、基础工具:字符串方法与序列匹配二、正则表达式:模式匹配的瑞士军刀2.1 re模块核心AP

Go语言使用net/http构建一个RESTful API的示例代码

《Go语言使用net/http构建一个RESTfulAPI的示例代码》Go的标准库net/http提供了构建Web服务所需的强大功能,虽然众多第三方框架(如Gin、Echo)已经封装了很多功能,但... 目录引言一、什么是 RESTful API?二、实战目标:用户信息管理 API三、代码实现1. 用户数据