metrale_circuit/
precision_policy.rs1use metrale_config::precision_plan::{Granularity, Operand};
19use metrale_config::weight_quantization::{ActFormat, KernelCaps};
20use metrale_config::{
21 DeclaredPrecisionPlan, W4a4Downcast, WeightQuantPolicy, WeightQuantTier, WeightQuantization,
22};
23use serde::Deserialize;
24
25use crate::format::{Format, Scale};
26use crate::precision::{EdgePrecision, LinearFormats, PrecisionError, glob};
27
28const NVFP4_GROUP: u32 = 16;
30
31#[derive(Debug, Clone)]
34pub struct CheckpointPlan {
35 pub checkpoint: String,
37 pub plan: DeclaredPrecisionPlan,
39}
40
41#[derive(Deserialize)]
42#[serde(deny_unknown_fields)]
43struct FixtureFile {
44 schema: u32,
45 checkpoint: String,
46 quantization_config: String,
47}
48
49impl CheckpointPlan {
50 pub fn parse(text: &str) -> Result<Self, PrecisionError> {
52 let f: FixtureFile =
53 toml::from_str(text).map_err(|e| PrecisionError::Parse(e.to_string()))?;
54 if f.schema != 1 {
55 return Err(PrecisionError::Parse(format!(
56 "checkpoint fixture schema {} (this build reads 1)",
57 f.schema
58 )));
59 }
60 let qc: serde_json::Value = serde_json::from_str(&f.quantization_config)
61 .map_err(|e| PrecisionError::Parse(format!("quantization_config: {e}")))?;
62 let plan = DeclaredPrecisionPlan::from_quantization_config(&qc)
63 .map_err(|e| PrecisionError::Parse(format!("quantization_config: {e:#}")))?;
64 Ok(CheckpointPlan {
65 checkpoint: f.checkpoint,
66 plan,
67 })
68 }
69}
70
71pub fn tier_named(name: &str) -> Result<WeightQuantTier, PrecisionError> {
73 let tier = WeightQuantization::ALL
74 .into_iter()
75 .find(|t| t.name() == name)
76 .ok_or_else(|| {
77 PrecisionError::Parse(format!("unknown weight-quantization tier `{name}`"))
78 })?;
79 WeightQuantTier::new(tier, W4a4Downcast::Off).map_err(|e| PrecisionError::Parse(e.to_string()))
80}
81
82pub fn caps_named(names: &[String]) -> Result<KernelCaps, PrecisionError> {
84 let mut caps = KernelCaps::default();
85 for n in names {
86 let bit = match n.as_str() {
87 "w8a8_decode" => &mut caps.w8a8_decode,
88 "w8a8_moe_decode" => &mut caps.w8a8_moe_decode,
89 "w8a8_block_scaled_decode" => &mut caps.w8a8_block_scaled_decode,
90 "fp8_lm_head_batched" => &mut caps.fp8_lm_head_batched,
91 other => {
92 return Err(PrecisionError::Parse(format!(
93 "unknown kernel cap `{other}`"
94 )));
95 }
96 };
97 *bit = true;
98 }
99 Ok(caps)
100}
101
102pub struct PolicyPrecision<'a> {
104 policy: WeightQuantPolicy<'a>,
105 engine: &'a [(String, LinearFormats)],
106}
107
108impl<'a> PolicyPrecision<'a> {
109 pub fn new(policy: WeightQuantPolicy<'a>, engine: &'a [(String, LinearFormats)]) -> Self {
111 PolicyPrecision { policy, engine }
112 }
113}
114
115const BF16: LinearFormats = LinearFormats {
116 weight: Format::Bf16,
117 activation: Format::Bf16,
118};
119
120fn fp8_weight(w: Operand) -> Format {
121 Format::Fp8E4m3 {
122 scale: match w.granularity {
123 Granularity::Block(r, c) => Scale::Block(r, c),
124 Granularity::Group(g) => Scale::Group(g),
125 Granularity::Tensor => Scale::PerTensor,
126 _ => Scale::PerChannel,
127 },
128 }
129}
130
131fn fp8_act(a: Option<Operand>) -> Format {
132 Format::Fp8E4m3 {
133 scale: match a.map(|a| a.granularity) {
134 Some(Granularity::Group(g)) => Scale::Group(g),
135 Some(Granularity::Tensor) => Scale::PerTensor,
136 _ => Scale::PerToken,
137 },
138 }
139}
140
141impl EdgePrecision for PolicyPrecision<'_> {
142 fn linear(&self, module: &str) -> LinearFormats {
143 if let Some((_, f)) = self.engine.iter().find(|(p, _)| glob(p, module)) {
144 return *f;
145 }
146 let mut declared = self.policy.declared(module);
149 if declared.weight.is_none()
150 && let Some(container) = crate::precision::expert_container(module)
151 {
152 declared = self.policy.declared(container);
153 }
154 let Some(w) = declared.weight else {
155 return BF16;
156 };
157 let nvfp4 = Format::Nvfp4 { group: NVFP4_GROUP };
158 if !self.policy.follows_plan() {
159 return LinearFormats {
160 weight: nvfp4,
161 activation: Format::Bf16,
162 };
163 }
164 if w.is_fp8() {
165 let activation = match self.policy.fp8_decode_act(module) {
166 Some(ActFormat::Fp8) => fp8_act(declared.activation),
167 _ => Format::Bf16,
168 };
169 return LinearFormats {
170 weight: fp8_weight(w),
171 activation,
172 };
173 }
174 LinearFormats {
175 weight: nvfp4,
176 activation: if declared.activation_is_fp4() {
177 nvfp4
178 } else {
179 Format::Bf16
180 },
181 }
182 }
183}
184
185#[cfg(test)]
186#[path = "precision_policy_tests.rs"]
187mod precision_policy_tests;