/home/claude/turboquant-experiments/run_reviewer_experiments.py:29:from batch_probe import ThermalController
/home/claude/turboquant-experiments/run_reviewer_experiments.py:31:# Global thermal controller — caps CPU temp at 80°C using Kalman-filtered PID
/home/claude/turboquant-experiments/run_reviewer_experiments.py:32:# CPU0 runs hot on Z840 with ethics embedding on GPU1 also generating heat
/home/claude/turboquant-experiments/run_reviewer_experiments.py:33:_thermal = ThermalController(target_temp=80.0, max_threads=6, min_threads=2, verbose=True)
/home/claude/turboquant-experiments/run_reviewer_experiments.py:36:def _apply_thermal_threads():
/home/claude/turboquant-experiments/run_reviewer_experiments.py:37:    """Set PyTorch and OS thread count from thermal controller."""
/home/claude/turboquant-experiments/run_reviewer_experiments.py:38:    n = _thermal.get_threads()
/home/claude/turboquant-experiments/run_reviewer_experiments.py:57:def get_db_embeddings(n=10000, table="chunks"):
/home/claude/turboquant-experiments/run_reviewer_experiments.py:58:    """Fetch n embeddings from the database."""
/home/claude/turboquant-experiments/run_reviewer_experiments.py:60:    log.info(f"Fetching {n} embeddings from {table}...")
/home/claude/turboquant-experiments/run_reviewer_experiments.py:63:    cur.execute(f"SELECT embedding FROM {table} WHERE embedding IS NOT NULL ORDER BY random() LIMIT %s", (n,))
/home/claude/turboquant-experiments/run_reviewer_experiments.py:79:    embeddings = np.array(parsed)
/home/claude/turboquant-experiments/run_reviewer_experiments.py:80:    log.info(f"Fetched {len(embeddings)} embeddings, shape: {embeddings.shape}")
/home/claude/turboquant-experiments/run_reviewer_experiments.py:81:    return embeddings
/home/claude/turboquant-experiments/run_reviewer_experiments.py:90:    cur.execute(f"SELECT content FROM {table} WHERE embedding IS NOT NULL ORDER BY random() LIMIT %s", (n,))
/home/claude/turboquant-experiments/run_reviewer_experiments.py:96:def pca_fit(embeddings, n_components=None):
/home/claude/turboquant-experiments/run_reviewer_experiments.py:97:    """Fit PCA on embeddings, return components and explained variance."""
/home/claude/turboquant-experiments/run_reviewer_experiments.py:100:        n_components = embeddings.shape[1]
/home/claude/turboquant-experiments/run_reviewer_experiments.py:101:    log.info(f"Fitting PCA with {n_components} components on {len(embeddings)} vectors...")
/home/claude/turboquant-experiments/run_reviewer_experiments.py:103:    pca.fit(embeddings)
/home/claude/turboquant-experiments/run_reviewer_experiments.py:107:def pca_truncate_cosine(embeddings, pca, k):
/home/claude/turboquant-experiments/run_reviewer_experiments.py:109:    projected = embeddings @ pca.components_[:k].T  # (N, k)
/home/claude/turboquant-experiments/run_reviewer_experiments.py:115:    norms_orig = np.linalg.norm(embeddings, axis=1, keepdims=True)
/home/claude/turboquant-experiments/run_reviewer_experiments.py:117:    cos_sims = np.sum(embeddings * reconstructed, axis=1) / (
/home/claude/turboquant-experiments/run_reviewer_experiments.py:123:def naive_truncate_cosine(embeddings, k):
/home/claude/turboquant-experiments/run_reviewer_experiments.py:125:    truncated = embeddings.copy()
/home/claude/turboquant-experiments/run_reviewer_experiments.py:128:    norms_orig = np.linalg.norm(embeddings, axis=1, keepdims=True)
/home/claude/turboquant-experiments/run_reviewer_experiments.py:130:    cos_sims = np.sum(embeddings * truncated, axis=1) / (
/home/claude/turboquant-experiments/run_reviewer_experiments.py:136:def recall_at_k(embeddings, pca, dims, k=10, n_queries=200):
/home/claude/turboquant-experiments/run_reviewer_experiments.py:137:    """Compute recall@k for PCA-truncated vs full embeddings."""
/home/claude/turboquant-experiments/run_reviewer_experiments.py:139:    norms = np.linalg.norm(embeddings, axis=1, keepdims=True)
/home/claude/turboquant-experiments/run_reviewer_experiments.py:140:    normed = embeddings / (norms + 1e-10)
/home/claude/turboquant-experiments/run_reviewer_experiments.py:154:    centered = embeddings - pca.mean_
/home/claude/turboquant-experiments/run_reviewer_experiments.py:195:    # GPU0 has ~1.6GB free — E5-large-v2 is ~1.3GB, try GPU first
/home/claude/turboquant-experiments/run_reviewer_experiments.py:196:    _device = "cuda:0" if torch.cuda.is_available() and torch.cuda.mem_get_info(0)[0] > 1_400_000_000 else "cpu"
/home/claude/turboquant-experiments/run_reviewer_experiments.py:197:    log.info(f"Using device: {_device}")
/home/claude/turboquant-experiments/run_reviewer_experiments.py:198:    model = SentenceTransformer("intfloat/e5-large-v2", device=_device)
/home/claude/turboquant-experiments/run_reviewer_experiments.py:199:    log.info(f"E5-large-v2 loaded, dim={model.get_sentence_embedding_dimension()}")
/home/claude/turboquant-experiments/run_reviewer_experiments.py:203:    _apply_thermal_threads()
/home/claude/turboquant-experiments/run_reviewer_experiments.py:205:    e5_embeddings = model.encode(prefixed, batch_size=16, show_progress_bar=True,
