40 layers › 2 groups of 6 layers › 5 reusing layers › Compressed sparse attention › Window keys and values
Rotate, round to FP8
×no parametersapply_rotary_emb(kv[..., -rd:], freqs_cis); act_quant(kv, …) · 706–707
Rotate the last 64 features by position and round the vector to 8-bit floats.
- in
- [B batch, T positions, 512 d_h]
- out
- [B batch, T positions, 512 d_h]
Rotate the last 64 features of the vector by position, in pairs (model.py 392–406), with base 160,000 and YaRN scaling. The rounding is over the whole vector, rotary part included; the reference simulates it in place.
Codemodel.py 369–406, 700–720
def _window_kv(self, x, freqs_cis, start_pos):
"""This layer's sliding-window K and the window positions every query may attend to. The K
stays fp8, quantized over the whole post-RoPE vector, RoPE tail included."""
bsz, seqlen, _ = x.size()
win = self.window_size
kv = self.kv_norm(self.wkv(x))
apply_rotary_emb(kv[..., -self.rope_head_dim :], freqs_cis)
act_quant(kv, fp8_block_size, scale_fmt, scale_dtype, True)
if start_pos == 0: # prefill: attend over this chunk, seeding the ring buffer for decode
if seqlen <= win:
self.window_kv_cache[:bsz, :seqlen] = kv
else:
cutoff = seqlen % win
self.window_kv_cache[:bsz, cutoff:win], self.window_kv_cache[:bsz, :cutoff] = kv[:, -win:].split(
[win - cutoff, cutoff], dim=1
)
window_kv = kv
else: # decode: one token into the ring buffer, attend over the whole window
self.window_kv_cache[:bsz, start_pos % win] = kv.squeeze(1)
window_kv = self.window_kv_cache[:bsz]
return window_kv, get_window_topk_idxs(win, bsz, seqlen, start_pos)def precompute_freqs_cis(dim, seqlen, original_seq_len, base, factor, beta_fast, beta_slow) -> torch.Tensor:
"""Rotary frequencies as complex exponentials, one row per position.
With original_seq_len > 0 this applies YaRN: dimensions whose wavelength already fits inside the
training context keep their frequency, those far beyond it are divided by `factor`, and the
`beta_fast`..`beta_slow` band in between is faded across with a linear ramp.
"""
freqs = 1.0 / (base ** (torch.arange(0, dim, 2, dtype=torch.float32) / dim))
if original_seq_len > 0:
# the dim whose wavelength completes `rotations` turns over the training context
def corrected_dim(rotations):
return dim * math.log(original_seq_len / (rotations * 2 * math.pi)) / (2 * math.log(base))
low = max(math.floor(corrected_dim(beta_fast)), 0)
high = min(math.ceil(corrected_dim(beta_slow)), dim - 1)
ramp = ((torch.arange(dim // 2, dtype=torch.float32) - low) / max(high - low, 1e-3)).clamp(0, 1)
smooth = 1 - ramp
freqs = freqs / factor * (1 - smooth) + freqs * smooth
freqs = torch.outer(torch.arange(seqlen), freqs)
return torch.polar(torch.ones_like(freqs), freqs)
def apply_rotary_emb(x: torch.Tensor, freqs_cis: torch.Tensor, inverse: bool = False) -> torch.Tensor:
"""Rotate `x` in place, taking adjacent element pairs as complex numbers. Accepts [b, s, d] and
[b, s, h, d]; `inverse` conjugates the rotation, which is how the attention output gets the
query's rotation removed again so the cache can stay in one shared rotated form."""
y = x
x = torch.view_as_complex(x.float().unflatten(-1, (-1, 2)))
if inverse:
freqs_cis = freqs_cis.conj()
if x.ndim == 3:
freqs_cis = freqs_cis.view(1, x.size(1), x.size(-1))
else:
freqs_cis = freqs_cis.view(1, x.size(1), 1, x.size(-1))
x = torch.view_as_real(x * freqs_cis).flatten(-2)
y.copy_(x)
return ySources2
Direct evidence
The window keys and values: one projection and a norm, the rotary part rotated, quantised to FP8, written to the ring buffer.
attention-window · deepseek-ai/DeepSeek-V4.1-Flash / inference/model.py
Pinned revision 2cba9e42aa02 ↗ · lines 700–720
Read code excerpt
def _window_kv(self, x, freqs_cis, start_pos):
"""This layer's sliding-window K and the window positions every query may attend to. The K
stays fp8, quantized over the whole post-RoPE vector, RoPE tail included."""
bsz, seqlen, _ = x.size()
win = self.window_size
kv = self.kv_norm(self.wkv(x))
apply_rotary_emb(kv[..., -self.rope_head_dim :], freqs_cis)
act_quant(kv, fp8_block_size, scale_fmt, scale_dtype, True)
if start_pos == 0: # prefill: attend over this chunk, seeding the ring buffer for decode
if seqlen <= win:
self.window_kv_cache[:bsz, :seqlen] = kv
else:
cutoff = seqlen % win
self.window_kv_cache[:bsz, cutoff:win], self.window_kv_cache[:bsz, :cutoff] = kv[:, -win:].split(
[win - cutoff, cutoff], dim=1
)
window_kv = kv
else: # decode: one token into the ring buffer, attend over the whole window
self.window_kv_cache[:bsz, start_pos % win] = kv.squeeze(1)
window_kv = self.window_kv_cache[:bsz]
return window_kv, get_window_topk_idxs(win, bsz, seqlen, start_pos)Direct evidence
Rotary frequencies with the YaRN scaling above the original context, and the rotation of adjacent feature pairs, with an inverse.
rope · deepseek-ai/DeepSeek-V4.1-Flash / inference/model.py
Pinned revision 2cba9e42aa02 ↗ · lines 369–406
Read code excerpt
def precompute_freqs_cis(dim, seqlen, original_seq_len, base, factor, beta_fast, beta_slow) -> torch.Tensor:
"""Rotary frequencies as complex exponentials, one row per position.
With original_seq_len > 0 this applies YaRN: dimensions whose wavelength already fits inside the
training context keep their frequency, those far beyond it are divided by `factor`, and the
`beta_fast`..`beta_slow` band in between is faded across with a linear ramp.
"""
freqs = 1.0 / (base ** (torch.arange(0, dim, 2, dtype=torch.float32) / dim))
if original_seq_len > 0:
# the dim whose wavelength completes `rotations` turns over the training context
def corrected_dim(rotations):
return dim * math.log(original_seq_len / (rotations * 2 * math.pi)) / (2 * math.log(base))
low = max(math.floor(corrected_dim(beta_fast)), 0)
high = min(math.ceil(corrected_dim(beta_slow)), dim - 1)
ramp = ((torch.arange(dim // 2, dtype=torch.float32) - low) / max(high - low, 1e-3)).clamp(0, 1)
smooth = 1 - ramp
freqs = freqs / factor * (1 - smooth) + freqs * smooth
freqs = torch.outer(torch.arange(seqlen), freqs)
return torch.polar(torch.ones_like(freqs), freqs)
def apply_rotary_emb(x: torch.Tensor, freqs_cis: torch.Tensor, inverse: bool = False) -> torch.Tensor:
"""Rotate `x` in place, taking adjacent element pairs as complex numbers. Accepts [b, s, d] and
[b, s, h, d]; `inverse` conjugates the rotation, which is how the attention output gets the
query's rotation removed again so the cache can stay in one shared rotated form."""
y = x
x = torch.view_as_complex(x.float().unflatten(-1, (-1, 2)))
if inverse:
freqs_cis = freqs_cis.conj()
if x.ndim == 3:
freqs_cis = freqs_cis.view(1, x.size(1), x.size(-1))
else:
freqs_cis = freqs_cis.view(1, x.size(1), 1, x.size(-1))
x = torch.view_as_real(x * freqs_cis).flatten(-2)
y.copy_(x)
return y