Coding-With-Bashir commited on
Commit
39e8985
·
verified ·
1 Parent(s): d2da114

Upload .\scripts\collect_all.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. .//scripts//collect_all.py +293 -0
.//scripts//collect_all.py ADDED
@@ -0,0 +1,293 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Main data collection script for BwengeAi."""
2
+
3
+ import json
4
+ import logging
5
+ import sys
6
+ from pathlib import Path
7
+
8
+ import yaml
9
+
10
+ PROJECT_ROOT = Path(__file__).resolve().parent.parent
11
+
12
+ sys.path.insert(0, str(PROJECT_ROOT / "src"))
13
+
14
+ from data_collection.huggingface_collector import HuggingfaceCollector
15
+ from data_collection.parallel_corpus_collector import ParallelCorpusCollector
16
+ from data_collection.cc100_oscar_collector import CC100OSCARCollector
17
+ from data_collection.masakhane_collector import MasakhaneCollector
18
+ from data_collection.wikipedia_collector import WikipediaCollector
19
+ from data_collection.igihe_scraper import IgiheScraper
20
+ from data_collection.kigalitoday_scraper import KigaliTodayScraper
21
+ from data_collection.rss_collector import RSSCollector
22
+ from data_collection.wikimedia_collector import WikisourceCollector, WiktionaryCollector
23
+ from data_collection.rbc_collector import RBCCollector
24
+ from data_collection.data_processor import DataProcessor
25
+
26
+ logging.basicConfig(
27
+ level=logging.INFO,
28
+ format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
29
+ )
30
+ logger = logging.getLogger(__name__)
31
+
32
+
33
+ def load_config(config_path: str = None) -> dict:
34
+ """Load configuration."""
35
+ if config_path is None:
36
+ config_path = str(PROJECT_ROOT / "configs/default.yaml")
37
+ with open(config_path, "r", encoding="utf-8") as f:
38
+ return yaml.safe_load(f)
39
+
40
+
41
+ def main():
42
+ """Run data collection pipeline."""
43
+ logger.info("=" * 60)
44
+ logger.info("BwengeAi Data Collection Pipeline")
45
+ logger.info("=" * 60)
46
+
47
+ config = load_config()
48
+ data_config = config.get("data", {})
49
+
50
+ raw_dir = str(PROJECT_ROOT / data_config.get("raw_dir", "data/raw"))
51
+ processed_dir = str(PROJECT_ROOT / data_config.get("processed_dir", "data/processed"))
52
+
53
+ hf_results = []
54
+ parallel_results = []
55
+ cc100_oscar_results = []
56
+ masakhane_results = []
57
+ wiki_results = []
58
+ igihe_results = []
59
+ kt_results = []
60
+ rss_results = []
61
+ wikisource_results = []
62
+ wiktionary_results = []
63
+ rbc_results = []
64
+
65
+ # Step 1: HuggingFace (main datasets)
66
+ logger.info("\n" + "=" * 40)
67
+ logger.info("Step 1: Collecting from Huggingface")
68
+ logger.info("=" * 40)
69
+
70
+ try:
71
+ hf_collector = HuggingfaceCollector(
72
+ output_dir=f"{raw_dir}/huggingface",
73
+ config=data_config,
74
+ )
75
+ hf_results = hf_collector.collect_all()
76
+ except Exception as e:
77
+ logger.error(f"Huggingface collection failed: {e}")
78
+
79
+ # Step 2: Massive parallel corpora (michsethowusu)
80
+ logger.info("\n" + "=" * 40)
81
+ logger.info("Step 2: Collecting massive parallel corpora")
82
+ logger.info("=" * 40)
83
+
84
+ try:
85
+ parallel_collector = ParallelCorpusCollector(
86
+ output_dir=f"{raw_dir}/parallel",
87
+ config=data_config,
88
+ )
89
+ parallel_results = parallel_collector.collect_all()
90
+ except Exception as e:
91
+ logger.error(f"Parallel corpus collection failed: {e}")
92
+
93
+ # Step 3: CC-100 and OSCAR monolingual
94
+ logger.info("\n" + "=" * 40)
95
+ logger.info("Step 3: Collecting CC-100 and OSCAR monolingual corpora")
96
+ logger.info("=" * 40)
97
+
98
+ try:
99
+ cc100_collector = CC100OSCARCollector(
100
+ output_dir=f"{raw_dir}/cc100_oscar",
101
+ config=data_config,
102
+ )
103
+ cc100_oscar_results = cc100_collector.collect_all(languages=["rw"])
104
+ except Exception as e:
105
+ logger.error(f"CC-100/OSCAR collection failed: {e}")
106
+
107
+ # Step 4: Masakhane benchmarks
108
+ logger.info("\n" + "=" * 40)
109
+ logger.info("Step 4: Collecting Masakhane benchmark datasets")
110
+ logger.info("=" * 40)
111
+
112
+ try:
113
+ masakhane_collector = MasakhaneCollector(
114
+ output_dir=f"{raw_dir}/masakhane",
115
+ config=data_config,
116
+ )
117
+ masakhane_results = masakhane_collector.collect_all()
118
+ except Exception as e:
119
+ logger.error(f"Masakhane collection failed: {e}")
120
+
121
+ # Step 5: Wikipedia (API + Dump)
122
+ logger.info("\n" + "=" * 40)
123
+ logger.info("Step 5: Collecting from Wikipedia")
124
+ logger.info("=" * 40)
125
+
126
+ try:
127
+ wiki_collector = WikipediaCollector(
128
+ output_dir=f"{raw_dir}/wikipedia",
129
+ config=data_config,
130
+ )
131
+
132
+ stats = wiki_collector.get_site_stats()
133
+ logger.info(f"Wikipedia stats: {stats}")
134
+
135
+ wiki_results = wiki_collector.collect_via_api()
136
+
137
+ dump_path = wiki_collector.download_dump()
138
+ if dump_path:
139
+ dump_articles = wiki_collector.parse_dump(dump_path)
140
+ logger.info(f"Parsed {len(dump_articles)} articles from dump")
141
+ except Exception as e:
142
+ logger.error(f"Wikipedia collection failed: {e}")
143
+
144
+ # Step 6: Igihe
145
+ logger.info("\n" + "=" * 40)
146
+ logger.info("Step 6: Collecting from Igihe (if permitted)")
147
+ logger.info("=" * 40)
148
+
149
+ try:
150
+ igihe_config = data_config.get("igihe", {})
151
+ contact_email = igihe_config.get("contact_email", "info@igihe.com")
152
+ logger.info(f"NOTE: Igihe content is copyrighted.")
153
+ logger.info(f"Contact {contact_email} for data licensing.")
154
+
155
+ igihe_scraper = IgiheScraper(
156
+ output_dir=f"{raw_dir}/igihe",
157
+ config=data_config,
158
+ )
159
+ igihe_results = igihe_scraper.collect_all()
160
+ except Exception as e:
161
+ logger.warning(f"Igihe collection failed: {e}")
162
+
163
+ # Step 7: Kigali Today
164
+ logger.info("\n" + "=" * 40)
165
+ logger.info("Step 7: Collecting from Kigali Today")
166
+ logger.info("=" * 40)
167
+
168
+ try:
169
+ kt_scraper = KigaliTodayScraper(
170
+ output_dir=f"{raw_dir}/kigalitoday",
171
+ config=data_config,
172
+ )
173
+ kt_results = kt_scraper.collect_all()
174
+ except Exception as e:
175
+ logger.warning(f"Kigali Today collection failed: {e}")
176
+
177
+ # Step 8: RSS Feeds (New Times)
178
+ logger.info("\n" + "=" * 40)
179
+ logger.info("Step 8: Collecting from RSS feeds (New Times)")
180
+ logger.info("=" * 40)
181
+
182
+ try:
183
+ rss_collector = RSSCollector(
184
+ output_dir=f"{raw_dir}/newtimes_rss",
185
+ config=data_config,
186
+ )
187
+ rss_results = rss_collector.collect_all()
188
+ except Exception as e:
189
+ logger.warning(f"RSS collection failed: {e}")
190
+
191
+ # Step 9: Wikisource
192
+ logger.info("\n" + "=" * 40)
193
+ logger.info("Step 9: Collecting from Wikisource")
194
+ logger.info("=" * 40)
195
+
196
+ try:
197
+ ws_collector = WikisourceCollector(
198
+ output_dir=f"{raw_dir}/wikisource",
199
+ config=data_config,
200
+ )
201
+ wikisource_results = ws_collector.collect_all()
202
+ except Exception as e:
203
+ logger.warning(f"Wikisource collection failed: {e}")
204
+
205
+ # Step 10: Wiktionary
206
+ logger.info("\n" + "=" * 40)
207
+ logger.info("Step 10: Collecting from Wiktionary")
208
+ logger.info("=" * 40)
209
+
210
+ try:
211
+ wt_collector = WiktionaryCollector(
212
+ output_dir=f"{raw_dir}/wiktionary",
213
+ config=data_config,
214
+ )
215
+ wiktionary_results = wt_collector.collect_all()
216
+ except Exception as e:
217
+ logger.warning(f"Wiktionary collection failed: {e}")
218
+
219
+ # Step 11: RBC
220
+ logger.info("\n" + "=" * 40)
221
+ logger.info("Step 11: Collecting from RBC")
222
+ logger.info("=" * 40)
223
+
224
+ try:
225
+ rbc_collector = RBCCollector(
226
+ output_dir=f"{raw_dir}/rbc",
227
+ config=data_config,
228
+ )
229
+ rbc_results = rbc_collector.collect_all()
230
+ except Exception as e:
231
+ logger.warning(f"RBC collection failed: {e}")
232
+
233
+ # Step 12: Process and combine
234
+ logger.info("\n" + "=" * 40)
235
+ logger.info("Step 12: Processing and combining data")
236
+ logger.info("=" * 40)
237
+
238
+ processor = DataProcessor(
239
+ raw_dir=raw_dir,
240
+ processed_dir=processed_dir,
241
+ )
242
+
243
+ import shutil
244
+ seen_names: set[str] = set()
245
+ for jsonl_file in Path(raw_dir).rglob("*.jsonl"):
246
+ if jsonl_file.parent == Path(raw_dir):
247
+ continue
248
+ parent_dir = jsonl_file.parent.name
249
+ prefixed_name = f"{parent_dir}_{jsonl_file.name}"
250
+ dest = Path(raw_dir) / prefixed_name
251
+ if prefixed_name not in seen_names:
252
+ shutil.copy2(jsonl_file, dest)
253
+ seen_names.add(prefixed_name)
254
+
255
+ processing_summary = processor.process_all()
256
+
257
+ logger.info("\n" + "=" * 60)
258
+ logger.info("Data Collection Complete!")
259
+ logger.info("=" * 60)
260
+
261
+ summary = {
262
+ "huggingface_datasets": len(hf_results),
263
+ "huggingface_successful": sum(1 for r in hf_results if r.get("status") == "success"),
264
+ "parallel_datasets": len(parallel_results),
265
+ "parallel_successful": sum(1 for r in parallel_results if r.get("status") == "success"),
266
+ "parallel_total_rows": sum(r.get("rows", 0) for r in parallel_results if r.get("status") == "success"),
267
+ "cc100_oscar_datasets": len(cc100_oscar_results),
268
+ "cc100_oscar_successful": sum(1 for r in cc100_oscar_results if r.get("status") == "success"),
269
+ "masakhane_datasets": len(masakhane_results),
270
+ "masakhane_successful": sum(1 for r in masakhane_results if r.get("status") == "success"),
271
+ "wikipedia_articles": len(wiki_results),
272
+ "igihe_articles": len(igihe_results),
273
+ "kigalitoday_articles": len(kt_results),
274
+ "newtimes_rss_articles": len(rss_results),
275
+ "wikisource_texts": len(wikisource_results),
276
+ "wiktionary_entries": len(wiktionary_results),
277
+ "rbc_articles": len(rbc_results),
278
+ "processing": processing_summary,
279
+ }
280
+
281
+ summary_path = Path(processed_dir) / "collection_summary.json"
282
+ with open(summary_path, "w", encoding="utf-8") as f:
283
+ json.dump(summary, f, indent=2, ensure_ascii=False)
284
+
285
+ logger.info(f"Summary saved to {summary_path}")
286
+ logger.info(f"Total tokens: {processing_summary.get('total_tokens', 0):,}")
287
+ logger.info(f"Total training samples: {processing_summary.get('total_training_samples', 0):,}")
288
+ logger.info(f"Total instruction samples: {processing_summary.get('total_instruction', 0):,}")
289
+ logger.info(f"Total chat samples: {processing_summary.get('total_chat', 0):,}")
290
+
291
+
292
+ if __name__ == "__main__":
293
+ main()