LLM推理优化——KV Cache篇(百倍提速)

LLM推理优化——KV Cache篇(百倍提速)

请添加图片描述

注意:KV Cache本质上是空间换时间的技术。与计算机组成原理中的cache不同,它不涉及访存优化。

不知道大家在用LLM的时候,有没有注意到一个问题:我们在输入我们的问题之后,需要等待一段漫长的时间才能看到第一个字符的响应,而等待第一个之后,后续的响应却非常之快,这就是使用了KV Cache加速后的带来的优势。

LLM推理过程与自注意力机制

LLM的推理过程和训练过程是有所区别的,LLM在训练过程中使用因果掩码并行化训练,无需像RNN一样等待之前的结果运算结束。但是他的推理过程却类似RNN,并且有大量的重复计算。详细解释可以参照上一篇Blog:LLM的训练与推断。我们已经知道LLM推断时实际上是一种自回归模型 f θ f_\theta fθ,假设在 t t t步及其之前的输入和推断表示为 x 1 : t x_{1:t} x1:t,我们可以用公式表示它:

x 1 : t + 1 = f θ ( x 1 : t ) (1) % \begin{align} x_{1:t+1} = f_\theta(x_{1:t}) \tag{1} % \end{align} x1:t+1=fθ(x1:t)(1)

从公式1我们可以看到,即使 x 1 : t x_{1:t} x1:t已经是计算过的,但是在计算 x t + 1 x_{t+1} xt+1时却还要重复计算 x 1 : t x_{1:t} x1:t,当序列愈来愈长,这个计算代价也越来越不可接受,尤其绝大多数计算都是在做无用功(重复计算)。

基于此,我们就有一个朴素的优化思考:我们能否去除掉这些重复计算?那答案是当然可以,不然就没有这篇博客了🤣。

那么如何去除呢?如果有动态规划、搜索基础的小伙伴可能会比较眼熟,类似于常用的剪枝操作。将后续仍然需要使用的计算结果保存起来,后续使用时不必再次计算

那么来看一下具体是如何实施的,从LLM的训练与推断中我们可以知道,需要重复计算的矛盾点来自于自注意力机制,首先回顾一下它:
a t t n ( Q , K , V ) = s o f t m a x ( Q T K d k ) V attn(Q,K,V) = softmax\left(\frac{Q^TK}{\sqrt{d_k}}\right)V attn(Q,K,V)=softmax(dk QTK)V
我们可以用行列向量的形式表示第t步计算 x t x_t xt时的 ( Q T K ) t (Q^TK)_t (QTK)t
( Q T K ) t = ( q 1 T k 1 q 1 T k 2 … q 1 T k t q 2 T k 1 q 2 T k 2 … q 2 T k t ⋮ ⋮ ⋱ ⋮ q t T k 1 q t T k 2 … q t T k t ) ( Q T K ) t + 1 = ( q 1 T k 1 q 1 T k 2 … q 1 T k t q 1 T k t + 1 q 2 T k 1 q 2 T k 2 … q 2 T k t q 2 T k t + 1 ⋮ ⋮ ⋮ ⋮ q t T k 1 q t T k 2 … q t T k t q t T k t + 1 q t + 1 T k 1 q t + 1 T k 2 … q t + 1 T k t q t + 1 T k t + 1 ) \begin{align} (Q^TK)_t&= \left( \begin{array}{cccc} q^T_1k_1 & q^T_1k_2&\ldots&q^T_1k_t\\ q^T_2k_1 & q^T_2k_2&\ldots&q^T_2k_t\\ \vdots& \vdots&\ddots&\vdots\\ q^T_tk_1 & q^T_tk_2&\ldots&q^T_tk_t\\ \end{array}\right)\notag \\ (Q^TK)_{t+1}&= \left( \begin{array}{ccccc} q^T_1k_1 & q^T_1k_2&\ldots&q^T_1k_t&q^T_1k_{t+1}\\ q^T_2k_1 & q^T_2k_2&\ldots&q^T_2k_t&q^T_2k_{t+1}\\ \vdots& \vdots&\ &\vdots&\vdots\\ q^T_tk_1 & q^T_tk_2&\ldots&q^T_tk_t&q^T_tk_{t+1}\\ q^T_{t+1}k_1 & q^T_{t+1}k_2&\ldots&q^T_{t+1}k_t&q^T_{t+1}k_{t+1}\\ \end{array}\right)\notag \\ \end{align} (QTK)t(QTK)t+1= q1Tk1q2Tk1qtTk1q1Tk2q2Tk2qtTk2q1Tktq2TktqtTkt = q1Tk1q2Tk1qtTk1qt+1Tk1q1Tk2q2Tk2qtTk2qt+1Tk2 q1Tktq2TktqtTktqt+1Tktq1Tkt+1q2Tkt+1qtTkt+1qt+1Tkt+1

从式子中可以看到,在计算 ( Q T K ) t + 1 (Q^TK)_{t+1} (QTK)t+1时,前t行t列已经被计算过,我们只需要计算最后一行并且保存即可。由 q t + 1 T k 1 , q t + 1 T k 2 , … , q t + 1 T k t , q t + 1 T k t + 1 q^T_{t+1}k_1, q^T_{t+1}k_2,\ldots,q^T_{t+1}k_t,q^T_{t+1}k_{t+1} qt+1Tk1,qt+1Tk2,,qt+1Tkt,qt+1Tkt+1可知,我们还需要知道之前每次计算出的 k k k值,所以在保存每行值之外,也应当保存 k 1 , k 2 , … , k t + 1 k_1, k_2,\ldots,k_{t+1} k1,k2,,kt+1的值。

这里可能会有疑惑,最后一列用了之前的 q 1 , q 2 , … , q t q_1,q_2, \ldots,q_t q1,q2,,qt,为什么不保存 q q q的值。实际上, Q T K Q^TK QTK矩阵会经过一个掩码操作,他最后得到是一个下三角矩阵,我们不必再次计算,直接补0即可。

保存 V V V值亦是同理。

保存 K , V K,V K,V是不是KV Cache名称的由来呢?

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

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

相关文章

vscode搭建rust开发环境

由于rustrover不是免费的,此处教学搭建一套基于vscode的rust开发环境,可运行,可调式 1.下载vscode1.91.1 Download Visual Studio Code - Mac, Linux, Windows 2.下载插件 打开网站下载插件 rust-analyzer-0.4.2049、vscode-lldb-1.10.0、…

java使用hutool工具判断ip或者域名是否可用,java使用ping判断ip或者域名是否可用

1.导入hutool的maven依赖 <dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.16</version></dependency>2.复制以下代码直接运行 import cn.hutool.core.net.NetUtil;public class …

论文解读:DiAD之SG网络

目录 一、SG网络功能介绍二、SG网络代码实现 一、SG网络功能介绍 DiAD论文最主要的创新点就是使用SG网络解决多类别异常检测中的语义信息丢失问题&#xff0c;那么它是怎么实现的保留原始图像语义信息的同时重建异常区域&#xff1f; 与稳定扩散去噪网络的连接&#xff1a; S…

将 magma example 改写成 cusolver example eqrf

1&#xff0c;简单安装Magma 1.1 下载编译 OpenBLAS $ git clone https://github.com/OpenMathLib/OpenBLAS.git $ cd OpenBLAS/ $ make -j DEBUG1 $ make install PREFIX/home/hipper/ex_magma/local_d/OpenBLAS/1.2 下载编译 magma $ git clone https://bitbucket.org/icl…

【Kubernetes】二进制部署k8s集群(中)之cni网络插件flannel和calico

&#xff01;&#xff01;&#xff01;继续上一篇实验部署&#xff01;&#xff01;&#xff01; 目录 一.k8s的三种网络模式 1.Pod 内容器与容器之间的通信 2.同一个 Node 内 Pod 之间的通信 3.不同 Node 上 Pod 之间的通信 二.k8s的三种接口 三.Flannel 网络插件 1.U…

美摄科技企业级视频拍摄与编辑SDK解决方案

在数字化浪潮汹涌的今天&#xff0c;视频已成为企业传递信息、塑造品牌、连接用户不可或缺的强大媒介。为了帮助企业轻松驾驭这一视觉盛宴的制作过程&#xff0c;美摄科技凭借其在影视级非编技术领域的深厚积累&#xff0c;推出了面向企业的专业视频拍摄与编辑SDK解决方案&…

每日OJ_牛客CM26 二进制插入

目录 牛客CM26 二进制插入 解析代码 牛客CM26 二进制插入 二进制插入_牛客题霸_牛客网 解析代码 m:1024&#xff1a;100000000 00 n:19 &#xff1a; 10011 要把n的二进制值插入m的第j位到第i位&#xff0c;只需要把n先左移j位&#xff0c;然后再进行或运算&#xff08;|&am…

高品质定制线缆知名智造品牌推荐-精工电联:高压线缆行业定制服务的领航者

定制线缆源头厂家推荐-精工电联&#xff1a;高压线缆行业定制服务的领航者 在当今这个高度信息化的社会&#xff0c;电力传输与分配系统的稳定运行至关重要。作为连接各个电力设备的纽带&#xff0c;高压线缆的质量直接关系到电力系统的安全性和稳定性。在定制高压线缆行业中&a…

android(安卓)最简单明了解释版本控制之MinSdkVersion、CompileSdkVersion、TargetSdkVersion

1、先明白几个概念 &#xff08;1&#xff09;平台版本&#xff08;Android SDK版本号&#xff09; 平台版本也就是我们平时说的安卓8、安卓9、安卓10 &#xff08;2&#xff09;API级别&#xff08;API Level&#xff09; Android 平台提供的框架 API 被称作“API 级别” …

Hugo 部署与自动更新(Git)

文章目录 Nginx部署Hugonginx.confhugo.conf Hugo自动更新Hugo自动更新流程添加访问令牌添加web hookrust实现自动更新接口 Nginx部署Hugo nginx.conf user nginx; worker_processes auto;error_log /var/log/nginx/error.log notice; pid /var/run/nginx.pid;even…

C++STL简介(三)

目录 1.vector的模拟实现 1.1begin&#xff08;&#xff09; 1.2end&#xff08;&#xff09; 1.3打印信息 1.4 reserve&#xff08;&#xff09; 1.5 size&#xff08;&#xff09; 1.6 capacity&#xff08;&#xff09; 1.7 push_back() 1.8[ ] 1.9 pop_back() 1.10 insert&…

合并K个有序链表

题目 给你一个链表数组&#xff0c;每个链表都已经按升序排列。 请你将所有链表合并到一个升序链表中&#xff0c;返回合并后的链表。 示例1&#xff1a; 输入&#xff1a; 输出&#xff1a; 示例2&#xff1a; 输入&#xff1a; 输出&#xff1a; 示例3&#xff1a; 输入&…

【音视频之SDL2】Windows配置SDL2项目模板

文章目录 前言 SDL2 简介核心功能 Windows配置SDL2项目模板下载SDL2编译好的文件VS配置SDL2 测试代码效果展示 总结 前言 在开发跨平台的音视频应用程序时&#xff0c;SDL2&#xff08;Simple DirectMedia Layer 2&#xff09;是一个备受欢迎的选择。SDL2 是一个开源库&#x…

自研Vue3开源Tree组件:节点拖拽bug修复

当dropType为after&#xff0c;且dropNode为父节点时&#xff0c;bug出现了&#xff1a; bug原因&#xff1a;插入扁平化列表的位置insertIndex计算的不对&#xff1a; 正确的逻辑&#xff0c;同inner要算上子孙节点所占的位置&#xff1a; bug修复&#xff01;

「数组」实现动态数组的功能(C++)

概述 动态数组&#xff0c;顾名思议即可变长度的数组。数组这种数据结构的实现是在栈空间或堆空间申请一段连续的可操作区域。 实现可变长度的动态数组结构&#xff0c;应该有以下操作&#xff1a;申请一段足够长的空间&#xff0c;如果数据的存入导致空间已满&#xff0c;则…

PackagesNotFoundError 错误表明 conda 在当前使用的镜像源中找不到 contourpy 版本 1.2.1。以下是可能的解决方法:

PackagesNotFoundError 错误表明 conda 在当前使用的镜像源中找不到 contourpy 版本 1.2.1。以下是可能的解决方法&#xff1a; PackagesNotFoundError 错误表明 conda 在当前使用的镜像源中找不到 contourpy 版本 1.2.1。以下是可能的解决方法&#xff1a; 1. 更换镜像源 虽…

rust 桌面 sip 软电话(基于tauri 、pjsip库)

本文尝试下rust 的tauri 桌面运用 原因在于体积小 1、pjsip 提供了rust 接口官方的 rust demo 没编译出来 在git找了个sip-phone-rs-master https://github.com/Charles-Schleich/sip-phone-rs 可以自己编译下pjsip lib库替换该项目的lib 2、创建一个tauri demo 引用 [depe…

计算机毕业设计选题推荐-某炼油厂盲板管理系统-Java/Python项目实战

✨作者主页&#xff1a;IT研究室✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Python…

实战:Zookeeper 简介和单点部署ZooKeeper

Zookeeper 简介 ZooKeeper是一个开源的分布式协调服务&#xff0c;它是Apache软件基金会下的一个项目&#xff0c;旨在解决分布式系统中的协调和管理问题。以下是ZooKeeper的详细简介&#xff1a; 一、基本定义 ZooKeeper是一个分布式的、开放源码的分布式应用程序协调服务&a…

SpringBoot的基础配置

目录 SpringBoot快速搭建web程序 第一步&#xff1a;导包 第二步&#xff1a;配置SpringBoot引导类 第三步&#xff1a;编写controller类 第四步&#xff1a;在SpirngBoot引导类中启动项目 起步依赖 SpringBoot基础配置 配置文件格式 yaml语法规则 读取yml配置文件的方…