use crate::serve::api::kv_spill_descriptor::KvSpillProvenance;
use crate::serve::kv_persist::families::tq_packed::{flags, TqBitsPerCoord};
#[derive(Debug, Clone)]
pub struct TqPackedSpillDescriptor {
pub bits_per_coord: TqBitsPerCoord,
pub num_layers: usize,
pub nkv_heads: Vec<u32>,
pub head_dim: Vec<u32>,
pub block_tokens: u32,
pub flags: u32,
pub scale: f64,
pub provenance: KvSpillProvenance,
}
impl TqPackedSpillDescriptor {
pub fn from_gemma_loaded_model_tq(
weights: &crate::inference::models::gemma4::MlxModelWeights,
provenance: KvSpillProvenance,
) -> Option<Self> {
let bits = read_tq_codebook_bits_env();
let bits_per_coord = TqBitsPerCoord::new(bits).ok()?;
let num_layers = weights.kv_caches.len();
if num_layers == 0 || weights.layers.len() != num_layers {
return None;
}
let mut nkv_heads = Vec::with_capacity(num_layers);
let mut head_dim = Vec::with_capacity(num_layers);
for layer_idx in 0..num_layers {
let layer_cfg = &weights.layers[layer_idx];
nkv_heads.push(layer_cfg.num_kv_heads as u32);
head_dim.push(layer_cfg.head_dim as u32);
}
Some(Self {
bits_per_coord,
num_layers,
nkv_heads,
head_dim,
block_tokens: crate::serve::kv_persist::format::BLOCK_TOKENS,
flags: flags::HADAMARD_ROTATED,
scale: 1.0_f64,
provenance,
})
}
}
pub(crate) fn parse_tq_codebook_bits(env: Option<&str>) -> u32 {
const DEFAULT_BITS: u32 = 8;
match env {
Some(v) => match v.trim().parse::<u32>() {
Ok(n) if matches!(n, 2 | 3 | 4 | 5 | 6 | 8) => n,
_ => DEFAULT_BITS,
},
None => DEFAULT_BITS,
}
}
pub(crate) fn read_tq_codebook_bits_env() -> u32 {
parse_tq_codebook_bits(std::env::var("HF2Q_TQ_CODEBOOK_BITS").ok().as_deref())
}
pub fn parse_tq_active_mode(env: Option<&str>) -> bool {
match env {
None => true,
Some(v) => {
let t = v.trim();
if t.is_empty() {
return true;
}
!(t.eq_ignore_ascii_case("0")
|| t.eq_ignore_ascii_case("false")
|| t.eq_ignore_ascii_case("off"))
}
}
}
pub fn is_tq_active_mode() -> bool {
parse_tq_active_mode(std::env::var("HF2Q_TQ_KV").ok().as_deref())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn parse_tq_codebook_bits_defaults_to_8_when_unset() {
assert_eq!(parse_tq_codebook_bits(None), 8);
}
#[test]
fn parse_tq_codebook_bits_accepts_documented_widths() {
for bits in [2u32, 3, 4, 5, 6, 8] {
let s = bits.to_string();
assert_eq!(
parse_tq_codebook_bits(Some(s.as_str())),
bits,
"bits={}",
bits
);
}
}
#[test]
fn parse_tq_codebook_bits_invalid_falls_back_to_default() {
for bad in ["", "0", "1", "7", "9", "16", "garbage", " "] {
assert_eq!(parse_tq_codebook_bits(Some(bad)), 8, "bad={:?}", bad);
}
}
#[test]
fn parse_tq_active_mode_default_on() {
assert!(parse_tq_active_mode(None));
for blank in ["", " ", "\t", "\n"] {
assert!(parse_tq_active_mode(Some(blank)), "blank={:?}", blank);
}
for falsy in ["0", "false", "off", "FALSE", "Off", " 0 "] {
assert!(!parse_tq_active_mode(Some(falsy)), "falsy={:?}", falsy);
}
for truthy in ["1", "yes", "true", "on", "anything", "TRUE", "ON"] {
assert!(parse_tq_active_mode(Some(truthy)), "truthy={:?}", truthy);
}
}
}