大模型推理性能优化之KV Cache解读

kvcache原理、参数量、代码详解 kvcache一句话来说就是把。训练的时候不需要保存。推理解码生成时都是自回归auto-regressive的方式,也就是每次生成一个token,都要依赖之前token的结果。如果没生成一个token的时候乘以W_K,W_V这俩参数矩阵要对所有token都算一遍,代价非常大,所以缓存起来就叫kvcache。举个例子,假如prompt=“The largest city of China is”,输入是6个tokens,返回是"Shang Hai"这两个tokens。 阅读详情

0. 引言

做大模型性能优化的一定对KV Cache不陌生,那么我们对这个技术了解到什么程度呢?请尝试回答如下问题:

  • KV Cache节省了Self-Attention层中哪部分的计算?

  • KV Cache对MLP层的计算量有影响吗?

  • KV Cache对block间的数据传输量有影响吗?本文打算剖析该技术并给出上面问题的答案。

1. KV Cache是啥

大模型推理性能优化的一个常用技术是KV Cache,该技术可以在不影响任何计算精度的前提下,通过空间换时间思想,提高推理性能。网上有一些关于该技术的分析博客,但读过后仍然会很迷糊,甚至可能会被带偏,认为这个Cache过程和数据库读取或CPU Cache加速类似的荒谬结论。刚开始我也有类似误解,直到逐行查阅并运行源码,才清楚了解到其Cache了啥,以及如何节省计算的。

2. 背景

生成式generative模型的推理过程很有特点,我们给一个输入文本,模型会输出一个回答(长度为N),其实该过程中执行了N次推理过程。即GPT类模型一次推理只输出一个token,输出token会与输入tokens 拼接在一起,然后作为下一次推理的输入,这样不断反复直到遇到终止符。

如上描述是我们通常认知的GPT推理过程。代码描述如下:

import torch
from transformers import GPT2LMHeadModel, GPT2Tokenizer


model = GPT2LMHeadModel.from_pretrained("gpt2", torchscript=True).eval()

# tokenizer
tokenizer = GPT2Tokenizer.from_pretrained("gpt2")
in_text = "Lionel Messi is a"
in_tokens = torch.tensor(tokenizer.encode(in_text))

# inference
token_eos = torch.tensor([198]) # line break symbol
out_token = None
i = 0
with torch.no_grad():
    while out_token != token_eos:
        logits, _ = model(in_tokens)
        out_token = torch.argmax(logits[-1, :], dim=0, keepdim=True)
        in_tokens = torch.cat((in_tokens, out_token), 0)
        text = tokenizer.decode(in_tokens)
        print(f'step {i} input: {text}', flush=True)
        i += 1

out_text = tokenizer.decode(in_tokens)
print(f' Input: {in_text}')
print(f'Output: {out_text}')

输出:

step 0 input: Lionel Messi is a player
step 1 input: Lionel Messi is a player who
step 2 input: Lionel Messi is a player who has
step 3 input: Lionel Messi is a player who has been
step 4 input: Lionel Messi is a player who has been a
step 5 input: Lionel Messi is a player who has been a key
step 6 input: Lionel Messi is a player who has been a key part
step 7 input: Lionel Messi is a player who has been a key part of
step 8 input: Lionel Messi is a player who has been a key part of the
step 9 input: Lionel Messi is a player who has been a key part of the team
step 10 input: Lionel Messi is a player who has been a key part of the team's
step 11 input: Lionel Messi is a player who has been a key part of the team's success
step 12 input: Lionel Messi is a player who has been a key part of the team's success.
step 13 input: Lionel Messi is a player who has been a key part of the team's success.

 Input: Lionel Messi is a
Output: Lionel Messi is a player who has been a key part of the team's success.

可以看出如上计算的问题吗?每次推理过程的输入tokens都变长了,导致推理FLOPs随之增大。有方法实现推理过程的FLOPs基本恒定不变或变小吗?(埋个伏笔,注意是基本恒定)。

3. 原理

在上面的推理过程中,每step内,输入一个token序列,经过Embedding层将输入token序列变为一个三维张量[b, s, h],经过一通计算,最后经logits层将计算结果映射至词表空间,输出张量维度为[b, s, vocab_size]。

当前轮输出token与输入tokens拼接,并作为下一轮的输入tokens,反复多次。可以看出第i+1轮输入数据只比第 轮i输入数据新增了一个token,其他全部相同!因此第i+1轮推理时必然包含了第i轮的部分计算。KV Cache的出发点就在这里,缓存当前轮可重复利用的计算结果,下一轮计算时直接读取缓存结果,就是这么简单,不存在什么Cache miss问题。

4. 实现细节

目前各大模型推理都实现了KV Cache,下面就看如何使用了。我们可以在上面代码基础上修改,主要改动:

  • 在推理时新增了past_key_values参数,该参数就会以追加方式保存每一轮的K V值。kvcache变量内容为((k,v), (k,v), ..., (k,v)),即有L个 k,v 组成的一个元组,其中 k 和 v 的维度均为[b, n_head, s, head_dims]。这里可以顺带计算出每轮推理对应的 cache 数据量为2bshL,这里s值等于当前轮次值。可以随着输出tokens的增长,cache数据量呈现线性增加特点。以GPT3-175B为例,假设以 float16 来保存 KV cache,senquence长度为100,batchsize=1,则KV cache占用显存为 2×100×12288×96×2 Byte = 472MB。

  • 推理输出的token直接作为下一轮的输入,不再拼接,因为上文信息已经在 kvcache 中。

代码示例:

import torch
from transformers import GPT2LMHeadModel, GPT2Tokenizer


model = GPT2LMHeadModel.from_pretrained("gpt2", torchscript=True).eval()

# tokenizer
tokenizer = GPT2Tokenizer.from_pretrained("gpt2")
in_text = "Lionel Messi is a"
in_tokens = torch.tensor(tokenizer.encode(in_text))

# inference
token_eos = torch.tensor([198]) # line break symbol
out_token = None
kvcache = None
out_text = in_text
i = 0
with torch.no_grad():
    while out_token != token_eos:
        logits, kvcache = model(in_tokens, past_key_values=kvcache) # 增加了一个 past_key_values 的参数
        out_token = torch.argmax(logits[-1, :], dim=0, keepdim=True)
        in_tokens = out_token # 输出 token 直接作为下一轮的输入,不再拼接
        text = tokenizer.decode(in_tokens)
        print(f'step {i} input: {text}', flush=True)
        i += 1
        out_text += text

print(f' Input: {in_text}')
print(f'Output: {out_text}')

通过上面代码只能看到调用层面的变化,实现细节还需看各框架的底层实现,例如Hugging Face的transformers库代码实现就比较清爽,在modeling_gpt2.py中Attention部分相关代码如下:

query = self._split_heads(query, self.num_heads, self.head_dim)
        key = self._split_heads(key, self.num_heads, self.head_dim)
        value = self._split_heads(value, self.num_heads, self.head_dim)

        if layer_past is not None: # 当输出第一个token后,layer_past就是非None了
            past_key, past_value = layer_past # 取出之前计算好的 key, value
            key = torch.cat((past_key, key), dim=-2) # past_key 与当前 token 对应的 key 拼接
            value = torch.cat((past_value, value), dim=-2) # past_value 与当前 token 对应的 value 拼接

        if use_cache is True:
            present = (key, value)
        else:
            present = None

在 block 层面也有相关代码,大家有空细品吧。还是那句话,说一千道一万不如阅读并运行源码一次。

其实,KV Cache 配置开启后,推理过程可以分为2个阶段:

  • 预填充阶段:发生在计算第一个输出token过程中,这时Cache是空的,计算时需要为每个 transformer layer 计算并保存key cache和value cache,在输出token时Cache完成填充;FLOPs同KV Cache关闭一致,存在大量gemm操作,推理速度慢。

  • 使用KV Cache阶段:发生在计算第二个输出token至最后一个token过程中,这时Cache是有值的,每轮推理只需读取Cache,同时将当前轮计算出的新的Key、Value追加写入至Cache;FLOPs降低,gemm变为gemv操作,推理速度相对第一阶段变快,这时属于Memory-bound类型计算。

这里用图可能更有助理解,下图是一个Decoder Block,含有Self-Attention和MLP,标红部分为KV Cache影响到的内容,即KV Cache开启后,标红的序列长度s变为 1,当batch_size=1时,Self-Attention中的2个dense全都变为gemv操作,MLP中的dense也全都变为gemv操作。看懂这个图就可以答对上面的3个问题啦。

21ac9bff69e7e7ffe48a5b487e6d2763.png


Decoder Block of GPT

如下链接也有这方面的定量分析,写的很棒,推荐大家看看。

回旋托马斯x:分析transformer模型的参数量、计算量、中间激活、KV cache

5. 总结

KV Cache是Transformer推理性能优化的一项重要工程化技术,各大推理框架都已实现并将其进行了封装(例如 transformers库 generate 函数已经将其封装,用户不需要手动传入past_key_values)并默认开启(config.json文件中use_cache=True)。本文尝试打开封装分析该技术内部实现,希望对大家有所帮助,文中如有纰漏,欢迎指正。

最后给我们团队的开源项目打个广告,Adlik 是中兴通讯贡献的深度学习推理工具,已获得 Linux AI 基金会支持,目前仍在持续完善中,期待大家的支持和关注。另外,我们也在做深度学习编译器和大模型方向的前沿技术研发工作,欢迎感兴趣的小伙伴加入我们 ~~

b99f4eb0374edb962b879dce09faad23.png

KV Cache 技术分析 LLM(大型语言模型)中的 Attention 机制中的 KV Cache(键值缓存)主要作用是存储键值对,以避免在每次生成 token 时重新计算键值向量,从而减少计算量和提高效率。利用预先计算好的 K 值和 V 值,可以节省大量计算时间,尽管这会占用一定的存储空间。随着模型规模的增大和数据量的增加,LLM 的窗口长度也在不断增大,因此就出现一组主要矛盾,即:对不断增长的 LLM 的窗口长度的需要与有限的 GPU 显存之间的矛盾。 阅读详情

相关推荐

LLM 的KV-cache是什么:大语言模型推理的“加速器“与“内存管家“

KV-cache是大语言模型推理中的关键优化技术,通过缓存注意力机制的Key和Value向量,避免重复计算,显著提升推理效率。它将计算复杂度从O(n²)降至O(n),支持长文本生成和多轮对话。KV-cache应用广泛,如ChatGPT、代码生成和内容创作,可提升响应速度3-10倍。优化技术包括分页存储、量化和滑动窗口,能降低显存占用50%以上,支持超长上下文。尽管存在内存占用和一致性等挑战,KV-cache已成为大模型推理的基础设施,使实时交互和硬件门槛降低成为可能,推动AI应用场景扩展。

ZhangJiqun&191cm&85kg 430

KV-Cache详解

本文探讨了 KV 缓存的概念、应用以及它在自注意力机制中优化的特定计算。

发几十块的吧 1万+

AutoCAD Plant 3D自定义零件库实战:手把手教你用Python创建参数化槽式三通

本文详细介绍了如何利用Python脚本在AutoCAD Plant 3D中创建参数化槽式三通组件,从API原理到实战开发,帮助用户构建高效的自定义零件库。通过Python装饰器系统控制零件属性和行为,实现几何建模、参数管理和规格编辑器集成,提升工业管道设计的标准化和效率。

weixin_28267011的博客 331

什么是 KV Cache(Key-Value Cache)

KV Cache(Key-Value Cache)是大模型(特别是Transformer架构)在推理过程中常用的一种优化技术,主要用于加速自回归生成任务(如文本生成)中的计算效率。它通过缓存中间计算结果(键和值的张量),避免重复计算,从而显著降低推理的计算量和延迟。

彬彬侠的博客 1万+

TDSQL-单机安装

根据腾讯云官方要求,TDSQL安装至少需要三台机器。本人想要学习TDSQL但是没有足够的机器资源,经过仔细分析研究TDSQL安装过程,尝试发现单台机器也可以成功安装TDSQL,现将本人单台机器安装TDSQL的过程以及安装过程中遇到的问题在此分享。具体安装过程可参考腾讯官方文档,本文仅分享与官方文档不一致的步骤。

u012607648的博客 6807

告别盲打:为NXOpen Python API生成智能代码提示的完整指南

本文提供了一份为NXOpen Python API生成智能代码提示的完整指南。通过配置匹配的Python环境、利用类型存根文件生成工具创建.pyi文件,并在PyCharm或VSCode中正确配置,开发者可以彻底告别“盲打”,获得精准的代码补全和参数提示,从而大幅提升NX二次开发的效率和体验。

weixin_29057695的博客 371

【硬核】啃透vLLM源码:从PagedAttention到连续批处理,大模型推理加速24倍的秘密

摘要:vLLM揭秘大模型推理加速24倍的底层技术 vLLM通过创新性的内存管理和调度机制,实现了高达24倍的大模型推理加速。其核心技术包括: PagedAttention:将KV Cache切分为固定大小的Block(默认16个token),通过逻辑-物理块映射消除内存浪费,支持多请求共享相同物理块。 连续批处理:动态调度请求,像地铁运行一样允许随时上下车,最大化GPU利用率。 CUDA Graph优化:将GPU操作打包成图形一次性提交,减少30%以上的kernel launch开销。 这些系统级优化使vL

学习代码 531

rsyslog交叉编译(armv7、armv8、aarch64、arm32平台通用)

该文档描述了如何交叉编译rsyslog到arm64嵌入式平台。

sinat_33909696的博客 1560

别再做AI“黑盒“开发者!用实验了解Qwen2.5预测机制,让你更好“理解“大模型,大模型入门到精通,收藏这篇就足够了!

别再做AI“黑盒“开发者!用实验了解Qwen2.5预测机制,让你更好“理解“大模型,大模型入门到精通,收藏这篇就足够了!

瓦罗兰特顶级C位的博客 861

华为od 面试八股文_Spring_03_含答案

控制反转IOC是一个很大的概念,可以用不同的方式来实现。其主要实现方式有两种:依赖注入和依赖查找依赖注入;

MISAYAONE的博客 2341

使用Microsoft Print to PDF进行编程:创建PDF文件的简单方法

Microsoft Print to PDF是一种内置于Windows操作系统中的功能,它允许我们通过打印操作将任何可打印的内容保存为PDF文件。然后,我们使用Microsoft Print to PDF打印机进行打印操作,并将输出文件保存为指定的PDF文件。使用Microsoft Print to PDF功能是一种方便且简单的方法来创建PDF文件,无论是在个人使用还是在企业开发中,它都可以提供良好的支持和灵活性。请注意,如果你使用的是其他编程语言,你可以根据相应的打印机接口或库来实现类似的功能。

TechSavant的博客 1635

KV Cache 到底是什么?一文讲透大模型推理加速原理

QKVToken:北京Q_beijingK_beijingV_beijingQ:我想找谁K:我是哪个信息V:我携带什么内容Q = 查询条件K = 索引V = 数据KV名称的来源。KV Cache 本质上是 Transformer Attention 的结果缓存机制,用空间换时间,避免历史 Token 的重复计算。重复计算问题已经算过的 K 和 V不要再算第二次决定模型能力KV Cache决定推理效率GPU 是推理系统的核心。

qq_36863796的博客 1418

全新YOLOv11一文弄懂 | YOLOv11网络结构解读 、yolov11.yaml配置文件详细解读与说明、模型训练参数详细解析 | 通俗易懂!入门必看系列!

本文全面介绍了YOLOv11目标检测算法,包含网络结构解析、yaml配置文件详解及训练教程。YOLOv11通过改进的C3k2f模块、SPPF和C2PSA注意力机制等创新设计,在COCO数据集上实现了比YOLOv8更优的性能。文章详细解读了yolov11.yaml配置文件的参数设置、主干网络(backbone)和头部网络(head)结构,并提供了完整的训练代码示例和参数说明。训练部分涵盖了模型选择、参数设置及优化技巧,包括epochs、batch size、学习率等关键参数的调整建议。最后总结了YOLOv11

Ai缝合怪、助力小伙伴高效发论文 3万+

大模型(LLM)推理加速之KV Cache技术

在学习Key-Value Cache(kv cache),读者需要熟悉Transformer架构,最好能够懂得。本文不会再对Transformer架构做赘述。

Cheny1m的博客 3936

第一讲:halcon模板匹配捆绑测量矩形检测芯片针脚

使用halcon模板匹配捆绑测量矩形,检测位置发生变换的芯片针脚缺陷。

uiopmn1的博客 2995

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

KV Cache分页管理技术解析 PagedAttention实现与性能优化实战

摘要:本文基于CANN社区ascend-transformer-boost仓库的PagedAttention实现,深入分析了KVCache分页管理技术。通过block_table内存布局设计,在LLaMA-70B模型上实现显存占用降低41%,吞吐量提升3.2倍的显著效果。文章详细解析了核心技术原理,包括块粒度设计、映射机制和内存复用策略,并提供了完整代码实现、企业级实践案例(如金融风控场景节省37.5%硬件成本)和性能优化技巧(如智能块大小选择算法)。测试数据显示,该方案在7B-180B不同规模模型上均表现

seven_1243096140的博客 931

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

一次大模型API请求背后:GPU推理与KV Cache优化实践

在大模型应用落地过程中,API调用的性能瓶颈往往不在模型精度,而在于从请求发起到结果返回的完整链路。理解GPU推理的基本原理,掌握显存分配与调度机制,是优化服务吞吐的关键。一次请求背后涉及文本向量化、prefill计算、逐token生成的decode阶段,以及贯穿始终的KV Cache管理。合理利用连续批处理、PagedAttention和KV Cache量化,能显著提升并发能力,避免OOM崩溃。本文结合部署与压测经验,拆解大模型API请求从排队调度到GPU计算、再到缓存释放的全过程,帮助开发者定位超时、显

weixin_33981932的博客 172

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

Unified Cache Manager(UCM)KV Cache 管理与复用系统深度指南

> 本文以开源仓库 [unified-cache-management](https://link.gitcode.com/i/fb69d14288cde25f7cc4a9c541c74080) 官方首页为核心骨架,系统讲解 UCM 的核心定位、三大复用能力、支持范围、快速开始步骤、架构与请求生命周期原理,以及运行评测方法。读完本文,你将掌握如何选择引擎与存储后端、配置并启动一个接入 UCM 的推

gitblog_01110的博客 609

Unified Cache Manager 中部署 MiniMax 系列模型:UCM × vLLM-Ascend / vLLM 的 KV Cache 分级缓存实战

本文基于 UCM(unified-cache-management)仓库中 MiniMax 模型族部署文档,完整讲解如何在 Atlas 800 A2(vLLM-Ascend,w8a8-QuaRot 量化)与 NVIDIA H100(vLLM)两套硬件上,用预构建 Docker 镜像部署 MiniMax-M2.7 并接入 UCM 外部 KV Cache 缓存。读完本文,你可以掌握从容器启动、UCM

gitblog_00028的博客 734

大模型推理性能优化:从KV Cache到显存泄漏的实战排查

大语言模型推理性能是影响AI应用落地的核心技术指标,其本质涉及计算调度、内存管理与硬件协同等底层原理。理解KV Cache机制、量化精度衰减、NCCL通信瓶颈等关键技术点,不仅能显著提升吞吐与首token延迟,还能规避生产环境中常见的CUDA OOM、梯度检查点残留等显存泄漏问题。在金融合同检索、长上下文生成、本地大模型部署等典型场景中,这些优化直接决定服务稳定性与成本效率。本文基于Qwen2.5、Llama-3.1等真实模型在16GB显存环境下的实测数据,结合MMLU、LiveCodeBench benc

weixin_29040367的博客 174

深入解读DeepSeek MLA技术:优化KV-Cache的注意力机制创新

上,无需配置复杂环境就能快速验证这类前沿技术方案。平台内置的AI辅助功能可以帮助理解论文中的公式推导,实时预览让技术对比更加直观。特别是对于需要演示界面和持续服务的模型优化项目,一键部署功能让研究成果的分享变得异常简单。最终缓存量仅为MQA的2.25倍,但效果接近完整MHA。量化压缩和窗口限制等方法各有其适用场景和局限性。访存带宽分级特性使得跨卡通信成为性能瓶颈。通过两部分拼接方式保留完整的特征表达能力。

BlackironFalcon78的博客 315

大模型推理加速的十大核心技术

大模型推理加速十大核心技术摘要 随着AI应用从训练转向推理,降低推理成本成为行业焦点。本文系统介绍了当前大模型推理优化的十大关键技术: KV Cache:缓存历史计算结果,避免重复计算,降低复杂度 Continuous Batching:动态批处理提升GPU利用率 PagedAttention:分页管理显存减少碎片 FlashAttention:优化内存访问加速Attention计算 量化技术:INT4/8压缩模型参数 Speculative Decoding:小模型预测+大模型验证加速生成 PD分离:解耦

qq_36863796的博客 3768

RaReCache解读:小模型预填充KV cache,解锁大模型快速推理

大模型服务中,首token延迟通常源于长提示词下的prefill阶段。传统KV cache虽缓存中间结果,但每遇新请求仍需重复预计算。RaReCache提出一种轻量化思路:让一个小模型先完成prefill,生成KV cache,再经映射网络转换给大模型复用,大模型仅需专注decode逐字生成。如此可将TTFT显著降低,缓解显存和算力压力。该方案适合长上下文问答、RAG检索增强生成等场景,也可与prefix cache、投机解码等策略组合,为大模型推理性能优化提供一套新的工程路径。

weixin_28678151的博客 116

ODCC 权威认证!XSKY MeshFusion 斩获 KV Cache 评测官方证书

XSKY 星辰天合 MeshFusion 获 ODCC 权威认证!六大技术突破,一站式解决 KV Cache 存储瓶颈。

XSKY星辰天合的博客 200
上一篇: ESL设计概述
下一篇: LSQ 的低比特量化之路
Linux基金会AI&Data基金会
博客等级 码龄6年 101粉丝 47原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Linux基金会AI&Data基金会

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值