| """ |
| Cached UAP Analyzer wrapper that uses embedding caching |
| Extends UAPAnalyzer with cached embedding support |
| """ |
|
|
| import pandas as pd |
| import numpy as np |
| import streamlit as st |
| from typing import Optional, Any |
| import logging |
| from sentence_transformers import SentenceTransformer |
| import torch |
| from uap_analyzer import get_embed_model |
|
|
| from uap_analyzer import UAPAnalyzer |
| from .embedding_cache import compute_embeddings_with_cache, get_embedding_cache |
|
|
| logger = logging.getLogger(__name__) |
|
|
| class CachedUAPAnalyzer(UAPAnalyzer): |
| """ |
| Extended UAPAnalyzer that uses cached embeddings |
| """ |
| |
| def __init__(self, data: pd.DataFrame, column: str, model_name: str = "microsoft/harrier-oss-v1-0.6b"): |
| """ |
| Initialize the cached analyzer |
| |
| Args: |
| data: DataFrame containing the data |
| column: Column name to analyze |
| model_name: Sentence transformer model name |
| """ |
| super().__init__(data, column) |
| self.model_name = model_name |
| self._embedding_model = None |
| self._embeddings_cached = False |
| |
| @property |
| def embedding_model(self): |
| """Lazy load the embedding model""" |
| if self._embedding_model is None: |
| if self.model_name == "microsoft/harrier-oss-v1-0.6b": |
| self._embedding_model = get_embed_model() |
| else: |
| self._embedding_model = SentenceTransformer(self.model_name, model_kwargs={"dtype": "auto"}) |
| return self._embedding_model |
| |
| def preprocess_data(self, top_n: int = 32) -> None: |
| """ |
| Preprocess data with cached embeddings |
| |
| Args: |
| top_n: Number of top items to keep |
| """ |
| |
| super().preprocess_data(top_n) |
| |
| |
| column_data = self.data[self.column] |
| |
| |
| cache_info = get_embedding_cache().get_cache_info() |
| if self.column in cache_info['columns']: |
| logger.info(f"Found cached embeddings for column '{self.column}'") |
| st.info(f"✓ Using cached embeddings for '{self.column}'") |
| else: |
| st.info(f"⏳ Computing new embeddings for '{self.column}'...") |
| |
| |
| self.embeddings = compute_embeddings_with_cache( |
| data=column_data, |
| column_name=self.column, |
| model_name=self.model_name, |
| encoder_func=self.embedding_model.encode |
| ) |
| |
| self._embeddings_cached = True |
| |
| |
| if hasattr(self, '__dict__'): |
| self.__dict__['embeddings'] = self.embeddings |
| |
| def compute_embeddings(self, texts: list) -> np.ndarray: |
| """ |
| Override the compute_embeddings method if it exists |
| |
| Args: |
| texts: List of texts to encode |
| |
| Returns: |
| Embeddings array |
| """ |
| |
| data_series = pd.Series(texts) |
| |
| return compute_embeddings_with_cache( |
| data=data_series, |
| column_name=self.column, |
| model_name=self.model_name, |
| encoder_func=self.embedding_model.encode |
| ) |
| |
| def get_cache_status(self) -> dict: |
| """Get cache status for this analyzer""" |
| cache_info = get_embedding_cache().get_cache_info() |
| |
| column_cache = cache_info['columns'].get(self.column, []) |
| |
| return { |
| 'column': self.column, |
| 'cached': len(column_cache) > 0, |
| 'cache_entries': column_cache, |
| 'embeddings_loaded': self._embeddings_cached |
| } |
|
|
| |
| @st.cache_resource |
| def create_cached_analyzer(_data: pd.DataFrame, column: str, model_name: str = "microsoft/harrier-oss-v1-0.6b") -> CachedUAPAnalyzer: |
| """ |
| Create a cached UAP analyzer instance |
| |
| Args: |
| _data: DataFrame (underscore prefix for Streamlit caching) |
| column: Column to analyze |
| model_name: Model name for embeddings |
| |
| Returns: |
| CachedUAPAnalyzer instance |
| """ |
| return CachedUAPAnalyzer(_data, column, model_name) |
|
|
| |
| def clear_embedding_cache_ui(column: Optional[str] = None) -> None: |
| """ |
| Clear embedding cache with UI feedback |
| |
| Args: |
| column: Specific column to clear, or None for all |
| """ |
| cache_manager = get_embedding_cache() |
| |
| if column: |
| cache_manager.clear_cache(column) |
| st.success(f"✓ Cleared embedding cache for column '{column}'") |
| else: |
| cache_manager.clear_cache() |
| st.success("✓ Cleared all embedding caches") |
| |
| |
| def display_cache_info() -> None: |
| """Display embedding cache information in Streamlit UI""" |
| cache_info = get_embedding_cache().get_cache_info() |
| |
| with st.expander("📊 Embedding Cache Status", expanded=False): |
| col1, col2, col3 = st.columns(3) |
| |
| with col1: |
| st.metric("Total Cached", cache_info['total_cached']) |
| |
| with col2: |
| st.metric("Memory Cached", cache_info['memory_cached']) |
| |
| with col3: |
| st.metric("Disk Size", f"{cache_info['disk_size_mb']:.1f} MB") |
| |
| if cache_info['columns']: |
| st.subheader("Cached Columns:") |
| for col_name, entries in cache_info['columns'].items(): |
| st.write(f"**{col_name}**") |
| for entry in entries: |
| st.write(f" - Model: {entry['model']}, Shape: {entry['shape']}, Cached: {entry['cached_at']}") |
| else: |
| st.info("No embeddings cached yet") |
| |
| |
| col1, col2 = st.columns(2) |
| with col1: |
| if st.button("Clear All Cache", key="clear_all_cache"): |
| clear_embedding_cache_ui() |
| st.experimental_rerun() |
| |
| with col2: |
| selected_col = st.selectbox( |
| "Clear specific column", |
| options=list(cache_info['columns'].keys()) if cache_info['columns'] else [], |
| key="clear_specific_cache" |
| ) |
| if selected_col and st.button(f"Clear {selected_col}", key=f"clear_{selected_col}"): |
| clear_embedding_cache_ui(selected_col) |
| st.experimental_rerun() |