kernel-lora-v2.0 / scripts /build_rag_index_v20.py
gaowanlong's picture
Add v2.0 merged index builder
e86c28a verified
Raw
History Blame Contribute Delete
3.38 kB
#!/usr/bin/env python3
"""
Build RAG index v2.0 — merged index combining:
1. v1 embedding index (9,919 doc/kconfig/qa chunks)
2. Source code function implementations (3,894 functions)
3. Documentation/ RST files (1,633 chunks)
All with sentence embeddings (all-MiniLM-L6-v2).
Usage: python scripts/build_rag_index_v20.py
"""
import json, pickle, time
from pathlib import Path
PROJECT_ROOT = Path(__file__).resolve().parent.parent
RAG_INDEX_DIR = PROJECT_ROOT / "data" / "rag_index_v20"
def main():
chunks = []
# 1) v1 embedding index (best performing so far)
v1_path = PROJECT_ROOT / "data" / "rag_index_emb" / "chunks.jsonl"
if v1_path.exists():
with open(v1_path) as f:
for line in f:
c = json.loads(line)
c["_source_group"] = "v1_doc"
chunks.append(c)
print(f"v1 doc chunks: {sum(1 for c in chunks if c['_source_group']=='v1_doc')}")
# 2) Source code functions
src_path = PROJECT_ROOT / "data" / "rag_index_source_emb" / "chunks.jsonl"
if src_path.exists():
with open(src_path) as f:
for line in f:
c = json.loads(line)
c["_source_group"] = "source_code"
chunks.append(c)
print(f"Source code chunks: {sum(1 for c in chunks if c['_source_group']=='source_code')}")
print(f"\nTotal chunks: {len(chunks)}")
# Deduplicate by content hash
seen = set()
unique_chunks = []
for c in chunks:
h = hash(c.get("content", "")[:300])
if h not in seen:
seen.add(h)
unique_chunks.append(c)
print(f"After dedup: {len(unique_chunks)} chunks")
# Build embeddings
print("\nLoading embedding model (all-MiniLM-L6-v2)...", flush=True)
from sentence_transformers import SentenceTransformer
model = SentenceTransformer("all-MiniLM-L6-v2")
print(" Model loaded", flush=True)
texts = [c["content"] for c in unique_chunks]
print(f"Encoding {len(texts)} chunks...", flush=True)
start = time.time()
embeddings = model.encode(texts, show_progress_bar=True, batch_size=64)
elapsed = time.time() - start
print(f" Encoded {len(embeddings)} embeddings in {elapsed:.1f}s")
print(f" Embedding dimension: {embeddings.shape[1]}")
# Save
RAG_INDEX_DIR.mkdir(parents=True, exist_ok=True)
with open(RAG_INDEX_DIR / "chunks.jsonl", "w") as f:
for c in unique_chunks:
f.write(json.dumps(c, ensure_ascii=False) + "\n")
with open(RAG_INDEX_DIR / "embeddings.pkl", "wb") as f:
pickle.dump(embeddings, f)
with open(RAG_INDEX_DIR / "model_name.txt", "w") as f:
f.write("all-MiniLM-L6-v2")
# Stats
from collections import Counter
type_counts = Counter(c.get("type", "unknown") for c in unique_chunks)
source_counts = Counter(c.get("_source_group", "unknown") for c in unique_chunks)
print(f"\nIndex saved to {RAG_INDEX_DIR}/")
print(f" chunks.jsonl: {len(unique_chunks)} chunks")
print(f" embeddings.pkl: {embeddings.shape}")
print(f"\nBy source group:")
for k, v in source_counts.most_common():
print(f" {k}: {v}")
print(f"\nBy type:")
for k, v in type_counts.most_common():
print(f" {k}: {v}")
if __name__ == "__main__":
main()