ViuAI commited on
Commit
06e08fa
·
verified ·
1 Parent(s): 804855f

fix: probe OOM reserve 4GB + expandable_segments + natural-mode stream shuffle (Hindi-only trap)

Browse files
.gitattributes CHANGED
@@ -4,3 +4,5 @@
4
  *.onnx filter=lfs diff=lfs merge=lfs -text
5
  tokenizer/outputs/*.json filter=lfs diff=lfs merge=lfs -text
6
  data/processed/* filter=lfs diff=lfs merge=lfs -text
 
 
 
4
  *.onnx filter=lfs diff=lfs merge=lfs -text
5
  tokenizer/outputs/*.json filter=lfs diff=lfs merge=lfs -text
6
  data/processed/* filter=lfs diff=lfs merge=lfs -text
7
+ data/processed_spiritual/train-p1p2_boost_sanatan_dharma_epics_upanishads-00000.parquet filter=lfs diff=lfs merge=lfs -text
8
+ data/processed_spiritual/train-p1p2_boost_sanatan_dharma_gita_ramayana-00000.parquet filter=lfs diff=lfs merge=lfs -text
data/processed_spiritual/train-p1p2_boost_hinduism_philosophy_qa-00000.parquet ADDED
Binary file (902 Bytes). View file
 
data/processed_spiritual/train-p1p2_boost_sanatan_dharma_epics_upanishads-00000.parquet ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:69bfd314261e8d7020c52aecfb7ad396f183c7a8429465ac65d548e7c13c9436
3
+ size 1853597
data/processed_spiritual/train-p1p2_boost_sanatan_dharma_gita_ramayana-00000.parquet ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:b2205306ac4cbfde6b7b25086cc3c72c8646081325fd1f27269f0c4e994ec46f
3
+ size 8458680
data/scripts/collect_spiritual_and_boost_corpus.py ADDED
@@ -0,0 +1,515 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Sanatan Dharma, Epics, Hinglish & Reasoning Data Collector
3
+ ==========================================================
4
+ Collects authentic open-source Hugging Face datasets:
5
+ 1. Shreemad Bhagavad Gita (verses with Sanskrit & Hindi anuvad)
6
+ 2. Shri Ramcharitmanas & Valmiki Ramayana (all Kandas & shlokas with Hindi translations)
7
+ 3. Mahabharata, Upanishads, Puranas, Chanakya Niti, and Charak Samhita
8
+ 4. Hinduism Philosophy & Scripture Q&A
9
+ 5. Chatbot Arena Hinglish Conversations
10
+ 6. GSM8k Hindi Math Word Problems & CoT
11
+ 7. Indian History & GK Hindi Q&A
12
+
13
+ All data is standardized into the unified 5-column schema:
14
+ ['text', 'lang', 'source', 'domain', 'safety_tag']
15
+ and exported as clean Parquet files for upload to ViuAI/viu-mini-raw-pretrain.
16
+ """
17
+
18
+ import os
19
+ import sys
20
+ import json
21
+ import time
22
+ import argparse
23
+ from pathlib import Path
24
+ import pandas as pd
25
+ import pyarrow as pa
26
+ import pyarrow.parquet as pq
27
+ from huggingface_hub import HfApi, hf_hub_download
28
+
29
+ # Enforce pure English logging
30
+ print("======================================================================")
31
+ print("Starting Sanatan Dharma & Knowledge Corpus Collector (ViuMini-MoE-242M)")
32
+ print("======================================================================")
33
+
34
+ DATA_REPO = "ViuAI/viu-mini-raw-pretrain"
35
+ OUTPUT_DIR = Path("data/processed_spiritual")
36
+ OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
37
+
38
+ SCHEMA = pa.schema([
39
+ ("text", pa.string()),
40
+ ("lang", pa.string()),
41
+ ("source", pa.string()),
42
+ ("domain", pa.string()),
43
+ ("safety_tag", pa.string()),
44
+ ])
45
+
46
+ def get_hf_token():
47
+ """Retrieve Hugging Face token securely from environment or secret stores."""
48
+ token = os.environ.get("HF_TOKEN") or os.environ.get("HUGGING_FACE_HUB_TOKEN")
49
+ if not token:
50
+ try:
51
+ from kaggle_secrets import UserSecretsClient
52
+ token = UserSecretsClient().get_secret("HF_TOKEN")
53
+ except Exception:
54
+ pass
55
+ if not token:
56
+ try:
57
+ from google.colab import userdata
58
+ token = userdata.get("HF_TOKEN")
59
+ except Exception:
60
+ pass
61
+ return token
62
+
63
+ TOKEN = get_hf_token()
64
+ api = HfApi(token=TOKEN)
65
+
66
+
67
+ def collect_gita_and_ramayana():
68
+ """Ingest Bhagavad Gita, Ramcharitmanas, and Valmiki Ramayana."""
69
+ print("\n[Step 1/5] Collecting Bhagavad Gita & Ramayana...")
70
+ records = []
71
+
72
+ # 1. Bhagavad Gita verses (OEvortex/Bhagavad_Gita)
73
+ try:
74
+ url = "https://huggingface.co/datasets/OEvortex/Bhagavad_Gita/resolve/main/bhagavad-gita.csv"
75
+ df = pd.read_csv(url)
76
+ for _, row in df.iterrows():
77
+ title = str(row.get("Title", "")).strip()
78
+ ch = row.get("Chapter", "")
79
+ vs = row.get("Verse", "")
80
+ anuvad = str(row.get("Sanskrit Anuvad", "")).strip()
81
+ if anuvad and len(anuvad) > 20:
82
+ text = f"श्रीमद्भगवद्गीता - अध्याय {ch}, श्लोक {vs}\nशीर्षक: {title}\n\nसंस्कृत श्लोक एवं हिन्दी अनुवाद:\n{anuvad}"
83
+ records.append({
84
+ "text": text,
85
+ "lang": "hi",
86
+ "source": "OEvortex/Bhagavad_Gita",
87
+ "domain": "sanatan_dharma",
88
+ "safety_tag": "safe"
89
+ })
90
+ print(f" - Loaded {len(records)} Bhagavad Gita verses from OEvortex/Bhagavad_Gita")
91
+ except Exception as exc:
92
+ print(f" - Warning loading OEvortex/Bhagavad_Gita: {exc}")
93
+
94
+ # 2. Ramcharitmanas complete Kandas (adiiva/ramcharitmanas)
95
+ try:
96
+ url = "https://huggingface.co/datasets/adiiva/ramcharitmanas/resolve/main/data/train-00000-of-00001.parquet"
97
+ df_ram = pd.read_parquet(url)
98
+ count_ram = 0
99
+ for _, row in df_ram.iterrows():
100
+ kanda = str(row.get("kanda", "")).strip()
101
+ pg = row.get("page_number", "")
102
+ content = str(row.get("content", "")).strip()
103
+ if content and len(content) > 30:
104
+ text = f"श्रीरामचरितमानस ({kanda}, पृष्ठ {pg}):\n\n{content}"
105
+ records.append({
106
+ "text": text,
107
+ "lang": "hi",
108
+ "source": "adiiva/ramcharitmanas",
109
+ "domain": "sanatan_dharma",
110
+ "safety_tag": "safe"
111
+ })
112
+ count_ram += 1
113
+ print(f" - Loaded {count_ram} pages from adiiva/ramcharitmanas (all 7 Kandas)")
114
+ except Exception as exc:
115
+ print(f" - Warning loading adiiva/ramcharitmanas: {exc}")
116
+
117
+ # 3. Valmiki Ramayana Shlokas with Hindi translations (thebharatai/Indian_Epics_Mythology)
118
+ try:
119
+ vr_path = hf_hub_download(
120
+ repo_id="thebharatai/Indian_Epics_Mythology",
121
+ filename="Valmiki_Ramayan_Shlokas.jsonl",
122
+ repo_type="dataset",
123
+ token=TOKEN
124
+ )
125
+ count_vr = 0
126
+ with open(vr_path, "r", encoding="utf-8") as f:
127
+ for line in f:
128
+ if not line.strip():
129
+ continue
130
+ item = json.loads(line)
131
+ shloka = str(item.get("input_text", "")).strip()
132
+ meaning = str(item.get("output_text", "")).strip()
133
+ if shloka and meaning:
134
+ text = f"वाल्मीकि रामायण श्लोक:\n{shloka}\n\nहिन्दी भावार्थ एवं संदर्भ:\n{meaning}"
135
+ records.append({
136
+ "text": text,
137
+ "lang": "hi",
138
+ "source": "thebharatai/Indian_Epics_Mythology/Valmiki_Ramayan",
139
+ "domain": "sanatan_dharma",
140
+ "safety_tag": "safe"
141
+ })
142
+ count_vr += 1
143
+ print(f" - Loaded {count_vr} Valmiki Ramayana shlokas with Hindi translations")
144
+ except Exception as exc:
145
+ print(f" - Warning loading Valmiki_Ramayan_Shlokas: {exc}")
146
+
147
+ # 4. Gita Mantras (thebharatai/Indian_Epics_Mythology)
148
+ try:
149
+ url_gm = "https://huggingface.co/datasets/thebharatai/Indian_Epics_Mythology/resolve/main/MERGED_GITA%20MANTRAS.csv"
150
+ df_gm = pd.read_csv(url_gm)
151
+ count_gm = 0
152
+ for _, row in df_gm.iterrows():
153
+ title = str(row.get("title", "")).strip()
154
+ mantra = str(row.get("mantra", "")).strip()
155
+ num = row.get("number", "")
156
+ if mantra and len(mantra) > 20:
157
+ text = f"भगवद्गीता मंत्र ({title}, संख्या: {num}):\n\n{mantra}"
158
+ records.append({
159
+ "text": text,
160
+ "lang": "hi",
161
+ "source": "thebharatai/Indian_Epics_Mythology/Gita_Mantras",
162
+ "domain": "sanatan_dharma",
163
+ "safety_tag": "safe"
164
+ })
165
+ count_gm += 1
166
+ print(f" - Loaded {count_gm} Gita mantras")
167
+ except Exception as exc:
168
+ print(f" - Warning loading Gita Mantras: {exc}")
169
+
170
+ out_file = OUTPUT_DIR / "train-p1p2_boost_sanatan_dharma_gita_ramayana-00000.parquet"
171
+ table = pa.Table.from_pylist(records, schema=SCHEMA)
172
+ pq.write_table(table, out_file, compression="snappy")
173
+ print(f"[Done Step 1] Saved {len(records):,} rows to {out_file} ({out_file.stat().st_size / (1024**2):.2f} MB)")
174
+ return out_file, len(records)
175
+
176
+
177
+ def collect_epics_and_ancient_wisdom():
178
+ """Ingest Mahabharata, Upanishads, Puranas, Chanakya Niti, and Charak Samhita."""
179
+ print("\n[Step 2/5] Collecting Mahabharata, Upanishads & Ancient Wisdom...")
180
+ records = []
181
+
182
+ # 1. Upanishads (thebharatai/Indian_Epics_Mythology)
183
+ try:
184
+ url_up = "https://huggingface.co/datasets/thebharatai/Indian_Epics_Mythology/resolve/main/MERGED_upanishads.csv"
185
+ df_up = pd.read_csv(url_up)
186
+ for _, row in df_up.iterrows():
187
+ title = str(row.get("title", "")).strip()
188
+ mantra = str(row.get("mantra", "")).strip()
189
+ num = row.get("number", "")
190
+ if mantra and len(mantra) > 20:
191
+ text = f"उपनिषद् दर्शन ({title}, मंत्र संख्या {num}):\n\n{mantra}"
192
+ records.append({
193
+ "text": text,
194
+ "lang": "hi",
195
+ "source": "thebharatai/Indian_Epics_Mythology/Upanishads",
196
+ "domain": "sanatan_dharma",
197
+ "safety_tag": "safe"
198
+ })
199
+ print(f" - Loaded Upanishads mantras")
200
+ except Exception as exc:
201
+ print(f" - Warning loading Upanishads: {exc}")
202
+
203
+ # 2. Chanakya Niti (thebharatai/Indian_Epics_Mythology)
204
+ try:
205
+ url_cn = "https://huggingface.co/datasets/thebharatai/Indian_Epics_Mythology/resolve/main/CHANKYA%20NITI_cleaned.csv"
206
+ df_cn = pd.read_csv(url_cn)
207
+ for _, row in df_cn.iterrows():
208
+ ch = row.get("chapter", "")
209
+ v_id = row.get("verse_id", "")
210
+ txt = str(row.get("text", "")).strip()
211
+ if txt and len(txt) > 20:
212
+ text = f"चाणक्य नीति (अध्याय {ch}, सूत्र {v_id}):\n\n{txt}"
213
+ records.append({
214
+ "text": text,
215
+ "lang": "hi",
216
+ "source": "thebharatai/Indian_Epics_Mythology/Chanakya_Niti",
217
+ "domain": "indian_wisdom",
218
+ "safety_tag": "safe"
219
+ })
220
+ print(f" - Loaded Chanakya Niti verses")
221
+ except Exception as exc:
222
+ print(f" - Warning loading Chanakya Niti: {exc}")
223
+
224
+ # 3. Charak Samhita (Ancient Ayurvedic Science)
225
+ try:
226
+ url_cs = "https://huggingface.co/datasets/thebharatai/Indian_Epics_Mythology/resolve/main/CIHARAK%20SAMHITA_cleaned.csv"
227
+ df_cs = pd.read_csv(url_cs)
228
+ for _, row in df_cs.iterrows():
229
+ sec = row.get("section", "")
230
+ ch = row.get("chapter", "")
231
+ v_id = row.get("verse_id", "")
232
+ txt = str(row.get("text", "")).strip()
233
+ if txt and len(txt) > 20:
234
+ text = f"चरक संहिता आयुर्वेद दर्शन ({sec}, अध्याय {ch}, सूत्र {v_id}):\n\n{txt}"
235
+ records.append({
236
+ "text": text,
237
+ "lang": "hi",
238
+ "source": "thebharatai/Indian_Epics_Mythology/Charak_Samhita",
239
+ "domain": "ayurveda_wisdom",
240
+ "safety_tag": "safe"
241
+ })
242
+ print(f" - Loaded Charak Samhita Ayurvedic verses")
243
+ except Exception as exc:
244
+ print(f" - Warning loading Charak Samhita: {exc}")
245
+
246
+ # 4. Mahabharat dialogues & episodes
247
+ try:
248
+ url_mb = "https://huggingface.co/datasets/thebharatai/Indian_Epics_Mythology/resolve/main/Mahabharat.csv"
249
+ df_mb = pd.read_csv(url_mb)
250
+ count_mb = 0
251
+ for _, row in df_mb.iterrows():
252
+ inp = str(row.get("input_text", "")).strip()
253
+ out = str(row.get("output_text", "")).strip()
254
+ if out and len(out) > 20:
255
+ text = f"महाभारत प्रसंग एवं संवाद:\n{inp}\n\nव्याख्या एवं विवरण:\n{out}" if inp else f"महाभारत प्रसंग:\n{out}"
256
+ records.append({
257
+ "text": text,
258
+ "lang": "hi",
259
+ "source": "thebharatai/Indian_Epics_Mythology/Mahabharat",
260
+ "domain": "sanatan_dharma",
261
+ "safety_tag": "safe"
262
+ })
263
+ count_mb += 1
264
+ print(f" - Loaded {count_mb} Mahabharat episodes from thebharatai")
265
+ except Exception as exc:
266
+ print(f" - Warning loading Mahabharat from thebharatai: {exc}")
267
+
268
+ # 5. Puranas (venkatarajendra/puranas)
269
+ try:
270
+ url_pur = "https://huggingface.co/datasets/venkatarajendra/puranas/resolve/main/data/train-00000-of-00001.parquet"
271
+ df_pur = pd.read_parquet(url_pur)
272
+ count_pur = 0
273
+ for _, row in df_pur.iterrows():
274
+ msgs = row.get("messages", [])
275
+ if isinstance(msgs, list):
276
+ convo_parts = []
277
+ for m in msgs:
278
+ role = m.get("role", "")
279
+ content = m.get("content", "")
280
+ convo_parts.append(f"<|{role}|> {content}")
281
+ text = "\n".join(convo_parts)
282
+ else:
283
+ text = str(msgs).strip()
284
+ if text and len(text) > 30:
285
+ records.append({
286
+ "text": text,
287
+ "lang": "en",
288
+ "source": "venkatarajendra/puranas",
289
+ "domain": "sanatan_dharma",
290
+ "safety_tag": "safe"
291
+ })
292
+ count_pur += 1
293
+ print(f" - Loaded {count_pur} Purana discourses from venkatarajendra/puranas")
294
+ except Exception as exc:
295
+ print(f" - Warning loading Puranas: {exc}")
296
+
297
+ out_file = OUTPUT_DIR / "train-p1p2_boost_sanatan_dharma_epics_upanishads-00000.parquet"
298
+ table = pa.Table.from_pylist(records, schema=SCHEMA)
299
+ pq.write_table(table, out_file, compression="snappy")
300
+ print(f"[Done Step 2] Saved {len(records):,} rows to {out_file} ({out_file.stat().st_size / (1024**2):.2f} MB)")
301
+ return out_file, len(records)
302
+
303
+
304
+ def collect_hinduism_philosophy_qa():
305
+ """Ingest Hinduism StackExchange Q&A (Scriptures, Deities, Temples, Rituals)."""
306
+ print("\n[Step 3/5] Collecting Hinduism Scripture & Philosophy Q&A...")
307
+ records = []
308
+ try:
309
+ qa_path = hf_hub_download(
310
+ repo_id="alberto98fx/hinduism-stackexchange",
311
+ filename="q_and_a.json",
312
+ repo_type="dataset",
313
+ token=TOKEN
314
+ )
315
+ with open(qa_path, "r", encoding="utf-8") as f:
316
+ data = json.load(f)
317
+
318
+ for item in data:
319
+ title = str(item.get("Title", "")).strip()
320
+ q_body = str(item.get("q_body", "")).strip()
321
+ # Clean HTML tags simply
322
+ import re
323
+ clean_q = re.sub(r"<[^>]+>", " ", q_body).strip()
324
+ clean_q = " ".join(clean_q.split())
325
+
326
+ answers = item.get("Answers", [])
327
+ ans_text = ""
328
+ if isinstance(answers, list) and len(answers) > 0:
329
+ # Find accepted answer or highest score answer
330
+ best_ans = answers[0]
331
+ for ans in answers:
332
+ if ans.get("Id") == item.get("AcceptedAnswerId"):
333
+ best_ans = ans
334
+ break
335
+ ans_body = str(best_ans.get("a_body", "")).strip()
336
+ ans_text = re.sub(r"<[^>]+>", " ", ans_body).strip()
337
+ ans_text = " ".join(ans_text.split())
338
+
339
+ if title and ans_text and len(ans_text) > 40:
340
+ text = f"<|user|> Question on Hindu Philosophy & Scriptures: {title}\n{clean_q}\n<|assistant|> <soch> Analyzing Hindu scriptures, context, and philosophical principles... </soch> {ans_text}"
341
+ records.append({
342
+ "text": text,
343
+ "lang": "en",
344
+ "source": "alberto98fx/hinduism-stackexchange",
345
+ "domain": "sanatan_dharma",
346
+ "safety_tag": "safe"
347
+ })
348
+ print(f" - Loaded {len(records):,} in-depth Hinduism Q&A entries")
349
+ except Exception as exc:
350
+ print(f" - Warning loading Hinduism StackExchange: {exc}")
351
+
352
+ out_file = OUTPUT_DIR / "train-p1p2_boost_hinduism_philosophy_qa-00000.parquet"
353
+ table = pa.Table.from_pylist(records, schema=SCHEMA)
354
+ pq.write_table(table, out_file, compression="snappy")
355
+ print(f"[Done Step 3] Saved {len(records):,} rows to {out_file} ({out_file.stat().st_size / (1024**2):.2f} MB)")
356
+ return out_file, len(records)
357
+
358
+
359
+ def collect_hinglish_and_reasoning_boost():
360
+ """Ingest Chatbot Arena Hinglish, Hindi GSM8k Math, and Indian History QA."""
361
+ print("\n[Step 4/5] Collecting Hinglish Arena, Hindi GSM8k Math & History QA...")
362
+ records_hinglish = []
363
+ records_math = []
364
+ records_hist = []
365
+
366
+ # 1. Chatbot Arena Hinglish Conversations (one-thing/chatbot_arena_conversations_hinglish)
367
+ try:
368
+ url_ch = "https://huggingface.co/datasets/one-thing/chatbot_arena_conversations_hinglish/resolve/main/data.csv"
369
+ df_ch = pd.read_csv(url_ch)
370
+ for _, row in df_ch.iterrows():
371
+ u_hing = str(row.get("user_hinglish", "")).strip()
372
+ a_hing = str(row.get("assistant_hinglish", "")).strip()
373
+ if u_hing and a_hing and len(u_hing) > 5 and len(a_hing) > 10:
374
+ text = f"<|user|> {u_hing}\n<|assistant|> {a_hing}"
375
+ records_hinglish.append({
376
+ "text": text,
377
+ "lang": "hinglish",
378
+ "source": "one-thing/chatbot_arena_conversations_hinglish",
379
+ "domain": "conversational",
380
+ "safety_tag": "safe"
381
+ })
382
+ print(f" - Loaded {len(records_hinglish):,} Hinglish conversation turns")
383
+ except Exception as exc:
384
+ print(f" - Warning loading Chatbot Arena Hinglish: {exc}")
385
+
386
+ # 2. GSM8K Hindi Math Word Problems with Reasoning Steps
387
+ try:
388
+ url_gsm = "https://huggingface.co/datasets/bingbangboom/gsm8k-hindi/resolve/main/data/train_main-00000-of-00001.parquet"
389
+ df_gsm = pd.read_parquet(url_gsm)
390
+ for _, row in df_gsm.iterrows():
391
+ q = str(row.get("question", "")).strip()
392
+ a = str(row.get("answer", "")).strip()
393
+ if q and a:
394
+ text = f"<|user|> {q}\n<|assistant|> <soch> गणितीय समस्या का चरणबद्ध समाधान करते हैं... </soch> {a}"
395
+ records_math.append({
396
+ "text": text,
397
+ "lang": "hi",
398
+ "source": "bingbangboom/gsm8k-hindi",
399
+ "domain": "math_reasoning",
400
+ "safety_tag": "safe"
401
+ })
402
+ print(f" - Loaded {len(records_math):,} GSM8K Hindi math reasoning problems")
403
+ except Exception as exc:
404
+ print(f" - Warning loading GSM8K Hindi: {exc}")
405
+
406
+ # 3. Indian History Hindi QA (kaifahmad/indian-history-hindi-QA-3.4k)
407
+ try:
408
+ url_hist = "https://huggingface.co/datasets/kaifahmad/indian-history-hindi-QA-3.4k/resolve/main/data/train-00000-of-00001.parquet"
409
+ df_hist = pd.read_parquet(url_hist)
410
+ for _, row in df_hist.iterrows():
411
+ q = str(row.get("question", "")).strip()
412
+ a = str(row.get("answer", "")).strip()
413
+ if q and a:
414
+ text = f"<|user|> भारतीय इतिहास प्रश्न: {q}\n<|assistant|> {a}"
415
+ records_hist.append({
416
+ "text": text,
417
+ "lang": "hi",
418
+ "source": "kaifahmad/indian-history-hindi-QA-3.4k",
419
+ "domain": "history_gk",
420
+ "safety_tag": "safe"
421
+ })
422
+ print(f" - Loaded {len(records_hist):,} Indian History QA rows")
423
+ except Exception as exc:
424
+ print(f" - Warning loading Indian History QA: {exc}")
425
+
426
+ # Save Hinglish
427
+ f_hinglish = OUTPUT_DIR / "train-p1p2_boost_hinglish_arena_chat-00000.parquet"
428
+ t_hing = pa.Table.from_pylist(records_hinglish, schema=SCHEMA)
429
+ pq.write_table(t_hing, f_hinglish, compression="snappy")
430
+ print(f" - Saved Hinglish: {len(records_hinglish):,} rows ({f_hinglish.stat().st_size / (1024**2):.2f} MB)")
431
+
432
+ # Save Math
433
+ f_math = OUTPUT_DIR / "train-p1p2_boost_hindi_math_gsm8k-00000.parquet"
434
+ t_math = pa.Table.from_pylist(records_math, schema=SCHEMA)
435
+ pq.write_table(t_math, f_math, compression="snappy")
436
+ print(f" - Saved Hindi Math: {len(records_math):,} rows ({f_math.stat().st_size / (1024**2):.2f} MB)")
437
+
438
+ # Save History
439
+ f_hist = OUTPUT_DIR / "train-p1p2_boost_indian_history_qa-00000.parquet"
440
+ t_hist = pa.Table.from_pylist(records_hist, schema=SCHEMA)
441
+ pq.write_table(t_hist, f_hist, compression="snappy")
442
+ print(f" - Saved Indian History: {len(records_hist):,} rows ({f_hist.stat().st_size / (1024**2):.2f} MB)")
443
+
444
+ return [
445
+ (f_hinglish, len(records_hinglish)),
446
+ (f_math, len(records_math)),
447
+ (f_hist, len(records_hist))
448
+ ]
449
+
450
+
451
+ def upload_shards_to_hub(shards):
452
+ """Upload all newly created boost shards to Hugging Face dataset repository."""
453
+ print("\n[Step 5/5] Uploading Shards to Hugging Face Dataset Hub...")
454
+ if not TOKEN:
455
+ print(" - [Error] HF_TOKEN not found! Cannot push to Hub.")
456
+ return False
457
+
458
+ for file_path, row_count in shards:
459
+ hub_path = f"domains/{file_path.name}"
460
+ print(f" - Uploading {file_path.name} ({row_count:,} rows) -> {DATA_REPO}/{hub_path}...")
461
+ try:
462
+ api.upload_file(
463
+ path_or_fileobj=str(file_path),
464
+ path_in_repo=hub_path,
465
+ repo_id=DATA_REPO,
466
+ repo_type="dataset",
467
+ commit_message=f"feat: add spiritual & reasoning boost {file_path.name} ({row_count:,} rows)"
468
+ )
469
+ print(f" ✓ Uploaded successfully!")
470
+ except Exception as exc:
471
+ print(f" ✗ Failed to upload {file_path.name}: {exc}")
472
+
473
+ print("\n[Complete] All Sanatan Dharma & Knowledge Boost Shards Processed!")
474
+ return True
475
+
476
+
477
+ def main():
478
+ start_time = time.time()
479
+ all_shards = []
480
+
481
+ # 1. Gita & Ramayana
482
+ f1, count1 = collect_gita_and_ramayana()
483
+ all_shards.append((f1, count1))
484
+
485
+ # 2. Epics, Upanishads & Wisdom
486
+ f2, count2 = collect_epics_and_ancient_wisdom()
487
+ all_shards.append((f2, count2))
488
+
489
+ # 3. Hinduism Philosophy Q&A
490
+ f3, count3 = collect_hinduism_philosophy_qa()
491
+ all_shards.append((f3, count3))
492
+
493
+ # 4. Hinglish, Math & History Boosts
494
+ more_shards = collect_hinglish_and_reasoning_boost()
495
+ all_shards.extend(more_shards)
496
+
497
+ total_rows = sum(cnt for _, cnt in all_shards)
498
+ total_bytes = sum(f.stat().st_size for f, _ in all_shards)
499
+
500
+ print("\n" + "=" * 70)
501
+ print("Collection Summary:")
502
+ print(f" Total Boost Shards: {len(all_shards)}")
503
+ print(f" Total Clean Rows: {total_rows:,}")
504
+ print(f" Total Parquet Size: {total_bytes / (1024**2):.2f} MB")
505
+ print("=" * 70)
506
+
507
+ # 5. Upload to Hugging Face
508
+ upload_shards_to_hub(all_shards)
509
+
510
+ elapsed = time.time() - start_time
511
+ print(f"\nElapsed time: {elapsed:.2f} seconds ({elapsed / 60:.2f} minutes)")
512
+
513
+
514
+ if __name__ == "__main__":
515
+ main()
docs/PROGRESS.md CHANGED
@@ -343,6 +343,12 @@ Kaggle par manual file upload se version mismatch hota hai (v1 tokenizer wala ca
343
  - **MED**: `from data.scripts.filter_by_safety` import CWD-depend fail hota tha (silent fallback). FIX: repo root `sys.path` me dala.
344
  - verify: syntax OK + `train.py --smoke` 3-step PASS (loss 6.31, MoE usages OK).
345
  - NOTE: DDP probe+broadcast fix local CPU pe full-test nahi ho sakta — next Kaggle T4x2 run me `[auto] ... [dist broadcast r0->all]` line dikhni chahiye.
 
 
 
 
 
 
346
 
347
  ## Kaise note likhna hai
348
  ```
 
343
  - **MED**: `from data.scripts.filter_by_safety` import CWD-depend fail hota tha (silent fallback). FIX: repo root `sys.path` me dala.
344
  - verify: syntax OK + `train.py --smoke` 3-step PASS (loss 6.31, MoE usages OK).
345
  - NOTE: DDP probe+broadcast fix local CPU pe full-test nahi ho sakta — next Kaggle T4x2 run me `[auto] ... [dist broadcast r0->all]` line dikhni chahiye.
346
+ - [x] 2026-09-24 Kaggle DDP verify RUN #1 (100 steps): **partial PASS + 2 bugs mile**:
347
+ - PASS: bootstrap, 2xT4, tok v2 mask_id=4, `rank 0/2 + 1/2`, `[dist broadcast r0->all]` (micro=4 accum=4), DDP wrapped synced, model 241.7M/166.2M, step 1 loss 12.85 shuru hua.
348
+ - **BUG OOM (exit 1)**: step-1 backward pe dono ranks CUDA OOM (13.3/14.5 GB). Root cause: probe me sirf ~2GB AdamW reserve — DDP grad buckets (~1GB) + fragmentation account nahi the. FIX: probe reserve 4→2→1GB阶梯 + `PYTORCH_ALLOC_CONF=expandable_segments:True`.
349
+ - **BUG data 100% Hindi**: `enforce_mix=false` + natural Hub order → `mix_rows={hinglish:0, hindi:109625, english:0}` (pehle hindi/* files). FIX: natural mode me `hf_ds.shuffle(buffer_size=100000)` (ratio enforce nahi, sirf order bias) + config `natural_shuffle_buffer: 100000`.
350
+ - Minor: cell HEAD check `next(list)` fail (cosmetic); `find_unused_parameters=True` warning (MoE unused experts possible — rakha).
351
+ - verify #2 pending after push.
352
 
353
  ## Kaise note likhna hai
354
  ```
model/configs/train_config.yaml CHANGED
@@ -41,9 +41,12 @@ hf_max_blocks: 50000
41
  hf_safety: strict
42
  # Streaming scan limit (rows): null = unlimited (max_blocks tak). Test ke liye 20000 set karo.
43
  hf_max_rows: null
44
- # Language-mix rule OPTIONAL (default OFF = natural Hub order).
45
- # ON karne ke liye: enforce_mix: true (weights lang_mix se; rare lang quota-skip scan se).
 
46
  enforce_mix: false
47
  lang_mix: {hinglish: 0.4, hindi: 0.3, english: 0.3}
48
  mix_scan_mult: 5
49
  mix_max_rows: 2000000
 
 
 
41
  hf_safety: strict
42
  # Streaming scan limit (rows): null = unlimited (max_blocks tak). Test ke liye 20000 set karo.
43
  hf_max_rows: null
44
+ # Language-mix rule OPTIONAL (default OFF = shuffled natural order, ratio enforce NAHI).
45
+ # OFF par Hub file-order bias hatane ke liye streaming buffer-shuffle hota hai
46
+ # (warna pehle N rows 100% Hindi aa sakte the). Ratio chahiye to enforce_mix: true.
47
  enforce_mix: false
48
  lang_mix: {hinglish: 0.4, hindi: 0.3, english: 0.3}
49
  mix_scan_mult: 5
50
  mix_max_rows: 2000000
51
+ # natural (enforce_mix=false) mode ka shuffle buffer (rows); 0 = off (purana buggy order)
52
+ natural_shuffle_buffer: 100000
model/scripts/train.py CHANGED
@@ -167,19 +167,21 @@ def resolve_amp(want, device, bf16_ok):
167
 
168
 
169
  def probe_micro_batch(model, seq_len, vocab_size, device, amp_dtype):
170
- """Asli OOM-test: bada micro-batch try karo, jo fite wahi lo. Target eff-batch same rehta hai."""
 
 
171
  model.train()
172
  best = 1
173
- # AdamW safety margin: reserve buffer on CUDA so probe accounts for ~2GB optimizer states
 
174
  adamw_buf = None
175
  if device.type == "cuda":
176
- try:
177
- adamw_buf = torch.empty((500_000_000,), dtype=torch.float32, device=device) # ~2.0 GB
178
- except RuntimeError:
179
  try:
180
- adamw_buf = torch.empty((250_000_000,), dtype=torch.float32, device=device) # ~1.0 GB
 
181
  except RuntimeError:
182
- pass
183
  try:
184
  for mb in (1, 2, 4, 8, 16, 32):
185
  try:
@@ -316,6 +318,8 @@ def sample_text(model, tok, prompt, device, max_new=30, seq_len=1024, temperatur
316
 
317
 
318
  def main():
 
 
319
  ap = argparse.ArgumentParser()
320
  ap.add_argument("--config", default="../configs/train_config.yaml")
321
  ap.add_argument("--model_config", default="../configs/viu1_moe_config.yaml")
@@ -442,7 +446,7 @@ def main():
442
  if R0:
443
  print(f"[hf] streaming dataset {hf_dataset} split={args.hf_split}")
444
  hf_ds = load_dataset(hf_dataset, split=args.hf_split, streaming=True)
445
- # Language-mix rule OPTIONAL (default OFF = natural Hub order).
446
  # enforce_mix=true par weighted block sampler chalta hai (lang_mix weights se).
447
  max_blocks_cfg = int(C("hf_max_blocks", 50000))
448
  safety_mode = str(C("hf_safety", "strict")).lower()
@@ -459,10 +463,18 @@ def main():
459
  mix_max_rows = int(C("mix_max_rows", 2000000))
460
  allow_toxic = safety_mode in ("research", "full")
461
  allow_uncensored = safety_mode in ("full",)
 
 
 
 
 
 
 
462
  if R0:
463
  print(f"[hf] safety={safety_mode} (toxic={allow_toxic}, uncensored={allow_uncensored}) "
464
  f"max_blocks={max_blocks_cfg} max_rows={max_rows_cfg or 'unlimited'} "
465
- f"enforce_mix={enforce_mix} lang_mix={lang_mix if enforce_mix else 'OFF (natural order)'}")
 
466
  try:
467
  from data.scripts.filter_by_safety import keep_row as _keep
468
  def _safety_ok(r):
 
167
 
168
 
169
  def probe_micro_batch(model, seq_len, vocab_size, device, amp_dtype):
170
+ """Asli OOM-test: bada micro-batch try karo, jo fite wahi lo. Target eff-batch same rehta hai.
171
+ NOTE: probe DDP wrap SE PEHLE chalta hai — isliye AdamW (~2x params) + DDP grad buckets (~1x params)
172
+ + fragmentation ka explicit reserve chahiye, warna wrap ke baad training step-1 pe OOM."""
173
  model.train()
174
  best = 1
175
+ # Reserve: AdamW states + DDP buckets + headroom. 242M fp32 ~0.97GB/param-tensor =>
176
+ # ~2GB AdamW + ~1GB buckets + ~1GB frag => try 4GB, warna 2GB, warna 1GB.
177
  adamw_buf = None
178
  if device.type == "cuda":
179
+ for n_elems in (1_000_000_000, 500_000_000, 250_000_000): # ~4.0 / 2.0 / 1.0 GB
 
 
180
  try:
181
+ adamw_buf = torch.empty((n_elems,), dtype=torch.float32, device=device)
182
+ break
183
  except RuntimeError:
184
+ adamw_buf = None
185
  try:
186
  for mb in (1, 2, 4, 8, 16, 32):
187
  try:
 
318
 
319
 
320
  def main():
321
+ # Fragmentation kam karo (T4 pe large-alloc OOM ke baad reserved-but-unused dikhta tha)
322
+ os.environ.setdefault("PYTORCH_ALLOC_CONF", "expandable_segments:True")
323
  ap = argparse.ArgumentParser()
324
  ap.add_argument("--config", default="../configs/train_config.yaml")
325
  ap.add_argument("--model_config", default="../configs/viu1_moe_config.yaml")
 
446
  if R0:
447
  print(f"[hf] streaming dataset {hf_dataset} split={args.hf_split}")
448
  hf_ds = load_dataset(hf_dataset, split=args.hf_split, streaming=True)
449
+ # Language-mix rule OPTIONAL (default OFF = natural order).
450
  # enforce_mix=true par weighted block sampler chalta hai (lang_mix weights se).
451
  max_blocks_cfg = int(C("hf_max_blocks", 50000))
452
  safety_mode = str(C("hf_safety", "strict")).lower()
 
463
  mix_max_rows = int(C("mix_max_rows", 2000000))
464
  allow_toxic = safety_mode in ("research", "full")
465
  allow_uncensored = safety_mode in ("full",)
466
+ # NATURAL mode trap fix: Hub file-order me pehle hindi/* aati hai — bina shuffle
467
+ # ke pehle N rows 100% Hindi milte the (verified: hinglish=0, english=0).
468
+ # enforce_mix=false par streaming buffer-shuffle se languages interleave hoti hain
469
+ # (ratio enforce NAHI — sirf order bias hatata hai).
470
+ natural_shuffle = int(C("natural_shuffle_buffer", 100000))
471
+ if (not enforce_mix) and natural_shuffle > 0:
472
+ hf_ds = hf_ds.shuffle(seed=mix_seed, buffer_size=natural_shuffle)
473
  if R0:
474
  print(f"[hf] safety={safety_mode} (toxic={allow_toxic}, uncensored={allow_uncensored}) "
475
  f"max_blocks={max_blocks_cfg} max_rows={max_rows_cfg or 'unlimited'} "
476
+ f"enforce_mix={enforce_mix} lang_mix={lang_mix if enforce_mix else 'OFF (shuffle-buffer order)'}"
477
+ + (f" natural_shuffle={natural_shuffle}" if (not enforce_mix and natural_shuffle > 0) else ""))
478
  try:
479
  from data.scripts.filter_by_safety import keep_row as _keep
480
  def _safety_ok(r):