vLLM中paged attention算子分析

news2025/5/13 8:05:32

简要分析vLLM中PA的代码架构和v1与v2的区别

vLLM版本:0.8.4

整体结构分析

首先从torch_bindings.cpp入手分析:
在这里插入图片描述
这里可以看到vLLM向pytorch中注册了两个PA算子:v1和v2
其中paged_attention_v1和paged_attention_v2分别实现在csrc/attention/paged_attention_v1.cu以及csrc/attention/paged_attention_v2.cu中:
在这里插入图片描述
在这里插入图片描述
paged_attention_v1和paged_attention_v2都是PA实现的顶层接口,是Python接口调用的入口点,接收来自PyTorch的张量和各种配置参数。
根据csrc/attention/paged_attention_v1.cu中的代码逻辑,我们可以知道vLLM使用了多层分发机制来实现灵活的算子调用,以csrc/attention/paged_attention_v1.cu中的paged_attention_v1为例,分发层级为:
paged_attention_v1:
-> DISPATCH_BY_KV_CACHE_DTYPE
-> CALL_V1_LAUNCHER_BLOCK_SIZE
-> CALL_V1_LAUNCHER_SPARSITY
-> CALL_V1_LAUNCHER
-> paged_attention_v1_launcher
-> LAUNCH_PAGED_ATTENTION_V1
-> paged_attention_v1_kernel (csrc/attention/attention_kernels.cuh实现)
-> paged_attention_kernel(csrc/attention/attention_kernels.cuh实现)

可知paged_attention_kernel是具体的PA算子,csrc/attention/attention_kernels.cuh的代码主要包含以下几个函数:
在这里插入图片描述
paged_attention_v1_kernel和paged_attention_v2_kernel分别是v1和v2对paged_attention_kernel的封装,功能是类似的。

v1与v2的具体区别

总体上:

  • v1版本提供了直接、无分区的注意力计算,适用于中短序列,实现简单,内核启动开销低。
  • v2版本引入了分区计算和归约合并的两阶段处理,解决了长序列的共享内存限制问题,提高了GPU利用率。
函数参数

在这里插入图片描述
paged_attention_v1和paged_attention_v2参数对比可以发现,v2版本新增了三个参数:exp_sums,max_logits,tmp_out,他们是用于分区注意力计算。
这三个参数的维度包含了max_num_partitions,表示序列被划分的最大分区数。

分区计算策略

v2版本引入了固定大小的分区(默认512个token),将长序列分割成多个分区并行处理。

 // v1版本 - 整体处理序列
dim3 grid(num_heads, num_seqs, 1);  // 注意z维度为1

// v2版本 - 分区处理序列
int max_num_partitions = DIVIDE_ROUND_UP(max_seq_len, PARTITION_SIZE);// 默认分区大小PARTITION_SIZE = 512
dim3 grid(num_heads, num_seqs, max_num_partitions);  // z维度为分区数
v2两阶段计算
#define LAUNCH_PAGED_ATTENTION_V2(HEAD_SIZE)                                   \
  vllm::paged_attention_v2_kernel<T, CACHE_T, HEAD_SIZE, BLOCK_SIZE,           \
                                  NUM_THREADS, KV_DTYPE, IS_BLOCK_SPARSE,      \
                                  PARTITION_SIZE>                              \
      <<<grid, block, shared_mem_size, stream>>>(                              \
          exp_sums_ptr, max_logits_ptr, tmp_out_ptr, query_ptr, key_cache_ptr, \
          value_cache_ptr, num_kv_heads, scale, block_tables_ptr,              \
          seq_lens_ptr, max_num_blocks_per_seq, alibi_slopes_ptr, q_stride,    \
          kv_block_stride, kv_head_stride, k_scale_ptr, v_scale_ptr, tp_rank,  \
          blocksparse_local_blocks, blocksparse_vert_stride,                   \
          blocksparse_block_size, blocksparse_head_sliding_step);              \
  vllm::paged_attention_v2_reduce_kernel<T, HEAD_SIZE, NUM_THREADS,            \
                                         PARTITION_SIZE>                       \
      <<<reduce_grid, block, reduce_shared_mem_size, stream>>>(                \
          out_ptr, exp_sums_ptr, max_logits_ptr, tmp_out_ptr, seq_lens_ptr,    \
          max_num_partitions);

相对于v1,v2包含两阶段计算,分别是:

// 第一阶段:分区计算
vllm::paged_attention_v2_kernel<<< ... >>>(/* 参数 */);

// 第二阶段:合并结果
vllm::paged_attention_v2_reduce_kernel<<< ... >>>(/* 参数 */);

而v1版本只需一个核函数:

vllm::paged_attention_v1_kernel<<< ... >>>(/* 参数 */);
共享内存的使用上
// v1版本 - 需要为整个序列分配共享内存
int padded_max_seq_len = DIVIDE_ROUND_UP(max_seq_len, BLOCK_SIZE) * BLOCK_SIZE;
int logits_size = padded_max_seq_len * sizeof(float);

// v2版本 - 只需为一个分区分配共享内存
int logits_size = PARTITION_SIZE * sizeof(float);

v2版本显著减少了每个线程块需要的共享内存大小.

v2版本的规约

v2版本在paged_attention_v2_reduce_kernel中实现了复杂的跨分区归约。

// 计算全局最大logit
max_logit = fmaxf(max_logit, VLLM_SHFL_XOR_SYNC(max_logit, mask));

// 计算重新缩放的指数和
float rescaled_exp_sum = exp_sums_ptr[i] * expf(l - max_logit);

// 聚合分区结果
float acc = 0.0f;
for (int j = 0; j < num_partitions; ++j) {
  acc += to_float(tmp_out_ptr[j * HEAD_SIZE + i]) * shared_exp_sums[j] * inv_global_exp_sum;
}

若有错误,欢迎指正!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

多样本整合Banksy空间聚类分析(Visium HD, Xenium, CosMx)

在空间数据分析中&#xff0c;传统的单细胞聚类算法&#xff0c;例如Seurat和Scanpy中的lovain和leiden等聚类算法&#xff0c;通常在处理空间数据时忽略了空间信息。然而&#xff0c;由于细胞状态受其周围细胞的影响&#xff0c;将转录组数据与细胞的空间信息结合起来进行聚类…

使用 OAuth 2.0 保护 REST API

使用 OAuth 2.0 保护 REST API 使用 OAuth 2.0 保护 REST API1.1 不安全的api1.2 安全默认值安全默认值Spring Security 默认值 需要对所有请求进行身份验证Servlet、过滤器和调度程序安全优势 使用所有请求的安全标头进行响应缓存标头 严格传输安全标头内容类型选项需要对所有…

解决下拉框数据提交后回显名称不对

问题背景描述 页面组件使用 antd 的 Select 组件&#xff0c;下拉框的 options 数据是动态获取的&#xff0c;基本就是有value 和 label 属性的对象数组。 提交数据后&#xff0c;我们有一个保存草稿的操作&#xff0c;支持返回或者刷新页面&#xff0c;浏览其他页面之后通过其…

lenis滑动插件的笔记

官网 lenis - npm 方法一&#xff1a;基础判断&#xff08;推荐&#xff09; 通过 Lenis 自带的 scroll 和 limit 属性直接判断&#xff1a; const lenis new Lenis()// 滚动事件监听 lenis.on(scroll, ({ scroll, limit }) > {const distanceToBottom limit - scroll…

Android Framework

Android 分区 /boot&#xff1a;存放引导程序&#xff0c;包括内核和内存操作程序。/system&#xff1a;相当于电脑 C 盘&#xff0c;存放 Android 系统及系统应用。/recovery&#xff1a;恢复分区&#xff0c;可以进入该分区进行系统恢复。/data&#xff1a;用户数据区&#…

OpenMCU(六):STM32F103开发板功能介绍

概述 距上一篇关于STM32F103的FreeRTOS博客的发布已经过去很长时间没有更新了。在这段时间内&#xff0c;大家可以看到博主发表了一系列的关于使用qemu 模拟实现STM32F103的博客&#xff0c;博主本来想借助qemu开发stm32F103相关的一些软件功能&#xff0c;博主开发出来并成功运…

Rspack:字节跳动自研 Web 构建工具-基于 Rust打造高性能前端工具链

字节跳动开源了一款采用 Rust 开发的前端模块打包工具&#xff1a;Rspack&#xff08;读音为 /ɑrspk/&#xff09;。 据介绍&#xff0c;Rspack 是一个基于 Rust 的高性能构建引擎&#xff0c;具备与 Webpack 生态系统的互操作性&#xff0c;可以被 Webpack 项目低成本集成&a…

高速系统设计实例设计分析

在上几章的内容中&#xff0c;我们从纯粹高速信号的理论分析&#xff0c;到 Cadence 工具的具体使用都做了详细的讲解和介绍。相信读者通过前面章节的学习&#xff0c;已经对高速系统的设计理念及 Cadence 相应的设计流程和工具有了一个基本的认识。但是&#xff0c;对于高速电…

查看购物车

一.查看购物车 查看购物车使用get请求。我们要查看当前用户的购物车&#xff0c;就要获取当前用户的userId字段进行条件查询。因为在用户登录时就已经将userId封装在token中了&#xff0c;因此我们只需要解析token获取userId即可&#xff0c;不需要前端再传入参数了。 Control…

开发工具分享: Web前端编码常用的在线编译器

1.OneCompiler 工具网址&#xff1a;https://onecompiler.com/ OneCompiler支持60多种编程语言&#xff0c;在全球有超过1280万用户&#xff0c;让开发者可以轻易实现代码的编写、运行和共享。 OneCompiler的线上调试功能完全免费&#xff0c;对编程语言的覆盖也很全&#x…

智启未来:新一代云MSP管理服务助力企业实现云成本管理和持续优化

在数字化转型浪潮下&#xff0c;企业纷纷寻求更高效、更经济的运营方式。随着云计算技术的深入应用&#xff0c;云成本优化已成为企业普遍关注的核心议题。 过去&#xff0c;传统云运维服务往往依赖于人力外包&#xff0c;缺乏系统性、规范性的管理&#xff0c;难以有效降低云…

window 显示驱动开发-将虚拟地址映射到内存段(二)

在将虚拟地址映射到段的一部分之前&#xff0c;视频内存管理器调用显示微型端口驱动程序的 DxgkDdiAcquireSwizzlingRange 函数&#xff0c;以便驱动程序可以设置用于访问可能重排的分配位的光圈。 驱动程序既不能将偏移量更改为访问分配的 PCI 光圈&#xff0c;也不能更改分配…

【文心智能体】使用文心一言来给智能体设计一段稳定调用工作流的提示词

&#x1f339;欢迎来到《小5讲堂》&#x1f339; &#x1f339;这是《文心智能体》系列文章&#xff0c;每篇文章将以博主理解的角度展开讲解。&#x1f339; &#x1f339;温馨提示&#xff1a;博主能力有限&#xff0c;理解水平有限&#xff0c;若有不对之处望指正&#xff0…

K8S中构建双架构镜像-从零到成功

背景介绍 公司一个客户的项目使用的全信创的环境&#xff0c;服务器采用arm64的机器&#xff0c;而我们的应用全部是amd64的&#xff0c;于是需要对现在公司流水线进行arm64版本的同步镜像生成。本文介绍从最开始到最终生成双架构的全部过程&#xff0c;以及其中使用的相关配置…

c语言第一个小游戏:贪吃蛇小游戏03

我们为贪吃蛇的节点设置为一个结构体&#xff0c;构成贪吃蛇的身子的话我们使用链表&#xff0c;链表的每一个节点是一个结构体 显示贪吃蛇身子的一个节点 我们这边node就表示一个蛇的身体 就是一小节 输出结果如下 显示贪吃蛇完整身子 效果如下 代码实现 这个hasSnakeNode(…

​​​​​​​大规模预训练范式(Large-scale Pre-training)

大规模预训练指在巨量无标注数据上&#xff0c;通过自监督学习训练大参数量的基础模型&#xff0c;使其具备通用的表征与推理能力。其重要作用如下&#xff1a; 一 跨任务泛化 单一模型可在微调后处理多种NLP&#xff08;自然语言处理&#xff09;、CV&#xff08;计算机视觉…

WPF之高级绑定技术

文章目录 引言多重绑定&#xff08;MultiBinding&#xff09;基本概念实现自定义IMultiValueConverterMultiBinding在XAML中的应用示例使用StringFormat简化MultiBinding 优先级绑定&#xff08;PriorityBinding&#xff09;基本概念PriorityBinding示例实现PriorityBinding的后…

调出事件查看器界面的4种方法

方法1. 方法2. 方法3. 方法4.

使用vite重构vue-cli的vue3项目

一、修改依赖 首先修改 package.json&#xff0c;修改启动方式与相应依赖 移除vue-cli并下载vite相关依赖&#xff0c;注意一些peerDependency如fast-glob需要手动下载 # 移除 vue-cli 相关依赖 npm remove vue/cli-plugin-babel vue/cli-plugin-eslint vue/cli-plugin-rout…

数据治理域——数据治理体系建设

摘要 本文主要介绍了数据治理系统的建设。数据治理对企业至关重要&#xff0c;其动因包括应对数据爆炸增长、提升内部管理效率、支撑复杂业务需求、加强风险防控与合规管理以及实现数字化转型战略。其核心目的是提升数据质量、统一数据标准、优化数据资产管理、支撑业务发展和…