Andrej Karpathy commited on
Commit ·
07c4dd4
1
Parent(s): e8fec97
manually control the over-active garbage collector, save a small few minutes from a typical run
Browse files- scripts/base_train.py +12 -0
scripts/base_train.py
CHANGED
|
@@ -11,6 +11,7 @@ If you are only on CPU/Macbook, you'll want to train a much much smaller LLM. Ex
|
|
| 11 |
python -m scripts.base_train --depth=4 --max-seq-len=512 --device-batch-size=1 --eval-tokens=512 --core-metric-every=-1 --total-batch-size=512 --num-iterations=20
|
| 12 |
"""
|
| 13 |
|
|
|
|
| 14 |
import os
|
| 15 |
os.environ["PYTORCH_ALLOC_CONF"] = "expandable_segments:True"
|
| 16 |
import argparse
|
|
@@ -429,8 +430,19 @@ while True:
|
|
| 429 |
wandb_run.log(log_data)
|
| 430 |
|
| 431 |
# state update
|
|
|
|
| 432 |
step += 1
|
| 433 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 434 |
# print a few more stats
|
| 435 |
print0(f"Peak memory usage: {get_max_memory() / 1024 / 1024:.2f}MiB")
|
| 436 |
print0(f"Total training time: {total_training_time/60:.2f}m")
|
|
|
|
| 11 |
python -m scripts.base_train --depth=4 --max-seq-len=512 --device-batch-size=1 --eval-tokens=512 --core-metric-every=-1 --total-batch-size=512 --num-iterations=20
|
| 12 |
"""
|
| 13 |
|
| 14 |
+
import gc
|
| 15 |
import os
|
| 16 |
os.environ["PYTORCH_ALLOC_CONF"] = "expandable_segments:True"
|
| 17 |
import argparse
|
|
|
|
| 430 |
wandb_run.log(log_data)
|
| 431 |
|
| 432 |
# state update
|
| 433 |
+
first_step_of_run = (step == 0) or (resuming and step == args.resume_from_step)
|
| 434 |
step += 1
|
| 435 |
|
| 436 |
+
# The garbage collector is sadly a little bit overactive and for some poorly understood reason,
|
| 437 |
+
# it spends ~500ms scanning for cycles quite frequently, just to end up cleaning up very few tiny objects each time.
|
| 438 |
+
# So we manually manage and help it out here
|
| 439 |
+
if first_step_of_run:
|
| 440 |
+
gc.collect() # manually collect a lot of garbage from setup
|
| 441 |
+
gc.freeze() # immediately freeze all currently surviving objects and exclude them from GC
|
| 442 |
+
gc.disable() # nuclear intervention here: disable GC entirely except:
|
| 443 |
+
elif step % 5000 == 0: # every 5000 steps...
|
| 444 |
+
gc.collect() # manually collect, just to be safe for very, very long runs
|
| 445 |
+
|
| 446 |
# print a few more stats
|
| 447 |
print0(f"Peak memory usage: {get_max_memory() / 1024 / 1024:.2f}MiB")
|
| 448 |
print0(f"Total training time: {total_training_time/60:.2f}m")
|