use super::super::ggml_type::GgmlType;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum ApexTier {
Quality,
IQuality,
Balanced,
IBalanced,
Compact,
ICompact,
Mini,
}
impl ApexTier {
pub const fn cli_name(self) -> &'static str {
match self {
ApexTier::Quality => "quality",
ApexTier::IQuality => "i-quality",
ApexTier::Balanced => "balanced",
ApexTier::IBalanced => "i-balanced",
ApexTier::Compact => "compact",
ApexTier::ICompact => "i-compact",
ApexTier::Mini => "mini",
}
}
pub const fn requires_imatrix(self) -> bool {
matches!(
self,
ApexTier::IQuality | ApexTier::IBalanced | ApexTier::ICompact
)
}
pub fn from_cli_name(s: &str) -> Option<Self> {
match s {
"quality" => Some(ApexTier::Quality),
"i-quality" => Some(ApexTier::IQuality),
"balanced" => Some(ApexTier::Balanced),
"i-balanced" => Some(ApexTier::IBalanced),
"compact" => Some(ApexTier::Compact),
"i-compact" => Some(ApexTier::ICompact),
"mini" => Some(ApexTier::Mini),
_ => None,
}
}
}
pub const SUPPORTED_APEX_TIERS: &[&str] = &[
"quality",
"i-quality",
"balanced",
"i-balanced",
"compact",
"i-compact",
"mini",
];
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct TierRules {
pub edge_exp: GgmlType,
pub near_exp: GgmlType,
pub mid_exp: GgmlType,
pub edge_shared: GgmlType,
pub mid_shared: GgmlType,
pub edge_attn: GgmlType,
pub mid_attn: GgmlType,
}
pub const fn tier_rules(tier: ApexTier) -> TierRules {
match tier {
ApexTier::Quality | ApexTier::IQuality => TierRules {
edge_exp: GgmlType::Q6_K,
near_exp: GgmlType::Q5_K,
mid_exp: GgmlType::IQ4_XS,
edge_shared: GgmlType::Q8_0,
mid_shared: GgmlType::Q8_0,
edge_attn: GgmlType::Q6_K,
mid_attn: GgmlType::Q6_K,
},
ApexTier::Balanced | ApexTier::IBalanced => TierRules {
edge_exp: GgmlType::Q6_K,
near_exp: GgmlType::Q5_K,
mid_exp: GgmlType::Q5_K,
edge_shared: GgmlType::Q8_0,
mid_shared: GgmlType::Q8_0,
edge_attn: GgmlType::Q6_K,
mid_attn: GgmlType::Q6_K,
},
ApexTier::Compact | ApexTier::ICompact => TierRules {
edge_exp: GgmlType::Q4_K,
near_exp: GgmlType::Q3_K,
mid_exp: GgmlType::Q3_K,
edge_shared: GgmlType::Q6_K,
mid_shared: GgmlType::Q6_K,
edge_attn: GgmlType::Q4_K,
mid_attn: GgmlType::Q4_K,
},
ApexTier::Mini => TierRules {
edge_exp: GgmlType::Q3_K,
near_exp: GgmlType::Q3_K,
mid_exp: GgmlType::IQ2_S,
edge_shared: GgmlType::Q5_K,
mid_shared: GgmlType::Q4_K,
edge_attn: GgmlType::Q4_K,
mid_attn: GgmlType::Q3_K,
},
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ExpRegion {
Edge,
Near,
Mid,
}
pub fn exp_region(layer: usize, n_layers: u32) -> ExpRegion {
let l = layer as i64;
let last = n_layers as i64 - 1;
let edge_hi: i64 = 4;
let edge_lo: i64 = last - 4;
if l <= edge_hi || l >= edge_lo {
return ExpRegion::Edge;
}
let near_hi: i64 = 9;
let near_lo: i64 = last - 9;
if l <= near_hi || l >= near_lo {
return ExpRegion::Near;
}
ExpRegion::Mid
}
pub fn shared_region(layer: usize, n_layers: u32) -> SharedRegion {
let l = layer as i64;
let last = n_layers as i64 - 1;
let edge_hi: i64 = 4;
let edge_lo: i64 = last - 4;
if l <= edge_hi || l >= edge_lo {
SharedRegion::Edge
} else {
SharedRegion::Mid
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SharedRegion {
Edge,
Mid,
}
pub fn attn_region(layer: usize, n_layers: u32) -> AttnRegion {
let l = layer as i64;
let layers = n_layers as i64;
if l <= 2 || l >= layers - 3 {
AttnRegion::Edge
} else {
AttnRegion::Mid
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum AttnRegion {
Edge,
Mid,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn tier_rules_quality_matches_mudler() {
let r = tier_rules(ApexTier::Quality);
assert_eq!(r.edge_exp, GgmlType::Q6_K);
assert_eq!(r.near_exp, GgmlType::Q5_K);
assert_eq!(r.mid_exp, GgmlType::IQ4_XS);
assert_eq!(r.edge_shared, GgmlType::Q8_0);
assert_eq!(r.mid_shared, GgmlType::Q8_0);
assert_eq!(r.edge_attn, GgmlType::Q6_K);
assert_eq!(r.mid_attn, GgmlType::Q6_K);
assert_eq!(r, tier_rules(ApexTier::IQuality));
}
#[test]
fn tier_rules_mini_matches_mudler() {
let r = tier_rules(ApexTier::Mini);
assert_eq!(r.edge_exp, GgmlType::Q3_K);
assert_eq!(r.near_exp, GgmlType::Q3_K);
assert_eq!(r.mid_exp, GgmlType::IQ2_S);
assert_eq!(r.edge_shared, GgmlType::Q5_K);
assert_eq!(r.mid_shared, GgmlType::Q4_K);
assert_eq!(r.edge_attn, GgmlType::Q4_K);
assert_eq!(r.mid_attn, GgmlType::Q3_K);
}
#[test]
fn exp_region_40_layers_boundaries() {
for i in 0..=4 {
assert_eq!(exp_region(i, 40), ExpRegion::Edge, "layer {i}");
}
for i in 5..=9 {
assert_eq!(exp_region(i, 40), ExpRegion::Near, "layer {i}");
}
for i in 10..=29 {
assert_eq!(exp_region(i, 40), ExpRegion::Mid, "layer {i}");
}
for i in 30..=34 {
assert_eq!(exp_region(i, 40), ExpRegion::Near, "layer {i}");
}
for i in 35..=39 {
assert_eq!(exp_region(i, 40), ExpRegion::Edge, "layer {i}");
}
}
#[test]
fn attn_region_40_layers_3_wide_edge() {
for i in 0..=2 {
assert_eq!(attn_region(i, 40), AttnRegion::Edge, "layer {i}");
}
for i in 3..=36 {
assert_eq!(attn_region(i, 40), AttnRegion::Mid, "layer {i}");
}
for i in 37..=39 {
assert_eq!(attn_region(i, 40), AttnRegion::Edge, "layer {i}");
}
}
#[test]
fn shared_region_no_near_band() {
for i in 0..=4 {
assert_eq!(shared_region(i, 40), SharedRegion::Edge, "layer {i}");
}
for i in 5..=34 {
assert_eq!(shared_region(i, 40), SharedRegion::Mid, "layer {i}");
}
for i in 35..=39 {
assert_eq!(shared_region(i, 40), SharedRegion::Edge, "layer {i}");
}
}
#[test]
fn exp_region_30_layers_gemma4() {
assert_eq!(exp_region(0, 30), ExpRegion::Edge);
assert_eq!(exp_region(4, 30), ExpRegion::Edge);
assert_eq!(exp_region(5, 30), ExpRegion::Near);
assert_eq!(exp_region(9, 30), ExpRegion::Near);
assert_eq!(exp_region(10, 30), ExpRegion::Mid);
assert_eq!(exp_region(19, 30), ExpRegion::Mid);
assert_eq!(exp_region(20, 30), ExpRegion::Near);
assert_eq!(exp_region(24, 30), ExpRegion::Near);
assert_eq!(exp_region(25, 30), ExpRegion::Edge);
assert_eq!(exp_region(29, 30), ExpRegion::Edge);
assert_eq!(attn_region(2, 30), AttnRegion::Edge);
assert_eq!(attn_region(3, 30), AttnRegion::Mid);
}
}