-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_data_processor.py
More file actions
174 lines (146 loc) · 5.71 KB
/
Copy pathtest_data_processor.py
File metadata and controls
174 lines (146 loc) · 5.71 KB
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
#!/usr/bin/env python3
"""
Test data processor - processes only a few parquet files for quick testing
"""
import sqlite3
import pickle
import json
from pathlib import Path
from typing import List, Dict, Any
import pandas as pd
import fastparquet as fp
import faiss
import numpy as np
from sentence_transformers import SentenceTransformer
from tqdm import tqdm
import re
import os
import gc
# Test database paths
BASE_DIR = Path(__file__).parent
DATA_DIR = BASE_DIR / "data"
FINEWIKI_DIR = BASE_DIR / "finewiki" / "data" / "enwiki"
TEST_DB_PATH = DATA_DIR / "test_docs.sqlite"
# Configuration
CHUNK_SIZE = 1000
CHUNK_OVERLAP = 200
EMBEDDING_MODEL = "BAAI/bge-m3"
EMBEDDING_DIM = 1024
def process_test_data():
"""Process just 3 parquet files for testing"""
print("🧪 Processing test data (3 files only)...")
# Get only the first 3 parquet files
parquet_files = sorted(list(FINEWIKI_DIR.glob("*.parquet")))[:3]
print(f"Processing {len(parquet_files)} files: {[f.name for f in parquet_files]}")
all_chunks = []
# Process files sequentially
for file_path in tqdm(parquet_files, desc="Processing files"):
try:
print(f"\nProcessing {file_path.name}...")
# Read parquet file
df = fp.ParquetFile(str(file_path)).to_pandas()
file_chunks = []
for _, row in df.iterrows():
# Skip very short articles
if len(row['text']) < 100:
continue
# Create chunks
text = re.sub(r'\s+', ' ', row['text'].strip())
chunks = []
start = 0
chunk_id = 0
while start < len(text):
end = min(start + CHUNK_SIZE, len(text))
chunk_text = text[start:end]
# Try to break at sentence boundaries
if end < len(text):
last_period = chunk_text.rfind('.')
last_newline = chunk_text.rfind('\n')
break_point = max(last_period, last_newline)
if break_point > start + CHUNK_SIZE // 2:
chunk_text = chunk_text[:break_point + 1]
end = start + break_point + 1
# Create unique ID
import time
unique_id = f"{row['page_id']}_{chunk_id}_{int(time.time() * 1000000)}"
chunk = {
'id': unique_id,
'text': chunk_text,
'title': row['title'],
'page_id': row['page_id'],
'start_pos': start,
'end_pos': end,
'url': row['url'],
'date_modified': row['date_modified'],
'wikidata_id': row['wikidata_id'],
'infoboxes': row['infoboxes'],
'has_math': row['has_math']
}
chunks.append(chunk)
start = max(start + CHUNK_SIZE - CHUNK_OVERLAP, end)
chunk_id += 1
file_chunks.extend(chunks)
all_chunks.extend(file_chunks)
print(f"✓ Processed {file_path.name}: {len(file_chunks)} chunks")
except Exception as e:
print(f"✗ Error processing {file_path}: {e}")
continue
print(f"\n✅ Created {len(all_chunks)} total chunks")
# Create SQLite database
print("\n📦 Creating SQLite database...")
conn = sqlite3.connect(TEST_DB_PATH)
cursor = conn.cursor()
# Create FTS5 virtual table
cursor.execute("""
CREATE VIRTUAL TABLE IF NOT EXISTS chunks_fts USING fts5(
text,
title,
content='chunks',
content_rowid='rowid'
)
""")
# Create regular table for metadata
cursor.execute("""
CREATE TABLE IF NOT EXISTS chunks (
id TEXT PRIMARY KEY,
text TEXT,
title TEXT,
page_id INTEGER,
url TEXT,
date_modified TEXT,
wikidata_id TEXT,
infoboxes TEXT,
has_math BOOLEAN,
start_pos INTEGER,
end_pos INTEGER
)
""")
# Insert chunks
id_mapping = {}
for i, chunk in enumerate(tqdm(all_chunks, desc="Indexing chunks")):
try:
cursor.execute("""
INSERT INTO chunks (
id, text, title, page_id, url, date_modified,
wikidata_id, infoboxes, has_math, start_pos, end_pos
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
""", (
chunk['id'], chunk['text'], chunk['title'], chunk['page_id'],
chunk['url'], chunk['date_modified'], chunk['wikidata_id'],
chunk['infoboxes'], chunk['has_math'], chunk['start_pos'], chunk['end_pos']
))
# Insert into FTS5
cursor.execute("""
INSERT INTO chunks_fts (text, title) VALUES (?, ?)
""", (chunk['text'], chunk['title']))
# Store mapping
id_mapping[i] = chunk['id']
except sqlite3.IntegrityError:
continue
conn.commit()
conn.close()
print(f"✅ SQLite test database created: {TEST_DB_PATH}")
print(f" Total chunks indexed: {len(all_chunks):,}")
return len(all_chunks)
if __name__ == "__main__":
process_test_data()