metrale_cache/kv_cache/paged_impl/
diagnostics.rs1use super::PagedKvCache;
11
12impl PagedKvCache {
13 fn bf16_reductions(buf: &[u8]) -> (f64, f64, f64) {
17 let (mut sum, mut ssq, mut sabs) = (0f64, 0f64, 0f64);
18 for c in buf.chunks_exact(2) {
19 let bits = u16::from_le_bytes([c[0], c[1]]);
20 let v = f32::from_bits((bits as u32) << 16) as f64;
21 sum += v;
22 ssq += v * v;
23 sabs += v.abs();
24 }
25 (sum, ssq, sabs)
26 }
27
28 pub fn debug_kv_checksum_per_layer(
36 &self,
37 blocks: &[u32],
38 boundary_idx: usize,
39 gpu: &dyn metrale_gpu_runtime::gpu::GpuBackend,
40 stream: u64,
41 tag: &str,
42 ) {
43 gpu.synchronize(stream).ok();
44 let boundary = boundary_idx.min(blocks.len());
45 let regions: [(&str, &[u32]); 2] = [
46 ("prefix", &blocks[..boundary]),
47 ("suffix", &blocks[boundary..]),
48 ];
49 for (li, layer) in self.layers.iter().enumerate() {
50 if layer.dtype != super::KvCacheDtype::Bf16 {
51 if li == 0 {
52 tracing::warn!(
53 target: "metrale_cache::kv_cache::paged_impl",
54 "METRALE_KV_CKSUM[{tag}] layer 0 dtype={:?} != bf16 — probe \
55 only decodes BF16; skipping",
56 layer.dtype
57 );
58 }
59 continue;
60 }
61 let nbytes = layer.k_block_stride;
64 for (rname, rblocks) in ®ions {
65 let (mut k_sum, mut k_ssq, mut k_sabs) = (0f64, 0f64, 0f64);
66 let (mut v_sum, mut v_ssq, mut v_sabs) = (0f64, 0f64, 0f64);
67 for &blk in *rblocks {
68 let mut kb = vec![0u8; nbytes];
69 let mut vb = vec![0u8; nbytes];
70 if gpu.copy_d2h(self.k_cache_ptr(li, blk), &mut kb).is_err()
71 || gpu.copy_d2h(self.v_cache_ptr(li, blk), &mut vb).is_err()
72 {
73 continue;
74 }
75 let (ks, kq, ka) = Self::bf16_reductions(&kb);
76 let (vs, vq, va) = Self::bf16_reductions(&vb);
77 k_sum += ks;
78 k_ssq += kq;
79 k_sabs += ka;
80 v_sum += vs;
81 v_ssq += vq;
82 v_sabs += va;
83 }
84 tracing::warn!(
85 target: "metrale_cache::kv_cache::paged_impl",
86 "METRALE_KV_CKSUM[{tag}] L{li} {rname} nblk={} \
87 k_sum={k_sum:.4} k_ssq={k_ssq:.4} k_sabs={k_sabs:.4} \
88 v_sum={v_sum:.4} v_ssq={v_ssq:.4} v_sabs={v_sabs:.4}",
89 rblocks.len(),
90 );
91 }
92 }
93 }
94
95 pub fn debug_kv_per_block(
100 &self,
101 layer_idx: usize,
102 blocks: &[u32],
103 gpu: &dyn metrale_gpu_runtime::gpu::GpuBackend,
104 stream: u64,
105 tag: &str,
106 ) {
107 gpu.synchronize(stream).ok();
108 let layer = &self.layers[layer_idx];
109 if layer.dtype != super::KvCacheDtype::Bf16 {
110 return;
111 }
112 let nbytes = layer.k_block_stride;
115 for (li, &blk) in blocks.iter().enumerate() {
116 let mut kb = vec![0u8; nbytes];
117 let mut vb = vec![0u8; nbytes];
118 if gpu
119 .copy_d2h(self.k_cache_ptr(layer_idx, blk), &mut kb)
120 .is_err()
121 || gpu
122 .copy_d2h(self.v_cache_ptr(layer_idx, blk), &mut vb)
123 .is_err()
124 {
125 continue;
126 }
127 let (_, k_ssq, _) = Self::bf16_reductions(&kb);
128 let (_, v_ssq, _) = Self::bf16_reductions(&vb);
129 tracing::warn!(
130 target: "metrale_cache::kv_cache::paged_impl",
131 "METRALE_KVBLK[{tag}] L{layer_idx} logical={li} phys={blk} \
132 k_ssq={k_ssq:.4} v_ssq={v_ssq:.4}"
133 );
134 }
135 }
136}