QAFD-RAG / src /passage_entity /config.py
tarzanagh's picture
Set alpha=1.5
8b2d098 verified
Raw
History Blame Contribute Delete
4.96 kB
"""
Configuration dataclass for the passage-entity KG pipeline in QAFD-RAG.
Combines passage-entity BaseConfig fields with QAFD algorithm parameters.
"""
from dataclasses import dataclass, field
from typing import Optional, Literal
@dataclass
class PassageEntityConfig:
"""Unified configuration for indexing, retrieval, and QAFD."""
# ── LLM ────────────────────────────────────────────────────────────────
llm_model: str = "gpt-4o-mini"
llm_base_url: str = "https://api.openai.com/v1"
llm_api_key: str = "" # falls back to OPENAI_API_KEY env
max_new_tokens: Optional[int] = 2048
temperature: float = 0.0
# ── Embedding ──────────────────────────────────────────────────────────
embedding_model_key: str = "nvidia-nv-embed-v2" # key in QAFD-RAG registry
embedding_batch_size: int = 16
# ── Dataset / paths ────────────────────────────────────────────────────
dataset: Optional[str] = None # musique, hotpotqa, 2wikimultihopqa
save_dir: str = "outputs"
force_index_from_scratch: bool = False
force_openie_from_scratch: bool = False
save_openie: bool = True
# ── Graph construction ─────────────────────────────────────────────────
is_directed_graph: bool = False
synonymy_edge_topk: int = 2047
synonymy_edge_query_batch_size: int = 1000
synonymy_edge_key_batch_size: int = 10000
synonymy_edge_sim_threshold: float = 0.8
# ── Retrieval ──────────────────────────────────────────────────────────
linking_top_k: int = 10
retrieval_top_k: int = 200
passage_node_weight: float = 0.05
damping: float = 0.5
# ── QA ─────────────────────────────────────────────────────────────────
qa_top_k: int = 5
# ── QAFD algorithm parameters ──────────────────────────────────────────
use_qafd: bool = True
qafd_alpha: float = 1.5
qafd_epsilon: float = 0.01
qafd_max_iterations: int = 500
qafd_weight_scheme: str = "multiply" # "multiply", "add", "original"
qafd_use_node_degree: bool = True
qafd_step_size: float = 0.2
qafd_random_seed: int = 42
# ── Query-aware enhancements (all default = original behaviour) ────────
sim_mode: str = "normalized" # Similarity contrast: "normalized", "relu", "relu_sq"
qa_sink_gamma: float = 0.0 # Query-aware sink capacity (0=off)
qa_warm_delta: float = 0.0 # Query-aware seed bias (0=off)
qa_warm_walk: bool = False # Use QA edge weights in warm-start walk
qa_warm_steps: int = 2 # Number of warm-start steps (default 2)
qa_accum_gamma: float = 0.0 # Query-aware x accumulation boost (0=off)
qa_post_lambda: float = 0.0 # Post-diffusion reranking (0=off)
batch_push: bool = False # Batch push-relabel (process all excess nodes per iter)
# ── Reranker ───────────────────────────────────────────────────────────
rerank_dspy_file_path: Optional[str] = None # path to DSPy JSON; None β†’ built-in prompt
def __post_init__(self):
if self.save_dir == "outputs" and self.dataset:
self.save_dir = f"outputs/{self.dataset}"
@property
def working_dir(self) -> str:
"""Model-specific sub-directory under save_dir.
Also checks kg/multihop/ for pre-downloaded KGs from HuggingFace.
If found there, uses that path instead of outputs/.
"""
import os
llm_label = self.llm_model.replace("/", "_")
emb_label = self.embedding_model_key.replace("/", "_")
# Check HuggingFace download location (kg/multihop/{llm}_{emb}_{dataset}/)
if self.dataset:
for task_dir in ["multihop", "ultradomain"]:
hf_path = os.path.join("kg", task_dir, f"{llm_label}_{emb_label}_{self.dataset}")
if os.path.isdir(hf_path) and os.path.exists(os.path.join(hf_path, "graph.pickle")):
return hf_path
return f"{self.save_dir}/{llm_label}_{emb_label}"