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}