1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
//! Model merging and delta-compression utilities, implemented natively on top of
//! the `hanzo-ml` tensor + safetensors APIs (no Python, no external tooling).
//!
//! Two features live here:
//!
//! * [`soup`] / [`delta_soup`] — *model soups*: average the weights (or the
//! fine-tune *deltas*) of several checkpoints into a single merged checkpoint.
//! See <https://arxiv.org/abs/2203.05482>.
//! * [`encode`] / [`decode_apply`] — *BitDelta*: compress a fine-tune into a
//! 1-bit-per-weight sign mask plus one f32 scale per tensor, reconstructing
//! `finetuned ≈ base + scale · sign(Δ)`.
//! See <https://arxiv.org/abs/2402.10193>.
//!
//! ```no_run
//! use std::path::{Path, PathBuf};
//! use hanzo_ml::model_delta;
//!
//! # fn main() -> hanzo_ml::Result<()> {
//! // Average three checkpoints with uniform weights.
//! let models = vec![PathBuf::from("a.safetensors"), PathBuf::from("b.safetensors")];
//! model_delta::soup(&models, None, Path::new("souped.safetensors"))?;
//!
//! // Compress a fine-tune relative to its base into a 1-bit delta, then restore it.
//! model_delta::encode(Path::new("base.safetensors"), Path::new("ft.safetensors"), Path::new("ft.bitdelta"))?;
//! model_delta::decode_apply(Path::new("base.safetensors"), Path::new("ft.bitdelta"), Path::new("restored.safetensors"))?;
//! # Ok(()) }
//! ```
pub use ;
pub use ;
use crate::;
use HashMap;
use Path;
/// All of this module's work happens on the CPU; merging/compression is memory-bound
/// elementwise arithmetic and keeping it on the host avoids needless device transfers.
pub const DEVICE: Device = Cpu;
/// Load a safetensors checkpoint into a name -> tensor map on the CPU.
pub
/// Write a name -> tensor map out as a safetensors checkpoint.
pub
/// Format a shape as `[a, b, c]` for error messages.
pub