面向 GLM-5.2 的共享 Indexer KV Cache Offload:CANN 平台上从 KV 容量释放到系统吞吐提升的完整方案
2026/9/19 8:53:26 网站建设 项目流程

面向 GLM-5.2 的共享 Indexer KV Cache Offload:CANN 平台上从 KV 容量释放到系统吞吐提升的完整方案

【免费下载链接】cann-recipes-infer本项目针对LLM与多模态模型推理业务中的典型模型、加速算法,提供基于CANN平台的优化样例项目地址: https://gitcode.com/cann/cann-recipes-infer

说明:本文基于 docs/models/glm_5_2/glm_5_2_offload_guide.md 编写,并以仓库内 GLM-5.2 样例源码(模型实现、缓存管理、算子加载、配置与评测)为佐证进行深度扩充。

本文围绕 CANN / cann-recipes-infer 仓库中 GLM-5.2 样例的共享 Indexer KV Cache Offload 方案展开:先梳理其从面向 DeepSeek V3.2 的基础按需加载 Offload 出发的设计演进,再深入讲解"更大的 Device 侧缓存池、跨层共享规划、组相联 FIFO 替换、SFA 优先回填后置"四个关键技术决策,最后给出三个定制 AscendC 算子的职责划分、仓库内完整的启用与算子编译流程,以及双机 Atlas A3 上的端到端评测数据。读完本文,你可以掌握长上下文场景下 KV Offload 从"容量收益"走向"吞吐收益"的完整设计思路与可复现的仓库实操路径。


一、问题背景:长上下文让 KV Cache 先于算力触及 HBM 上限

大语言模型的上下文窗口正在持续增长。长文档问答、代码库分析、长时间多轮对话等场景,正将推理服务推向数十 K 乃至上百 K token 的上下文规模。这一趋势给推理系统带来一个结构性的挑战:KV Cache 的显存占用。

在自回归 decode 过程中,每个生成的 token 都会在 HBM 中产生 Key-Value 状态,序列越长、并发请求越多,累积的 KV Cache 就越庞大,且增长是线性的。HBM 容量是固定的。当 KV Cache 占据显存的大半,即便计算单元负载尚低,系统也无法接纳更多并发请求——内存先于计算触及上限。

KV Cache Offload 的思路很直接:将完整的 KV Cache 放到容量更大、成本更低的 Host 内存中,仅在注意力计算真正需要时,将相关数据搬运回 HBM。这打破了 HBM 的容量限制,理论上可以将 batch size 翻倍甚至更高。但在实际部署中,一个问题随之而来:Host 到 Device 的数据搬运(H2D)直接叠加在 decode 延迟上。如果新增的 batch 容量被传输开销抵消,Offload 便只解决了内存容量,却未能转化为吞吐提升。

本文介绍的方案沿一条递进路径展开,其出发点是此前面向 DeepSeek V3.2 实现的基础 KV Offload 方案(相关实现已开源,见 deepseek_v3.2_exp_inference_guide.md),最终落地为面向 GLM-5.2 的共享 Indexer KV Cache Offload,实现代码位于 models/glm_5_2。


二、此前方案:面向 DeepSeek V3.2 的按需加载式 KV Offload

2.1 稀疏注意力的数据加载模型

此前面向 DeepSeek V3.2 实现的 KV Offload 方案是本工作的出发点。其 decode 路径有两个紧密配合的组件:

  • Lightning Indexer:从全部历史 token 中筛选出与当前 query 最相关的 2048 个位置(即 Top-K 稀疏索引);
  • Sparse Flash Attention(SFA):仅在这 2048 个位置上执行注意力计算。

Indexer 决定哪些 token 参与注意力,SFA 执行实际计算。两者之间有一个数据搬运环节:SFA 所需的 2048 条 KV 数据散布在完整序列的 KV Cache 中,需要被收集到一起。

当前 query | v Lightning Indexer ----> Top-K token 位置 | v Host 侧完整 KV Cache -------> 选中的 KV -------> SFA

该基础方案将完整 KV Cache 放置在 Host 内存中。Prefill 阶段,模型在 Device 侧逐层生成 KV 后,将其传输至 Host;decode 阶段,GatherSelectionKvCache算子根据 Indexer 的 Top-K 结果,从 Host 侧完整 KV Cache 中加载对应的 KV 数据,并交由 SFA 使用。这一流程释放了完整序列 KV Cache 此前占据的大部分 HBM,腾出的空间可支撑更大的 batch 或更长的上下文。

在仓库中,GatherSelectionKvCache算子位于 ops/ascendc/src/gather_selection_kv_cache,包含op_host(算子原型、tiling)与op_kernel(内核实现,含split_bs_reuse复用变体)两部分,并有独立的 torch 绑定 与 文档说明。在 GLM-5.2 样例中,custom_op_loader.py 的load_offload_gather_op()会在 import 时把该算子挂载为torch_npu.npu_gather_selection_kv_cache

2.2 相邻 step 复用

Gather 算子还利用了一个重要的局部性:相邻 decode step 的 Top-K 往往高度重叠。上一个 step 已搬到 Device 侧的 KV 可直接复用,无需再次从 Host 读取。

全模型 Top-K 轨迹分析显示,相邻 step 的平均复用率约为 60%。这意味着每次 decode,约六成 KV 可从 Device 侧直接获得,Host 只需提供剩余约四成。

当前 Top-K = 上一步选集中命中的部分 + 从 Host 侧完整 KV Cache 加载的缺失部分

这一复用将 H2D 数据传输量降至全部从 Host 加载的约 40%,但复用范围仅限于上一步的 2048 个位置。仍有近五分之二的选中 token 需要进行离散的 H2D 搬运——每次未命中对应一个独立位置的小段 KV 数据。

2.3 容量收益与吞吐缺口

该基础方案带来了明确的容量收益:相同上下文长度下,可承载的 batch size 约可翻倍。但 batch 扩大后,每步需要同时处理的请求和数据规模随之增加;叠加剩余的 Gather 搬运开销,decode 延迟显著上升。在端到端评估中,扩展的 batch 容量尚未充分转化为吞吐提升。

这明确了下一步的优化目标:提升缓存命中率,将 H2D 数据搬运移出关键路径


三、更大的 KV 缓存池:瓶颈从数据搬运转向缓存管理

基础方案的选择缓冲区只有 2048 个条目,因为它的容量等于 SFA 的 Top-K 输入量。如果进一步扩大复用范围,让 Device 侧保留一个更大的 KV 缓存池——例如 8192 或 16384 个条目,下一轮的 Top-K 就能以更高概率命中 Device 侧已有的数据。

我们构建了一个包含 8192 个条目、采用 LRU 策略管理的 Device 侧 KV 缓存池。在相同 Top-K 轨迹下,平均命中率从 58.85% 提升至 90.50%。平均而言,仅有 9.50% 的选中 token 需要从 Host 加载。在这一命中率水平上,H2D 数据搬运已不再是主要开销。

但大容量缓存池改变了开销的构成。每层仍需独立处理自己的 Top-K id:逐条判定数据位于缓存池还是 Host、对重复未命中去重、选定替换槽位、维护缓存元数据。LRU 的细粒度管理还需要维护访问时序和淘汰决策。这些操作多属于 Vector Core 不擅长的标量和控制密集型计算。KV 数据路径虽已通畅,逐层重复的缓存管理操作却形成了新的 decode 瓶颈。

Device 侧缓存设计平均命中率主导压力
仅保留上一步的 2K Top-K 选集58.85%离散 H2D KV 加载
8K KV 缓存池 + LRU90.50%命中分类与缓存管理

这一瓶颈迁移指明了后续工作的方向:增大 Device 侧缓存池缓解了数据搬运问题,但将缓存池管理做成高效算子,还需要在控制面上寻找进一步的优化机会。GLM-5.2 的架构恰好提供了这样的切入点。


四、GLM-5.2 共享 Indexer:从逐层规划到逐组复用

4.1 IndexShare:四层一组的 Top-K 复用结构

GLM-5.2 在 attention 设计中引入了一项关键特性:共享 Indexer(IndexShare)。默认配置下,一层独立执行 Indexer 生成新的 Top-K,紧接着的三层直接复用这组结果,构成四层一组的 Indexer 共享组。

在仓库源码中,这一结构由 configuration_glm.py 显式建模:每层通过indexer_types标记为full(本层运行 Lightning Indexer、持有 indexer 权重)或shared(复用上一个 full 层的 top-k、不持有 indexer 权重)。若未显式指定,则按如下规则推导:

# models/glm_5_2/models/configuration_glm.py # full iff (max(i - index_skip_topk_offset + 1, 0) % index_topk_freq) == 0 self.indexer_types = [ "full" if (max(i - offset + 1, 0) % freq) == 0 else "shared" for i in range(num_hidden_layers) ]

即默认表现为"每 N 层一组、组首层为 full、其余层为 shared"的周期结构。模型侧实现(modeling_glm.py)中,shared层通过skip_topk = indexer_types[layer_idx] == "shared"跳过本层 Indexer 计算,直接复用上一层输出的prev_topk_indices

四层共享同一组 Top-K id,因此也共享了基于这些 id 的缓存决策。某个 token id 在组内任一层命中 Device 侧缓存池,在其余三层也会映射到相同的缓存槽位;某个 token id 未命中,整组也需要执行相同的回填规划。

命中分类和未命中规划是标量最密集、Vector Core 最不擅长的操作。共享 Indexer 结构将它们从逐层执行压缩为逐组执行——规划做一次,四层复用。标量开销被分摊到四层,而各层独立的 KV 数据搬运不受影响。

4.2 共享规划

规划器(DsaPlan)对共享 Top-K 执行一次性处理:逐条记录数据来自缓存池还是 Host,同时输出一份紧凑的未命中条目列表,用于后续回填。

组内后续层直接沿用同一份规划。各层拥有各自的 KV 和 RoPE 数据,搬运过程独立进行,但命中检测、来源分类、未命中去重和替换位置选择均不再重复计算。

在仓库实现中,这一"一次规划、整组复用"的语义由 offload_cache.py 的共享组元数据管理支撑:build_dsa_shared_group_specs()indexer_types把各层归入共享组并标记owner_layer(组首 full 层);规划结果通过set_dsa_shared_group_plan()/get_dsa_shared_group_plan()暂存,组内共享层直接取用,待组末层处理完毕后再clear_dsa_shared_group_plan()清除。

4.3 组相联 FIFO

大容量缓存池需要配套的替换策略。LRU 能够较好地匹配访问模式,但在 NPU 上高效实现 LRU,需要持续维护条目的最近访问状态和淘汰顺序,执行开销较高。

我们采用组相联 FIFO组织缓存池。所谓组相联(set-associative),是指先将缓存池划分为若干独立的组。每个 token id 通过哈希映射到唯一一组,但可以存放在该组内任意一个槽位。相比每个 token 只能对应一个固定槽位的直接映射方式,组相联可以降低哈希冲突;相比允许条目存放在整个缓存池任意位置的全相联方式,它又将查找和替换范围限制在较小的组内。

每组包含固定数量的槽位,替换仅发生在组内。每组维护一个 FIFO 指针,仅在装入新条目时推进一次。当组内需要装入新条目时,指针指向的槽位被替换,随后指针移动到下一个槽位;缓存命中不会改变该指针。因此,实现上采用轮转替换,语义上等价于按照装入顺序执行组内 FIFO。

该方案在 NPU 上有三个适配性优势:

  • 查找和替换状态被限制在较小的组内,元数据开销可控;
  • 不同组之间相互独立,天然支持多核划分与并行处理;
  • FIFO 仅在新条目装入时更新,无需在每次命中时维护访问时序。

仓库中的常量定义印证了这一设计(offload_cache.py):默认池大小_DSA_DEFAULT_POOL_SIZE = 8192enlarge_pool_size: True时切换到_DSA_LARGE_POOL_SIZE = 16384;组相联度_DSA_SET_ASSOCIATIVITY = 16lru_counter的形状为(batch_size_per_rank, dsa_pool_size // 16),即每个 set 维护一个替换计数(FIFO 指针);同时以id_to_slot哈希表(dsa_id_range不小于 131072)完成 token id 到槽位的映射。缓存数据侧,每个共享组在 Device 上维护独立的常驻池张量dsa_pool_key_values(nope 与 rope 两部分,shape 为(batch, pool_size, dim),见init_cache())。

组相联在降低哈希冲突的同时,将查找和替换范围限制在组内;FIFO 则将替换机制做得足够轻量,适配并行执行的要求。

4.4 SFA 优先,回填后置

当前层注意力计算直接依赖选中的 KV——数据未就绪,SFA 就无法启动。因此执行调度优先准备选中的 KV,数据就绪后立即推进 SFA。

缓存池回填的时限要宽松得多:新装入的条目是供后续 decode step 使用的。回填因此在辅流上发起,与 SFA 和 MoE 并行推进。

共享 Indexer Top-K | v 共享规划 | +----> 逐层 KV 准备 ----> SFA ----> MoE | +----> 辅流缓存池回填

这一调度将 Offload 的关键阻塞段压缩到"准备选中 KV"这一步,缓存维护开销则尽可能与计算重叠,不单独占用 decode 延迟。


五、实现:三个算子,三条路径

上述设计在代码层面映射为三个定制 AscendC 算子(源码位于 ops/ascendc/src/dsa_plan、ops/ascendc/src/dsa_serve、ops/ascendc/src/dsa_install):

算子执行频率职责
DsaPlan每个 Indexer 共享组一次分类 Top-K、判定缓存池命中或未命中、生成紧凑的未命中记录
DsaServe每层一次从缓存池和 Host 侧完整 KV Cache 中准备 SFA 所需的 KV 和 RoPE
DsaInstall每层一次回填未命中条目、执行 FIFO 淘汰、更新缓存池状态

DsaPlan承载所有共享的标量工作:将 Top-K id 和缓存池元数据转化为紧凑的执行规划。DsaServe依照规划执行数据搬运,优先交付 SFA 所需的数据。DsaInstall依照未命中记录,在辅流上执行延迟回填。

三个算子的划分形成三条职责分明的执行路径:规划在组级别完成,不随层数放大;数据服务每层独立进行,但不再包含重复的决策逻辑;回填与计算并行,不占用关键延迟。

5.1 模型侧编排:以源码为证

模型侧的编排逻辑集中在 shared_indexer_offload.py 的run_shared_indexer_offload()中,与上述设计一一对应:

  • 逐组规划offload_cache.is_dsa_shared_group_owner(layer_idx)判定当前层是否为组首 owner 层;owner 层调用torch.ops.custom.dsa_plan生成planinstall_records并存入共享组,非 owner 层直接复用get_dsa_shared_group_plan()取回的同一份规划;
  • 逐层数据服务:每层独立调用torch.ops.custom.dsa_serve,将plan作用到本层的full_kv_cache/full_k_rope与缓存池pool_kv_view/pool_rope_view,产出 SFA 所需的selection_kv_cache/selection_k_ropecompact_layout=1表示池按[batch, pool_size, dim]紧凑布局存储);
  • 辅流回填:非 owner 层回填本层、组末层额外回填 owner 层的数据(metadata_update仅在组末层触发,用于推进 FIFO 指针并更新pool_ids/id_to_slot/lru_counter);enable_install_stream开启时,回填经npu_stream_switch切到独立辅流执行,并通过record_event/wait_event与主计算流同步,从而与 SFA、MoE 计算重叠。

在 eager / npugraph_ex / ge_graph 三种执行模式下,算子加载路径由 custom_op_loader.py 统一处理:

  • load_offload_gather_op():挂载npu_gather_selection_kv_cache(基础 Offload 算子);
  • register_dsa_shared_ge_converters():ge_graph 模式注册 DsaPlan/DsaServe/DsaInstall 的 torchair GE converter(含dsa_functionalization辅助模块);
  • register_dsa_shared_npugraph_reinplace():npugraph_ex 模式注册dsa_serve_functional/dsa_servedsa_install_functional/dsa_install的 inplace 配对,使图捕获阶段能够正确执行 host-device 数据搬运。

Runner 侧(runner_glm.py)在shared_indexer_offload开启时按exe_mode选择上述加载路径。此外,offload_cache.py 还实现了 MTP 场景的 gather 复用(enable_mtp_gather_reuse):MTP draft 步冻结首个 decode step 的 top-k 后,其选中的历史位置 KV 不可变,首个 step 收集到的 selection buffer 在后续 draft 步中保持有效,可跳过冗余的重复 gather。


六、在仓库中启用共享 Indexer Offload

6.1 依赖的定制算子编译安装

KV Offload 依赖仓内自定义 AscendC 算子(非 torch_npu 内置),须先编译安装(详见 models/glm_5_2/README.md):

# 1) 编译算子内核(A3 默认 ascend910_93;bisheng 随 CANN 提供) cd ops/ascendc bash build.sh -n "gather_selection_kv_cache;dsa_plan;dsa_serve;dsa_install" # 安装包位于 output/CANN-custom_ops-*-linux.<arch>.run # 2) 安装内核到 CANN opp cd output ./CANN-custom_ops-*-linux.*.run --quiet --install-path="${ASCEND_HOME_PATH}/opp" # 3) 编译并安装 torch 绑定(缺 ninja 时先 pip install ninja) cd ../torch_ops_extension bash build_and_install.sh # 生成并 pip 安装 custom_ops wheel # 4) 运行前 source 自定义算子环境(设置 ASCEND_CUSTOM_OPP_PATH / LD_LIBRARY_PATH) source "${ASCEND_HOME_PATH}/opp/vendors/customize/bin/set_env.bash"

modeling_glm.py在 import 时自动把基础 offload 算子挂到torch_npu.npu_gather_selection_kv_cache;开启shared_indexer_offload时,Runner 初始化会按需加载共享 IndexShare offload 相关自定义算子。因此模型侧无需改动,只要上面的算子已安装、且运行前 source 了第 4 步的环境即可。若遇到'_OpNamespace' 'custom' object has no attribute类报错,可参考 ops/ascendc/README.md 重新编译对应算子。

6.2 配置项:offload 三开关与执行模式

仓库提供了两份 offload 示例配置(models/glm_5_2/config):

  • glm_5_2_rank_32_32ep_w8a8_offload.yaml:基础 KV Offload 路径;
  • glm_5_2_rank_32_32ep_w8a8_offload_mtp.yaml:开启共享 Indexer Offload 与 MTP3 的完整路径。

model_config中设置 offload 选项(详细参数说明见 config/README.md):

model_config: enable_offload: True # [False, True] 开启 KV Offload(长序列、大 batch 场景) shared_indexer_offload: True # [False, True] 使用 GLM-5.2 IndexShare 共享规划路径 enlarge_pool_size: False # [False, True] 设备侧常驻 token 池从 8K 扩大到 16K next_n: 3 # MTP 步数,支持 [0, 1, 2, 3] pa_block_size: 128 # PagedAttention 块大小,支持 [128, 256] with_ckpt: True # 是否加载权重 enable_multi_streams: True # 多流并行 enable_online_split_weight: True # 在线切分权重 exe_mode: "npugraph_ex" # ["ge_graph", "eager", "npugraph_ex"],decode 执行模式

三个开关的语义与作用:

  • enable_offload: True:把全量 MLA KV 卸载到 Host swapped memory,decode 时按 DSA top-k 把命中的 block gather 回 Device,面向全量 KV 放不下 HBM 的长上下文场景;
  • shared_indexer_offload: True:利用 GLM-5.2 的 IndexShare 特性复用同一组 top-k 规划,减少共享层重复的命中判断和缓存管理开销,并将常驻池回填与 SFA、MoE 计算并行;
  • enlarge_pool_size: True:把设备侧常驻 token 池从 8K 扩大到 16K,进一步提高命中率并减少 host 到 device 的 KV 搬运。该开关经 offload_cache.py 的resolve_dsa_pool_size()生效(8192 → 16384)。

配套的并行配置参考(A3 单卡双 die、world_size = 2 * chip_num):embed_tp_size/lmhead_tp_size切到 32(W8A8 权重下 embedding 与 lm_head 走 TP),attn_tp_size/dense_tp_size/moe_tp_size为 1,MoE 经 32 路 EP 展开。数据侧示例input_max_len: 4096batch_size: 32可按评测需求调整。

6.3 运行流程

各节点同步执行 infer.sh 即可拉起多卡推理:

# infer.sh 中指定配置文件 export YAML_FILE_NAME=glm_5_2_rank_32_32ep_w8a8_offload_mtp.yaml bash infer.sh

运行前需在 executor/scripts/set_env.sh 中填写各节点 IP(第 1 个为 master)与 CANN 包路径,并在 yaml 中把model_path指向转换好的 W8A8 权重(转换命令见 models/glm_5_2/README.md 的weight_convert.sh部分)。


七、双机 Atlas A3 评测

7.1 评测环境与口径

评测环境为生产级配置:双机 Atlas A3(共 16 卡)、GLM-5.2-W8A8 模型、64K 输入序列、MTP3。针对 64K 输入序列,在相同设备资源约束下,不使用 Offload 时,KV Cache 容量仅能支持全局 batch size 上限为 64;启用 Offload 后,该上限提升至 128。实验分别测试 8K 和 16K 两种 Device 侧 KV 缓存池容量,并覆盖 GE Graph 和 NPUGraph Ex 两种执行模式。

吞吐按两种口径报告:

  • 统一假设口径:为在相同 MTP 接收长度假设下比较不同配置,将 MTP 平均接收长度统一设为 2.7。该数值为经验假设,仅用于归一化估算,不代表各配置的实测接收长度;
  • 实测口径:使用推理过程中实际观测到的 MTP 平均接收长度。

计算方式:

吞吐 = 全局 batch size × MTP 平均接收长度 /(主模型 + MTP3 单步延迟)

7.2 完整评测数据

执行模式配置全局 batch缓存池容量主+MTP3 延迟吞吐(2.7 假设)吞吐(实测)
GE Graph无 Offload64-71.21 ms2,427 token/s2,504 token/s
GE Graph共享 Indexer Offload1288K100.55 ms3,437 token/s(+41.6%)3,642 token/s(+45.4%)
GE Graph共享 Indexer Offload12816K92.03 ms3,755 token/s(+54.8%)3,982 token/s(+59.0%)
NPUGraph Ex无 Offload64-71.59 ms2,414 token/s2,507 token/s
NPUGraph Ex共享 Indexer Offload1288K105.04 ms3,290 token/s(+36.3%)3,452 token/s(+37.7%)
NPUGraph Ex共享 Indexer Offload12816K95.67 ms3,612 token/s(+49.6%)3,791 token/s(+51.2%)

7.3 从数据中归纳的三点结论

  • 可承载的 batch 上限翻倍,延迟增长可控。针对 64K 输入序列,Offload 将可承载的全局 batch size 上限从 64 提升至 128。16K 缓存池下,主模型 + MTP3 单步延迟相较无 Offload 配置增长 29.2%(GE Graph)和 33.6%(NPUGraph Ex)。延迟增长幅度远低于 batch 上限的增幅,表明 Offload 的附加开销处于有效控制之下。

  • 吞吐净增约 50%。16K 缓存池下,按统一的 2.7 经验假设估算,GE Graph 和 NPUGraph Ex 的吞吐分别提升 54.8% 和 49.6%;按各配置的实测接收长度计算,吞吐分别提升 59.0% 和 51.2%。batch 容量的扩大切实转化为了系统吞吐收益。

  • 16K 缓存池优于 8K 缓存池。在最终的组相联 FIFO 方案下,缓存池容量从 8K 扩大至 16K 后,平均命中率由约 85% 提升至 90% 以上,需要从 Host 加载并回填的未命中数据随之减少。在相同全局 batch size 128 下,16K 缓存池相较 8K 缓存池,吞吐进一步提升约 9.3%(GE Graph)和 9.8%(NPUGraph Ex,按 2.7 MTP 接受长度经验假设估算)。这表明扩大缓存池容量所带来的命中率提升,可以进一步降低 Offload 的端到端开销。

这些对比印证了 Offload 设计的核心判断:Host 内存用于承载完整 KV Cache,从而提高可支持的全局 batch 上限;Device 侧缓存池、跨层复用和调度优化则用于压低附加开销。两者协同,使 batch 上限翻倍最终转化为约 50% 的吞吐净增。


八、扩展思考:KV Cache 管理的系统化方向

GLM-5.2 的共享 Indexer 为本次 Offload 方案提供了关键的结构性支撑。四层一组的 Top-K 复用使标量规划开销得以分摊,这一点离开了模型的特定架构是无法成立的。换言之,KV Offload 的上限很大程度上由模型结构决定。不同模型的注意力设计、层间关联、计算与带宽的配比各不相同,缓存大小、替换策略和执行调度的最优选择也会随之变化。

从更长远的视角看,KV Cache 的管理最终需要走向一个系统化的方向。Offload 解决了容量问题,但单靠 Offload 还不足以应对上下文持续增长带来的全方位压力。一个更完整的思路是将 KV Cache 视为可分级、可调度的资源:在 Host 内存与 Device HBM 之间建立缓存层次,依据访问热度动态调配数据位置,结合淘汰策略自动适应工作负载变化。与此同时,稀疏注意力压缩每步计算量,投机解码通过并行生成均摊延迟——三者各自有效,但要系统性地应对长上下文下的吞吐和延迟挑战,需要将它们协同部署,每项技术的短板恰可由其他技术补足。


参考:本文涉及的仓库关键路径

  • 技术文档本体:docs/models/glm_5_2/glm_5_2_offload_guide.md,相关图示位于 docs/models/glm_5_2/figures
  • GLM-5.2 样例说明与算子编译步骤:models/glm_5_2/README.md
  • 配置示例:glm_5_2_rank_32_32ep_w8a8_offload.yaml、glm_5_2_rank_32_32ep_w8a8_offload_mtp.yaml、config/README.md
  • 模型侧编排:shared_indexer_offload.py、offload_cache.py、custom_op_loader.py、configuration_glm.py、runner_glm.py
  • 定制算子:ops/ascendc/src/gather_selection_kv_cache、ops/ascendc/src/dsa_plan、ops/ascendc/src/dsa_serve、ops/ascendc/src/dsa_install
  • 启动脚本:models/glm_5_2/infer.sh、executor/scripts/set_env.sh

【免费下载链接】cann-recipes-infer本项目针对LLM与多模态模型推理业务中的典型模型、加速算法,提供基于CANN平台的优化样例项目地址: https://gitcode.com/cann/cann-recipes-infer

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询