pub enum KvLayout {
Gqa {
n_kv_heads: usize,
head_dim: usize,
},
MlaLatent {
kv_lora_rank: usize,
qk_rope_head_dim: usize,
},
MlaExpanded {
n_heads: usize,
k_head_dim: usize,
v_head_dim: usize,
},
}Expand description
How one layer’s KV cache is shaped. Which variant applies is a
property of the decoder that will run, not of the architecture
name – see KvLayout::MlaLatent’s doc comment for the one place
that distinction bites.
Variants§
Gqa
Multi-head / grouped-query attention: one K vector and one V
vector of n_kv_heads * head_dim per token, per layer. MHA is
just the n_kv_heads == n_heads case – there is no separate
variant for it, and the halving GQA buys shows up entirely in
n_kv_heads.
MlaLatent
MLA in its absorbed form: the cache holds only the compressed
latent plus the decoupled RoPE slice, kv_lora_rank + rope_dim
scalars per token per layer, and K/V are reconstructed from it
on the fly. One vector, not two – there is no * 2 here.
ferrox does not run this form today. mla::mla_forward_token
(and therefore kimi_decoder, glm_dsa, glm52_decoder)
caches the expanded per-head K and V, so a real ferrox MLA run
costs KvLayout::MlaExpanded. This variant is what the
absorbed form would cost, and is the right number to plan
against only once a decoder actually caches the latent.
MlaExpanded
MLA as ferrox actually caches it: per-head K of
qk_nope_head_dim + qk_rope_head_dim and per-head V of
v_head_dim, both materialised (mla::mla_forward_token’s
k_cache/v_cache). K and V head dims differ, which is exactly
why this cannot reuse the Gqa arm.
Implementations§
Trait Implementations§
impl Copy for KvLayout
impl Eq for KvLayout
impl StructuralPartialEq for KvLayout
Auto Trait Implementations§
impl Freeze for KvLayout
impl RefUnwindSafe for KvLayout
impl Send for KvLayout
impl Sync for KvLayout
impl Unpin for KvLayout
impl UnsafeUnpin for KvLayout
impl UnwindSafe for KvLayout
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more