Skip to content

Commit 43ca69d

Browse files
author
Ronald Tse
committed
fix: resumable parity reference decode
Five consecutive ara-diac2 gate attempts died mid-reference-decode (39min-2.5h, variable, traceback-less container kills — localized by the stage log: every attempt logged start, none logged reference-decode done). The reference now checkpoints per-input to reference_progress.jsonl on the volume and resumes on relaunch — the same pattern the r-series evals have used since r5. Kills now cost only the undecoded tail.
1 parent 0304f6f commit 43ca69d

2 files changed

Lines changed: 38 additions & 3 deletions

File tree

src/gpu/modal_export.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,12 @@ def stage(event: str) -> None:
294294
MODELS_VOLUME.commit()
295295

296296
stage(f"start model={model_id} pairs={len(pairs)}")
297-
reference = reference_decode(model, [src for src, _ in pairs], max_len=128)
297+
reference = reference_decode(
298+
model,
299+
[src for src, _ in pairs],
300+
max_len=128,
301+
resume_path=Path("/outputs/imf") / model_id / "reference_progress.jsonl",
302+
)
298303
stage("reference-decode done")
299304

300305
out_dir = Path("/outputs/imf") / model_id

src/imf/parity.py

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,9 +118,39 @@ def _sessions_from_zip(zip_path: Path):
118118
return enc, dec
119119

120120

121-
def reference_decode(model, sources, max_len: int = 256) -> list[list[int]]:
121+
def reference_decode(model, sources, max_len: int = 256, resume_path=None):
122122
"""Torch-reference greedy decode of many inputs, computed once and
123-
shared across precision variants by run_parity."""
123+
shared across precision variants by run_parity.
124+
125+
resume_path: append-only JSONL of per-input results. Container-level
126+
kills (variable-lifetime, traceback-less — observed five times on
127+
ara-diac2) then cost only the tail: a relaunch resumes from the
128+
saved prefix instead of redoing hours of decode."""
129+
if resume_path is not None:
130+
import json as _json
131+
from pathlib import Path as _Path
132+
133+
resume_path = _Path(resume_path)
134+
done: dict[int, list[int]] = {}
135+
if resume_path.exists():
136+
for line in resume_path.read_text(encoding="utf-8").splitlines():
137+
if line.strip():
138+
row = _json.loads(line)
139+
done[row["i"]] = row["tokens"]
140+
results: list[list[int]] = [[]] * len(sources)
141+
with resume_path.open("a", encoding="utf-8") as fh:
142+
for i, source in enumerate(sources):
143+
if i in done:
144+
results[i] = done[i]
145+
continue
146+
tokens = _torch_greedy_tokens(model, source, max_len)
147+
results[i] = tokens
148+
fh.write(
149+
_json.dumps({"i": i, "tokens": tokens}, ensure_ascii=False) + "\n"
150+
)
151+
if i % 100 == 0:
152+
fh.flush()
153+
return results
124154
return [_torch_greedy_tokens(model, source, max_len) for source in sources]
125155

126156

0 commit comments

Comments
 (0)