use std::path::PathBuf;
use anyhow::{Context, Result};
use clap::Parser;
use frink_models::splice_pooler;
#[derive(Parser, Debug)]
pub struct SplicePoolerArgs {
#[arg(short = 'm', long = "model")]
pub gguf: PathBuf,
#[arg(long)]
pub safetensors: PathBuf,
#[arg(short = 'o', long)]
pub output: PathBuf,
}
pub fn run(args: SplicePoolerArgs) -> Result<()> {
if args.output == args.gguf {
anyhow::bail!(
"--output must differ from --model: the input is read while the output is written"
);
}
let done = splice_pooler(&args.gguf, &args.safetensors, &args.output)
.with_context(|| format!("splicing a pooler into {}", args.gguf.display()))?;
println!(
"wrote {}: cls.weight [{n}, {n}] + cls.bias [{n}] (F32) from {}",
done.output.display(),
args.safetensors.display(),
n = done.n_embd,
);
println!(
"identity: cls.output ({:?}, {} output(s)) agrees with classifier.* to |diff| <= {:.3e} \
(bound {:.3e})",
done.head_dtype, done.n_out, done.classifier_max_abs_diff, done.classifier_allowed,
);
println!(
"the head is classifier(tanh(pooler(cls))) now; /v1/rerank reports it as \
frink_score_head on every response"
);
Ok(())
}