candding 0.1.0

Pure candle embeddings for Rust with no ONNX: dense, sparse, multi-vector and rerank models today, image models on the roadmap
Documentation
use super::*;

#[test]
fn a_tied_checkpoint_reads_its_embedding_rows() {
  let model = load(true, false, [YES, NO], ScoreActivation::Identity).unwrap();
  let got = scores(&model, [3, 2]);
  assert_close(got[0], expected(7, &matrix(0.0)), "row 0");
  assert_close(got[1], expected(13, &matrix(0.0)), "row 1");
  assert_eq!(model.rows.dims(), [HIDDEN, 2]);
}

/// The lm_head rows differ from the embedding's, so a head that read the embedding here would miss.
#[test]
fn an_untied_checkpoint_reads_its_lm_head_rows() {
  let model = load(false, true, [YES, NO], ScoreActivation::Identity).unwrap();
  let got = scores(&model, [3, 2]);
  assert_close(got[0], expected(7, &matrix(1.3)), "row 0");
  assert_close(got[1], expected(13, &matrix(1.3)), "row 1");
  assert!((expected(7, &matrix(1.3)) - expected(7, &matrix(0.0))).abs() > 0.1);
  assert_eq!(model.rows.dims(), [HIDDEN, 2]);
}

#[test]
fn the_tie_is_guarded_both_ways() {
  assert!(matches!(
    load(true, true, [YES, NO], ScoreActivation::Identity),
    Err(CanddingError::TiedEmbeddingsWithLmHead)
  ));
  assert!(matches!(
    load(false, false, [YES, NO], ScoreActivation::Identity),
    Err(CanddingError::MissingLmHead)
  ));
}

#[test]
fn the_entry_and_the_config_must_agree_on_the_tie() {
  for (declared, tied) in [(Unembedding::Tied, false), (Unembedding::Untied, true)] {
    for lm_head in [false, true] {
      let refused = load_declared(
        declared,
        tied,
        lm_head,
        [YES, NO],
        ScoreActivation::Identity,
      );
      match refused {
        Err(CanddingError::UnembeddingDisagreesWithConfig {
          declared: name,
          tie_word_embeddings,
        }) => assert_eq!(
          (name.as_str(), tie_word_embeddings),
          (declared.name(), tied)
        ),
        other => panic!(
          "{declared:?} on tie_word_embeddings {tied}, lm_head {lm_head}: {:?}",
          other.err()
        ),
      }
    }
  }
}