Coding-With-Bashir commited on
Commit
c896f79
·
verified ·
1 Parent(s): c4ee137

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

Browse files
.//src//data_collection//cc100_oscar_collector.py ADDED
@@ -0,0 +1,185 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """CC-100 and OSCAR massive monolingual corpus collector."""
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
+ CC100_VALID_LANGUAGES = {
13
+ "am", "ar", "bg", "bn", "br", "bs", "ca", "cs", "cy", "da", "de",
14
+ "el", "en", "eo", "es", "et", "eu", "fa", "fi", "fr", "fy", "ga",
15
+ "gd", "gl", "gu", "ha", "he", "hi", "hr", "hu", "hy", "id", "is",
16
+ "it", "ja", "jv", "ka", "kk", "km", "kn", "ko", "ku", "ky", "la",
17
+ "lt", "lv", "mg", "mk", "ml", "mn", "mr", "ms", "my", "ne", "nl",
18
+ "no", "om", "or", "pa", "pl", "ps", "pt", "ro", "ru", "sa", "sd",
19
+ "si", "sk", "sl", "so", "sq", "sr", "su", "sv", "sw", "ta", "te",
20
+ "th", "tl", "tr", "ug", "uk", "ur", "uz", "vi", "vo", "xh", "yi",
21
+ "yo", "zh", "zu",
22
+ }
23
+
24
+ OSCAR_VALID_LANGUAGES = {
25
+ "ab", "af", "am", "ar", "as", "az", "be", "bg", "bn", "br", "bs",
26
+ "ca", "cs", "cy", "da", "de", "el", "en", "eo", "es", "et", "eu",
27
+ "fa", "fi", "fr", "fy", "ga", "gd", "gl", "gu", "ha", "he", "hi",
28
+ "hr", "hu", "hy", "id", "is", "it", "ja", "jv", "ka", "kk", "km",
29
+ "kn", "ko", "ku", "ky", "la", "lt", "lv", "mg", "mk", "ml", "mn",
30
+ "mr", "ms", "my", "ne", "nl", "no", "om", "or", "pa", "pl", "ps",
31
+ "pt", "ro", "ru", "sa", "sd", "si", "sk", "sl", "so", "sq", "sr",
32
+ "su", "sv", "sw", "ta", "te", "th", "tl", "tr", "ug", "uk", "ur",
33
+ "uz", "vi", "vo", "xh", "yi", "yo", "zh", "zu",
34
+ }
35
+
36
+
37
+ class CC100OSCARCollector:
38
+ """Collects massive monolingual corpora from CC-100 and OSCAR."""
39
+
40
+ def __init__(self, output_dir: str, config: dict[str, Any]):
41
+ self.output_dir = Path(output_dir)
42
+ self.output_dir.mkdir(parents=True, exist_ok=True)
43
+ self.config = config
44
+
45
+ def collect_cc100(self, language: str = "rw", max_rows: int | None = None) -> dict[str, Any]:
46
+ """Collect CC-100 data for a specific language."""
47
+ logger.info(f"Collecting CC-100 for language: {language}")
48
+
49
+ if language not in CC100_VALID_LANGUAGES:
50
+ logger.warning(
51
+ f"CC-100 does not support language '{language}'. "
52
+ f"Supported: {sorted(CC100_VALID_LANGUAGES)}. Skipping."
53
+ )
54
+ return {
55
+ "name": f"cc100_{language}",
56
+ "language": language,
57
+ "rows": 0,
58
+ "status": "skipped",
59
+ "error": f"Language '{language}' not in CC-100 dataset",
60
+ }
61
+
62
+ done_marker = self.output_dir / f"cc100_{language}.jsonl.done"
63
+ output_path = self.output_dir / f"cc100_{language}.jsonl"
64
+
65
+ if done_marker.exists():
66
+ logger.info(f"CC-100 {language} already collected, skipping")
67
+ return {
68
+ "name": f"cc100_{language}",
69
+ "language": language,
70
+ "rows": sum(1 for _ in open(output_path, encoding="utf-8")),
71
+ "output_path": str(output_path),
72
+ "status": "success",
73
+ }
74
+
75
+ try:
76
+ dataset = load_dataset("statmt/cc100", language, split="train", streaming=True)
77
+
78
+ count = 0
79
+ with open(output_path, "w", encoding="utf-8") as f:
80
+ for item in dataset:
81
+ f.write(json.dumps(item, ensure_ascii=False) + "\n")
82
+ count += 1
83
+ if max_rows and count >= max_rows:
84
+ break
85
+ if count % 100000 == 0:
86
+ logger.info(f" CC-100 {language}: {count} rows...")
87
+
88
+ done_marker.write_text(str(count))
89
+ return {
90
+ "name": f"cc100_{language}",
91
+ "language": language,
92
+ "rows": count,
93
+ "output_path": str(output_path),
94
+ "status": "success",
95
+ }
96
+
97
+ except Exception as e:
98
+ logger.error(f"Failed to collect CC-100 {language}: {e}")
99
+ return {"name": f"cc100_{language}", "status": "failed", "error": str(e)}
100
+
101
+ def collect_oscar(self, language: str = "rw", max_rows: int | None = None) -> dict[str, Any]:
102
+ """Collect OSCAR data for a specific language."""
103
+ logger.info(f"Collecting OSCAR for language: {language}")
104
+
105
+ if language not in OSCAR_VALID_LANGUAGES:
106
+ logger.warning(
107
+ f"OSCAR-2201 does not support language '{language}'. "
108
+ f"Supported: {sorted(OSCAR_VALID_LANGUAGES)}. Skipping."
109
+ )
110
+ return {
111
+ "name": f"oscar_{language}",
112
+ "language": language,
113
+ "rows": 0,
114
+ "status": "skipped",
115
+ "error": f"Language '{language}' not in OSCAR-2201 dataset",
116
+ }
117
+
118
+ done_marker = self.output_dir / f"oscar_{language}.jsonl.done"
119
+ output_path = self.output_dir / f"oscar_{language}.jsonl"
120
+
121
+ if done_marker.exists():
122
+ logger.info(f"OSCAR {language} already collected, skipping")
123
+ return {
124
+ "name": f"oscar_{language}",
125
+ "language": language,
126
+ "rows": sum(1 for _ in open(output_path, encoding="utf-8")),
127
+ "output_path": str(output_path),
128
+ "status": "success",
129
+ }
130
+
131
+ try:
132
+ dataset = load_dataset("oscar-corpus/OSCAR-2201", language, split="train", streaming=True)
133
+
134
+ count = 0
135
+ with open(output_path, "w", encoding="utf-8") as f:
136
+ for item in dataset:
137
+ f.write(json.dumps(item, ensure_ascii=False) + "\n")
138
+ count += 1
139
+ if max_rows and count >= max_rows:
140
+ break
141
+ if count % 100000 == 0:
142
+ logger.info(f" OSCAR {language}: {count} rows...")
143
+
144
+ done_marker.write_text(str(count))
145
+ return {
146
+ "name": f"oscar_{language}",
147
+ "language": language,
148
+ "rows": count,
149
+ "output_path": str(output_path),
150
+ "status": "success",
151
+ }
152
+
153
+ except Exception as e:
154
+ logger.error(f"Failed to collect OSCAR {language}: {e}")
155
+ return {"name": f"oscar_{language}", "status": "failed", "error": str(e)}
156
+
157
+ def collect_all(self, languages: list[str] | None = None) -> list[dict[str, Any]]:
158
+ """Collect all configured monolingual corpora."""
159
+ if languages is None:
160
+ languages = ["rw"]
161
+
162
+ results = []
163
+ for lang in languages:
164
+ results.append(self.collect_cc100(lang))
165
+ results.append(self.collect_oscar(lang))
166
+
167
+ successful = sum(1 for r in results if r["status"] == "success")
168
+ skipped = sum(1 for r in results if r["status"] == "skipped")
169
+ failed = sum(1 for r in results if r["status"] == "failed")
170
+ total_rows = sum(r.get("rows", 0) for r in results if r["status"] == "success")
171
+
172
+ summary = {
173
+ "total": len(results),
174
+ "successful": successful,
175
+ "skipped": skipped,
176
+ "failed": failed,
177
+ "total_rows": total_rows,
178
+ }
179
+
180
+ summary_path = self.output_dir / "cc100_oscar_summary.json"
181
+ with open(summary_path, "w", encoding="utf-8") as f:
182
+ json.dump(summary, f, indent=2, ensure_ascii=False)
183
+
184
+ logger.info(f"CC-100/OSCAR collection: {summary}")
185
+ return results