#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum ScaleGranularity {
PerTensor,
PerToken,
PerChannel,
}
impl ScaleGranularity {
pub fn scale_count(&self, rows: usize, cols: usize) -> usize {
match self {
Self::PerTensor => 1,
Self::PerToken => rows,
Self::PerChannel => cols,
}
}
pub fn as_str(&self) -> &'static str {
match self {
Self::PerTensor => "per_tensor",
Self::PerToken => "per_token",
Self::PerChannel => "per_channel",
}
}
}
impl std::fmt::Display for ScaleGranularity {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(self.as_str())
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct ScalePair {
pub activation: ScaleGranularity,
pub weight: ScaleGranularity,
}
impl ScalePair {
pub const fn new(activation: ScaleGranularity, weight: ScaleGranularity) -> Self {
Self { activation, weight }
}
pub const PRODUCTION_DECODE: Self = Self {
activation: ScaleGranularity::PerToken,
weight: ScaleGranularity::PerChannel,
};
pub const SIMPLE: Self = Self {
activation: ScaleGranularity::PerTensor,
weight: ScaleGranularity::PerTensor,
};
}
impl std::fmt::Display for ScalePair {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "act_{}_weight_{}", self.activation, self.weight)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn scale_count_matches_granularity() {
let g = ScaleGranularity::PerTensor;
assert_eq!(g.scale_count(100, 200), 1);
let g = ScaleGranularity::PerToken;
assert_eq!(g.scale_count(100, 200), 100);
let g = ScaleGranularity::PerChannel;
assert_eq!(g.scale_count(100, 200), 200);
}
#[test]
fn display_strings_match_convention() {
assert_eq!(ScaleGranularity::PerTensor.to_string(), "per_tensor");
assert_eq!(ScaleGranularity::PerToken.to_string(), "per_token");
assert_eq!(ScaleGranularity::PerChannel.to_string(), "per_channel");
}
#[test]
fn scale_pair_display_matches_baracuda_symbol_convention() {
let p = ScalePair::PRODUCTION_DECODE;
assert_eq!(p.to_string(), "act_per_token_weight_per_channel");
let p = ScalePair::SIMPLE;
assert_eq!(p.to_string(), "act_per_tensor_weight_per_tensor");
}
#[test]
fn presets_have_expected_pairings() {
assert_eq!(
ScalePair::PRODUCTION_DECODE.activation,
ScaleGranularity::PerToken
);
assert_eq!(
ScalePair::PRODUCTION_DECODE.weight,
ScaleGranularity::PerChannel
);
assert_eq!(ScalePair::SIMPLE.activation, ScaleGranularity::PerTensor);
assert_eq!(ScalePair::SIMPLE.weight, ScaleGranularity::PerTensor);
}
}