use metrale_model_weights::weights::KvScaleCensus;
#[derive(Debug, Clone, PartialEq, Eq)]
pub(crate) enum Fp8KvScaleSource {
Calibration { tokens: usize, shadowed: usize },
Checkpoint { layers: usize },
Partial {
from_checkpoint: usize,
attention_layers: usize,
},
Unscaled { attention_layers: usize },
}
pub(crate) fn fp8_kv_scale_source(
calibration_tokens: usize,
checkpoint_layers: usize,
attention_layers: usize,
) -> Fp8KvScaleSource {
if calibration_tokens > 0 {
Fp8KvScaleSource::Calibration {
tokens: calibration_tokens,
shadowed: checkpoint_layers,
}
} else if checkpoint_layers == 0 {
Fp8KvScaleSource::Unscaled { attention_layers }
} else if checkpoint_layers >= attention_layers {
Fp8KvScaleSource::Checkpoint {
layers: checkpoint_layers,
}
} else {
Fp8KvScaleSource::Partial {
from_checkpoint: checkpoint_layers,
attention_layers,
}
}
}
pub(crate) fn log_fp8_kv_scale_source(
source: &Fp8KvScaleSource,
census: &KvScaleCensus,
auto_enabled: bool,
) {
let spellings = census.spellings().join(", ");
match *source {
Fp8KvScaleSource::Calibration {
tokens,
shadowed: 0,
} => {
tracing::info!(
"FP8 KV scales: online calibration on every layer (checkpoint ships no k/v \
scales): accumulating per-tensor K/V amax over the first {tokens} observed \
tokens (across requests, readiness probe included) before freezing.{}",
if auto_enabled {
" (auto-enabled from MODEL.toml)"
} else {
""
},
);
}
Fp8KvScaleSource::Calibration { tokens, shadowed } => tracing::info!(
"FP8 KV scales: online calibration over {tokens} tokens on every layer; the \
{shadowed} per-layer checkpoint scales ({spellings}) are loaded but NOT used. \
Pass --fp8-kv-calibration-tokens 0 to use them.",
),
Fp8KvScaleSource::Checkpoint { layers } => tracing::info!(
"FP8 KV scales: from the checkpoint on all {layers} attention layers ({spellings}); \
no calibration needed.",
),
Fp8KvScaleSource::Partial {
from_checkpoint,
attention_layers,
} => tracing::warn!(
"FP8 KV scales: PARTIAL — the checkpoint ships scales ({spellings}) for only \
{from_checkpoint} of {attention_layers} attention layers; the other {} run at \
1.0, which wastes E4M3 range on small K/V and clips any |x| > 448. Enable \
--fp8-kv-calibration-tokens 256, or use --kv-cache-dtype bf16/nvfp4.",
attention_layers - from_checkpoint,
),
Fp8KvScaleSource::Unscaled { attention_layers } => tracing::warn!(
"FP8 KV scales: 1.0 on all {attention_layers} attention layers — the checkpoint \
ships NO k/v scales and calibration is off. 1.0 wastes E4M3 range on small K/V \
and clips any |x| > 448. Enable --fp8-kv-calibration-tokens 256 for online \
calibration, or use --kv-cache-dtype nvfp4/bf16."
),
}
}
#[cfg(test)]
#[path = "fp8_kv_scale_source_tests.rs"]
mod tests;