Coding-With-Bashir commited on
Commit
68a8e59
·
verified ·
1 Parent(s): 94aa00a

Upload .\src\data_collection\parallel_corpus_collector.py with huggingface_hub

Browse files
.//src//data_collection//parallel_corpus_collector.py ADDED
@@ -0,0 +1,111 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Parallel corpus collector for massive multilingual datasets."""
2
+
3
+ import json
4
+ import logging
5
+ from pathlib import Path
6
+ from typing import Any
7
+
8
+ from datasets import load_dataset
9
+
10
+ logger = logging.getLogger(__name__)
11
+
12
+
13
+ class ParallelCorpusCollector:
14
+ """Collects parallel translation corpora from HuggingFace."""
15
+
16
+ def __init__(self, output_dir: str, config: dict[str, Any]):
17
+ self.output_dir = Path(output_dir)
18
+ self.output_dir.mkdir(parents=True, exist_ok=True)
19
+ self.config = config
20
+
21
+ def collect_dataset(self, name: str, split: str = "train", max_rows: int | None = None) -> dict[str, Any]:
22
+ """Download and save a parallel dataset using streaming."""
23
+ safe_name = name.replace("/", "_")
24
+ output_path = self.output_dir / f"{safe_name}.jsonl"
25
+ done_marker = self.output_dir / f"{safe_name}.jsonl.done"
26
+
27
+ if done_marker.exists():
28
+ try:
29
+ row_count = int(done_marker.read_text().strip())
30
+ logger.info(f"Already collected: {name} ({row_count} rows), skipping")
31
+ return {
32
+ "name": name,
33
+ "split": split,
34
+ "rows": row_count,
35
+ "output_path": str(output_path),
36
+ "status": "success",
37
+ }
38
+ except (ValueError, OSError):
39
+ pass
40
+
41
+ logger.info(f"Collecting parallel corpus: {name} (split: {split})")
42
+
43
+ try:
44
+ dataset = load_dataset(name, split=split, streaming=True)
45
+
46
+ count = 0
47
+ with open(output_path, "w", encoding="utf-8") as f:
48
+ for item in dataset:
49
+ f.write(json.dumps(item, ensure_ascii=False) + "\n")
50
+ count += 1
51
+ if max_rows and count >= max_rows:
52
+ break
53
+ if count % 100_000 == 0:
54
+ logger.info(f" {name}: {count:,} rows collected...")
55
+
56
+ done_marker.write_text(str(count))
57
+
58
+ return {
59
+ "name": name,
60
+ "split": split,
61
+ "rows": count,
62
+ "output_path": str(output_path),
63
+ "status": "success",
64
+ }
65
+
66
+ except Exception as e:
67
+ logger.error(f"Failed to collect {name}: {e}")
68
+ return {"name": name, "split": split, "status": "failed", "error": str(e)}
69
+
70
+ def collect_all(self) -> list[dict[str, Any]]:
71
+ """Collect all parallel corpora from config."""
72
+ datasets_config = self.config.get("huggingface", {}).get("datasets", [])
73
+
74
+ parallel_keywords = ["sentence-pairs", "parallel", "bitext", "ccmatrix", "nllb"]
75
+ parallel_datasets = []
76
+ seen_names = set()
77
+
78
+ for ds in datasets_config:
79
+ name = ds.get("name", "")
80
+ desc = ds.get("description", "").lower()
81
+ if name in seen_names:
82
+ continue
83
+ if any(kw in name.lower() or kw in desc for kw in parallel_keywords):
84
+ if "michsethowusu" in name or "sentence-pairs" in name.lower():
85
+ parallel_datasets.append(name)
86
+ seen_names.add(name)
87
+
88
+ logger.info(f"Found {len(parallel_datasets)} parallel datasets from config")
89
+
90
+ results = []
91
+ for name in parallel_datasets:
92
+ result = self.collect_dataset(name)
93
+ results.append(result)
94
+
95
+ successful = sum(1 for r in results if r["status"] == "success")
96
+ failed = sum(1 for r in results if r["status"] == "failed")
97
+ total_rows = sum(r.get("rows", 0) for r in results if r["status"] == "success")
98
+
99
+ summary = {
100
+ "total_datasets": len(results),
101
+ "successful": successful,
102
+ "failed": failed,
103
+ "total_rows": total_rows,
104
+ }
105
+
106
+ summary_path = self.output_dir / "parallel_summary.json"
107
+ with open(summary_path, "w", encoding="utf-8") as f:
108
+ json.dump(summary, f, indent=2, ensure_ascii=False)
109
+
110
+ logger.info(f"Parallel corpus collection: {summary}")
111
+ return results