File size: 4,959 Bytes
4c67792 2d61d41 4c67792 8b2d098 4c67792 2d61d41 4c67792 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | """
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}"
|