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

昇腾CANN ATB KV Cache 与 PagedAttention:显存碎片消除的完整方案

LLM 推理的最大瓶颈不是计算——是显存。长上下文下KV Cache 的显存占用是二次增长的seq_len128K → KV Cache 128K × 每层 KV 大小 128K × (2 × hidden × head_num) 128K × 2 × 8192 × 32 32GB。加上模型参数70B × 2bytes 140GB→ 总共 172GB → Ascend 910 只有 128GB → OOM。ATB 用 PagedAttention 虚拟内存管理解决这个问题把 KV Cache 分页存储Page Table不连续分配按需申请页面。像操作系统管理虚拟内存一样管理 KV Cache。KV Cache 的显存碎片问题标准 KV Cache 是连续分配的三维张量 [batch, seq_len, hidden, head_num×2]连续分配 KV Cache 的问题 请求 1seq_len128K → 需要 32GB 连续块 请求 2seq_len512 → 需要 16MB 连续块 请求 3seq_len64K → 需要 16GB 连续块 ... 32GB 16MB 16GB ... 180GB 128GB 即使空闲总量够很多小请求释放后但无法分配 32GB 连续块 → OOM对比 PagedAttentionPagedAttention 方式 KV Cache 被分成 16KB 的 pages每 16KB1 page 请求 1 的 32GB → 分配 32GB/16KB 2,097,152 pages 请求 2 的 16MB → 分配 16MB/16KB 1024 pages 请求 3 的 16GB → 分配 16GB/16KB 1,048,576 pages ... page 不需要连续碎片不再是问题——任何空闲 page 都能分配ATB 的 PagedAttention 实现// ascend-transformer-boost/memory/paged_attention.cppclassPagedAttentionMemory{private:// 全局 page 池所有请求共享staticconstexprintPAGE_SIZE16*1024;// 16KBstructPage{intid;// page 编号全局唯一DevicePtr ptr;// page 在 HBM 上的地址boolallocated;// 是否已分配intref_count;// 引用计数多请求共享};std::vectorPageglobal_page_pool_;// 全局 page 池inttotal_pages_;// 总 page 数 HBM 大小 / PAGE_SIZE// 每个请求的 page 表structPageTable{std::vectorintpage_ids;// 虚拟地址 → 物理 page 映射intnum_pages;// 已分配 page 数intseq_len;// 当前序列长度};std::unordered_mapint,PageTablerequest_page_tables_;// request_id → page 表public:// 分配 pages StatusAllocatePages(intrequest_id,intnum_pages_needed){PageTableptrequest_page_tables_[request_id];for(inti0;inum_pages_needed;i){intpage_idFindFreePage();if(page_id-1){returnStatus::OUT_OF_MEMORY;// 没有空闲 page}// 分配 pageglobal_page_pool_[page_id].allocatedtrue;global_page_pool_[page_id].ref_count1;pt.page_ids.push_back(page_id);pt.num_pages;}pt.seq_lennum_pages_needed*(PAGE_SIZE/sizeof(float16)/(hidden*2));returnStatus::OK;}// 逻辑地址 → 物理地址转换 DevicePtrLogicalToPhysical(intrequest_id,intlogical_offset){PageTableptrequest_page_tables_[request_id];// 计算逻辑偏移在哪一页和页内偏移intpage_indexlogical_offset/PAGE_SIZE;intoffset_in_pagelogical_offset%PAGE_SIZE;// 从 page 表查询物理地址intphysical_page_idpt.page_ids[page_index];DevicePtr physical_pageglobal_page_pool_[physical_page_id].ptr;returnphysical_pageoffset_in_page;}// 释放 pages请求完成或溢出voidFreePages(intrequest_id){PageTableptrequest_page_tables_[request_id];for(intpage_id:pt.page_ids){global_page_pool_[page_id].ref_count--;if(global_page_pool_[page_id].ref_count0){global_page_pool_[page_id].allocatedfalse;// 真正释放}}pt.page_ids.clear();pt.num_pages0;}};PagedAttention 的 Attention 计算修改标准注意力计算完整 KV Cache// 标准 Attentionfor(intk0;kseq_len;k){floatscoredot(Q[token],K[k]);// Q 与 K 的一维点积softmax_scores[k]exp(score);}PagedAttention 计算按页计算// ascend-transformer-boost/kernels/paged_attention_kernel.cpp__aicore__voidPagedAttentionKernel(GlobalTensorfloat16Q,// [batch, num_heads, d_head]GlobalTensorfloat16K_pages,// [total_pages, page_size]GlobalTensorfloat16V_pages,// [total_pages, page_size]GlobalTensorfloat16output,// [batch, num_heads, d_head]GlobalTensorintpage_table,// [request_id, max_pages]intnum_pages,inthead_dim){intrequest_idblockIdx.x;// 每个 block 处理一个请求inthead_idthreadIdx.y;// 每个 thread 处理一个注意力头// 初始化累加器LocalTensorfloat16O_local(head_dim);for(intd0;dhead_dim;d)O_local[d]0.0f;floatmax_val-65504.0f;floatsum_exp0.0f;// 逐页计算 Attentionfor(intp0;pnum_pages;p){intphysical_page_idpage_table[request_id*MAX_PAGESp];// 加载一页的 K 和 V连续访问——物理地址LocalTensorfloat16K_page(page_size);LocalTensorfloat16V_page(page_size);DataCopy(K_page,K_pagesphysical_page_id*page_size,page_size);DataCopy(V_page,V_pagesphysical_page_id*page_size,page_size);// 计算 QK^T 在这一页的分数for(inti0;ipage_tokens;i){// K_page[i] 是 K[token_i]计算 Q·K[token_i]floatscore0.0f;for(intd0;dhead_dim;d){scorefloat(Q[head_id*head_dimd])*float(K_page[i*head_dimd]);}// Online softmax逐页更新floatexp_scoreexpf(score-max_val);// 如果这一页有更大的 score → 重新标定累加器if(scoremax_val){floatold_maxmax_val;max_valscore;// 重新标定之前累加的 O_local 和 sum_expfloatcorrectionexpf(old_max-max_val);for(intd0;dhead_dim;d){O_local[d]O_local[d]*correction;}sum_expsum_exp*correction;}// 累加 V * softmax_scorefor(intd0;dhead_dim;d){O_local[d]V_page[i*head_dimd]*exp_score;}sum_expexp_score;}}// 归一化for(intd0;dhead_dim;d){output[request_id*head_dimd]float16(O_local[d]/sum_exp);}}PagedAttention 的关键page 表中的物理地址是离散的但每个 page 内部的访问是连续的。分页解决了碎片不会降低注意力计算的性能因为每个 page 内部依然是连续访问。page 分配的贪心策略// ascend-transformer-boost/memory/page_allocator.cppclassPageAllocator{private:intFindFreePage(){// 贪心找第一个空闲 pagefor(inti0;itotal_pages_;i){if(!global_page_pool_[i].allocated){returni;}}return-1;// 无空闲}// 预取策略预测下一个 page 位置intPrefetchNextPage(intcurrent_page_id){// 如果当前 page 后一个也是该请求的 → 预取减少延迟intnext_pagecurrent_page_id1;if(next_pagetotal_pages_!global_page_pool_[next_page].allocated){PrefetchToCache(next_page);// 预取到 SRAM}}public:// 批量预取所有已分配 pagevoidPrefetchAllPages(intrequest_id){PageTableptrequest_page_tables_[request_id];for(intpage_id:pt.page_ids){PrefetchToCache(page_id);}}};踩坑一page 表查找的延迟PagedAttention 需要频繁查 page 表每次访问 K/V 都要逻辑→物理转换。page 表本身在 HBM 中——每次查表都是 HBM 访问。修复把 page 表拷贝到 L1 缓存// 加速 page 表查找__aicore__voidFastPageLookup(GlobalTensorintpage_table_in_hbm,// page 表在 HBM 中LocalTensorintpage_table_in_l1,// 拷贝到 L1intnum_pages){// 拷贝 page 表到 L1一次性把所有 page 的映射都搬上来DataCopy(page_table_in_l1,page_table_in_hbm,num_pages*sizeof(int));// 之后所有查表都在 L1 中——延迟 1 cycle不是 HBM 的百 cycle}L1 中的 page 表查表延迟1 cycle。HBM 中查表延迟~300 cycles。PagedAttention 每页查一次表——page2MB → 查表延迟节省 2MB × (300-1) ~600M cycles。踩坑二page 引用计数泄漏多个请求可能共享相同的 K/V pages如共享前缀。引用计数减到 0 才真正释放。但如果忘记减引用计数——page 永远不释放 → 内存泄漏。// 引用计数的正确管理classRefCountManager{public:// 分配ref_count 1新请求独占voidAllocPage(intpage_id){global_page_pool_[page_id].ref_count1;}// 共享ref_count其他请求加入voidSharePage(intpage_id,intrequest_id){global_page_pool_[page_id].ref_count;// 记录哪几个请求在共享这个 pageshared_requests_[page_id].push_back(request_id);}// 释放ref_count--只有变成 0 才释放voidReleasePage(intpage_id,intrequest_id){global_page_pool_[page_id].ref_count--;if(global_page_pool_[page_id].ref_count0){// 真正释放标记为可用global_page_pool_[page_id].allocatedfalse;shared_requests_[page_id].clear();}}// 校验多请求释放时的安全检查voidValidateRefCount(intpage_id,intrequest_id){autosharedshared_requests_[page_id];if(std::find(shared.begin(),shared.end(),request_id)shared.end()){// 这个请求没有共享这个 page → 不应该减引用计数throwRefCountError(request not in shared list);}}};踩坑三page 表更新时的时序竞争推理过程中Decoder 生成新 token 时KV Cache 需要扩展添加新的 K, V。如果此时上一个请求的 page 正在被 Attention 计算读 → 数据竞争。方案Copy-on-WriteCoW// Copy-on-Write page 更新StatusExtendKVPage(intrequest_id,intnew_page_id){PageTableptrequest_page_tables_[request_id];intold_page_idpt.page_ids.back();// 如果只有这个请求在用这个 page → 直接更新if(global_page_pool_[old_page_id].ref_count1){// 无竞争直接覆盖旧 pageglobal_page_pool_[old_page_id].allocatedtrue;returnStatus::OK;}// 多个请求在共享这个 page → Copy-on-Write// 分配新 page拷贝旧内容写入新数据intnew_pageFindFreePage();if(new_page-1)returnStatus::OUT_OF_MEMORY;// CoW拷贝旧 page 到新 pagememcpy(global_page_pool_[new_page].ptr,global_page_pool_[old_page_id].ptr,PAGE_SIZE);// 在新 page 上追加 K,V 数据WriteKV(global_page_pool_[new_page].ptr,new_K,new_V);// 更新 page 表pt.page_ids.back()new_page;// 释放旧 page 的引用ReleasePage(old_page_id,request_id);returnStatus::OK;}KV Cache 是 LLM 推理中最大的显存消耗者——128K 上下文下占 32GB。ATB 的 PagedAttention 把连续分配变成分页分配page 池全局共享、page 表做逻辑→物理映射、Copy-on-Write 解决共享页的更新冲突。像操作系统管理虚拟内存一样管理 KV Cache——碎片不再导致 OOM。

相关文章:

昇腾CANN ATB KV Cache 与 PagedAttention:显存碎片消除的完整方案

LLM 推理的最大瓶颈不是计算——是显存。长上下文下,KV Cache 的显存占用是二次增长的:seq_len128K → KV Cache 128K 每层 KV 大小 128K (2 hidden head_num) 128K 2 8192 32 32GB。加上模型参数(70B 2bytes 140GB)…...

Ubuntu 20.04上virt-manager报GDBus错误?别慌,三步排查法搞定‘Message recipient disconnected‘

Ubuntu 20.04 virt-manager报GDBus错误的深度排查指南当你在Ubuntu 20.04上使用virt-manager管理KVM虚拟机时,突然遇到"GDBus.Error:org.freedesktop.DBus.Error.NoReply: Message recipient disconnected"这样的错误提示,确实会让人感到困惑。…...

GParted实战:从虚拟机沙盒到实体机,安全演练Linux分区合并与扩容全流程

GParted实战:从虚拟机沙盒到实体机,安全演练Linux分区合并与扩容全流程在虚拟机的安全环境中练习Linux分区操作,就像飞行员在模拟器中训练紧急情况处理一样重要。GParted作为Linux系统管理员的"瑞士军刀",其强大功能背后…...

黑群晖硬盘满了别慌!手把手教你用SSH命令行扩容,Linux系统也通用

黑群晖存储扩容实战:SSH命令行全流程指南与Linux通用技巧当你发现黑群晖的存储空间亮起红灯时,那种焦虑感我深有体会。去年我的媒体服务器突然报出"存储空间不足"警告,当时存放的4TB家庭影像资料和重要工作备份几乎占满了整个磁盘。…...

CentOS 7上解决soffice转换doc到docx报错‘no export filter‘的完整指南(附字体安装)

CentOS 7服务器深度修复:soffice文档转换no export filter全链路解决方案当你在CentOS 7服务器上执行soffice --convert-to docx命令时,终端突然抛出Error: no export filter的红色警告——这不是简单的命令错误,而是典型的环境依赖链断裂。作…...

ERR_CONNECTION_REFUSED 根本原因与四步定位法

1. 这个报错不是网络问题,而是本地服务没跑起来的“心跳停止”信号你刚在终端敲下npm run dev,浏览器自动打开http://localhost:3000,页面一片空白,F12 打开 Console,赫然一行红字:Failed to load resource…...

Tomcat隐藏Server响应头的三种实战方案

1. 为什么连Tomcat默认的版本号都得藏起来?你有没有在浏览器开发者工具的Network面板里,随手点开一个Java Web应用的响应头,就看到这么一行:Server: Apache-Coyote/1.1或者更直白的Server: Apache Tomcat/9.0.83?我第一…...

CVE、CNVD、CNNVD、NVD四大漏洞编号体系深度解析

1. 这些字母组合不是密码,而是漏洞世界的“身份证号” 刚入行做安全运维那会儿,我在日报里看到一条告警:“检测到 CVE-2021-44228 漏洞利用尝试”,顺手抄下来准备查资料,结果一搜发现——同一款 Log4j 组件&#xff0c…...

用Python复现论文里的CDSM融合:从NuScenes数据预处理到3D检测模型训练全流程

用Python复现论文里的CDSM融合:从NuScenes数据预处理到3D检测模型训练全流程自动驾驶感知系统的核心挑战在于如何有效融合多模态传感器数据。本文将手把手带你实现论文《CDSM: Cross-Domain Spatial Matching for Camera-Radar Fusion in 3D Object Detection》的核…...

不止于潮汐:程序员视角下的海洋波动现象与信号处理实战

从信号处理视角解码海洋波动:工程师的实战指南海洋波动现象长期以来被视为海洋学家的专属领域,但当我们戴上信号处理的"眼镜"重新审视这些自然现象时,一个全新的世界就此展开。作为数据科学家和工程师,我们习惯于处理各…...

Web渗透测试全流程实战指南:从侦察到报告的结构化方法

1. 这不是“黑客速成班”,而是一张能真正带你进渗透测试实战现场的路线图很多人点开“Web渗透测试学习流程图”时,心里想的是:学完这个,我是不是就能黑进某个网站?能不能接单赚钱?甚至幻想自己坐在咖啡馆里…...

3步快速上手SSDD:合成孔径雷达舰船检测终极指南

3步快速上手SSDD:合成孔径雷达舰船检测终极指南 【免费下载链接】Official-SSDD SAR Ship Detection Dataset (SSDD): Official Release and Comprehensive Data Analysis 项目地址: https://gitcode.com/gh_mirrors/of/Official-SSDD SSDD(SAR S…...

ArcGIS Pro 3.7 重磅升级!这四大模块更新,让GIS效率翻倍

ArcGIS Pro 3.7 正式发布,这次不仅性能大幅提升,还带来了 GeoAI 工具集、实时等高线、本地知识图谱等一系列“黑科技”。无论你是制图师、空间分析师还是开发者。 01 性能与生产力:更快、更顺、更好找 新增「分析地图」窗格 可量化评估地图的…...

KV Cache的生老病死:FlashAttention里的显存管理全流程

某团队在昇腾NPU上跑Llama-2-7B-chat,前几个query响应正常,但当对话超过20轮之后,模型开始变得迟钝——生成速度从每秒15个token骤降到每秒2个token。运维查了半天,发现显存占用一直在涨,但batch_size明明没变。 问题出…...

d2dx终极教程:三步让暗黑破坏神2在现代PC上焕然一新

d2dx终极教程:三步让暗黑破坏神2在现代PC上焕然一新 【免费下载链接】d2dx D2DX is a complete solution to make Diablo II run well on modern PCs, with high fps and better resolutions. 项目地址: https://gitcode.com/gh_mirrors/d2/d2dx 还在为暗黑破…...

3步解锁Windows远程桌面多人连接:RDP Wrapper Library完整指南

3步解锁Windows远程桌面多人连接:RDP Wrapper Library完整指南 【免费下载链接】rdpwrap RDP Wrapper Library 项目地址: https://gitcode.com/gh_mirrors/rd/rdpwrap 你是否曾因Windows家庭版无法支持多人远程桌面连接而感到困扰?当团队成员需要…...

【Java后端开发】花了2k+多的人民币,烧了几十亿Token,慢慢整理出来适用于Java开发人员的codex配置,还在持续优化中

📕我是廖志伟,一名Java开发工程师、《Java项目实战——深入理解大型互联网企业通用技术》(基础篇)、(进阶篇)、《解密程序员的思维密码——沟通、演讲、思考的实践》作者、清华大学出版社签约作家、Java领域…...

告别双系统!用WSL2+Ubuntu20.04+ROS Noetic,在Windows上丝滑运行AirSim仿真(保姆级避坑指南)

在Windows上构建WSL2ROSAirSim一体化仿真环境:从零避坑到实战 对于机器人开发者而言,跨平台仿真环境的搭建往往意味着无尽的配置噩梦。当我在研究生课题中首次尝试将AirSim与ROS联调时,经历了整整两周的黑暗时期——双系统切换导致工作流断裂…...

别再只用MaxPool了!试试在YOLOv9里集成Haar小波下采样(HWD),实测涨点还省显存

突破传统下采样瓶颈:YOLOv9集成Haar小波下采样的实战指南当你在训练YOLOv9模型时,是否遇到过这样的困境——为了提升检测精度而增加模型复杂度,却发现显存迅速耗尽;或是采用激进的下采样策略后,小目标检测性能明显下降…...

openEuler 22.03 LST上安装RealVNC 6.11,我踩过的那些依赖坑(附离线包下载方法)

在openEuler 22.03 LST离线环境中部署RealVNC 6.11的完整指南当我们需要在隔离网络的生产环境中部署远程桌面服务时,依赖管理往往成为最棘手的挑战。本文将分享我在openEuler 22.03 LST系统上安装RealVNC 6.11时积累的实战经验,特别是如何处理复杂的离线…...

2026年合肥惊现AI奇迹,广禾元引领本土企业行业之巅

2026年合肥AI行业现状与用户痛点2026年,随着科技的飞速发展,合肥的AI行业呈现出蓬勃发展的态势。然而,用户在选择AI服务时,往往面临着诸多痛点。例如,市场上AI企业众多,服务质量参差不齐,用户难…...

别再死记硬背公式了!用Python代码和可视化动画,5分钟搞懂RoPE旋转位置编码

用Python动画拆解RoPE:当词向量在Attention中跳起旋转之舞想象一下,如果每个词向量都能在神经网络里跳一支优雅的芭蕾,用旋转的角度告诉模型自己的位置——这正是RoPE旋转位置编码的魔法。传统的位置编码像是给词向量贴上编号标签&#xff0c…...

慢速上传导致浏览器重试

触发场景:Chrome 开启网络限速后,Go 上传接口 20 秒超时,但浏览器端一个 upload 请求 pending 约 40 秒。 该博客由 AI 根据调试过程整理。触发场景 项目中有一个音频上传接口: mux.Handle("POST /v1/audio/upload", ch…...

神经网络辅助可变形匹配滤波器在光通信中的应用

1. 神经网络辅助可变形匹配滤波器技术解析在光通信系统中,匹配滤波器作为信号检测的关键组件,其性能直接影响整个通信链路的可靠性。传统固定匹配滤波器基于理想信道假设设计,当面对实际系统中的带宽限制、大气湍流等复杂信道条件时&#xff…...

多模态融合与多任务学习在智慧农业视觉系统的实战应用

1. 项目概述与核心价值 在可控环境农业(Controlled-Environment Agriculture, CEA)里,比如我们熟悉的垂直农场、智能温室,作物生长环境是高度可控的,但随之而来的管理复杂度也呈指数级上升。传统上,一个种植…...

【2024播客降本增效终极方案】:单人团队如何用开源TTS实现月产60期高保真节目(附实测MOS分对比表)

更多请点击: https://codechina.net 第一章:AI语音合成在播客制作中的应用 AI语音合成技术正深刻重塑播客内容的生产流程,从脚本转语音、多角色配音到个性化音色定制,已实现端到端自动化与高质量听感的统一。相比传统录音方式&am…...

去偏机器学习在交通行为因果推断中的应用:从关联分析到因果效应评估

1. 项目概述:当交通研究遇上因果推断在交通工程与城市规划领域,我们常常面临一个核心挑战:如何从海量的观测数据中,剥离出某个特定因素(比如一项新政策、一种交通管控措施)对人们行为的“真实”影响&#x…...

SRC 漏洞挖掘实战|反射型 XSS 漏洞详解、复现全流程与 SRC 报告模板

反射型 XSS 是 Web 安全领域入门级高频漏洞,也是 SRC 漏洞提交中最易上手的类型之一。它无数据持久化存储、触发方式简单、测试门槛极低,是零基础网安爱好者入门漏洞挖掘的首选突破口。本文从核心原理、危害、挖掘思路、实战复现到标准报告模板全流程拆解…...

Debian Bullseye定制Live ISO避坑指南:从debootstrap到xorriso的完整流程解析

Debian Bullseye定制Live ISO避坑指南:从debootstrap到xorriso的完整流程解析当我们需要快速部署一套标准化的Debian环境时,定制Live ISO无疑是最优雅的解决方案之一。不同于传统的系统安装方式,Live ISO允许我们将预先配置好的系统环境打包成…...

Hermes Agent 总记不住你说的话?3 步治好 AI 助手的“健忘症“

你有没有这样的经历:你跟它说"每次写营销文章,记得先加载技能审核",它答应得好好的。结果下一篇写出来,你又得说一遍同样的话。它就像一个只点头不记事的实习生——每轮对话都重头来过。又或者,昨天刚刚聊完…...