开源llama.cpp Releases·原文 2026年9月24日

llama.cpp b11140为dsv4预填充重新启用CUDA稀疏注意力

这次更新让flash_attn_mask_to_sparse_indices内核在编译期确定循环边界,稀疏掩码扫描从 46 微秒降到 17 微秒,批量稀疏算子从 586 微秒降到 244 微秒(49k上下文)。

AI解读:llama.cpp发布b11140,主题是把CUDA稀疏flash attention(sparse-fa)重新启用到dsv4预填充路径。提交说明里写的是“again”,说明这项改动此前被撤下或回退过。

这次改动解决的是GPU上稀疏掩码扫描慢的问题。原因在于flash_attn_mask_to_sparse_indices的查询循环长度在运行时才能确定,编译器没法把同一lane上的多次取数一起发射。

做法是把内核按ncols1模板化,让循环在编译期就有界;再在宿主代码里决定越界检查和列上界,让ncols1 == 8 的扫描循环变成直线代码。

官方给出的数字是:在 49k列的稀疏解码形状下,扫描从 46 微秒降到 17 微秒;在 49k上下文下,批量稀疏算子从 586 微秒降到 244 微秒。

对用CUDA跑DeepSeek V4类稀疏注意力模型长上下文预填充或解码的人来说,这是实打实的延迟下降;但这是特定形状下的测量,不代表所有模型和batch配置都能拿到同样的比例。

llama.cpp发布b11140版本,其中最相关的提交是“CUDA: enable sparse-fa for dsv4 prefill (again)”(PR #29298),作者署名中包括Pascal。

该提交的改动分三步:第一,重新在dsv4预填充中启用CUDA稀疏flash attention;第二,把flash_attn_mask_to_sparse_indices的查询循环展开;第三,把稀疏掩码扫描的越界判断移到宿主代码。

提交说明解释了为什么要展开查询循环:该循环的trip count在运行时确定,导致同一lane上展开的扫描无法把各次load一起发射。做法是把内核按ncols1模板化,让循环在编译期有界;其结果是在 49k列的稀疏解码形状下,批量单次解码编译成直线代码,扫描从 46 微秒降到 17 微秒。

第三项改动针对ncols1 == 8 的扫描:该查询循环保留了运行时边界和提前退出,因此第一次迭代之后不会继续展开。做法是按“最后一组查询是否只有部分”对内核做模板化,由宿主代码根据n_queries决定,并把列上界提到循环外;结果是循环变成直线代码,49k上下文下的批量稀疏算子从 586 微秒降到 244 微秒。

该提交由Pascal参与联合署名。

信息来源

llama.cpp Releases原始来源