train: hubckpt -- download_checkpoint prefix/landing-dir fix (found by P1 v2)
Browse files- train/hubckpt.py +17 -5
train/hubckpt.py
CHANGED
|
@@ -211,15 +211,20 @@ def download_checkpoint(repo, path_in_repo, dest, api, repo_type="dataset", toke
|
|
| 211 |
"""
|
| 212 |
import time as _t
|
| 213 |
prefix = path_in_repo.rstrip("/") + "/"
|
| 214 |
-
|
| 215 |
-
if not
|
| 216 |
-
raise RuntimeError(f"{repo}
|
|
|
|
|
|
|
|
|
|
|
|
|
| 217 |
os.makedirs(dest, exist_ok=True)
|
| 218 |
t0 = _t.time()
|
| 219 |
tot = 0
|
|
|
|
| 220 |
for rel in sorted(have):
|
| 221 |
p = api.hf_hub_download(repo_id=repo, filename=prefix + rel, repo_type=repo_type,
|
| 222 |
-
|
| 223 |
sz = os.path.getsize(p)
|
| 224 |
if sz != have[rel][0]:
|
| 225 |
raise RuntimeError(f"{rel}: hub lists {have[rel][0]} bytes, {sz} arrived")
|
|
@@ -227,8 +232,15 @@ def download_checkpoint(repo, path_in_repo, dest, api, repo_type="dataset", toke
|
|
| 227 |
if sha and len(sha) == 64 and sha256_file(p) != sha:
|
| 228 |
raise RuntimeError(f"{rel}: sha256 does not match the hub's lfs oid")
|
| 229 |
tot += sz
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 230 |
return {"files": len(have), "bytes": tot, "seconds": round(_t.time() - t0, 1),
|
| 231 |
-
"
|
| 232 |
|
| 233 |
|
| 234 |
def write_latest_pointer(repo, cur, api, repo_type="dataset", token=None):
|
|
|
|
| 211 |
"""
|
| 212 |
import time as _t
|
| 213 |
prefix = path_in_repo.rstrip("/") + "/"
|
| 214 |
+
listing = hub_listing(repo, repo_type, token=token)
|
| 215 |
+
if not any(k.startswith(prefix) for k in listing):
|
| 216 |
+
raise RuntimeError(f"{repo} has no files under {prefix} -- refusing to resume from nothing")
|
| 217 |
+
# Keys come back as full repo paths; strip the prefix once here so `rel` and `filename` agree.
|
| 218 |
+
# (Passing prefix+full_path downstream asked the Hub for ckpt/x/ckpt/x/cursor.json -- a 404 that
|
| 219 |
+
# looked like a missing checkpoint, found by preflight P1 on CPU rather than mid-main-run.)
|
| 220 |
+
have = {k[len(prefix):]: v for k, v in listing.items() if k.startswith(prefix)}
|
| 221 |
os.makedirs(dest, exist_ok=True)
|
| 222 |
t0 = _t.time()
|
| 223 |
tot = 0
|
| 224 |
+
landed = []
|
| 225 |
for rel in sorted(have):
|
| 226 |
p = api.hf_hub_download(repo_id=repo, filename=prefix + rel, repo_type=repo_type,
|
| 227 |
+
local_dir=dest, token=token)
|
| 228 |
sz = os.path.getsize(p)
|
| 229 |
if sz != have[rel][0]:
|
| 230 |
raise RuntimeError(f"{rel}: hub lists {have[rel][0]} bytes, {sz} arrived")
|
|
|
|
| 232 |
if sha and len(sha) == 64 and sha256_file(p) != sha:
|
| 233 |
raise RuntimeError(f"{rel}: sha256 does not match the hub's lfs oid")
|
| 234 |
tot += sz
|
| 235 |
+
landed.append(p)
|
| 236 |
+
# local_dir mirrors the repo layout, so a checkpoint at ckpt/checkpoint-7/ lands *inside* dest with
|
| 237 |
+
# its subdirectories. The caller needs the directory that actually holds the weights, not the one it
|
| 238 |
+
# asked for, or the resume silently points at an empty prefix and starts from step 0.
|
| 239 |
+
dirs = {os.path.dirname(p) for p in landed}
|
| 240 |
+
if len(dirs) != 1:
|
| 241 |
+
raise RuntimeError(f"checkpoint files landed in {len(dirs)} directories: {sorted(dirs)[:4]}")
|
| 242 |
return {"files": len(have), "bytes": tot, "seconds": round(_t.time() - t0, 1),
|
| 243 |
+
"dir": dirs.pop(), "requested_dest": dest, "path_in_repo": path_in_repo}
|
| 244 |
|
| 245 |
|
| 246 |
def write_latest_pointer(repo, cur, api, repo_type="dataset", token=None):
|