p4_stop_probe: dated scratch ckpt repo per attempt instead of clearing one (v3 died on HfApi.delete_folder's argument order in 20 s); define PROBE before the argv that uses it
Browse files- kernels/p4_stop_probe.py +8 -39
kernels/p4_stop_probe.py
CHANGED
|
@@ -48,7 +48,11 @@ import hubckpt
|
|
| 48 |
from huggingface_hub import HfApi
|
| 49 |
|
| 50 |
MIX = "Cion-lab/ounce100m-mix-v1"
|
| 51 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 52 |
ROOT, RUN = "/kaggle/working/mixroot", "/kaggle/working/run"
|
| 53 |
# Two modes, one file, so the assertions are literally the same code in both. `smoke` is the user's
|
| 54 |
# suggestion and it is the right order: 20 steps costs ~12 minutes and answers "does the training code run
|
|
@@ -126,7 +130,8 @@ rc, out = run([sys.executable, "-c",
|
|
| 126 |
if rc != 0:
|
| 127 |
raise SystemExit("VERDICT P4PROBE_STOP could not fetch the published mix")
|
| 128 |
man = json.load(open(os.path.join(ROOT, "manifest.json")))
|
| 129 |
-
print("mix", man["n_shards"], "shards", format(int(man["total_tokens"]), ","), "tokens",
|
|
|
|
| 130 |
|
| 131 |
common = ["train_ounce100m.py", "--root", ROOT, "--out", RUN,
|
| 132 |
"--hub-repo", PROBE, "--prune", "--seq-len", "1024", "--attn", "eager",
|
|
@@ -149,43 +154,7 @@ def diag(tag):
|
|
| 149 |
return out
|
| 150 |
|
| 151 |
|
| 152 |
-
|
| 153 |
-
"""Empty the scratch checkpoint repo before leg 1.
|
| 154 |
-
|
| 155 |
-
Probe 1 v2 was refused at 48 s for exactly the right reason: v1 had left `final` at step 20 in this
|
| 156 |
-
repo, so `--stop-after-steps 10` is not beyond the resume point and the new guard stopped it. The
|
| 157 |
-
refusal is the guard working; the dirty repo is what this reset exists for.
|
| 158 |
-
"""
|
| 159 |
-
api = HfApi(token=os.environ["HF_TOKEN"])
|
| 160 |
-
try:
|
| 161 |
-
names = list(api.list_repo_files(PROBE, repo_type="dataset"))
|
| 162 |
-
except Exception as e:
|
| 163 |
-
print("probe repo unreadable (%s) -- creating it fresh" % type(e).__name__, flush=True)
|
| 164 |
-
api.create_repo(PROBE, repo_type="dataset", private=False, exist_ok=True)
|
| 165 |
-
names = []
|
| 166 |
-
gone = []
|
| 167 |
-
for folder in ("ckpt", "final"):
|
| 168 |
-
if any(n.startswith(folder + "/") for n in names):
|
| 169 |
-
try:
|
| 170 |
-
api.delete_folder(PROBE, path_in_repo=folder, repo_type="dataset")
|
| 171 |
-
gone.append(folder + "/")
|
| 172 |
-
except Exception as e:
|
| 173 |
-
print(" delete_folder %s: %s %s" % (folder, type(e).__name__, str(e)[:120]), flush=True)
|
| 174 |
-
if "latest.json" in names:
|
| 175 |
-
try:
|
| 176 |
-
api.delete_file(PROBE, path_in_repo="latest.json", repo_type="dataset")
|
| 177 |
-
gone.append("latest.json")
|
| 178 |
-
except Exception as e:
|
| 179 |
-
print(" delete_file latest.json: %s %s" % (type(e).__name__, str(e)[:120]), flush=True)
|
| 180 |
-
ptr = hubckpt.latest_pointer(PROBE, token=os.environ["HF_TOKEN"])
|
| 181 |
-
print("PROBE_RESET deleted", gone, "pointer now",
|
| 182 |
-
{k: ptr.get(k) for k in ("step", "not_found", "error")}, flush=True)
|
| 183 |
-
if not ptr.get("not_found") and int(ptr.get("step") or 0) != 0:
|
| 184 |
-
raise SystemExit("the scratch repo still points at step %s after the reset -- refusing to run a "
|
| 185 |
-
"probe whose first leg would resume from a previous attempt" % ptr.get("step"))
|
| 186 |
-
|
| 187 |
-
|
| 188 |
-
reset_probe_repo()
|
| 189 |
shutil.rmtree(RUN, ignore_errors=True)
|
| 190 |
rc1, o1 = run(TORCHRUN + common + ["--stop-after-steps", str(STOP1)], "LEG1_STOP_EARLY", T_LEG1)
|
| 191 |
if rc1 != 0:
|
|
|
|
| 48 |
from huggingface_hub import HfApi
|
| 49 |
|
| 50 |
MIX = "Cion-lab/ounce100m-mix-v1"
|
| 51 |
+
# A scratch repo per attempt (dated), never the real run's repo: v1 left `final` at step 20 and v2 was
|
| 52 |
+
# correctly refused by the stale-stop guard, so rather than clearing state between attempts each one gets an
|
| 53 |
+
# empty repo. That also makes every attempt walk the RepoMissing resume branch (E-034) that session 1 hits.
|
| 54 |
+
PROBE = os.environ.get("P4_PROBE_REPO") or (
|
| 55 |
+
"Cion-lab/ounce100m-ckpt-probe-" + time.strftime("%m%d-%H%M", time.gmtime()))
|
| 56 |
ROOT, RUN = "/kaggle/working/mixroot", "/kaggle/working/run"
|
| 57 |
# Two modes, one file, so the assertions are literally the same code in both. `smoke` is the user's
|
| 58 |
# suggestion and it is the right order: 20 steps costs ~12 minutes and answers "does the training code run
|
|
|
|
| 130 |
if rc != 0:
|
| 131 |
raise SystemExit("VERDICT P4PROBE_STOP could not fetch the published mix")
|
| 132 |
man = json.load(open(os.path.join(ROOT, "manifest.json")))
|
| 133 |
+
print("mix", man["n_shards"], "shards", format(int(man["total_tokens"]), ","), "tokens",
|
| 134 |
+
"| probe repo", PROBE, flush=True)
|
| 135 |
|
| 136 |
common = ["train_ounce100m.py", "--root", ROOT, "--out", RUN,
|
| 137 |
"--hub-repo", PROBE, "--prune", "--seq-len", "1024", "--attn", "eager",
|
|
|
|
| 154 |
return out
|
| 155 |
|
| 156 |
|
| 157 |
+
print("PROBE_REPO", PROBE, flush=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 158 |
shutil.rmtree(RUN, ignore_errors=True)
|
| 159 |
rc1, o1 = run(TORCHRUN + common + ["--stop-after-steps", str(STOP1)], "LEG1_STOP_EARLY", T_LEG1)
|
| 160 |
if rc1 != 0:
|