Skip to content

valen: export the trained stack to an unmerged safetensors artifact set - #147

Open
MrDongsls wants to merge 35 commits into
InferMatrixLab:mainfrom
MrDongsls:spec/valen-export
Open

MrDongsls wants to merge 35 commits into
InferMatrixLab:mainfrom
MrDongsls:spec/valen-export

Conversation

@MrDongsls

@MrDongsls MrDongsls commented Oct 15, 2026 •

Copy link
Copy Markdown
Collaborator

Stacks on #146 (model/valen-noul-score) — merge #146 first; this PR's diff shows both changes until then, and drops the noul/score commits automatically once #146 merges.

Required human contributor answers

  1. What outcome are you trying to achieve?

Make the pinned Valen checkpoint loadable outside the training-framework pickle, with proof it computes identically.

  1. What is the highest-leverage variable for that outcome?

Numerical parity between the exported artifact set and the original checkpoint through the same kernels.

  1. How will this work move that variable rather than create busywork?

Every transformation is recorded in a JSON manifest, the LoRA application semantics are anchored, and the parity gate and determinism check are reproducible.

  1. Who is the customer or user, and what do they actually need?

Valen users who need a loadable artifact set with provenance.

After answering the four questions: is a PR needed at all to achieve this outcome?

Yes, without this every consumer converts the pickle on its own.

For a bug fix: link actual observed failure evidence.

N/A.

Purpose

One deterministic command turns the pinned checkpoint.pt plus its Qwen3.5-2B base into a five-file safetensors artifact set:

  • model.safetensors — the base verbatim, except the trained vision-top blocks 20–23 and merger as plain BF16 replacements, and the 36 FP32 tensors downcast to BF16 (lossless against the reference's BF16 runtime).
  • lora.safetensors — the 372 FP32 LoRA tensors verbatim under their PEFT key names, served unmerged; the manifest's lora block records the rank 32 / alpha 64 / scale 2 configuration and the application semantics a consumer implements (BF16 base GEMM plus the FP32 delta on the activations, one final rounding — peft 0.18.1 Linear.forward boundaries).
  • head.safetensors — the decision head's two FP32 (256×2048) projections, no bias.
  • config.json — the base config copied verbatim for from_pretrained.
  • valen_export.json — the manifest (valen-checkpoint-export/2): per-tensor name/shape/dtype/component/provenance, source revisions and SHA-256s, the downcast list, the head configuration, the consumption path, and the parity record.

The export enforces the artifact pins before writing, is deterministic and byte-identical, and validates with streaming digests.

Worker behavior is unchanged; no Rust changes.

Large-change packaging

Added for review readiness (measured at the current head: code/test +4702/−102, total +5210/−143 over 24 files):

  • Size, authored vs total: authored code/tests are +4860/−102 across 16 files (the export tool, the parity gate, the shared comparison, their Python tests, and the export battery implementation under tests/valen/export_reference_checks.py); the total text diff is 25 files, +5376/−143. Excluded from the authored count as docs/fixtures/registration: 9 files, +516/−41 (export.md + reference.md, the model README, the two example request JSONs, and the README / supported-models / mkdocs / recipe-README rows). Measured with git diff --numstat f5ae5acf..7a801f01 (merge-base with main at the current head).
  • Why it stays one PR: the artifact set and its proof are one contract — the manifest schema, the exporter that writes it, the parity gate that fills its parity slot and the tests that mutation-check it only have meaning together, so splitting export from verification would land an unverifiable artifact format first and re-review the same manifest code twice; the one independent seam is the Valen: serve noul and score questions through the reference worker #146 noul/score work, which is already split out and merges first.
  • Component review order: 1. recipe/valen/export_checkpoint.py (deterministic export + manifest schema) → 2. recipe/valen/verify_export_parity.py (dual-stack gate, non-finite rejection) → 3. recipe/valen/compare_reference.py + its test script (shared comparison + regressions, non-finite scalar rejection) → 4. tests/valen/test_export.py, tests/valen/test_export_parity.py, recipe/valen/test_export_reference.py → 5. docs and registration, read last.

Test Plan

From the repository root with the pinned artifacts (recipe/valen/reference.md documents the setup):

PYTHONPATH=src .venv/bin/python -m pytest tests/valen -q
PYTHONPATH=src .venv/bin/python -m compileall -q \
  recipe/valen tests/valen/test_export.py tests/valen/test_export_parity.py
.venv/bin/python recipe/valen/test_export_reference.py
VALEN_EXPORT=weights/valen-export .venv/bin/python recipe/valen/test_export_reference.py
# CPU-only, run twice and compare digests:
PYTHONPATH=src .venv/bin/python recipe/valen/export_checkpoint.py \
  --checkpoint "$VALEN_CKPT" --base "$VALEN_BASE" --out <dir>
# GPU host (serial dual-stack, one subprocess per load):
.venv/bin/python recipe/valen/verify_export_parity.py \
  --valen-source "$VALEN_SRC" --checkpoint "$VALEN_CKPT" \
  --base "$VALEN_BASE" --export weights/valen-export --device cuda

Test Result

System1-Omni Version / Commit: head 7a801f01 on spec/valen-export (based on model/valen-noul-score 40f991c, which merges current main f5ae5ac and forward-ports the non-finite gates into #146); the CPU checks were re-run from this committed tree, and the determinism gate (double export, byte-identical) was re-run against the pinned artifacts at 70478332 — the follow-up commits (80dcc6a3 merge, ab7bf996 sourceless-stray gate, 7a801f01 battery relocation) touch only the clean-source gate, its regressions, the battery's location and docs, none of which participates in the export/parity path the determinism and GPU records pin. The GPU parity record is the run pinned in recipe/valen/reference.md and the exported manifest's parity slot.

Validated on WSL2 x86_64, RTX 5060 Laptop GPU (sm_120), BF16, PyTorch 2.11.0+cu128, peft 0.18.1, pinned Valen source / Preview checkpoint / Qwen3.5-2B base:

  • pytest tests/valen: 115 passed, 2 artifact-gated skips at the current head (110 + the five clean-source-gate regressions and the shared-gate pin).

  • compileall, test_export_reference.py (with and without VALEN_EXPORT, and without PYTHONPATH=src, as documented): pass.

  • compare_reference.py --case all on the GPU host: 4/4 cases (image, text, noul, score) PASS at the declared 1e-6 tolerance, re-run at this head after the non-finite scalar gate.

  • Determinism: two consecutive exports produce identical files; manifest files digests — model.safetensors 4,548,216,808 B 0313882b…, lora.safetensors 134,613,824 B 4f6d9590…, head.safetensors f365a09e…, config.json ed1c1723….

  • Parity: passed with max probability delta 0.0 on both the text and image fixtures — exact answer agreement, equal tokens (48/48 and 108/108), at the declared 1e-6 tolerance. Verbatim block below; recorded in recipe/valen/reference.md and the manifest's parity slot (tool-filled; re-runs refuse to overwrite a different record).

  • Manifest audit: 1006 tensor records, 36 declared downcasts, mutation-tested tamper detection.

  • Review-follow-up re-verification at 7a801f01 (sourceless-stray gate + battery relocation): pytest tests/valen 115 passed, 2 artifact-gated skips; test_compare_reference.py 35/35 ok; test_export_reference.py ok (2 skips); test_compare_with_backend.py ok; compileall passed; mkdocs build --strict passed; pytest tests/benchmarks 65 passed. The reviewer's sourceless-module repro (a standalone importable peft.pyc beside a clean tracked tree) is now rejected by _verify_clean_checkout before any record is produced, and the same gate serves both evidence entrypoints (verify_export_parity.stage_environment calls reference._verify_clean_checkout).
    Not run / unverified: the Rust suite (no Rust changed; CI covers it), any other hardware, and consumption by an actual native Rust loader — the consumption path is documented in the manifest and exercised here through from_pretrained plus the peft application; the native worker is separate upcoming work.

Demo / evidence

Nonvisual tooling change: video N/A. The evidence is the parity record — verbatim verify_export_parity.py output at the PR head, also recorded in recipe/valen/reference.md with reproduction commands and the pinned revisions:

case: text
logical tokens: 48
compute tokens: 48
max probability delta: 0.0000000000e+00
answer agreement: PASS
probability tolerance <= 1e-06: PASS
token accounting: PASS

case: image
logical tokens: 108
compute tokens: 108
max probability delta: 0.0000000000e+00
answer agreement: PASS
probability tolerance <= 1e-06: PASS
token accounting: PASS

device: cuda:0 (NVIDIA GeForce RTX 5060 Laptop GPU (sm_120, 7.96 GiB))
parity slot filled: weights/valen-export/valen_export.json
verify_export_parity: ok

Usage and artifact documentation: recipe/valen/export.md; the manifest schema is documented in the tool's docstrings.

Self-review

  • I have reviewed the full diff and addressed the issues I found.
  • I have checked that the change follows the project's architecture and stays focused on the stated purpose.
  • I have run the checks appropriate to this change and reported commands, results, and anything I could not verify above.
  • I have checked that the PR description, documentation, and any accuracy or performance claims match the implementation and available evidence.

Mr.Dong added 6 commits October 14, 2026 22:19
Extend the reference worker's contract with the two remaining Valen task
types alongside choice: noul (fixed or custom true/false wording, answered
as P(true) plus the probability pair and confidence) and score (2-10
ordered levels, per-level branches decoded as a cross-level softmax with
the expected level, legend and concentration confidence, formulas copied
from the pinned reference). Mixed-type requests share one state encoding;
usage keeps the logical/compute split.

Choice behavior is unchanged (the image/text parity blocks match the
merged records byte for byte); noul and score parity against the pinned
reference passes at 1e-6 on RTX 5060. 47 CPU tests; compare_reference
gains --case noul|score|all with new example requests.
The cardinality check's message read like the satisfied condition; name
the requirement so the 500-side error is actionable.

(cherry picked from commit 3afa240)
The noul/score blocks were originally recorded from a working tree, and the
rebase onto current upstream main (the reference slice landed as InferMatrixLab#115)
orphaned the earlier verification SHAs. All four parity blocks and the
frontend byte-identity were re-verified verbatim at 3afa240; the records now
reference that tree.

(cherry picked from commit 28072dc)
… the PR

Align the noul/score documentation with the d3 recipe convention: the
recipe records the procedure, commands and fixtures, while measured run
output — the observed responses, the verbatim noul/score parity blocks
and their provenance SHAs — lives in the pull request description. The
model README drops its duplicate request examples and states the compiler
record rules and answer fields in compact bullets. Only content this
branch added or rewrote changes; the InferMatrixLab#115 slice's records stay as they
were.
Address the review findings on compare_reference: dispatch the per-type
comparison on the type requested in the wire body (rejecting answers that
drift to another shape instead of silently skipping the noul/score checks),
and include the confidence delta in the pass criteria with its own
tolerance verdict line.
The four compare_reference blocks were re-run verbatim from the committed
tool at 507c448; every block now carries the confidence tolerance verdict
and the criteria paragraph states the requested-type and confidence gates.
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-15T14:18:18.454106Z 9f55f55 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

Mr.Dong added 16 commits October 15, 2026 22:14
The LoRA merge bf16(fp32(W) + 2*(B@A)) is verified bit-equal against the
pinned peft 0.18.1 Linear.merge on synthetic tensors; the FP32->BF16
downcast mirrors the reference's own from_pretrained cast. Checkpoint keys
decompose into LoRA pairs, vision-top blocks 20-23, merger and head with
strict rejection of anything outside the pinned vision_top layout.
run_export writes model.safetensors (merged backbone in the base's own key
layout, BF16 only), the fp32 head.safetensors, the copied base config and
the valen_export.json contract through an incremental safetensors writer,
tensor by tensor in sorted order, so host memory stays far below the 4.5
GiB artifact set. validate_export re-reads headers and digests and rejects
tampered bytes, unlisted tensors, downcast-list drift and head-config
drift. The tiny synthetic fixture proves determinism and path
independence.
export() hashes checkpoint.pt and the base shard, checks them against
training_metadata.json, valen_manifest.json and the checkpoint's own
base_manifest (both record per-shard sha mappings), refuses any stage but
the pinned vision_top layout, and records the revisions, repo and tool
versions in the manifest sources. main() runs it as the one-command
recipe. The env-gated regression (VALEN_CKPT/VALEN_BASE) exports the real
artifacts twice and requires byte-identical output plus the pinned
inventory; run on this host it passed in 3m33s with all four files
identical across runs.
Add recipe/valen/verify_export_parity.py (spec 02, E2): it loads the
original pinned stack (ValenExecutor: base + unmerged FP32 LoRA +
checkpoint) and the exported stack (from_pretrained(weights/valen-export)
backbone + DecisionHead rebuilt from head.safetensors, run through the
pinned Valen class) serially, one subprocess each so the ~6.6 GiB VRAM
footprint never overlaps, answers the recipe's existing text and image
choice fixtures through the pinned Compiler, and gates on exact answer
agreement plus probability deltas <= 1e-6. It also measures the merge
drift of all 186 merged keys on the real tensors (research-001 method:
unmerged PEFT semantics vs the exported BF16 GEMM, 256 bf16 probe rows,
seed 0, CPU single thread), cross-checks every exported tensor bit-exactly
against E1's merge math, fills the manifest's parity slot with the
verdict and re-validates the artifact set.

tests/valen/test_export_parity.py covers the pure contract CPU-only
(bf16 ulp ruler, per-module drift against peft 0.18.1's Linear.forward,
aggregation, case verdicts, parity record + slot filling) and wires the
env-gated full-artifact regression (VALEN_CKPT/VALEN_BASE/VALEN_SRC +
CUDA), asserting the recorded verdict's internal consistency rather than
a desired outcome.
Add recipe/valen/export.md (usage, artifact inventory, manifest schema,
merge decision, downcasts, head, consumption, pins/licenses, parity
pointer) and recipe/valen/test_export_reference.py, which chains the
tests/valen/test_export.py battery and the env-gated real-artifact
determinism gate and validates an exported set through the tool's own
validate_export. Link the export from recipe/README.md,
src/models/valen/README.md and one line in reference.md.
Append the spec-02 export-parity block to recipe/valen/reference.md:
the two serially loaded stacks (original ValenExecutor build vs the
exported artifact set's documented consumption path), the verbatim gate
output on the RTX 5060 host (text delta 7.06e-04, image delta 1.73e-02,
exact answer agreement on both fixtures), the 186-module merge-drift
aggregate (max one BF16 ulp per adapted module, ~53% bit-exact, worst
relative drift 7.6e-3), the control checks (same-stack bit-identical
re-runs, original stack matching the committed serving records, exported
tensors bit-checked against the merge math), and the honest verdict: the
declared 1e-6 tolerance fails, so the spec-02 fallback (separate FP32
LoRA export, unmerged serving) is triggered; the merged set keeps exact
discrete answers and parity.status = failed in the manifest.
…iles

The manifest cross-check read every artifact whole (read_bytes), pulling
the ~4.5 GiB model.safetensors into host memory and contradicting the
documented headers-and-digests-only contract. Sizes now come from stat()
and digests from the module's streaming sha256_file, and the per-tensor
safetensors header check reuses one handle per file instead of reopening
per tensor.
A missing training_metadata.json silently skipped the checkpoint digest
check right before a weights_only=False unpickle, and the base weights
pins were conditional on both sides declaring a digest. Following the
worker precedent (engine.py pins unconditionally), a missing
training_metadata.json or an undeclared base digest is now an error;
the doc's pin paragraph says so.
verify_sources_match_manifest checked the checkpoint sha and base
revision strings but not the base weights digests the manifest records,
although 392 tensors pass through the export byte by byte. The gate now
re-hashes the base shard against sources.base.weights_sha256; tampered
records or swapped shard bytes are rejected before any model loads.
- validate_export counts every directory entry, so a stray subdirectory
  no longer bypasses the exactly-four-files audit;
- run_export cleans up its partial output on failure (removing a
  directory it created), so a failed run never blocks the retry;
- classify_checkpoint_weights rejects vision blocks outside 20-23, not
  only sub-20 blocks, matching the pinned vision_top inventory;
- drop the unused BACKBONE_PREFIX/VISUAL_PREFIX constants and the unused
  cuda mem_get_info free byte.
The fallback paragraph claimed the gate passes and the fallback is
deliberately unimplemented, contradicting reference.md's recorded FAILED
verdict (max probability delta 1.7e-2). It now states the failure and
leaves the fallback decision to the spec owner (local ticket E4). The
suite count is updated to the measured 105 passed / 2 artifact-gated
skips.
The recipe regression script introspects tests/valen/test_export.py and
injects fixtures by parameter name, but only knew tmp_path; the new
streaming/cleanup tests take monkeypatch and failed under the script
while passing under pytest. The battery now hands each test a fresh
pytest MonkeyPatch (undone after the test) for that parameter.
@MrDongsls MrDongsls changed the title Spec/valen export valen: export the trained stack to an unmerged safetensors artifact set Oct 15, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9f55f55088

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +935 to +936
payload = torch.load(
checkpoint_path, map_location="cpu", weights_only=False, mmap=True

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Verify the checkpoint against a trusted digest before loading

When --checkpoint points to a corrupted or attacker-supplied directory, its sibling training_metadata.json can simply declare the corrupted file's hash, so the preceding check is not a trust anchor. This call then uses weights_only=False, allowing pickle reducers to execute before any inventory validation; unlike ValenExecutor, the exporter never compares the file to the fixed CHECKPOINT_SHA256 in src/models/valen/engine.py. Verify the hard-coded pinned digest before this load (or avoid unrestricted pickle loading).

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 5bad3c1: the exporter now enforces the worker's pinned CHECKPOINT_SHA256 (src/models/valen/engine.py) before torch.load, so training_metadata.json remains a consistency record only. Regression test test_export_rejects_checkpoint_below_the_worker_pin proves the rejection fires before any unpickling.

Comment thread recipe/valen/compare_reference.py Outdated
Comment on lines +278 to +280
passed = decision_exact and legend_exact and prob_ok and tokens_exact
if scalar_answers:
passed = passed and max_answer_delta <= tolerance

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Gate noul and score parity on confidence

For the newly added noul/score cases, a regression in the worker's confidence formula can still make this harness exit successfully: max_conf_delta is computed and printed, but it is never included in passed. For example, matching probabilities, score, legend, and tokens with worker confidence 0.99 versus reference confidence 0.4 reports a 5.9e-01 confidence delta and still returns True, so the advertised reference comparison would not catch an incorrect response field.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed by 507c448 (the same fix as #146), which this branch includes since the rebase — the reviewed 9f55f55 was the pre-rebase tree: max_conf_delta is gated by its own confidence tolerance verdict line and included in passed.

from frontend.valen import _verify_source_revision

source = Path(args.valen_source).resolve()
_verify_source_revision(source)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Reject dirty Valen source checkouts during parity runs

When the pinned Valen checkout has local modifications, this check still passes because _verify_source_revision in src/frontend/valen.py only runs git rev-parse HEAD. Both the original and exported subprocesses then import the same modified compiler/model code, so a shared local change (for example, a changed Valen.forward) can make the two stacks agree and fill a passing parity record even though neither used the claimed pinned source; require a clean tracked working tree (and account for relevant untracked files) before producing evidence.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 5bad3c1 and extended in b6490ae: both evidence harnesses (verify_export_parity.py and compare_reference.py) now reject a dirty pinned checkout — tracked modifications and untracked .py files — before any record is produced, and reference.md's pre-flight checks match. Regression tests cover both rejection paths.

@hsliuustc0106 hsliuustc0106 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Independent review — PR #147 "valen: export the trained stack to an unmerged safetensors artifact set"

Reviewer: independent read-only review (system1-omni-review skill). No repo modifications, nothing posted to GitHub. Review body drafted 2026-10-18.

Provenance

  • Repository: ThinkFlowLab/system1-omni (ID 1386454853).
  • Base: main, live e66ff34996760a84ad56690f0ae4cf434e669e65 (moved past the PR's recorded base f2d3d3289…; the PR's stated upstream base 037c44b9… is the merge-base — main moved by the unrelated #111/#116 merges after branching). PR GitHub base field: f2d3d32897c1fe190fecf853a82a9456d3791462.
  • Head: 369202d60da14dd061936d03963671f78531a9da (spec/valen-export), re-fetched live before reporting; GitHub headRefOid matches.
  • Skill load record: .agents/skills/system1-omni-review/SKILL.md read from the local working tree, SHA-256 58be3bc60806c4c5af7038a0c6a80fadb94f3360d714556a3e965c8903dde108 (matches the pinned value). References actually read: docs/architecture.md (no export-specific clauses; export is recipe-level per the jemm/open_jev precedent), .agents/skills/system1-omni-review/references/repository-contracts.md, CONTRIBUTING.md at the head, .agents/skills/self-review/SKILL.md at the head (incl. Committed artifact hygiene), the Valen recipe and docs at the head.
  • Inspected scope: full git diff origin/main...origin/pr/147 (24 files, +4924/−144), deep read of the export-side files; the tree was extracted to /tmp/pr-review-2026-10-15/head (working tree untouched).

PR structure and stacking

  • The branch stacks on open PR #146 (model/valen-noul-score, head 75efa400…): commits 1–6 of this branch are #146's line. This is disclosed first thing in the PR body ("merge #146 first … drops the noul/score commits automatically once #146 merges").
  • Full diff vs main: 24 files, +4924/−144. Export-only delta (origin/pr/146...origin/pr/147): 12 files, +3672/−16 — export_checkpoint.py (1063), verify_export_parity.py (567), export.md (212), tests/valen/test_export.py (1099), tests/valen/test_export_parity.py (389), recipe/valen/test_export_reference.py (158), plus reference.md/README/compare_reference/mkdocs/recipe-README touches.
  • Authored vs total: all 25 commits authored by the PR author (Mr.Dong / MrDongsls); authored == total. Above the 3,000-line threshold, CONTRIBUTING's self-review requirements apply: full self-review checklist checked by the contributor, split rationale present (stacked PR, serving split from export), validation across affected areas present. The body has no explicit component map/review order — minor readiness note only, since the layout is recipe/tests/docs and the Purpose section enumerates the artifacts.
  • Merge order matters: until #146 merges, this PR's GitHub diff shows both lines. The export review below is based on the export-only delta plus the head tree.

Verdict

No blocking findings. The export side is unusually carefully engineered: pins enforced before the pickle is loaded, every artifact byte digest-pinned in the manifest, fail-closed validation of partial/tamper/stale states, deterministic streaming writer, and a parity gate whose executable form matches its declared semantics (tested bit-equal against installed peft). Findings below are low/informational.

Findings (by severity)

  1. Low — atomicity is exception-driven cleanup, not staging+rename. run_export (recipe/valen/export_checkpoint.py:330-384) writes in place into a fresh-or-empty --out and removes partial artifacts on any raised exception (tested: test_run_export_failure_leaves_no_partial_output, test_run_export_failure_cleans_preexisting_empty_output). A hard-killed process (SIGKILL/OOM/power loss) can leave partial files, and the not-empty guard then blocks retries until an operator removes the directory. Documented behavior; no corruption risk because validate_export rejects any non-exact directory. Temp-dir + atomic rename would close the gap.
  2. Low — compare_case zip truncation nit (recipe/valen/verify_export_parity.py:95-98): the original/exported probability lists are zipped without an equal-length check; a malformed stage payload with a different list length would silently truncate the max-delta scan. Candidate order is checked and both sides are produced by the same tool, so this is a robustness nit in the evidence harness, not a gate criterion.
  3. Low — run_export(base_config_path=None) writes a set its own validate_export rejects (allowed set requires config.json, export_checkpoint.py:690-709). Not reachable via export()/CLI/tests (all pass the config); API-surface consistency only.
  4. Info — the manifest does not record the exporting code's revision. sources records checkpoint SHA-256 + revision, per-shard base digests + revision + repo, and torch/safetensors/peft versions; the format string valen-checkpoint-export/2 is the contract anchor and the PR pins the code — but a repo commit field in sources would make the manifest self-contained for future audits. Note the asymmetry: the parity harness pins the Valen source revision and demands a clean checkout with no stray .py (_verify_clean_checkout), which is stronger than the #140 fixture-pinning precedent.
  5. Info — the artifact set deliberately excludes tokenizer/processor files ("Five files, nothing else"). "Nothing else is needed to reconstruct the model" is accurate; reconstructing the serving stack still needs the pinned base for the processor/tokenizer. A one-line note in export.md could preempt confusion. Optional.
  6. Info — supported-models row not extended for the export. The Valen row (docs/supported-models.md:18) is updated for noul/score but does not mention the export recipe; defensible, since the row's native-worker column is still "Not supported" and the export is reachable via recipe/README.md and the mkdocs nav. Revisit when the native consumer lands.

Per-focus review

1. Export identity/pinning

  • Pinned bytes: manifest.files carries size + SHA-256 for every non-manifest artifact: model.safetensors (~4.5 GiB), lora.safetensors, head.safetensors, config.json — four of four. The manifest itself (valen_export.json) cannot self-hash; its parity slot is filled only by the tool, formatting-preserving, refusing silent overwrite (fill_parity_slot, tested idempotent + refuse-without-force).
  • Source pins, fail-closed, before any write or unpickle: checkpoint.pt SHA-256 vs the worker's hard-coded CHECKPOINT_SHA256 (src/models/valen/engine.py:22, value matches the PR body and the env-gated test assertion 836622ef…f42f5a012); training_metadata.json must exist and agree; base shard digest must be declared by both valen_manifest.json and the checkpoint's embedded base_manifest with exact per-shard mapping, and revisions must agree; stage must be vision_top. Missing pins raise; they are never skipped (tests cover each missing/mismatched pin individually). This is the review-bot P1 from an earlier round, fixed and regression-tested ("the exporter must enforce the worker's pinned digest before the pickle is ever loaded").
  • Rejection of stale/partial exports: validate_export enforces exactly-five-files directory contents (extra files or directories fail), format match, streamed file digests + sizes, full two-way tensor inventory vs safetensors headers with shape/dtype, downcast list vs per-tensor flags, head-config consistency, and the adapter inventory (one A + one B per target at the declared rank, each mapping onto a listed backbone tensor). verify_export_parity additionally re-hashes the checkpoint and base shard against the manifest's sources before loading (a swapped base fails: test_verify_sources_rejects_swapped_base_shard_bytes).
  • #140 lesson (pin executables/config too): the parity harness pins the Valen source revision (frontend.valen._verify_source_revision) and rejects dirty checkouts or untracked .py files before evidence is produced. The export itself pins config.json bytes. No tokenizer is part of the artifact set (finding 5).

2. Unmerged-ness semantics

  • The set preserves original base weights + separate FP32 adapters + separate FP32 head: model.safetensors = base verbatim (578 pass-through, of which 36 FP32 linear_attn.A_log/norm.weight downcast to BF16) with trained vision-top blocks 20–23 and merger substituted as plain BF16 replacements (full tensors, not merges); lora.safetensors = 372 FP32 adapter tensors verbatim under PEFT key names; head.safetensors = 2 FP32 matrices. Exporting a merged path was deliberately dropped (commit "export the language LoRA separately and drop the merged path"), with the merge-vs-unmerged math documented (export.md: "Merging … changes the computed outputs relative to the trained artifact's unmerged semantics, which is why the export does not do it").
  • BF16 rounding locations are explicit and machine-checked: LORA_APPLICATION is recorded verbatim in the manifest (y = bf16(fp32(bf16(x @ W.t())) + scaling·((x.float() @ A.t()) @ B.t())) — base GEMM BF16, delta FP32, exactly one final rounding, peft 0.18.1 unmerged semantics with FP32 adapters) and unmerged_lora_output is its executable form, tested bit-exact against installed peft plus a hand-computed rounding case and a zero-B reduction case. Downcasts are claimed lossless against the reference's own BF16 runtime and gated: any FP32 base tensor outside the two declared families is an error. Head math stays FP32 with formulas recorded.
  • Loader-side contract: the manifest's consumption block + export.md's "Consumption" section specify the full load (from_pretrained backbone, peft re-wrap at manifest rank/alpha loading lora.safetensors by key with adapters kept FP32, head rebuild). The native consumer is future work and is disclosed (PR body: "the native worker is separate upcoming work"; export.md: "serving from it is the consumer's side"; src/models/valen/README.md: "Consuming that export does not change this worker"). The documented consumption path is exercised for real only in the author's GPU parity run (see unverified checks).

3. Determinism / reproducibility

  • Sorted keys everywhere (classification, tensor plans, manifest JSON sort_keys=True), streaming writer with fixed per-file ordering, single-threaded CPU math, no timestamps, no absolute paths — tested byte-identical across runs and across different input directory names (test_run_export_is_deterministic_and_path_independent, run locally). The real-artifact double-export determinism gate is env-gated (VALEN_CKPT/VALEN_BASE) — author-run, with per-file digests recorded in the PR body.
  • Source revisions pinned (checkpoint SHA-256 + HF revision when derivable, base per-shard digests + revision + repo, tool versions in sources.environment). Exporting code pinned by the PR head + FORMAT version (finding 4 for the residual gap).

4. Docs

  • recipe/valen/export.md is complete and matches the code: usage + expected console output, artifact table with exact counts (578/372/48/6/2 = 1006 manifest tensor records), manifest schema, LoRA application semantics, downcast rationale, head formulas, consumption, pins/licenses (Apache-2.0 per the #115 record, with a re-check instruction), parity-evidence placement, determinism + regression commands with recorded counts ("105 tests passed, 2 artifact-gated skips" — matches my run).
  • reference.md gains a full "Export parity" section with verbatim tool output (RTX 5060 Laptop, sm_120, bit-level deltas 0.0, recorded 2026-10-15) and the reproduce command; the honest "~3e-8 worker-vs-reference spread" between the parity run's original stack and the earlier serving records is disclosed. Anchors referenced by export.md exist.
  • src/models/valen/README.md adds a "Checkpoint export" section; recipe/README.md, mkdocs nav, README matrix and supported-models updated for noul/score. Template readiness: complete (see below).

5. Tests

  • Weight-free coverage is strong and CPU-only: unmerged-vs-peft bit equality, hand-computed BF16 rounding, downcast RNE, key classification incl. adversarial cases (block 24 swap, unpaired adapters, unknown keys, head bias), tiny-fixture end-to-end export contract, path-independent byte determinism, failure cleanup, per-pin rejection tests, validate_export tamper matrix (flipped bytes, dropped tensor entries, downcast/head/lora drift, extra files/dirs), streaming-digest enforcement (monkeypatched Path.read_bytes refusal), parity verdict matrix, parity-slot overwrite policy, source-pin cross-checks, clean-checkout gate.
  • Fixture provenance: all synthetic, seeded, generated in-test; the two example request JSONs are maintained fixtures consumed by reference.md curl commands and compare_reference.py — no committed run output anywhere in the 24 files (all text source/docs/fixtures, no binaries).

6. Artifact hygiene (all 24 files)

16 modified + 8 added files; all are source, tests, docs, or maintained request fixtures. No exported weights, no parity dumps, no logs, no site/ build output committed. Authored counts = total (all commits by the PR author).

Commands run (this host, macOS arm64, no GPU, no Rust)

All on the extracted head tree /tmp/pr-review-2026-10-15/head with a throwaway venv (Python 3.12.8; torch 2.14.1 CPU, safetensors 0.8.0, peft 0.21.2, pytest 9.1.1, pillow — not the author's pinned GPU matrix, torch 2.11.0+cu128 / peft 0.18.1):

  1. git fetch origin main --force → live main e66ff34996760a84ad56690f0ae4cf434e669e65; git fetch origin pull/147/head:refs/remotes/origin/pr/147 --force → head 369202d60da14dd061936d03963671f78531a9da (matches GitHub).
  2. shasum -a 256 .agents/skills/system1-omni-review/SKILL.md → 58be3bc6…dde108 (pin verified).
  3. PYTHONPATH=src python -m pytest tests/valen -q → 105 passed, 2 skipped in 4.99s — matches the author's claim and export.md verbatim. Skips are exactly the artifact-gated gates (test_export.py:1054 needs VALEN_CKPT/VALEN_BASE; test_export_parity.py:348 needs VALEN_* + CUDA).
  4. Export-only subset pytest tests/valen/test_export.py tests/valen/test_export_parity.py -q → 58 passed, 2 skipped.
  5. python recipe/valen/test_export_reference.py → export_reference tests: ok (2 skipped) (full 39-test battery in-process + skip lines for artifact-gated phases, exit 0).
  6. python recipe/valen/test_compare_reference.py → compare_reference tests: ok (incl. the new score-confidence-fallback case).
  7. python -m compileall -q recipe/valen tests/valen → pass.
  8. python -m mkdocs build --strict → exit 0 (done because the Docs workflow evidence was initially not visible to me; it turned out green at head — see below).
  9. gh pr checks 147 / check-runs API at head 369202d → rust: pass (2m0s), build: pass, benchmarks: pass, cuda-contract: pass, deploy: skipped, Docs: pass (run 2026-10-15T15:21:57Z at the head SHA). Note: no GPU/model validation runs in CI; the rust/docs results are consistent with a Python/docs-only change.

Template state (post-#138)

Complete and traceable: the four required human answers are present and specific; the PR-necessity decision answered ("Yes, without this every consumer converts the pickle on its own"); bug-fix evidence marked N/A (not a bug fix); Purpose/Test Plan/Test Result/Demo-evidence filled with pinned head SHA (369202d), environment, per-file manifest digests, and verbatim parity output; all four self-review checkboxes checked by the contributor; the stacking on #146 and the not-yet-implemented native consumer are both disclosed. NON-draft, so template completeness was required — it is met.

Material unverified checks

  • GPU parity evidence is author-run, not independently reproduced (this host has no GPU, no pinned weights): bit-level 0.0 deltas on the text/image fixtures, RTX 5060 Laptop (sm_120), torch 2.11.0+cu128, peft 0.18.1. It is recorded verbatim in reference.md (with reproduce command) and the manifest parity slot; the env-gated tests (test_real_artifact_export_is_deterministic, test_real_artifact_export_parity_gate) are the reproducible form and were skipped here. Per the skill: missing GPU/weights is an evidence gap on my side, not a PASS by me.
  • The documented consumption path executed against real weights (from_pretrained + peft re-wrap key-name mapping + head rebuild) ran only in the author's parity run; there is no weight-free test of load_exported_stack (inherent — it needs transformers and a real model). The PEFT key-name round-trip (file keys backbone.language_model.base_model.model.… vs wrapped-model parameter names through the top-level Valen container) reads consistent and is covered end-to-end by the author's run, but I could not execute it.
  • Real-artifact byte determinism — author-run (digests in the PR body); env-gated test skipped locally.
  • transformers-internals claim in export.md ("no keep_in_fp32_modules for this architecture; upcasts with .float() at use") — not independently verified against the pinned transformers version here; it is corroborated indirectly by the bit-level parity result.
  • Rust checks: not run locally (no Rust toolchain on this host); CI rust job green at head. My local Python versions differ from the author's pinned matrix (noted above); the peft bit-equality test passing on peft 0.21.2 is a small independent corroboration of the declared semantics, not a substitute for the pinned-env GPU run.

Bottom line

The export half is ready on the evidence presented, modulo the disclosed future consumer: pins enforced before load, every artifact byte pinned, fail-closed validation, deterministic output, semantics anchored and tested. Merge-order dependency on #146 is real (the GitHub diff collapses after #146 merges). The low findings are polish; none block on correctness.

Review follow-ups on the export recipe, kept minimal:

- run_export now stages the artifact set in a sibling directory and moves
  it into place with one rename, so a hard-killed run can no longer strand
  partial files under --out (a stale staging directory is cleared by the
  next run with the same target).
- run_export rejects base_config_path=None instead of writing a set its
  own validate_export refuses (the allowed set includes config.json).
- compare_case fails a case whose probability lists do not cover every
  candidate instead of silently truncating the delta scan.
- export.md notes the artifact set deliberately excludes tokenizer and
  processor files (reconstructing the serving stack reads them from the
  pinned base) and records the new suite count (108 passed, 2 skipped).
@MrDongsls

Copy link
Copy Markdown
Collaborator Author

Thanks for the thorough review. All three Low findings are addressed in d1236c6:

  1. Atomicity — run_export now stages the artifact set in a sibling directory (<out>.export-partial) and moves it into place with a single os.replace, so --out only ever holds a complete export. A run killed mid-write leaves at most the staging directory behind, and the next run with the same target clears it automatically — no operator intervention needed for retries. Exported bytes are unchanged (the manifest never recorded paths), so the recorded digests and the parity evidence remain valid.
  2. compare_case truncation — a probability list that doesn't cover every candidate now fails the case with an explicit problem line instead of silently truncating the delta scan.
  3. base_config_path=None — run_export now rejects it up front rather than writing a set its own validate_export refuses. No reachable caller passed None, so no behavior change elsewhere.

On the Info items:

  1. Manifest code revision — left as-is for now: adding a sources field means deciding whether validate_export requires it, which changes the /2 contract for existing manifests. The parity harness already pins the source revision and demands a clean checkout before evidence is produced. Happy to revisit (with a format bump) if you'd rather have the manifest self-contained.
  2. Tokenizer note — added to export.md next to the artifact table: the set deliberately excludes tokenizer/processor files, and reconstructing the serving stack still reads them from the pinned base.
  3. supported-models row — agreed, deferring until the native consumer lands, as suggested.

Regression coverage: three new tests (test_run_export_requires_base_config_path, test_run_export_clears_stale_staging_directory, test_compare_case_probability_length_mismatch_fails) plus staging-cleanup assertions in the two existing failure tests. PYTHONPATH=src pytest tests/valen -q → 108 passed, 2 artifact-gated skips; test_export_reference.py also re-validated the local weights/valen-export set (parity slot filled). export.md records the new count.

@hsliuustc0106 hsliuustc0106 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incremental re-check at new head d1236c661b: one new commit since my review at 369202d60d — "valen: stage the export atomically and gate compare_case on list lengths" (5 files, +95/−24); the 25 reviewed commits are patch-identical (git range-diff, named refs, cat-file verified).

All three Low findings from my review are fixed, verified in the diff and by execution:

  • Atomicity — fixed: run_export now stages the artifact set in a sibling .export-partial directory and moves it into place with a single rename, so out_dir only ever holds a complete export; a killed run leaves at most the staging directory, which the next run with the same target clears.
  • compare_case zip — fixed: a case whose probability lists don't cover every candidate now fails the case instead of silently truncating the delta scan.
  • base_config_path=None — fixed: run_export now raises instead of producing a set its own validate_export rejects.

Also carried: the tokenizer/processor exclusion got its documented one-liner in export.md, and the suite count was updated. Locally run in a fresh CPU-only venv at this head: 108 passed, 2 skipped (exactly the doc's updated count; the 2 skips are the artifact-gated determinism gates). mkdocs build --strict passes; fork CI (rust/build/cuda-contract/benchmarks) green at this exact head.

No actionable findings remain. APPROVED. Unverified checks (unchanged from my first review): the RTX 5060 bit-level parity and real-artifact double-export determinism remain author-run (no GPU/weights on this host — the 2 skips are those gates); the documented consumption path against real weights exists only in the author's run; Rust suite covered by exact-head CI. Provenance: review skill at main@71857e0 (SHA-256 58be3bc6…dde108); remote head re-pinned immediately before posting.

@psv666

psv666 commented Oct 23, 2026

Copy link
Copy Markdown
Collaborator

[P2] NaN probabilities are accepted as zero-error export parity.

At verify_export_parity.py:109, max_delta = max(max_delta, abs(...)) silently retains the previous finite maximum when the new difference is NaN. I called the actual compare_case() with identical keys/token counts and:

original probabilities: [0.6, 0.4]
exported probabilities: [NaN, 0.4]
result: exact_answer_agreement=True
        max_probability_delta=0.0
        probability_tolerance_pass=True
        passed=True, problems=[]

Python's argmax also retains the first candidate in this example, so the discrete gate does not rescue the result. run_fixtures() can emit NaNs from torch.softmax, and the subprocess JSON path accepts them. main() uses these verdicts to write the manifest's parity.status="passed" and return success. A non-finite export can therefore be recorded as numerically equivalent.

Please reject non-finite probabilities on both sides before subtraction/argmax, validate probability ranges/normalization, and add regressions for NaN in either side and matching infinities. Keep non-standard numbers out of serialized evidence as well.

Personally run: 108 CPU tests passed, 2 artifact-gated tests skipped, plus the failing NaN probe above. Environment: Python 3.11.15, torch 2.14.1+cpu, PEFT 0.18.1, Transformers 5.19.0, safetensors 0.8.0. This differs from the author's GPU/reference environment and is only CPU-tooling evidence. Strict docs passed. No pinned Valen/Qwen2B artifacts or real dual-stack GPU export comparison were available locally; historical author parity is not re-certified. GitHub currently reports conflicts with main.

Readiness: the effective source/test diff is over 3,000 changed lines; please also supply separate authored/total counts, split rationale and component review order under current CONTRIBUTING. This is preparation feedback, separate from the numerical defect above.

Review provenance and scope
  • Head d1236c661bf90dcbdcda3928508e84b424486272; PR API base f2d3d32897c1fe190fecf853a82a9456d3791462; diff merge-base 037c44b94240009eb9831f9faebdb966016a0c12. Head checked unchanged before publication. Tests used isolated source archives and per-PR Rust build directories.
  • Code/test diff +4487/−103; total text diff +4995/−144; 24 changed files. Code counts exclude generated JSON fixtures/docs.
  • Repository ID 1386454853. Loaded trusted .agents/skills/system1-omni-review/SKILL.md from target main@5ba6a3ba668cb33028eb0bce2c6d17cdc53aebe7, SHA-256 ae2dfac116376ae2ec41f65122cc1bf5aea10751b8b907198a56154e5d67230e, plus architecture, repository contracts, CONTRIBUTING, self-review artifact/demo rules, current workflows and affected component docs. Observed CI is recorded separately from personally run checks.

@MrDongsls

MrDongsls commented Oct 23, 2026 •

Copy link
Copy Markdown
Collaborator Author

Fixed in 7243b67: compare_case fails the case on non-finite probabilities (NaN/±inf) on either side before any delta/argmax, in both recipe/valen/compare_reference.py and recipe/valen/verify_export_parity.py (the cited line); the evidence JSON writers now pass allow_nan=False. Regressions cover NaN on either side and matching infinities (harness 32/32 ok; tests/valen 110 passed, 2 skipped). Main conflicts resolved via 77945e9 (#146) and c94caf80 here; authored/total counts, split rationale and review order added to the body.

@hsliuustc0106 hsliuustc0106 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Independent review — PR #147 "valen: export the trained stack to an unmerged safetensors artifact set" — incremental delta re-check

Review scope provenance. Local repo /Users/hsliu/thinkflowlab/system1-omni. Prior review: APPROVED, 2026-10-18 (pass-64) at head d1236c661bf90dcbdcda3928508e84b424486272 — all three Lows verified fixed, 108 passed + 2 skips verified locally. Live head at this re-check: 7243b6750062242f7e1b40be76837fe3168e94cd. origin/main re-pinned at a893f0cf (#131 merge); merge-base(origin/main, head) = f5ae5acf. GitHub diff vs merge-base: 24 files, +5108/−144 (recomputed exactly — matches the body's Large-change packaging line). Non-draft, OPEN, base main. Stacks on #146: this head contains #146's line (77945e9b5) as c94caf80's second parent — merge #146 first.

Own-series integrity (gate 1)

First-parent chain from the previously approved head (git log --first-parent d1236c661..7243b6750, all commits cat-file -e verified):

  1. c94caf80 — merge "Merge branch 'model/valen-noul-score' into spec/valen-export"; c94caf80^1 == d1236c661 byte-identical (no rewrite of the approved series); second parent is #146's new head 77945e9b5 (which itself absorbs upstream/main f5ae5acf — that is the "absorbed main" in the delta).
  2. 7243b675 — the only new authored commit: "valen: reject non-finite probabilities in the parity comparison" (4 files, +115/−2).

Everything else in the +18444/−1200 overall delta is main-side content entering through the #146 line. Nothing enters that is not main-side or own-side: git diff 77945e9b5 7243b6750 --stat = 12 files, +3856/−16 (the export delta plus the authored commit); git diff f5ae5acf 7243b6750 collapses to exactly the 24-file PR footprint.

Merge hygiene (gate 2)

git merge-tree --write-tree d1236c661 77945e9b5 reports one content conflict: mkdocs.yml (both sides added a nav line at the same spot). The resolution was read in full: the −3 relative to the conflicted auto-merge content is exactly the removal of the three conflict-marker lines — both content lines survive (final file, lines 69–72: Valen reference worker, Valen checkpoint export, Cua-S1 native screenshots, Cua-S1 vision CUDA Graph), and recipe/cua_s1/native_screenshot.md exists in the tree. Correct content union; no leftover markers anywhere (git grep); the merged nav is validated by the green mkdocs build --strict Docs run at this exact head (below).

Authored commit 7243b675 — full review

The commit hardens both parity gates against non-finite probabilities — the machinery my APPROVE relied on:

  • recipe/valen/verify_export_parity.py compare_case: after the candidate-order and probability-length gates and before the zip/argmax work, any non-finite (math.isfinite) value on either side appends a named problem, sets exact = False, and continues. Verified fail-closed end-to-end: the verdict's passed = exact and tokens_agree and tolerance_pass. Placement is correct (the length gate still runs first; the new gate cannot be bypassed by a shorter list).
  • recipe/valen/compare_reference.py compare_case: same gate after the answer-type and candidate-order gates, before the delta scan and the per-type (noul/score/choice) comparisons; sets decision_exact = False, so passed (which requires decision_exact and legend_exact and prob_ok and confidence_ok and tokens_exact [+ answer tolerance]) fails. Rejection is in the comparison gate, not the exporter — matching the commit message.
  • Exporter-side defense in depth: fill_parity_slot and the run_stage payload dump now serialize with allow_nan=False, so a non-finite value cannot even reach a stage file or a manifest parity slot — it fails loudly at write time.
  • Tests pin it: three new checks in recipe/valen/test_compare_reference.py (worker NaN fails, reference NaN fails, matching infinities on both sides still fail — closing the inf − inf = NaN and equal-argmax holes) and two new tests in tests/valen/test_export_parity.py (exported NaN fails; matching infinities fail), asserting passed is False, exact_answer_agreement is False, and the problem string. The asserted verdict fields exist in the verdict dict as read at this head.

New finding

P3-1 — the finite gate is asymmetric: scalar answer and confidence deltas still swallow NaN via max().
Where: recipe/valen/compare_reference.py:259 and :274 (max_answer_delta = max(max_answer_delta, abs(answer["noul"|"score"] − ref))), :266/:285/:292 (max_conf_delta).
Trigger→consequence: CPython's max(a, b) keeps a unless b > a; abs(NaN) > a is False, so a NaN delta is silently dropped and the answer tolerance / confidence tolerance lines PASS — exactly the failure mode named in the commit's own comment ("a NaN difference keeps the previous finite maximum"), surviving one layer over in the same function on the scalar paths the commit did not cover. A worker response (Python json.loads accepts NaN/Infinity literals) with finite probabilities but a NaN score, noul or confidence field would pass those gates.
Why only Low: not reachable from the pinned worker — the scalar answers and confidence are derived by postprocess.py from the same probability vectors the new gate now proves finite; the reference-side confidence values were inspected finite in the prior round; and verify_export_parity.py has no scalar path at all (and is allow_nan=False at both writes). Same evidence-harness robustness class as the zip-length Low fixed in pass-64.
Suggested fix: extend the same math.isfinite sweep to answer["confidence"], answer["noul"], answer["score"] and any reference-carried confidence before the per-type branches (one small helper, plus one NaN-confidence regression per side).

Note (no action required beyond the fix above): recipe/valen/export.md:209 still says "108 tests passed, 2 artifact-gated skips at the time of writing" — the suite is now 110 + 2 (the body's Test Result correctly says 110). The qualifier keeps it honest, but the author's own practice (the count was refreshed at d1236c661) is to keep it in sync; refresh alongside the P3 fix.

Prior findings — status at the new head (re-verified, not copied)

All three pass-64 Lows re-verified intact in the new tree; the authored commit touches none of them:

  1. Atomic staging — intact: run_export still stages in the sibling .export-partial directory and installs with a single os.replace(staging, out_dir) (export_checkpoint.py:366–388), with except BaseException staging cleanup and stale-staging removal on retry.
  2. compare_case zip length gates — intact: explicit length-vs-keys check in verify_export_parity.py (runs before the new finite gate); compare_reference.py's candidate-order check doubles as its length gate before the zip.
  3. base_config_path=None — intact: raises "base_config_path is required…" (export_checkpoint.py:359–361).
    The pass-63 informational items (manifest does not record the exporting code revision; tokenizer/processor exclusion documented; supported-models row not extended) are unchanged and remain notes.

Template readiness and body pinning (post-#138 gate)

All four required human answers, the PR-necessity answer, bug-fix N/A, and all four self-review checkboxes present. The body was re-pinned to the new stack: head 7243b67, based on 77945e9, "which merges current main f5ae5ac"; the Large-change packaging section cites git diff --numstat f5ae5acf..7243b675 and its headline (24 files, +5108/−144) is exactly correct; component review order updated for "non-finite rejection". Test Result claims pytest tests/valen: 110 passed, 2 artifact-gated skips at this head — author-reported; statically consistent (pass-64's verified 108 + the 2 new tests), not independently executed this pass (see below).

Commands run and results (this host: macOS arm64, Python 3.12.8, no GPU, no Rust)

  • Worktrees at both heads (removed after): PYTHONPATH=. python -m pytest tests/benchmarks -q → 65 passed at 7243b6750 (and at 77945e9b5).
  • PYTHONPATH=src python -m pytest tests/valen -q --ignore=tests/valen/test_export.py --ignore=tests/valen/test_export_parity.py → 47 passed at this head.
  • python recipe/valen/test_compare_reference.py → compare_reference tests: ok — includes the three new non-finite checks, so the new gate logic is exercised on this host.
  • Series/merge forensics: parent-hash equality, merge-tree + resolution diffs, collapse-to-footprint stats, case_side/verdict-dict cross-checks (all above).
  • Blocked, environment-side: the export battery (tests/valen/test_export.py, test_export_parity.py, recipe/valen/test_export_reference.py) could not execute this pass — every torch install on this host is broken (libtorch_cpu.dylib missing from the installed wheels) and PyPI is unreachable from the sandbox, so no replacement venv could be built. This is a gap on my side; those tests were executed and verified in pass-64 and the only changes since are the two reviewed additions.
  • PR bodies fetched via API; check-runs + workflow-runs queried for both head SHAs in both ThinkFlowLab and InferMatrixLab.

CI observed at this exact head

gh pr checks 147 plus the Actions/check-runs APIs at 7243b6750062… in both orgs: rust pass (2m12s), build pass, benchmarks pass, cuda-contract pass, Docs pass (mkdocs --strict), deploy skipped (main-only). All five non-skipped checks success at the exact head SHA in ThinkFlowLab and InferMatrixLab. CI does not execute tests/valen.

Material unverified checks (carried from the prior approval)

  1. RTX 5060 bit-level parity (0.0 deltas, both fixtures) and real-artifact double-export determinism at this head — author-reported (body says both were re-run at 7243b67); no GPU/weights here; the env-gated tests remain the reproducible form.
  2. The full-suite 110-count and the export battery at this head — author-reported; statically consistent with my pass-64 execution plus the two reviewed tests; not executed this pass (torch environment gap above).
  3. The documented consumption path against real weights — author-run only (unchanged, disclosed).

Verdict

COMMENTED — downgraded from APPROVE: one new P3 (NaN-swallowing residue on the scalar answer/confidence delta paths of compare_reference.py, the same failure class this PR's new commit fixes for probabilities). Everything else is clean: series identity byte-verified, merge resolution correct, prior Lows intact, template re-pinned and complete, CI green at the exact head in both repos. Fixing the P3 (a small same-pattern extension of the new gate, plus the optional export.md count refresh) restores approval-eligibility. Per the standing rules this report is not posted anywhere and does not modify draft state, labels, or checkboxes.

@MrDongsls

Copy link
Copy Markdown
Collaborator Author

P3 addressed in 70478332 (minimal scope — recipe/valen/compare_reference.py only, plus its regression script and the export.md count refresh):

  • New scalar_answer_fields() collects every scalar the per-type branches fold into a running maximum — the worker confidence on all types, the noul/score answer field by type, and the reference decode's noul/score/confidence — and compare_case now fails the case on any non-finite value there before the per-type branches, mirroring the probability gate. Reference values derived from the probabilities (the choice-shaped noul decode, the fallback score) remain covered by the existing probability gate.
  • Regressions in recipe/valen/test_compare_reference.py: worker NaN confidence, worker NaN noul with finite probabilities (the reported path — verified to wrongly pass on the pre-fix tree), and reference-side NaN confidence. Harness 35/35 ok.
  • recipe/valen/export.md suite count refreshed to 110 + 2.

Re-run from the committed tree at 70478332: pytest tests/valen 110 passed + 2 artifact-gated skips; compileall and test_export_reference.py (with VALEN_EXPORT) pass; the double-export determinism gate is byte-identical with the same manifest digests (0313882b… / 4f6d9590… / f365a09e… / ed1c1723…); compare_reference.py --case all on the GPU host passes 4/4 at the declared 1e-6. The PR body is re-pinned to the new head.

@hsliuustc0106 hsliuustc0106 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Independent review — PR #147 "valen: export the trained stack to an unmerged safetensors artifact set" — incremental delta re-check

Review scope provenance. Local repo /Users/hsliu/thinkflowlab/system1-omni. Prior review: COMMENTED (pass-93, 2026-10-24) at head 7243b6750062242f7e1b40be76837fe3168e94cd — one P3 (NaN-swallowing scalar answer/confidence deltas in compare_reference.py) plus a stale export.md test count. Live head at this re-check: 70478332ae6fa0fb87a4b8b589ed433a43bb37fc (= gh pr view 147 --json headRefOid). Non-draft, OPEN, title unchanged, base main. Stacks on #146 (head contains #146's line via c94caf80, unchanged from prior passes) — merge #146 first.

Own-series integrity (gate 1)

git log --first-parent --oneline 7243b6750..70478332a contains exactly one commit: 70478332 "valen: reject non-finite scalar answers and confidences in the parity comparison" (3 files, +104/−1). Parent check: 70478332^ == 7243b6750062242f7e1b40be76837fe3168e94cd byte-identical (exact full SHA) — the previously reviewed series, including the pass-93 probability-finite commit 7243b675, was not rebased or rewritten; no range-diff needed. All seven relevant SHAs (prior head, new head, prior heads of #151/#152, origin/main a893f0cf) verified with git cat-file -e. Commit read in full (git show).

The authored commit 70478332 — closes pass-93 P3-1 in full

Coverage of every path the pass-93 P3 flagged. New helper scalar_answer_fields (recipe/valen/compare_reference.py:191-213) collects, and the new gate in compare_case (:273-286) sweeps for math.isfinite before any per-type branch runs:

  • worker answer["confidence"] — always, so the max_conf_delta fold at all three prior sites (:304 noul, :323 score, :329 choice) is covered regardless of answer type;
  • worker answer["noul"] / answer["score"] for the respective expected types — covers the max_answer_delta folds (:297, :312);
  • reference-carried noul / score / confidence when present in ref_answer — covers the reference sides of the same folds.

Every remaining source of a compared scalar is derived from the probability vectors, which the pass-93 commit 7243b675 already gates (the choice-shaped noul decode reads ref_answer["probabilities"], the fallback confidences are formulas over gated ref_probs), so no compare path can absorb a non-finite value anymore.

Fail-closed semantics — same as the probability fix. Placement is after the answer-type, candidate-order and probability gates and before the delta scan; a hit appends a named problem, sets decision_exact = False, and continues. Verified end-to-end that passed = decision_exact and legend_exact and prob_ok and confidence_ok and tokens_exact (+ answer tolerance when scalar_answers) at :378-382 — the verdict fails closed. No regression to the probability gates: the diff leaves them untouched, the battery still exercises worker-NaN / reference-NaN / matching-infinity probability cases, and the weight-free valen subset and benchmark counts are unchanged from pass-93 (below).

Tests pin it. Three new checks in recipe/valen/test_compare_reference.py (worker NaN confidence in choice shape, worker NaN noul, reference NaN confidence in score shape), each asserting not ok plus the new problem string, the first also "decision agreement: FAIL". All three observed passing locally; the standalone battery is 35/35 ok at this head.

The export.md staleness note — also addressed. recipe/valen/export.md:209 now says "110 tests passed, 2 artifact-gated skips" — accurate: this commit adds no pytest-collected test (the new checks live in the standalone recipe/valen/test_compare_reference.py script), and a static count of tests/valen gives exactly 112 test defs = 110 + 2, matching the body's Test Result.

Prior findings — status at the new head

  1. Pass-93 P3-1 (scalar/confidence NaN swallowed by max()) — RESOLVED, verified in full above.
  2. Pass-93 note (export.md "108 tests") — RESOLVED (now 110, and now correct).
  3. All three pass-64 Lows re-spot-checked intact: atomic staging + single os.replace (export_checkpoint.py), zip/candidate-order length gates (unchanged, run before the new gate), base_config_path=None refusal. Pass-63 informational items unchanged (manifest does not record the exporting code revision; tokenizer/processor exclusion documented; supported-models row not extended).

Body / evidence check at the new head

Template complete: the four required human contributor answers, the PR-necessity answer, the bug-fix N/A, and all four self-review checkboxes are present. The body is re-pinned to the new head: Version/Commit says "head 70478332 on spec/valen-export … CPU checks were re-run from this committed tree, and the determinism gate … re-run against the pinned artifacts at this head"; Test Result adds "compare_reference.py --case all on the GPU host: 4/4 cases … re-run at this head after the non-finite scalar gate" (author-reported); the component review order now cites "non-finite scalar rejection". The Large-change packaging headline was re-measured and recomputes exactly: git diff --numstat f5ae5acf..70478332a = 24 files, +5210/−143, matching the body verbatim; the authored/excluded split (+4702/−102 across 15 vs +508/−41 across 9) is arithmetically consistent with it.

Commands run and results (this host: macOS arm64, miniconda Python 3.12.8, no GPU, no Rust)

  • Worktree at 70478332a (removed after): PYTHONPATH=src python -m pytest tests/valen -q --ignore=tests/valen/test_export.py --ignore=tests/valen/test_export_parity.py → 47 passed (unchanged from pass-93 — no regression).
  • python recipe/valen/test_compare_reference.py → 35/35 ok, including the three new non-finite scalar checks and the pass-93 probability checks (worker NaN, reference NaN, matching infinities).
  • PYTHONPATH=. python -m pytest tests/benchmarks -q → 65 passed (unchanged).
  • Static count of tests/valen (112 defs) to confirm the refreshed export.md/body 110+2 claim — the torch suite itself remains blocked environment-side (every torch install on this host is broken: libtorch_cpu.dylib missing; unchanged since pass-93), so the full-suite run stays author-reported.
  • Series forensics: parent-hash equality, first-parent log, cat-file -e on all SHAs, numstat recompute (above).

CI observed at the exact head

gh pr checks 147 (ThinkFlowLab): rust pass (2m13s), build pass, benchmarks pass, cuda-contract pass; deploy skipped (main-only). Actions API queried at the full SHA 70478332ae6fa… in both ThinkFlowLab and InferMatrixLab: CI and Docs both completed / success with head_sha matching the PR head exactly. CI does not execute tests/valen.

Notes (informational, no action required)

  • The new scalar tests pin NaN on both sides but not ±∞ explicitly; the gate uses math.isfinite, so infinities take the identical path, and the probability-side matching-infinity test (test_compare_reference.py:302-309) still pins that pattern one layer down. Reference-side NaN noul/score are not directly exercised (only reference NaN confidence), but they flow through the same sweep loop as the tested field.
  • scalar_answer_fields indexes answer["confidence"]/answer["noul"]/answer["score"] unconditionally — the same shape assumption the per-type branches below it have always made; no new failure mode.

Material unverified checks (carried; unchanged from the prior approval basis)

  1. RTX 5060 bit-level parity (0.0 deltas) and double-export determinism at this head — author-reported (body says both re-ran at 70478332); no GPU/weights here; the env-gated tests remain the reproducible form.
  2. The full-suite 110-count execution at this head — author-reported; statically consistent (112 defs; pass-64 executed 108+2; the two export-file tests added since were reviewed) — not executed this pass (torch environment gap).
  3. The documented consumption path against real weights — author-run only (disclosed).

Verdict

APPROVED — restored from pass-93's COMMENTED. The single open P3 is fixed in full: every flagged scalar/confidence delta path is now swept with the same fail-closed gate semantics as the probability fix, pinned by three new passing checks, and the export.md count is refreshed and accurate. Series identity byte-verified, no new findings, template complete and re-pinned, CI green at the exact head in both orgs, local weight-free suites green and unchanged. The remaining author-reported items (GPU parity, determinism, full-suite execution) are the same ones the pass-64 APPROVE accepted as disclosed.

psv666 commented Oct 24, 2026

Copy link
Copy Markdown
Collaborator

Follow-up at 70478332ae6fa0fb87a4b8b589ed433a43bb37fc: the NaN scalar fix is verified, but [P2] the clean-source gate still permits importable sourceless modules.

compare_reference.py:439–443 rejects untracked files only when their names end in .py. A standalone .pyc is also importable. The checked directory is then prepended to sys.path at line 463; verify_export_parity.stage_environment uses the same gate. Thus unverified bytecode can shadow a dependency while the run claims clean pinned reference code.

CPU-only reproduction from this PR checkout; the temporary module only sets a harmless marker:

import pathlib, py_compile, subprocess, sys, tempfile
sys.path.insert(0, "recipe/valen")
import compare_reference as c

with tempfile.TemporaryDirectory() as directory:
    root = pathlib.Path(directory)
    subprocess.run(["git", "init", "-q", str(root)], check=True)
    (root / "README.md").write_text("fixture\n")
    subprocess.run(["git", "-C", str(root), "add", "README.md"], check=True)
    subprocess.run([
        "git", "-C", str(root), "-c", "user.name=Fixture",
        "-c", "user.email=fixture@example.invalid",
        "commit", "-qm", "fixture",
    ], check=True)
    source = root / "peft.py"
    source.write_text("REVIEW_MARKER = 'unverified module imported'\n")
    py_compile.compile(str(source), cfile=str(root / "peft.pyc"), doraise=True)
    source.unlink()
    print(subprocess.check_output(
        ["git", "-C", str(root), "status", "--porcelain"], text=True))
    c._verify_clean_checkout(root)  # observed: accepts
    print(subprocess.check_output([
        sys.executable, "-c",
        "import sys; sys.path.insert(0, sys.argv[1]); "
        "import peft; print(peft.REVIEW_MARKER)",
        str(root),
    ], text=True))

Observed: Git reports ?? peft.pyc; the gate returns normally; a fresh interpreter imports that file and prints the marker. This proves the validation bypass, not an observed bad GPU result.

Next step: close the importable-file gap (source, sourceless and extension modules/packages, including relevant ignored entries), or run the reference from a clean snapshot materialized from the pinned commit. Add the sourceless regression under root tests/ and verify that both evidence entrypoints use the corrected gate. Keep #146 → #147 ordering and carry the finite-value fixes into #146 as discussed there.

A separate readiness cleanup: the newly added recipe/valen/test_export_reference.py contains test implementation outside root tests/; please move that implementation/fixtures under tests/valen and update documented invocations, retaining only necessary recipe entrypoint glue.

Personally executed on the candidate merge with current main: 110 Valen tests passed, 2 artifact-dependent tests skipped; 35 comparison checks passed; export regression script passed with real-artifact phases skipped; compileall, diff check and strict MkDocs passed. PyTorch 2.11.0+cpu / PEFT 0.18.1 / Python 3.12.13. GPU parity and real-artifact determinism were not rerun. Authored code/test diff +4702/−102; total +5210/−143 across 24 files; diff merge-base f5ae5acf65e2d68150aef944aae00f4dffc0da27.

Review provenance: InferMatrixLab/system1-omni (repository ID 1386454853); canonical .agents/skills/system1-omni-review/SKILL.md loaded from trusted main@cd302b6e3d7723ebfc33bba9698da2c1e881f203, SHA-256 ae2dfac116376ae2ec41f65122cc1bf5aea10751b8b907198a56154e5d67230e, with repository/architecture/contributor contracts and current workflows. Validation below used isolated candidate merges with main@7b4c194; original PR heads were rechecked unchanged. This is a comment, not an approval.

Mr.Dong added 4 commits October 25, 2026 01:47
…s in the parity comparison

Forward-port the finite-value guards from spec/valen-export
(7243b67, 7047833) into this prerequisite branch. max() keeps its
first argument against a NaN difference and a NaN-free argmax list
silently keeps its first candidate, so a non-finite probability,
scalar answer or confidence on either the worker or the reference
side fails the case before any delta, argmax or tolerance verdict.
Regressions cover worker NaN probabilities, reference NaN
probabilities, matching infinities, worker NaN confidence, worker
NaN noul answers and reference NaN confidence. The export-side
harness (verify_export_parity.py) and its tests stay on
spec/valen-export, as does the score-confidence formula fallback.
# Conflicts:
#	recipe/valen/compare_reference.py
#	recipe/valen/test_compare_reference.py
…-source gate

_verify_clean_checkout only rejected untracked .py files: a standalone
.pyc (or a .so extension module) imports by name exactly like its .py
source, and the checked-out directory is prepended to sys.path, so
unverified bytecode could shadow a dependency while the run still
claimed clean pinned reference code. The sweep now covers every
importable suffix from importlib.machinery (source, bytecode,
extension) over untracked *and* ignored entries (a checkout-local
ignore rule hides from plain status), while __pycache__ caches stay
allowed since they are not importable on their own. Both evidence
entrypoints share the gate: verify_export_parity.stage_environment
calls reference._verify_clean_checkout. Regressions cover the
reviewer's sourceless-module repro, an ignored .pyc, an
interpreter-tagged extension module, the __pycache__ allowance and the
shared-gate pin. reference.md's pre-flight check mirrors the widened
rule.
…alen

The export regression runner (contract-battery chaining plus the
env-gated artifact-set validation) lived entirely in
recipe/valen/test_export_reference.py, putting test implementation
outside the root tests/ tree. The implementation now lives in
tests/valen/export_reference_checks.py and the recipe path is thin
entrypoint glue over its main(), so the documented invocation is
unchanged. export.md points at the implementation's home and its suite
count is refreshed (115 passed, 2 artifact-gated skips).
@MrDongsls

Copy link
Copy Markdown
Collaborator Author

All three items addressed (pushed, new head 7a801f01):

[P2] importable sourceless modules — addressed in ab7bf996. _verify_clean_checkout now sweeps every importable suffix (importlib.machinery source + bytecode + extension suffixes, so .pyc, .so, .pyd and interpreter-tagged variants, case-insensitively) over untracked and ignored entries (--ignored=matching, closing the checkout-local-ignore path), while __pycache__ bytecode stays allowed since it is a cache of a real import and not importable on its own — so re-runs after a first import remain clean. Your peft.pyc reproduction is now rejected (untracked importable file peft.pyc) while the module still imports from a fresh interpreter, proving the gate now covers the actual shadowing path. Regressions added under root tests/ (tests/valen/test_export_parity.py): the sourceless repro, an ignored .pyc, an interpreter-tagged extension module, the __pycache__ allowance, and a pin that verify_export_parity.stage_environment calls reference._verify_clean_checkout — both evidence entrypoints share the one corrected gate. reference.md's pre-flight check mirrors the widened rule.

#146 → #147 ordering and the finite-value fixes in #146 — done. #146 is now at 40f991c carrying the probability/scalar guards and their six regressions (your #146 reproduction returns False there), and this branch merged that head (80dcc6a3), so the stack order is preserved with the guards in the prerequisite PR.

Battery relocation — addressed in 7a801f01. The export regression implementation (contract-battery chaining plus the env-gated artifact-set validation) moved to tests/valen/export_reference_checks.py; recipe/valen/test_export_reference.py is now thin entrypoint glue over its main(), and the documented invocation is unchanged. export.md points at the implementation's home and its suite count is refreshed (115 passed, 2 artifact-gated skips).

Re-run at the new head on this host: pytest tests/valen 115 passed + 2 artifact-gated skips; test_compare_reference.py 35/35 ok; test_export_reference.py ok (2 skips); test_compare_with_backend.py ok; compileall, mkdocs build --strict, pytest tests/benchmarks (65) all pass. The GPU parity, determinism and manifest records pinned at 70478332 are untouched by these commits — the follow-ups change only the clean-source gate, its regressions, the battery's location and docs.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants