Download code/tests/test_data_store.py from viai957/align: direct link, hf CLI and curl.
- Browser
- Download file 7.82 kB
-
https://huggingface.co/viai957/align/resolve/main/code/tests/test_data_store.py
- Command line
-
hf download hf://viai957/align/code/tests/test_data_store.py
-
curl -L -o test_data_store.py https://huggingface.co/viai957/align/resolve/main/code/tests/test_data_store.py
7.82 kB
| """Ragged shard store + receipts. | |
| Run: uv run pytest tests/test_data_store.py -m "not gpu" -v | |
| The store is the only place training data enters the run, so it is where the | |
| "missing value silently replaced by a plausible one" failure class has to be | |
| made impossible: `problem_id`, `subject` and the per-row boundary receipt are | |
| MANDATORY keyword arguments with no defaults, validated at write time. | |
| """ | |
| from __future__ import annotations | |
| import json | |
| import os | |
| import numpy as np | |
| import pytest | |
| from align.data import tokenization as tk | |
| from align.data.store import ( | |
| ShardDataset, | |
| ShardReader, | |
| ShardWriter, | |
| read_shard_receipt, | |
| ) | |
| NL = 781 # test-side constant; the PACKAGE derives it, never hardcodes it | |
| def _spec() -> tk.BoundarySpec: | |
| return tk.BoundarySpec(newline_id=NL, tokenizer_hash="test", vocab_absorbers=0) | |
| def _row_ids(n_steps: int) -> list[int]: | |
| """A synthetic token row with `n_steps - 1` newline-bigram boundaries.""" | |
| out: list[int] = [] | |
| for k in range(n_steps): | |
| if k: | |
| out += [NL, NL] | |
| out += [100 + k, 200 + k, 300 + k] | |
| return out | |
| def test_shard_metadata_carries_problem_id_and_subject(tmp_workdir): | |
| """Every row written to a shard round-trips problem_id and subject via | |
| metadata extras. | |
| Incident: the predecessor added these post-hoc -- subject was `null` on all | |
| 10,606 RL prompts and Stage 4 would have aborted AFTER loading a 7B model. | |
| Here they are build-time mandatory and travel with the row.""" | |
| spec = _spec() | |
| with ShardWriter(tmp_workdir, "sft-0000") as w: | |
| for i in range(5): | |
| ids = _row_ids(i + 2) | |
| w.add_row( | |
| ids, | |
| problem_id=f"pid{i:04d}", | |
| subject=["Algebra", "Geometry"][i % 2], | |
| boundary_positions=tk.find_step_boundaries(ids, spec.newline_id), | |
| ) | |
| receipt = w.receipt | |
| assert receipt.n_rows == 5 | |
| r = ShardReader(tmp_workdir, "sft-0000") | |
| assert len(r) == 5 | |
| for i in range(5): | |
| row = r[i] | |
| assert row.problem_id == f"pid{i:04d}" | |
| assert row.subject == ["Algebra", "Geometry"][i % 2] | |
| assert row.input_ids.tolist() == _row_ids(i + 2) | |
| # The receipt is on disk and reloads identically -- the manifest quotes it. | |
| assert read_shard_receipt(tmp_workdir, "sft-0000") == receipt | |
| def test_receipts_roundtrip_against_fresh_scan(tmp_workdir): | |
| """Boundary positions stored in shard extras match a fresh integer scan of | |
| the stored input_ids for EVERY row of a small built shard (uses the | |
| section-02 scan; no decode anywhere). | |
| Incident: a receipt that drifts from the ids it describes is undetectable | |
| downstream -- interp would patch the wrong positions and report a real | |
| number about the wrong tokens.""" | |
| spec = _spec() | |
| with ShardWriter(tmp_workdir, "sft-0000") as w: | |
| for i in range(8): | |
| ids = _row_ids(i + 1) | |
| w.add_row( | |
| ids, | |
| problem_id=f"p{i}", | |
| subject="Algebra", | |
| boundary_positions=tk.find_step_boundaries(ids, spec.newline_id), | |
| ) | |
| ds = ShardDataset(tmp_workdir) | |
| assert len(ds) == 8 | |
| checked = 0 | |
| for i in range(len(ds)): | |
| row = ds[i] | |
| fresh = tk.find_step_boundaries(row.input_ids.tolist(), spec.newline_id) | |
| assert row.boundary_positions.tolist() == fresh | |
| checked += 1 | |
| assert checked == 8 | |
| def test_row_missing_mandatory_extras_raises(tmp_workdir): | |
| """Writing a row without problem_id/subject/boundary receipts raises; the | |
| store never backfills a plausible default (the silent-substitution failure | |
| class). Both directions: a complete row writes silently.""" | |
| spec = _spec() | |
| ids = _row_ids(3) | |
| good = tk.find_step_boundaries(ids, spec.newline_id) | |
| with ShardWriter(tmp_workdir, "s0") as w: | |
| with pytest.raises(TypeError): | |
| w.add_row(ids, subject="Algebra", boundary_positions=good) | |
| with pytest.raises(TypeError): | |
| w.add_row(ids, problem_id="p", boundary_positions=good) | |
| with pytest.raises(TypeError): | |
| w.add_row(ids, problem_id="p", subject="Algebra") | |
| for bad in ("", None): | |
| with pytest.raises(ValueError): | |
| w.add_row(ids, problem_id=bad, subject="Algebra", boundary_positions=good) | |
| with pytest.raises(ValueError): | |
| w.add_row(ids, problem_id="p", subject=bad, boundary_positions=good) | |
| # A receipt pointing outside the row is a corrupt receipt, not a row | |
| # to be quietly clipped. | |
| with pytest.raises(ValueError): | |
| w.add_row(ids, problem_id="p", subject="Algebra", boundary_positions=[len(ids) + 5]) | |
| with pytest.raises(ValueError): | |
| w.add_row( | |
| ids, problem_id="p", subject="Algebra", boundary_positions=[good[-1], good[0]] | |
| ) # not increasing | |
| # Silent direction: the complete row goes through. | |
| w.add_row(ids, problem_id="p", subject="Algebra", boundary_positions=good) | |
| assert w.receipt.n_rows == 1 | |
| def test_content_hash_detects_a_flipped_token(tmp_workdir): | |
| """The shard content hash is what the build manifest pins, so it must | |
| change when a single stored token changes. Both directions: an identical | |
| rebuild reproduces the hash exactly.""" | |
| spec = _spec() | |
| def build(dirname: str, tweak: int) -> str: | |
| d = os.path.join(tmp_workdir, dirname) | |
| with ShardWriter(d, "s") as w: | |
| ids = _row_ids(3) | |
| ids[0] += tweak | |
| w.add_row( | |
| ids, | |
| problem_id="p", | |
| subject="Algebra", | |
| boundary_positions=tk.find_step_boundaries(ids, spec.newline_id), | |
| ) | |
| return w.receipt.content_hash | |
| a = build("a", 0) | |
| b = build("b", 0) | |
| c = build("c", 1) | |
| assert a == b # deterministic rebuild | |
| assert a != c # one flipped token changes the hash | |
| def test_extras_sidecar_is_one_json_object_per_row(tmp_workdir): | |
| """The extras sidecar is line-delimited so a shard streams; a row count | |
| mismatch between the binary blob and the sidecar raises at open time | |
| rather than mis-pairing metadata with tokens.""" | |
| spec = _spec() | |
| with ShardWriter(tmp_workdir, "s") as w: | |
| for i in range(3): | |
| ids = _row_ids(2) | |
| w.add_row( | |
| ids, | |
| problem_id=f"p{i}", | |
| subject="Algebra", | |
| boundary_positions=tk.find_step_boundaries(ids, spec.newline_id), | |
| ) | |
| path = os.path.join(tmp_workdir, "s.extras.jsonl") | |
| lines = [json.loads(ln) for ln in open(path) if ln.strip()] | |
| assert len(lines) == 3 | |
| assert {"problem_id", "subject", "boundary_positions"} <= set(lines[0]) | |
| with open(path, "a") as f: | |
| f.write( | |
| json.dumps({"problem_id": "ghost", "subject": "Algebra", "boundary_positions": []}) | |
| + "\n" | |
| ) | |
| with pytest.raises(RuntimeError, match="row count"): | |
| ShardReader(tmp_workdir, "s") | |
| def test_lengths_read_from_index_only(tmp_workdir): | |
| """Length-grouped batching scans every row length each epoch; that scan | |
| must not touch the data pages (it would page in the whole corpus on a box | |
| with no swap).""" | |
| spec = _spec() | |
| with ShardWriter(tmp_workdir, "s") as w: | |
| for i in range(6): | |
| ids = _row_ids(i + 1) | |
| w.add_row( | |
| ids, | |
| problem_id=f"p{i}", | |
| subject="Algebra", | |
| boundary_positions=tk.find_step_boundaries(ids, spec.newline_id), | |
| ) | |
| ds = ShardDataset(tmp_workdir) | |
| lengths = ds.lengths() | |
| assert lengths.tolist() == [len(_row_ids(i + 1)) for i in range(6)] | |
| assert isinstance(lengths, np.ndarray) | |