mirror of
https://github.com/samvallad33/vestige.git
synced 2026-05-08 23:32:37 +02:00
fix: specify cache location for ORT fastembed_cache
This commit is contained in:
parent
d921427106
commit
47f7d4d55a
4 changed files with 40 additions and 18 deletions
|
|
@ -33,18 +33,26 @@ pub const BATCH_SIZE: usize = 32;
|
||||||
/// Result type for model initialization
|
/// Result type for model initialization
|
||||||
static EMBEDDING_MODEL_RESULT: OnceLock<Result<Mutex<TextEmbedding>, String>> = OnceLock::new();
|
static EMBEDDING_MODEL_RESULT: OnceLock<Result<Mutex<TextEmbedding>, String>> = OnceLock::new();
|
||||||
|
|
||||||
/// Get the default cache directory for fastembed models
|
/// Get the default cache directory for fastembed models.
|
||||||
/// Uses FASTEMBED_CACHE_PATH env var, or falls back to platform cache directory
|
///
|
||||||
fn get_cache_dir() -> std::path::PathBuf {
|
/// Resolution order:
|
||||||
|
/// 1. `FASTEMBED_CACHE_PATH` env var (explicit override)
|
||||||
|
/// 2. Platform cache dir via `directories::ProjectDirs`
|
||||||
|
/// - Linux: `$XDG_CACHE_HOME/vestige/fastembed` (typically `~/.cache/vestige/fastembed`)
|
||||||
|
/// - macOS: `~/Library/Caches/vestige/fastembed`
|
||||||
|
/// - Windows: `%LOCALAPPDATA%\vestige\cache\fastembed`
|
||||||
|
/// 3. `~/.cache/vestige/fastembed` (home-dir fallback)
|
||||||
|
/// 4. `.fastembed_cache` relative to CWD (absolute last resort, should never trigger)
|
||||||
|
pub(crate) fn get_cache_dir() -> std::path::PathBuf {
|
||||||
if let Ok(path) = std::env::var("FASTEMBED_CACHE_PATH") {
|
if let Ok(path) = std::env::var("FASTEMBED_CACHE_PATH") {
|
||||||
return std::path::PathBuf::from(path);
|
return std::path::PathBuf::from(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use platform-appropriate cache directory via directories crate
|
// qualifier="" produces a clean app-name-only path on Linux/Windows;
|
||||||
// macOS: ~/Library/Caches/com.vestige.core/fastembed
|
// on macOS the qualifier is used for the bundle ID so we keep it empty
|
||||||
// Linux: ~/.cache/vestige/fastembed
|
// to get ~/Library/Caches/vestige/fastembed rather than
|
||||||
// Windows: %LOCALAPPDATA%\vestige\cache\fastembed
|
// ~/Library/Caches/com.vestige.vestige/fastembed.
|
||||||
if let Some(proj_dirs) = directories::ProjectDirs::from("com", "vestige", "core") {
|
if let Some(proj_dirs) = directories::ProjectDirs::from("", "vestige", "vestige") {
|
||||||
return proj_dirs.cache_dir().join("fastembed");
|
return proj_dirs.cache_dir().join("fastembed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -53,7 +61,7 @@ fn get_cache_dir() -> std::path::PathBuf {
|
||||||
return base_dirs.home_dir().join(".cache/vestige/fastembed");
|
return base_dirs.home_dir().join(".cache/vestige/fastembed");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Last resort fallback (shouldn't happen)
|
// Last resort fallback (shouldn't happen in practice)
|
||||||
std::path::PathBuf::from(".fastembed_cache")
|
std::path::PathBuf::from(".fastembed_cache")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -210,9 +218,7 @@ impl Default for EmbeddingService {
|
||||||
impl EmbeddingService {
|
impl EmbeddingService {
|
||||||
/// Create a new embedding service
|
/// Create a new embedding service
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self { _unused: () }
|
||||||
_unused: (),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check if the model is ready
|
/// Check if the model is ready
|
||||||
|
|
@ -240,9 +246,13 @@ impl EmbeddingService {
|
||||||
/// Get the model name
|
/// Get the model name
|
||||||
pub fn model_name(&self) -> &'static str {
|
pub fn model_name(&self) -> &'static str {
|
||||||
#[cfg(feature = "nomic-v2")]
|
#[cfg(feature = "nomic-v2")]
|
||||||
{ "nomic-ai/nomic-embed-text-v2-moe" }
|
{
|
||||||
|
"nomic-ai/nomic-embed-text-v2-moe"
|
||||||
|
}
|
||||||
#[cfg(not(feature = "nomic-v2"))]
|
#[cfg(not(feature = "nomic-v2"))]
|
||||||
{ "nomic-ai/nomic-embed-text-v1.5" }
|
{
|
||||||
|
"nomic-ai/nomic-embed-text-v1.5"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the embedding dimensions
|
/// Get the embedding dimensions
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ mod code;
|
||||||
mod hybrid;
|
mod hybrid;
|
||||||
mod local;
|
mod local;
|
||||||
|
|
||||||
|
pub(crate) use local::get_cache_dir;
|
||||||
pub use local::{
|
pub use local::{
|
||||||
cosine_similarity, dot_product, euclidean_distance, matryoshka_truncate, Embedding,
|
cosine_similarity, dot_product, euclidean_distance, matryoshka_truncate, Embedding,
|
||||||
EmbeddingError, EmbeddingService, BATCH_SIZE, EMBEDDING_DIMENSIONS, MAX_TEXT_LENGTH,
|
EmbeddingError, EmbeddingService, BATCH_SIZE, EMBEDDING_DIMENSIONS, MAX_TEXT_LENGTH,
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,8 @@
|
||||||
//! Falls back to BM25-like term overlap scoring when the cross-encoder
|
//! Falls back to BM25-like term overlap scoring when the cross-encoder
|
||||||
//! model is unavailable.
|
//! model is unavailable.
|
||||||
|
|
||||||
|
#[cfg(feature = "embeddings")]
|
||||||
|
use crate::embeddings::get_cache_dir;
|
||||||
#[cfg(feature = "embeddings")]
|
#[cfg(feature = "embeddings")]
|
||||||
use fastembed::{RerankInitOptions, RerankerModel, TextRerank};
|
use fastembed::{RerankInitOptions, RerankerModel, TextRerank};
|
||||||
|
|
||||||
|
|
@ -127,6 +129,7 @@ impl Reranker {
|
||||||
}
|
}
|
||||||
|
|
||||||
let options = RerankInitOptions::new(RerankerModel::JINARerankerV1TurboEn)
|
let options = RerankInitOptions::new(RerankerModel::JINARerankerV1TurboEn)
|
||||||
|
.with_cache_dir(get_cache_dir())
|
||||||
.with_show_download_progress(true);
|
.with_show_download_progress(true);
|
||||||
|
|
||||||
match TextRerank::try_new(options) {
|
match TextRerank::try_new(options) {
|
||||||
|
|
@ -163,7 +166,9 @@ impl Reranker {
|
||||||
top_k: Option<usize>,
|
top_k: Option<usize>,
|
||||||
) -> Result<Vec<RerankedResult<T>>, RerankerError> {
|
) -> Result<Vec<RerankedResult<T>>, RerankerError> {
|
||||||
if query.is_empty() {
|
if query.is_empty() {
|
||||||
return Err(RerankerError::InvalidInput("Query cannot be empty".to_string()));
|
return Err(RerankerError::InvalidInput(
|
||||||
|
"Query cannot be empty".to_string(),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
if candidates.is_empty() {
|
if candidates.is_empty() {
|
||||||
|
|
@ -190,7 +195,9 @@ impl Reranker {
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
results.sort_by(|a, b| {
|
results.sort_by(|a, b| {
|
||||||
b.score.partial_cmp(&a.score).unwrap_or(std::cmp::Ordering::Equal)
|
b.score
|
||||||
|
.partial_cmp(&a.score)
|
||||||
|
.unwrap_or(std::cmp::Ordering::Equal)
|
||||||
});
|
});
|
||||||
|
|
||||||
if let Some(min_score) = self.config.min_score {
|
if let Some(min_score) = self.config.min_score {
|
||||||
|
|
@ -217,7 +224,11 @@ impl Reranker {
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
results.sort_by(|a, b| b.score.partial_cmp(&a.score).unwrap_or(std::cmp::Ordering::Equal));
|
results.sort_by(|a, b| {
|
||||||
|
b.score
|
||||||
|
.partial_cmp(&a.score)
|
||||||
|
.unwrap_or(std::cmp::Ordering::Equal)
|
||||||
|
});
|
||||||
|
|
||||||
if let Some(min_score) = self.config.min_score {
|
if let Some(min_score) = self.config.min_score {
|
||||||
results.retain(|r| r.score >= min_score);
|
results.retain(|r| r.score >= min_score);
|
||||||
|
|
|
||||||
|
|
@ -180,7 +180,7 @@ async fn main() {
|
||||||
if let Err(e) = s.init_embeddings() {
|
if let Err(e) = s.init_embeddings() {
|
||||||
error!("Failed to initialize embedding service: {}", e);
|
error!("Failed to initialize embedding service: {}", e);
|
||||||
error!("Smart ingest will fall back to regular ingest without deduplication");
|
error!("Smart ingest will fall back to regular ingest without deduplication");
|
||||||
error!("Hint: Check FASTEMBED_CACHE_PATH or ensure ~/.fastembed_cache exists");
|
error!("Hint: Check FASTEMBED_CACHE_PATH or ensure ~/.cache/vestige/fastembed is writable");
|
||||||
} else {
|
} else {
|
||||||
info!("Embedding service initialized successfully");
|
info!("Embedding service initialized successfully");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue