40 layers › Engram
Looked-up rows
×tensorself.embed(hash_ids)
24 rows of 256 features, concatenated.
- shape
- [B batch, T positions, 6144 rows × 256]
Sources
Contextual evidence from Engram table
The Engram table is an FP8 embedding with one scale per 32 features of a row, dequantised when rows are read.
engram-table · deepseek-ai/DeepSeek-V4.1-Flash / inference/model.py
Pinned revision 2cba9e42aa02 ↗ · lines 296–325
Read code excerpt
class ParallelEngramEmbedding(nn.Module):
"""The n-gram hash table, sharded over its rows. Stays fp8: rows are dequantized on lookup."""
def __init__(self, num_embeddings: int, dim: int):
super().__init__()
self.num_embeddings = num_embeddings
self.dim = dim
self.part_num_embeddings = (num_embeddings + world_size - 1) // world_size
self.vocab_start_idx = rank * self.part_num_embeddings
self.vocab_end_idx = self.vocab_start_idx + self.part_num_embeddings
self.block_size = fp8_block_size
# the table stays fp8 as stored: rows are dequantized with `scale` on lookup
self.weight = nn.Parameter(torch.empty(self.part_num_embeddings, dim, dtype=torch.float8_e4m3fn))
self.scale = nn.Parameter(torch.empty(self.part_num_embeddings, dim // self.block_size, dtype=scale_dtype))
def forward(self, indices: torch.Tensor) -> torch.Tensor:
mask = (indices < self.vocab_start_idx) | (indices >= self.vocab_end_idx)
local_indices = indices - self.vocab_start_idx
local_indices = local_indices.masked_fill(mask, 0)
values = F.embedding(local_indices, self.weight)
scales = F.embedding(local_indices, self.scale)
values = values.float().unflatten(-1, (-1, self.block_size)) * scales.float().unsqueeze(-1)
values = values.flatten(-2).to(torch.bfloat16)
values = values.masked_fill(mask.unsqueeze(-1), 0)
if world_size > 1:
dist.all_reduce(values)
return valuesContextual evidence from Engram table
Engram reads 24 table rows per position, projects them to four keys and one value, gates the value per stream by a normalised dot product of the stream and its key, and adds it to every stream; image positions get none.
engram · deepseek-ai/DeepSeek-V4.1-Flash / inference/model.py
Pinned revision 2cba9e42aa02 ↗ · lines 328–365
Read code excerpt
class Engram(nn.Module):
"""Writes an n-gram lookup into the residual stream, gated by how well it matches that stream.
The hash ids fetch `n_hash_cols` rows; `wkv` turns them into one key per hc copy plus a shared
value. The gate is a normalized dot product of stream against key.
"""
def __init__(self, args: ModelArgs, layer_id: int, layout: EngramLayout):
super().__init__()
self.layer_id = layer_id
self.layer_hash_index = layout.layer_ids.index(layer_id)
self.dim = args.dim
self.hc_mult = args.hc_mult
self.clamp_value = 1e-6
self.embed = ParallelEngramEmbedding(layout.num_embeddings[self.layer_hash_index], layout.head_dim)
n_hash_cols = (layout.max_ngram_size - 1) * layout.n_heads
self.wkv = Linear(n_hash_cols * layout.head_dim, args.dim * (args.hc_mult + 1))
self.eps = args.norm_eps
self.q_weight = nn.Parameter(torch.ones(args.hc_mult, args.dim))
self.k_weight = nn.Parameter(torch.ones(args.hc_mult, args.dim))
def forward(self, x: torch.Tensor, hash_ids: torch.Tensor, token_mask: torch.Tensor | None = None) -> torch.Tensor:
"""x: [B, L, hc_mult, dim]; hash_ids: [B, L, n_hash_cols]; token_mask: [B, L], False shuts
the gate so those positions pass through untouched."""
kv = self.wkv(self.embed(hash_ids).flatten(-2))
key, value = kv.split([self.hc_mult * self.dim, self.dim], dim=-1)
key = key.float().unflatten(-1, (self.hc_mult, self.dim))
weight = self.q_weight.float() * self.k_weight.float() # only ever used as a product
h, eps = x.float(), self.eps
# normalized per (token, hc copy) over `dim`, NOT jointly over the copies
rstd = torch.rsqrt(h.square().mean(-1) + eps) * torch.rsqrt(key.square().mean(-1) + eps)
dot = (h * weight * key).sum(-1) * rstd * self.dim**-0.5
# signed sqrt before the sigmoid, matching the training kernel
gate = torch.sigmoid(torch.copysign(dot.abs().clamp_min(self.clamp_value).sqrt(), dot))
if token_mask is not None:
gate = gate.masked_fill(~token_mask.unsqueeze(-1), 0)
return (h + gate.unsqueeze(-1) * value.float().unsqueeze(-2)).to(x.dtype)