
CANN causal_conv1d_update 完整指南从 0 到 1 上手昇腾因果一维卷积状态更新【免费下载链接】python-firePython Fire is a library for automatically generating command line interfaces (CLIs) from absolutely any Python object.项目地址: https://gitcode.com/gh_mirrors/py/python-firecausal_conv1d_update 是 CANN 提供的因果一维卷积状态更新算子专门服务 LLM 的 decode 阶段把当前 token 的输入和缓存里的历史拼出完整卷积上下文算出输出顺手把新 token 推进状态缓存供下一步增量计算。昇腾 NPU 上做解码卷积、又不想手工管状态基本就是冲它来的。⚠️ 硬件支持现状目前仅 Ascend 950PR / Ascend 950DT 支持Atlas A2 训练/推理系列、Atlas A3 训练/推理系列、Atlas 200I / 500 A2 等推理产品均不支持。原理篇从公式到缓存计算公式每个时间步在算什么$$ y_t \text{Activation}\left(\sum_{j0}^{W-1} w_j \cdot x_{t-j} b\right) $$公式不长符号分工却很明确$W$ 是卷积核宽度只支持 2、3、4决定了要看回几步历史$w_j$ 是第 $j$ 个位置对应的卷积权重$x_{t-j}$ 是从当前时刻往回数第 $j$ 步的输入$b$ 是可缺省的偏置外层 $\text{Activation}$ 是激活函数取 SiLU 或不加。翻译成人话当前 token 加上最近 $W-1$ 步的历史输入做一次加权求和再过一遍激活。缓存与增量更新conv_state 是一个滑动窗口decode 阶段每个时间步只新增一个 token把整条序列重算一遍代价太高。算子因此维护一块状态缓存 conv_stateshape 为 [num_cache_lines, state_len, dim]把最近 W-1 步的输入像滑动窗口一样存着每来一个新 token就用窗口里的历史拼出卷积上下文算完 y 再把新数据写回窗口。模式也不用手动声明由输入形状自动推断——x 是 2D 或 3D 且 seq_len 1 时就按 decode / update增量更新处理。快速上手几行代码跑起来最小可跑版本固定 batch SiLU 激活不碰任何可选参数。import torch import torch_npu from cann_ops_transformer.ops import causal_conv1d_update torch_npu.npu.set_device(0) # 绑定 NPU 设备 B, D, kW 4, 512, 2 x torch.randn(B, D, devicenpu, dtypetorch.float16) # 输入 [batch, dim]等价 seq_len1 weight torch.randn(kW, D, devicenpu, dtypetorch.float16) # 卷积权重 [kW, dim] conv_state torch.zeros(B, kW - 1, D, devicenpu, dtypetorch.float16) # 状态缓存算完原地更新 y causal_conv1d_update(x, conv_state, weight, activationsilu) print(y.shape, y.dtype) # 与 x 同形同型 两个隐含行为值得记住conv_state 计算后会被原地更新连跑多步时它承载的就是最新历史输出 y 的 shape 与 dtype 和 x 完全一致。参数速查表参数类型必选/可选默认值说明与形状xTensor必选-输入序列float16 / bfloat16[batch, 1, dim]固定 batch或 [cu_seq_len, dim]变长conv_stateTensor必选-卷积状态缓存dtype 同 x[num_cache_lines, state_len, dim]state_len ≥ kW-1计算后原地更新weightTensor必选-卷积权重dtype 同 x[kW, dim]kW 仅支持 2、3、4biasTensor可选None卷积偏置dtype 同 x[dim]不传即不使用activationstr可选silu激活类型silu 或 noneconv_state_indicesTensor可选None缓存索引int32[batch]不传时恒等映射值 ∈ [0, num_cache_lines)等于 null_block_id 则跳过num_accepted_tokensTensor可选None投机解码中每个 batch 已接受的 token 数int32[batch]值 ∈ [0, seq_len]仅 kW4 支持query_start_locTensor可选None变长序列起点索引int32[batch1]首元素必须为 0、末元素必须等于 cu_seq_len、非递减max_query_lenint可选-1最大查询长度-1 表示不限制null_block_idint可选0无效缓存槽位标记conv_state_indices[i] 等于它时跳过该序列、输出填零block_idx_last_scheduled_tokenTensor可选None最后调度 token 的块索引int32[batch]initial_state_idxTensor可选None初始状态索引int32[batch]踩坑清单场景 → 规则想在训练任务或图模式里挂这个算子 → 仅限推理场景使用且目前只支持单算子模式调用图模式走不通。weight 第一维填了 1 或 5 → kW 只接受 2、3、4其它核宽不合法。conv_state 开得比需要的窄 → state_len 必须 ≥ kW-1没提供 conv_state_indices 时num_cache_lines 还得 ≥ batch。变长场景下 query_start_loc 没对齐 → 首元素必须是 0末元素必须等于 cu_seq_len中间只能非递减。用 conv_state_indices 做槽位映射 → 取值必须落在 [0, num_cache_lines) 内出现等于 null_block_id默认 0的序列会被整体跳过、输出填零真要用 0 号槽位时先想清楚这个默认值。张量是从别的输出上切出来的非连续视图 → 不支持非连续 Tensor先 .contiguous() 再传。输入混了 ±inf 或 NaN → 明确不允许而且入参与所有中间结果都不能超出 float16 / bfloat16 的值域dtype 也只认这两种。进阶玩法投机解码num_accepted_tokens解决什么问题投机解码一次投出多个候选 tokenbatch 里每个样本真正被接受的长度各不相同。num_accepted_tokensint32[batch]负责告诉算子每个样本接受了几个取值范围 [0, seq_len]0 表示该样本全是投机 token。⚠️ 仅 kW4 支持这个参数核宽为 2 或 3 时别传。变长序列query_start_loc 与 max_query_len 这是变长 decode 的标准姿势batch 里序列长度参差不齐时把 x 压成 2D 的 [cu_seq_len, dim]再用 query_start_locint32[batch1]标出每条序列的起点max_query_len默认 -1不限制负责约束最大查询长度。y causal_conv1d_update(x, conv_state, weight, query_start_locstart_loc, # int32[batch1]首元素必须为 0 conv_state_indicesslot_ids) # int32[batch]把序列映射到指定缓存行缓存索引conv_state_indices解决什么问题多槽位缓存管理下batch 里的序列并不天然对应 conv_state 的前 batch 行。conv_state_indicesint32[batch]把每条序列映射到指定的一行不传时按恒等映射第 i 条对应第 i 行。配合 null_block_id 还能标记无效槽位——索引等于它的序列直接跳过、输出填零。小结causal_conv1d_update 的定位很聚焦昇腾 NPU 上 LLM decode 链路的因果卷积增量引擎一次调用同时完成卷积计算、可选 SiLU 激活和 conv_state 状态推进。固定 batch 的常规推理用上面的最小示例就够了投机解码、变长序列、多槽位缓存这些进阶需求交给对应的可选参数即可。【免费下载链接】python-firePython Fire is a library for automatically generating command line interfaces (CLIs) from absolutely any Python object.项目地址: https://gitcode.com/gh_mirrors/py/python-fire创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考