kernels: attention sinks + sliding window in decode attention
decode_attention_bf16_kernel gains an optional per-head sink logit and a sliding-window kv_start. The sink joins the softmax max+denominator but contributes no value (rebase max to include it, add exp(sink-m) to the denom, scale O accordingly); window>0 restricts keys to the last `window`. New launch_decode_attention_sink_bf16 + decode_attention_sink() wrapper; the existing launch_decode_attention_bf16 passes nullptr/0 so qwen3's decode path is byte-for-byte unchanged. Builds green on dash5. First piece of the gpt-oss performance path (GPU sink-attention). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -216,7 +216,9 @@ __global__ void decode_attention_bf16_kernel(
|
|||||||
__nv_bfloat16* __restrict__ O,
|
__nv_bfloat16* __restrict__ O,
|
||||||
int num_q_heads, int num_kv_heads,
|
int num_q_heads, int num_kv_heads,
|
||||||
int kv_len, int head_dim,
|
int kv_len, int head_dim,
|
||||||
float scale
|
float scale,
|
||||||
|
const float* __restrict__ sinks, // [num_q_heads] or nullptr (gpt-oss)
|
||||||
|
int window // >0: only attend last `window` keys; 0: full
|
||||||
) {
|
) {
|
||||||
int bh = blockIdx.x;
|
int bh = blockIdx.x;
|
||||||
int batch_idx = bh / num_q_heads;
|
int batch_idx = bh / num_q_heads;
|
||||||
@@ -228,6 +230,10 @@ __global__ void decode_attention_bf16_kernel(
|
|||||||
|
|
||||||
int tid = threadIdx.x;
|
int tid = threadIdx.x;
|
||||||
|
|
||||||
|
// Sliding window: the query is at position kv_len-1 (decode appends it), so it
|
||||||
|
// attends to keys [kv_start, kv_len). kv_start=0 for full attention.
|
||||||
|
int kv_start = (window > 0 && kv_len > window) ? (kv_len - window) : 0;
|
||||||
|
|
||||||
// Pointers to this batch/head's data
|
// Pointers to this batch/head's data
|
||||||
// Q: [batch, num_q_heads, 1, head_dim]
|
// Q: [batch, num_q_heads, 1, head_dim]
|
||||||
const __nv_bfloat16* Q_ptr = Q + ((long long)batch_idx * num_q_heads + q_head) * head_dim;
|
const __nv_bfloat16* Q_ptr = Q + ((long long)batch_idx * num_q_heads + q_head) * head_dim;
|
||||||
@@ -251,7 +257,7 @@ __global__ void decode_attention_bf16_kernel(
|
|||||||
local_O[d] = 0.0f;
|
local_O[d] = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int pos = tid; pos < kv_len; pos += DECODE_THREADS) {
|
for (int pos = kv_start + tid; pos < kv_len; pos += DECODE_THREADS) {
|
||||||
// Compute dot(Q, K[pos]) * scale
|
// Compute dot(Q, K[pos]) * scale
|
||||||
const __nv_bfloat16* K_pos = K_base + pos * head_dim;
|
const __nv_bfloat16* K_pos = K_base + pos * head_dim;
|
||||||
float dot = 0.0f;
|
float dot = 0.0f;
|
||||||
@@ -336,8 +342,20 @@ __global__ void decode_attention_bf16_kernel(
|
|||||||
__syncthreads();
|
__syncthreads();
|
||||||
global_sum = smem_sum[0];
|
global_sum = smem_sum[0];
|
||||||
|
|
||||||
|
// gpt-oss attention sink: a per-head learned logit that joins the softmax
|
||||||
|
// denominator but contributes no value. Rebase max to include it, then add
|
||||||
|
// exp(sink - m_new) to the denominator. O was accumulated relative to
|
||||||
|
// global_max, so it picks up a factor exp(global_max - m_new).
|
||||||
|
float o_scale = 1.0f;
|
||||||
|
if (sinks != nullptr) {
|
||||||
|
float sink = sinks[q_head];
|
||||||
|
float m_new = fmaxf(global_max, sink);
|
||||||
|
o_scale = expf(global_max - m_new);
|
||||||
|
global_sum = global_sum * o_scale + expf(sink - m_new);
|
||||||
|
}
|
||||||
|
|
||||||
// Step 4: Reduce O across block (dimension by dimension using shared mem)
|
// Step 4: Reduce O across block (dimension by dimension using shared mem)
|
||||||
float inv_sum = (global_sum > 0.0f) ? (1.0f / global_sum) : 0.0f;
|
float inv_sum = (global_sum > 0.0f) ? (o_scale / global_sum) : 0.0f;
|
||||||
|
|
||||||
// Process head_dim in chunks: each iteration reduces one dimension
|
// Process head_dim in chunks: each iteration reduces one dimension
|
||||||
// Use shared memory accumulator: each warp contributes via warp reduction + atomic
|
// Use shared memory accumulator: each warp contributes via warp reduction + atomic
|
||||||
|
|||||||
Reference in New Issue
Block a user