metrale_model_arch/deepseek_v41_ref/compress/
compressor.rs1use super::super::hc::rms_norm;
13use super::super::moe::linear_bf16;
14use super::super::to_bf16_rne;
15use super::linear_f32;
16
17pub struct CompressorWeights<'a> {
20 pub wkv: &'a [f32],
21 pub wgate: Option<&'a [f32]>,
22 pub norm: &'a [f32],
23}
24
25pub struct CompressorState {
26 pub kv_state: Vec<f32>,
27 pub score_state: Vec<f32>,
28}
29
30impl CompressorState {
31 pub fn new(ratio: usize, hd: usize) -> Self {
32 CompressorState {
33 kv_state: vec![0f32; ratio * hd],
34 score_state: vec![f32::NEG_INFINITY; ratio * hd],
35 }
36 }
37}
38
39pub fn compressor(
43 x: &[f32],
44 seqlen: usize,
45 start_pos: usize,
46 ratio: usize,
47 dim: usize,
48 hd: usize,
49 w: &CompressorWeights,
50 st: &mut CompressorState,
51 eps: f32,
52) -> Option<Vec<f32>> {
53 if ratio == 1 {
54 return Some(rms_norm(
55 &linear_bf16(x, w.wkv, seqlen, dim, hd),
56 w.norm,
57 seqlen,
58 hd,
59 eps,
60 ));
61 }
62 let kv = linear_f32(x, w.wkv, seqlen, dim, hd);
63 let score = linear_f32(x, w.wgate.expect("wgate at ratio > 1"), seqlen, dim, hd);
64 let pool = |kvg: &[f32], scg: &[f32]| -> Vec<f32> {
65 let mut out = vec![0f32; hd];
68 for d in 0..hd {
69 let m = (0..ratio)
70 .map(|r| scg[r * hd + d])
71 .fold(f32::NEG_INFINITY, f32::max);
72 let ex: Vec<f32> = (0..ratio).map(|r| (scg[r * hd + d] - m).exp()).collect();
73 let sum: f32 = ex.iter().sum();
74 out[d] = (0..ratio).map(|r| kvg[r * hd + d] * (ex[r] / sum)).sum();
75 }
76 out
77 };
78 let pooled: Vec<f32> = if start_pos == 0 {
79 let remainder = seqlen % ratio;
80 let cutoff = seqlen - remainder;
81 if remainder > 0 {
82 st.kv_state[..remainder * hd].copy_from_slice(&kv[cutoff * hd..]);
83 st.score_state[..remainder * hd].copy_from_slice(&score[cutoff * hd..]);
84 }
85 if seqlen < ratio {
86 return None;
87 }
88 (0..cutoff / ratio)
89 .flat_map(|g| {
90 pool(
91 &kv[g * ratio * hd..(g + 1) * ratio * hd],
92 &score[g * ratio * hd..(g + 1) * ratio * hd],
93 )
94 })
95 .collect()
96 } else {
97 let slot = start_pos % ratio;
98 st.kv_state[slot * hd..(slot + 1) * hd].copy_from_slice(&kv);
99 st.score_state[slot * hd..(slot + 1) * hd].copy_from_slice(&score);
100 if !(start_pos + 1).is_multiple_of(ratio) {
101 return None;
102 }
103 pool(&st.kv_state, &st.score_state)
104 };
105 let groups = pooled.len() / hd;
106 let as_bf16: Vec<f32> = pooled.into_iter().map(to_bf16_rne).collect();
107 Some(rms_norm(&as_bf16, w.norm, groups, hd, eps))
108}