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