metrale_model_layers/quant_format/
fp8_blockscaled.rs

1// SPDX-License-Identifier: MIT OR Apache-2.0
2
3//! 2026-09-25: The FP8 E4M3 block-scaled layout (`.weight` with
4//! `.weight_scale_inv`), mapped to [`Nvfp4Variant::Fp8Dequanted`].
5//!
6//! Owner: model-layers (weight loading).
7//! Invariants: none beyond the types.
8
9use crate::quant_format::{IgnoreList, QuantFormat};
10use crate::weight_map::Nvfp4Variant;
11use metrale_config::precision_plan::IgnoreDialect;
12
13/// 2026-09-25: An FP8 block-scaled checkpoint.
14#[derive(Debug)]
15pub struct Fp8BlockScaledFormat {
16    /// 2026-09-30: The config's `ignore` / `exclude_modules` (`QuantizationConfig::ignore_modules`;
17    /// an HF `modules_to_not_convert` list does not reach it). The FP8 checkpoints that carry
18    /// one are ModelOpt exports (nvidia/DeepSeek-V4-Flash-NVFP4: `*.attn.*`, `mtp.*`), so it
19    /// matches as ModelOpt does: exact names or globs.
20    pub ignore: IgnoreList,
21}
22
23impl Fp8BlockScaledFormat {
24    /// 2026-09-30: A malformed ignore entry is refused.
25    pub fn new(ignore_modules: &[String]) -> anyhow::Result<Self> {
26        Ok(Self {
27            ignore: IgnoreList::new(IgnoreDialect::ModelOpt, ignore_modules)?,
28        })
29    }
30}
31
32impl QuantFormat for Fp8BlockScaledFormat {
33    fn name(&self) -> &'static str {
34        "fp8-blockscaled"
35    }
36
37    fn base_variant(&self) -> Nvfp4Variant {
38        Nvfp4Variant::Fp8Dequanted
39    }
40
41    fn is_ignored(&self, module_path: &str) -> bool {
42        self.ignore.matches(module_path)
43    }
44}