Download blend_edu.py from SlayerLab/gollem-v5-ckpts: direct link, hf CLI and curl.
- Browser
- Download file 2.95 kB
-
https://huggingface.co/SlayerLab/gollem-v5-ckpts/resolve/eef1515f681d0d35d0bc7dccd3cab748812550be/blend_edu.py
- Command line
-
hf download hf://SlayerLab/gollem-v5-ckpts@eef1515f681d0d35d0bc7dccd3cab748812550be/blend_edu.py
-
curl -L -o blend_edu.py https://huggingface.co/SlayerLab/gollem-v5-ckpts/resolve/eef1515f681d0d35d0bc7dccd3cab748812550be/blend_edu.py
2.95 kB
| #!/usr/bin/env python3 | |
| """fork-B blend: doc-level 50:50 (parametrizable) mix of arcmix + edu -> train.bin (uint16). | |
| Single-factor ablation (RB4/S10): fork-A=arcmix, fork-B=arcmix+edu. This builds fork-B's | |
| train.bin by taking ~equal token budgets from each source, splitting on eot-doc-boundaries, | |
| shuffling the tagged doc list (seeded) and concatenating. The trainer samples random windows | |
| uniformly over the flat stream -> overall token exposure = arcmix:edu at the chosen ratio. | |
| Val: fork-B should reuse arcmix_val.bin (same val as fork-A) so val-loss is comparable; | |
| copy it into the out-dir separately. Only train.bin is produced here. | |
| """ | |
| import argparse | |
| from pathlib import Path | |
| import numpy as np | |
| def doc_spans(arr, eot): | |
| """(start,end) spans split on eot (end exclusive, includes the eot token).""" | |
| idx = np.where(arr == eot)[0] | |
| prev = 0 | |
| for e in idx: | |
| yield prev, int(e) + 1 | |
| prev = int(e) + 1 | |
| def take_docs(arr, budget, eot): | |
| spans, tot = [], 0 | |
| for s, e in doc_spans(arr, eot): | |
| spans.append((s, e)) | |
| tot += e - s | |
| if tot >= budget: | |
| break | |
| return spans, tot | |
| def main(): | |
| ap = argparse.ArgumentParser() | |
| ap.add_argument("--arcmix", required=True, help="path to arcmix train.bin (uint16)") | |
| ap.add_argument("--edu", required=True, help="path to edu train.bin (uint16)") | |
| ap.add_argument("--out", required=True, help="output blend train.bin") | |
| ap.add_argument("--arcmix-tokens", type=int, default=2_000_000_000) | |
| ap.add_argument("--edu-tokens", type=int, default=2_000_000_000) | |
| ap.add_argument("--eot", type=int, default=12287) | |
| ap.add_argument("--seed", type=int, default=1337) | |
| a = ap.parse_args() | |
| arc = np.memmap(a.arcmix, dtype=np.uint16, mode="r") | |
| edu = np.memmap(a.edu, dtype=np.uint16, mode="r") | |
| print(f"arcmix.bin={len(arc):,} tok | edu.bin={len(edu):,} tok", flush=True) | |
| arc_spans, arc_tot = take_docs(arc, a.arcmix_tokens, a.eot) | |
| edu_spans, edu_tot = take_docs(edu, a.edu_tokens, a.eot) | |
| print(f"take arcmix docs={len(arc_spans):,} tok={arc_tot:,} | " | |
| f"edu docs={len(edu_spans):,} tok={edu_tot:,}", flush=True) | |
| tagged = [(0, s, e) for s, e in arc_spans] + [(1, s, e) for s, e in edu_spans] | |
| rng = np.random.default_rng(a.seed) | |
| rng.shuffle(tagged) | |
| out = open(a.out, "wb") | |
| buf, buflen, written = [], 0, 0 | |
| for src, s, e in tagged: | |
| buf.append(np.asarray((arc if src == 0 else edu)[s:e])) | |
| buflen += e - s | |
| if buflen >= 20_000_000: | |
| np.concatenate(buf).tofile(out) | |
| written += buflen | |
| buf, buflen = [], 0 | |
| if buf: | |
| np.concatenate(buf).tofile(out) | |
| written += buflen | |
| out.close() | |
| frac = arc_tot / max(written, 1) | |
| print(f"WROTE {a.out} tok={written:,} | arcmix={arc_tot:,} ({frac:.1%}) edu={edu_tot:,} ({1-frac:.1%})", | |
| flush=True) | |
| if __name__ == "__main__": | |
| main() | |