Upload train/train_ounce100m.py with huggingface_hub
Browse files- train/train_ounce100m.py +35 -0
train/train_ounce100m.py
CHANGED
|
@@ -259,6 +259,15 @@ def main():
|
|
| 259 |
help="4 x 1024 x 32 accum x 2 cards = 262,144 tokens/step, the frozen batch size")
|
| 260 |
ap.add_argument("--accum", type=int, default=32)
|
| 261 |
ap.add_argument("--lr", type=float, default=6e-4)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 262 |
ap.add_argument("--tokens", type=int, default=1_000_000_000)
|
| 263 |
ap.add_argument("--max-steps", type=int, default=0, help="0 = derive from --tokens; >0 overrides")
|
| 264 |
ap.add_argument("--warmup-frac", type=float, default=0.02)
|
|
@@ -365,6 +374,20 @@ def main():
|
|
| 365 |
vstore = SD.PackedTokenStore(args.root, man, files=vs)
|
| 366 |
n_val = min(max(1, args.val_tokens // args.seq_len), vstore.total_tokens // args.seq_len)
|
| 367 |
val_ds = SD.make_dataset(vstore, args.seq_len, args.data_seed, shuffle=False, count=n_val)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 368 |
|
| 369 |
cfg = build_config(args.seq_len, args.layers or None, args.hidden or None, attn=args.attn)
|
| 370 |
set_seed(args.seed) # before init: both ranks must start from identical weights, not two draws
|
|
@@ -410,6 +433,10 @@ def main():
|
|
| 410 |
tacc = TrainingArguments(
|
| 411 |
output_dir=args.out,
|
| 412 |
per_device_train_batch_size=args.micro_batch,
|
|
|
|
|
|
|
|
|
|
|
|
|
| 413 |
gradient_accumulation_steps=args.accum,
|
| 414 |
learning_rate=args.lr,
|
| 415 |
weight_decay=0.1,
|
|
@@ -423,6 +450,12 @@ def main():
|
|
| 423 |
# measured decision, not a default: A-B found eager attention 52 % faster at seq 1024 and OOM at
|
| 424 |
# 2048; checkpointing is what makes eager at 2048 possible at all, at the cost of a recompute pass
|
| 425 |
gradient_checkpointing=args.grad_ckpt,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 426 |
ddp_find_unused_parameters=False,
|
| 427 |
dataloader_num_workers=2,
|
| 428 |
dataloader_pin_memory=False,
|
|
@@ -556,6 +589,8 @@ def main():
|
|
| 556 |
"accum": args.accum, "world": world,
|
| 557 |
"params": pc["sum_numel"], "attn": args.attn,
|
| 558 |
"grad_ckpt": bool(args.grad_ckpt),
|
|
|
|
|
|
|
| 559 |
"effective_attn": eff_attn,
|
| 560 |
"peak_gpu_gb": peak_gb()}, sort_keys=True))
|
| 561 |
|
|
|
|
| 259 |
help="4 x 1024 x 32 accum x 2 cards = 262,144 tokens/step, the frozen batch size")
|
| 260 |
ap.add_argument("--accum", type=int, default=32)
|
| 261 |
ap.add_argument("--lr", type=float, default=6e-4)
|
| 262 |
+
ap.add_argument("--optim", default="adamw_torch",
|
| 263 |
+
help="only mathematically-equivalent implementations are fair game at freeze time "
|
| 264 |
+
"(adamw_torch / adamw_torch_fused / adamw_apex_fused); 8-bit variants change the "
|
| 265 |
+
"update, so they are excluded by rule, not by preference")
|
| 266 |
+
ap.add_argument("--gc-nonreentrant", default=False, action=argparse.BooleanOptionalAction,
|
| 267 |
+
help="pass use_reentrant=False to gradient checkpointing: same recomputation, "
|
| 268 |
+
"different autograd path, and reports on whether it is faster under DDP conflict")
|
| 269 |
+
ap.add_argument("--torch-compile", default=False, action=argparse.BooleanOptionalAction,
|
| 270 |
+
help="Trainer's torch_compile hook; fused kernels, no change to the update rule")
|
| 271 |
ap.add_argument("--tokens", type=int, default=1_000_000_000)
|
| 272 |
ap.add_argument("--max-steps", type=int, default=0, help="0 = derive from --tokens; >0 overrides")
|
| 273 |
ap.add_argument("--warmup-frac", type=float, default=0.02)
|
|
|
|
| 374 |
vstore = SD.PackedTokenStore(args.root, man, files=vs)
|
| 375 |
n_val = min(max(1, args.val_tokens // args.seq_len), vstore.total_tokens // args.seq_len)
|
| 376 |
val_ds = SD.make_dataset(vstore, args.seq_len, args.data_seed, shuffle=False, count=n_val)
|
| 377 |
+
need = steps_planned * seqs_per_step
|
| 378 |
+
if len(train_ds) < need:
|
| 379 |
+
# Reading past the end of the stream makes the Trainer begin epoch 2 at the top of the same
|
| 380 |
+
# permutation: the run would then report the full token target while quietly re-training on the
|
| 381 |
+
# first windows. The mix is built with ~12 % headroom over the target for exactly this reason, so
|
| 382 |
+
# arriving here means that assumption stopped being true (review finding), and the honest response
|
| 383 |
+
# is to stop before step 1 rather than to discover it in the final report.
|
| 384 |
+
raise SystemExit(
|
| 385 |
+
f"dataset too small for the plan: {len(train_ds):,} windows available from sample "
|
| 386 |
+
f"{start_sample:,}, {need:,} needed for {steps_planned} steps x {seqs_per_step} sequences "
|
| 387 |
+
f"({need * args.seq_len:,} tokens). Lower --tokens to the 0.9 B fallback (D-012) or rebuild "
|
| 388 |
+
"the mix larger -- never let the epoch wrap.")
|
| 389 |
+
say(f"data: {len(train_ds):,} training windows available, {need:,} needed "
|
| 390 |
+
f"({100.0 * len(train_ds) / need - 100:.1f} % margin), {n_val:,} held-out val windows")
|
| 391 |
|
| 392 |
cfg = build_config(args.seq_len, args.layers or None, args.hidden or None, attn=args.attn)
|
| 393 |
set_seed(args.seed) # before init: both ranks must start from identical weights, not two draws
|
|
|
|
| 433 |
tacc = TrainingArguments(
|
| 434 |
output_dir=args.out,
|
| 435 |
per_device_train_batch_size=args.micro_batch,
|
| 436 |
+
# Same geometry for the validation pass: with the library default (8) the end-of-run eval measures
|
| 437 |
+
# a peak that has nothing to do with the training configuration, which is how an OOM in the no-
|
| 438 |
+
# checkpointing cell could be mistaken for a passing one (review finding).
|
| 439 |
+
per_device_eval_batch_size=args.micro_batch,
|
| 440 |
gradient_accumulation_steps=args.accum,
|
| 441 |
learning_rate=args.lr,
|
| 442 |
weight_decay=0.1,
|
|
|
|
| 450 |
# measured decision, not a default: A-B found eager attention 52 % faster at seq 1024 and OOM at
|
| 451 |
# 2048; checkpointing is what makes eager at 2048 possible at all, at the cost of a recompute pass
|
| 452 |
gradient_checkpointing=args.grad_ckpt,
|
| 453 |
+
# Same recomputation, different autograd path -- offered as a cells-vs-baseline question, not a
|
| 454 |
+
# belief. Reports on use_reentrant=False under DDP contradict each other across versions.
|
| 455 |
+
gradient_checkpointing_kwargs={"use_reentrant": not args.gc_nonreentrant}
|
| 456 |
+
if args.grad_ckpt else None,
|
| 457 |
+
optim=args.optim,
|
| 458 |
+
torch_compile=args.torch_compile,
|
| 459 |
ddp_find_unused_parameters=False,
|
| 460 |
dataloader_num_workers=2,
|
| 461 |
dataloader_pin_memory=False,
|
|
|
|
| 589 |
"accum": args.accum, "world": world,
|
| 590 |
"params": pc["sum_numel"], "attn": args.attn,
|
| 591 |
"grad_ckpt": bool(args.grad_ckpt),
|
| 592 |
+
"optim": args.optim, "gc_nonreentrant": bool(args.gc_nonreentrant),
|
| 593 |
+
"torch_compile": bool(args.torch_compile),
|
| 594 |
"effective_attn": eff_attn,
|
| 595 |
"peak_gpu_gb": peak_gb()}, sort_keys=True))
|
| 596 |
|