# Embeddings_Create.py # Description: Functions for Creating and managing Embeddings in ChromaDB with LLama.cpp/OpenAI/Transformers # # Imports: import logging from typing import List, Dict, Any import numpy as np # # 3rd-Party Imports: import requests from transformers import AutoTokenizer, AutoModel import torch # # Local Imports: from App_Function_Libraries.LLM_API_Calls import get_openai_embeddings from App_Function_Libraries.Summarization_General_Lib import summarize from App_Function_Libraries.Utils.Utils import load_comprehensive_config from App_Function_Libraries.Chunk_Lib import chunk_options, improved_chunking_process, determine_chunk_position # # ####################################################################################################################### # # Functions: # FIXME - Add all globals to summarize.py loaded_config = load_comprehensive_config() embedding_provider = loaded_config['Embeddings']['embedding_provider'] embedding_model = loaded_config['Embeddings']['embedding_model'] embedding_api_url = loaded_config['Embeddings']['embedding_api_url'] embedding_api_key = loaded_config['Embeddings']['embedding_api_key'] # Embedding Chunking Settings chunk_size = loaded_config['Embeddings']['chunk_size'] overlap = loaded_config['Embeddings']['overlap'] # FIXME - Add logging # FIXME - refactor/setup to use config file & perform chunking def create_embedding(text: str, provider: str, model: str, api_url: str = None, api_key: str = None) -> List[float]: try: if provider == 'openai': embedding = get_openai_embeddings(text, model) elif provider == 'local': embedding = create_local_embedding(text, model, api_url, api_key) elif provider == 'huggingface': embedding = create_huggingface_embedding(text, model) elif provider == 'llamacpp': embedding = create_llamacpp_embedding(text, api_url) else: raise ValueError(f"Unsupported embedding provider: {provider}") if isinstance(embedding, np.ndarray): embedding = embedding.tolist() elif isinstance(embedding, torch.Tensor): embedding = embedding.detach().cpu().numpy().tolist() return embedding except Exception as e: logging.error(f"Error creating embedding: {str(e)}") raise def create_huggingface_embedding(text: str, model: str) -> List[float]: tokenizer = AutoTokenizer.from_pretrained(model) model = AutoModel.from_pretrained(model) inputs = tokenizer(text, return_tensors="pt", padding=True, truncation=True, max_length=512) with torch.no_grad(): outputs = model(**inputs) embeddings = outputs.last_hidden_state.mean(dim=1) return embeddings[0].tolist() # FIXME def create_stella_embeddings(text: str) -> List[float]: if embedding_provider == 'local': # Load the model and tokenizer tokenizer = AutoTokenizer.from_pretrained("dunzhang/stella_en_400M_v5") model = AutoModel.from_pretrained("dunzhang/stella_en_400M_v5") # Tokenize and encode the text inputs = tokenizer(text, return_tensors="pt", padding=True, truncation=True, max_length=512) # Generate embeddings with torch.no_grad(): outputs = model(**inputs) # Use the mean of the last hidden state as the sentence embedding embeddings = outputs.last_hidden_state.mean(dim=1) return embeddings[0].tolist() # Convert to list for consistency elif embedding_provider == 'openai': return get_openai_embeddings(text, embedding_model) else: raise ValueError(f"Unsupported embedding provider: {embedding_provider}") def create_llamacpp_embedding(text: str, api_url: str) -> List[float]: response = requests.post( api_url, json={"input": text} ) response.raise_for_status() return response.json()['embedding'] def create_local_embedding(text: str, model: str, api_url: str, api_key: str) -> List[float]: response = requests.post( api_url, json={"text": text, "model": model}, headers={"Authorization": f"Bearer {api_key}"} ) response.raise_for_status() return response.json().get('embedding', None) def chunk_for_embedding(text: str, file_name: str, api_name, custom_chunk_options: Dict[str, Any] = None) -> List[Dict[str, Any]]: options = chunk_options.copy() if custom_chunk_options: options.update(custom_chunk_options) # FIXME if api_name is not None: # Generate summary of the full document full_summary = summarize(text, None, api_name, None, None, None) else: full_summary = "Full document summary not available." chunks = improved_chunking_process(text, options) total_chunks = len(chunks) chunked_text_with_headers = [] for i, chunk in enumerate(chunks, 1): chunk_text = chunk['text'] chunk_position = determine_chunk_position(chunk['metadata']['relative_position']) chunk_header = f""" Original Document: {file_name} Full Document Summary: {full_summary} Chunk: {i} of {total_chunks} Position: {chunk_position} --- Chunk Content --- """ full_chunk_text = chunk_header + chunk_text chunk['text'] = full_chunk_text chunk['metadata']['file_name'] = file_name chunked_text_with_headers.append(chunk) return chunked_text_with_headers def create_openai_embedding(text: str, model: str) -> List[float]: embedding = get_openai_embeddings(text, model) return embedding # # End of File. #######################################################################################################################