adyoi commited on
Commit
ae6ec20
·
verified ·
1 Parent(s): 00c2a02

Upload pipeline.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. pipeline.py +181 -0
pipeline.py ADDED
@@ -0,0 +1,181 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import argparse
2
+ import datetime
3
+ import json
4
+ import os
5
+ import shutil
6
+ import subprocess
7
+ import sys
8
+ from pathlib import Path
9
+
10
+ ROOT = Path(__file__).resolve().parent
11
+ sys.path.insert(0, str(ROOT))
12
+
13
+ import train
14
+
15
+
16
+ def git_short():
17
+ try:
18
+ return subprocess.check_output(
19
+ ["git", "rev-parse", "--short", "HEAD"], cwd=str(ROOT), text=True
20
+ ).strip()
21
+ except Exception:
22
+ return "nogit"
23
+
24
+
25
+ def pull_hf(repo_id, dest, patterns):
26
+ from huggingface_hub import snapshot_download
27
+
28
+ path = snapshot_download(
29
+ repo_id=repo_id,
30
+ repo_type="dataset",
31
+ allow_patterns=patterns,
32
+ local_dir=str(dest),
33
+ )
34
+ n = sum(
35
+ 1 for f in Path(path).rglob("*")
36
+ if f.is_file() and ".cache" not in f.parts and f.suffix.lstrip(".") in
37
+ {p.lstrip("*.") for p in patterns}
38
+ )
39
+ print(f"[pipeline] dataset '{repo_id}' ditarik -> {dest} ({n} file)")
40
+ return str(dest)
41
+
42
+
43
+ def main():
44
+ ap = argparse.ArgumentParser(
45
+ description="Pipeline latih Indigo: kumpul data -> tokenizer -> training -> manifest -> finalize/push"
46
+ )
47
+ ap.add_argument("--tag", required=True, help="nama run; artefak di <runs>/<tag>/")
48
+ ap.add_argument("--data", nargs="*", default=[], help="file/folder teks lokal tambahan")
49
+ ap.add_argument("--hf-dataset", default=None, help="repo dataset HF untuk menarik file teks")
50
+ ap.add_argument("--hf-patterns", nargs="*", default=["*.txt", "*.md"])
51
+ ap.add_argument("--runs", default="runs")
52
+ ap.add_argument("--device", default=None, help="diteruskan ke train.py (default auto)")
53
+ ap.add_argument("--finalize", action="store_true",
54
+ help="promosikan checkpoint terbaik run ini ke folder out/ kanonik")
55
+ ap.add_argument("--push", action="store_true", help="upload checkpoint terbaik ke repo HF")
56
+ ap.add_argument("--repo", default="adyoi/indigo")
57
+ t = ap.add_argument_group("hyperparameter training (diteruskan ke train.py)")
58
+ t.add_argument("--steps", type=int, default=2000)
59
+ t.add_argument("--batch-size", type=int, default=32)
60
+ t.add_argument("--block-size", type=int, default=128)
61
+ t.add_argument("--n-layer", type=int, default=4)
62
+ t.add_argument("--n-head", type=int, default=4)
63
+ t.add_argument("--n-embd", type=int, default=128)
64
+ t.add_argument("--dropout", type=float, default=0.1)
65
+ t.add_argument("--lr", type=float, default=3e-4)
66
+ t.add_argument("--warmup", type=int, default=100)
67
+ t.add_argument("--weight-decay", type=float, default=0.1)
68
+ t.add_argument("--eval-interval", type=int, default=200)
69
+ t.add_argument("--eval-iters", type=int, default=20)
70
+ t.add_argument("--seed", type=int, default=1337)
71
+ t.add_argument("--init-from", default=None)
72
+ t.add_argument("--tokenizer", default="char", choices=["char", "bpe"])
73
+ t.add_argument("--vocab-size", type=int, default=512)
74
+ t.add_argument("--val-fraction", type=float, default=0.1)
75
+ args = ap.parse_args()
76
+
77
+ run_dir = ROOT / args.runs / args.tag
78
+ data_dir = run_dir / "data"
79
+ data_dir.mkdir(parents=True, exist_ok=True)
80
+
81
+ sources = []
82
+ for p in args.data:
83
+ src = Path(p)
84
+ if not src.exists():
85
+ raise SystemExit(f"sumber data tidak ada: {src}")
86
+ if src.is_dir():
87
+ shutil.copytree(src, data_dir / src.name, dirs_exist_ok=True)
88
+ else:
89
+ shutil.copy2(src, data_dir / src.name)
90
+ sources.append(str(src))
91
+
92
+ if args.hf_dataset:
93
+ pull_hf(args.hf_dataset, data_dir / "_hf", args.hf_patterns)
94
+ sources.append(f"hf:{args.hf_dataset}")
95
+
96
+ out_dir = run_dir / "ckpt"
97
+ argv = [
98
+ "--data", str(data_dir),
99
+ "--out", str(out_dir),
100
+ "--steps", str(args.steps),
101
+ "--batch-size", str(args.batch_size),
102
+ "--block-size", str(args.block_size),
103
+ "--n-layer", str(args.n_layer),
104
+ "--n-head", str(args.n_head),
105
+ "--n-embd", str(args.n_embd),
106
+ "--dropout", str(args.dropout),
107
+ "--lr", str(args.lr),
108
+ "--warmup", str(args.warmup),
109
+ "--weight-decay", str(args.weight_decay),
110
+ "--eval-interval", str(args.eval_interval),
111
+ "--eval-iters", str(args.eval_iters),
112
+ "--seed", str(args.seed),
113
+ "--tokenizer", args.tokenizer,
114
+ "--vocab-size", str(args.vocab_size),
115
+ "--val-fraction", str(args.val_fraction),
116
+ ]
117
+ if args.init_from:
118
+ argv += ["--init-from", args.init_from]
119
+ if args.device:
120
+ argv += ["--device", args.device]
121
+
122
+ print(f"[pipeline] run='{args.tag}' | sumber={sources or ['<kosong>' ]}")
123
+ stats = train.main(argv) or {}
124
+ stats["pipeline"] = {
125
+ "tag": args.tag,
126
+ "timestamp": datetime.datetime.now().isoformat(timespec="seconds"),
127
+ "git": git_short(),
128
+ "sources": sources,
129
+ "hf_dataset": args.hf_dataset,
130
+ "run_dir": str(run_dir),
131
+ }
132
+
133
+ manifest = run_dir / "manifest.json"
134
+ with open(manifest, "w", encoding="utf-8") as f:
135
+ json.dump(stats, f, ensure_ascii=False, indent=2)
136
+ print(f"[pipeline] manifest -> {manifest}")
137
+
138
+ best = out_dir / "indigo_best.safetensors"
139
+ if args.finalize:
140
+ has_best = (out_dir / "indigo_best.safetensors").exists()
141
+ has_final = (out_dir / "indigo.safetensors").exists()
142
+ if not has_best and not has_final:
143
+ raise SystemExit("finalize dibatalkan: tidak ada checkpoint")
144
+ if not has_best:
145
+ print("[pipeline] peringatan: tanpa data validasi; memakai checkpoint akhir sebagai best")
146
+ dst = ROOT / "out"
147
+ dst.mkdir(exist_ok=True)
148
+ copied = []
149
+ for name in ("indigo_best.safetensors", "indigo_best_meta.json",
150
+ "indigo.safetensors", "indigo_meta.json", "indigo_optimizer.pt"):
151
+ srcp = out_dir / name
152
+ if srcp.exists():
153
+ shutil.copy2(srcp, dst / name)
154
+ copied.append(name)
155
+ print(f"[pipeline] finalisasi ke out/: {', '.join(copied)}")
156
+
157
+ if args.push:
158
+ from huggingface_hub import HfApi
159
+
160
+ api = HfApi()
161
+ api.upload_file(
162
+ path_or_fileobj=str(best),
163
+ path_in_repo="out/indigo_best.safetensors",
164
+ repo_id=args.repo,
165
+ repo_type="model",
166
+ )
167
+ meta_f = out_dir / "indigo_best_meta.json"
168
+ if meta_f.exists():
169
+ api.upload_file(
170
+ path_or_fileobj=str(meta_f),
171
+ path_in_repo="out/indigo_best_meta.json",
172
+ repo_id=args.repo,
173
+ repo_type="model",
174
+ )
175
+ print(f"[pipeline] checkpoint best ter-upload ke {args.repo}")
176
+
177
+ print("[pipeline] selesai.")
178
+
179
+
180
+ if __name__ == "__main__":
181
+ main()