From 266cf7b417a400676cdea472a65b0a0cfc183a04 Mon Sep 17 00:00:00 2001 From: Ronald Tse Date: Mon, 19 Oct 2026 18:14:19 +0800 Subject: [PATCH 1/2] refactor: attic the superseded framework stack (WO56) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit src/framework, src/gpu (custom-arch era), src/tasks, and the old src/cli move to attic/ — git mv, history preserved, nothing deleted. Their 20 test files move along; the live imf/sadeedbench/pipeline packages and all model-era tests stay. One hidden entanglement surfaced and was fixed: imf/parity imported char_error_rate from the retired framework — now inlined in imf/text_metrics.py. pyproject packages drop framework*/tasks*; the stale smoke-cli job (python -m src.cli) is replaced by an isxml smoke; release.yml re-points at the attic cli. Suite 141 green (108 archival tests traveled with their modules), ruff clean. --- .github/workflows/release.yml | 6 +- .github/workflows/test.yml | 6 +- {src => attic}/cli.py | 0 {src => attic}/framework/__init__.py | 0 {src => attic}/framework/config.py | 0 {src => attic}/framework/data.py | 0 {src => attic}/framework/device.py | 0 {src => attic}/framework/evaluator.py | 0 {src => attic}/framework/exporter.py | 0 {src => attic}/framework/model.py | 0 {src => attic}/framework/pipeline.py | 0 {src => attic}/framework/registry.py | 0 {src => attic}/framework/torch_exporter.py | 0 {src => attic}/framework/trainer.py | 0 {src => attic}/gpu/__init__.py | 0 {src => attic}/gpu/distill_specs.yaml | 0 {src => attic}/gpu/engram.py | 0 {src => attic}/gpu/gkd.py | 0 {src => attic}/gpu/modal_distill.py | 0 {src => attic}/gpu/modal_export.py | 0 {src => attic}/gpu/modal_golden_matrix.py | 0 {src => attic}/gpu/modal_score_artifact.py | 0 {src => attic}/gpu/modal_teacher_sadeed.py | 0 {src => attic}/gpu/modal_teacher_thai.py | 0 {src => attic}/gpu/modal_train.py | 0 {src => attic}/gpu/mtp.py | 0 {src => attic}/gpu/muon.py | 0 {src => attic}/gpu/pkm.py | 0 attic/gpu/probe_heb_parity.py | 79 +++++++++++++++++++ {src => attic}/gpu/ride.py | 0 {src => attic}/gpu/runstate.py | 0 {src => attic}/gpu/sinkhorn_update.py | 0 {src => attic}/tasks/__init__.py | 0 .../tasks/rababa_arabic/__init__.py | 0 .../tasks/rababa_arabic/config.yaml | 0 {src => attic}/tasks/rababa_arabic/data.py | 0 {src => attic}/tasks/rababa_arabic/metrics.py | 0 {src => attic}/tasks/rababa_arabic/student.py | 0 .../tasks/rababa_hebrew/__init__.py | 0 .../tasks/rababa_hebrew/config.yaml | 0 {src => attic}/tasks/rababa_hebrew/data.py | 0 {src => attic}/tasks/rababa_hebrew/metrics.py | 0 {src => attic}/tasks/rababa_hebrew/student.py | 0 .../tasks/secryst_thai_ipa/__init__.py | 0 .../tasks/secryst_thai_ipa/config.yaml | 0 {src => attic}/tasks/secryst_thai_ipa/data.py | 0 .../tasks/secryst_thai_ipa/metrics.py | 0 .../tasks/secryst_thai_ipa/student.py | 0 {tests => attic/tests}/test_config.py | 0 {tests => attic/tests}/test_e2e_cpu.py | 0 {tests => attic/tests}/test_engram.py | 0 {tests => attic/tests}/test_engram_attach.py | 0 {tests => attic/tests}/test_gkd.py | 0 {tests => attic/tests}/test_gpu_mtp.py | 0 {tests => attic/tests}/test_gpu_pkm_muon.py | 0 {tests => attic/tests}/test_gpu_runstate.py | 0 {tests => attic/tests}/test_muon_headwise.py | 0 .../tests}/test_paired_bootstrap.py | 0 .../tests}/test_parity_stage_skip.py | 0 {tests => attic/tests}/test_pipeline.py | 0 {tests => attic/tests}/test_rababa_arabic.py | 0 {tests => attic/tests}/test_rababa_hebrew.py | 0 {tests => attic/tests}/test_registry.py | 0 {tests => attic/tests}/test_ride.py | 0 .../tests}/test_secryst_thai_ipa.py | 0 .../tests}/test_sinkhorn_update.py | 0 {tests => attic/tests}/test_stitch.py | 0 {tests => attic/tests}/test_student_config.py | 0 pyproject.toml | 2 +- src/imf/parity.py | 2 +- src/imf/text_metrics.py | 34 ++++++++ src/pipeline/cli.py | 36 +++++++++ 72 files changed, 157 insertions(+), 8 deletions(-) rename {src => attic}/cli.py (100%) rename {src => attic}/framework/__init__.py (100%) rename {src => attic}/framework/config.py (100%) rename {src => attic}/framework/data.py (100%) rename {src => attic}/framework/device.py (100%) rename {src => attic}/framework/evaluator.py (100%) rename {src => attic}/framework/exporter.py (100%) rename {src => attic}/framework/model.py (100%) rename {src => attic}/framework/pipeline.py (100%) rename {src => attic}/framework/registry.py (100%) rename {src => attic}/framework/torch_exporter.py (100%) rename {src => attic}/framework/trainer.py (100%) rename {src => attic}/gpu/__init__.py (100%) rename {src => attic}/gpu/distill_specs.yaml (100%) rename {src => attic}/gpu/engram.py (100%) rename {src => attic}/gpu/gkd.py (100%) rename {src => attic}/gpu/modal_distill.py (100%) rename {src => attic}/gpu/modal_export.py (100%) rename {src => attic}/gpu/modal_golden_matrix.py (100%) rename {src => attic}/gpu/modal_score_artifact.py (100%) rename {src => attic}/gpu/modal_teacher_sadeed.py (100%) rename {src => attic}/gpu/modal_teacher_thai.py (100%) rename {src => attic}/gpu/modal_train.py (100%) rename {src => attic}/gpu/mtp.py (100%) rename {src => attic}/gpu/muon.py (100%) rename {src => attic}/gpu/pkm.py (100%) create mode 100644 attic/gpu/probe_heb_parity.py rename {src => attic}/gpu/ride.py (100%) rename {src => attic}/gpu/runstate.py (100%) rename {src => attic}/gpu/sinkhorn_update.py (100%) rename {src => attic}/tasks/__init__.py (100%) rename {src => attic}/tasks/rababa_arabic/__init__.py (100%) rename {src => attic}/tasks/rababa_arabic/config.yaml (100%) rename {src => attic}/tasks/rababa_arabic/data.py (100%) rename {src => attic}/tasks/rababa_arabic/metrics.py (100%) rename {src => attic}/tasks/rababa_arabic/student.py (100%) rename {src => attic}/tasks/rababa_hebrew/__init__.py (100%) rename {src => attic}/tasks/rababa_hebrew/config.yaml (100%) rename {src => attic}/tasks/rababa_hebrew/data.py (100%) rename {src => attic}/tasks/rababa_hebrew/metrics.py (100%) rename {src => attic}/tasks/rababa_hebrew/student.py (100%) rename {src => attic}/tasks/secryst_thai_ipa/__init__.py (100%) rename {src => attic}/tasks/secryst_thai_ipa/config.yaml (100%) rename {src => attic}/tasks/secryst_thai_ipa/data.py (100%) rename {src => attic}/tasks/secryst_thai_ipa/metrics.py (100%) rename {src => attic}/tasks/secryst_thai_ipa/student.py (100%) rename {tests => attic/tests}/test_config.py (100%) rename {tests => attic/tests}/test_e2e_cpu.py (100%) rename {tests => attic/tests}/test_engram.py (100%) rename {tests => attic/tests}/test_engram_attach.py (100%) rename {tests => attic/tests}/test_gkd.py (100%) rename {tests => attic/tests}/test_gpu_mtp.py (100%) rename {tests => attic/tests}/test_gpu_pkm_muon.py (100%) rename {tests => attic/tests}/test_gpu_runstate.py (100%) rename {tests => attic/tests}/test_muon_headwise.py (100%) rename {tests => attic/tests}/test_paired_bootstrap.py (100%) rename {tests => attic/tests}/test_parity_stage_skip.py (100%) rename {tests => attic/tests}/test_pipeline.py (100%) rename {tests => attic/tests}/test_rababa_arabic.py (100%) rename {tests => attic/tests}/test_rababa_hebrew.py (100%) rename {tests => attic/tests}/test_registry.py (100%) rename {tests => attic/tests}/test_ride.py (100%) rename {tests => attic/tests}/test_secryst_thai_ipa.py (100%) rename {tests => attic/tests}/test_sinkhorn_update.py (100%) rename {tests => attic/tests}/test_stitch.py (100%) rename {tests => attic/tests}/test_student_config.py (100%) create mode 100644 src/imf/text_metrics.py diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6a7b598f..a09f3b29 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -60,9 +60,9 @@ jobs: run: | mkdir -p models/$TASK if [ "$VARIANT" = "fp32" ]; then - python -m src.cli export --task $TASK --data-root data --out-root models/$TASK + PYTHONPATH=attic python -m cli export --task $TASK --data-root data --out-root models/$TASK else - python -m src.cli export --task $TASK --variant $VARIANT --data-root data --out-root models/$TASK + PYTHONPATH=attic python -m cli export --task $TASK --variant $VARIANT --data-root data --out-root models/$TASK fi - name: Compute SHA256 env: @@ -94,7 +94,7 @@ jobs: env: TASK: ${{ needs.parse-tag.outputs.task }} run: | - python -m src.cli evaluate --task $TASK --data-root data --out-root models \ + PYTHONPATH=attic python -m cli evaluate --task $TASK --data-root data --out-root models \ > $TASK-benchmarks.json - uses: actions/upload-artifact@v4 with: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index eb91dc39..8a6bd798 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -39,10 +39,10 @@ jobs: with: python-version: "3.11" - run: pip install -e ".[dev,export]" - - name: CLI smoke test + - name: CLI smoke test (isxml) run: | - PYTHONPATH=src python -m src.cli list - test "$(PYTHONPATH=src python -m src.cli list | jq 'length')" -ge 3 + PYTHONPATH=src isxml --help + PYTHONPATH=src isxml validate --help export-fixture: runs-on: ubuntu-latest diff --git a/src/cli.py b/attic/cli.py similarity index 100% rename from src/cli.py rename to attic/cli.py diff --git a/src/framework/__init__.py b/attic/framework/__init__.py similarity index 100% rename from src/framework/__init__.py rename to attic/framework/__init__.py diff --git a/src/framework/config.py b/attic/framework/config.py similarity index 100% rename from src/framework/config.py rename to attic/framework/config.py diff --git a/src/framework/data.py b/attic/framework/data.py similarity index 100% rename from src/framework/data.py rename to attic/framework/data.py diff --git a/src/framework/device.py b/attic/framework/device.py similarity index 100% rename from src/framework/device.py rename to attic/framework/device.py diff --git a/src/framework/evaluator.py b/attic/framework/evaluator.py similarity index 100% rename from src/framework/evaluator.py rename to attic/framework/evaluator.py diff --git a/src/framework/exporter.py b/attic/framework/exporter.py similarity index 100% rename from src/framework/exporter.py rename to attic/framework/exporter.py diff --git a/src/framework/model.py b/attic/framework/model.py similarity index 100% rename from src/framework/model.py rename to attic/framework/model.py diff --git a/src/framework/pipeline.py b/attic/framework/pipeline.py similarity index 100% rename from src/framework/pipeline.py rename to attic/framework/pipeline.py diff --git a/src/framework/registry.py b/attic/framework/registry.py similarity index 100% rename from src/framework/registry.py rename to attic/framework/registry.py diff --git a/src/framework/torch_exporter.py b/attic/framework/torch_exporter.py similarity index 100% rename from src/framework/torch_exporter.py rename to attic/framework/torch_exporter.py diff --git a/src/framework/trainer.py b/attic/framework/trainer.py similarity index 100% rename from src/framework/trainer.py rename to attic/framework/trainer.py diff --git a/src/gpu/__init__.py b/attic/gpu/__init__.py similarity index 100% rename from src/gpu/__init__.py rename to attic/gpu/__init__.py diff --git a/src/gpu/distill_specs.yaml b/attic/gpu/distill_specs.yaml similarity index 100% rename from src/gpu/distill_specs.yaml rename to attic/gpu/distill_specs.yaml diff --git a/src/gpu/engram.py b/attic/gpu/engram.py similarity index 100% rename from src/gpu/engram.py rename to attic/gpu/engram.py diff --git a/src/gpu/gkd.py b/attic/gpu/gkd.py similarity index 100% rename from src/gpu/gkd.py rename to attic/gpu/gkd.py diff --git a/src/gpu/modal_distill.py b/attic/gpu/modal_distill.py similarity index 100% rename from src/gpu/modal_distill.py rename to attic/gpu/modal_distill.py diff --git a/src/gpu/modal_export.py b/attic/gpu/modal_export.py similarity index 100% rename from src/gpu/modal_export.py rename to attic/gpu/modal_export.py diff --git a/src/gpu/modal_golden_matrix.py b/attic/gpu/modal_golden_matrix.py similarity index 100% rename from src/gpu/modal_golden_matrix.py rename to attic/gpu/modal_golden_matrix.py diff --git a/src/gpu/modal_score_artifact.py b/attic/gpu/modal_score_artifact.py similarity index 100% rename from src/gpu/modal_score_artifact.py rename to attic/gpu/modal_score_artifact.py diff --git a/src/gpu/modal_teacher_sadeed.py b/attic/gpu/modal_teacher_sadeed.py similarity index 100% rename from src/gpu/modal_teacher_sadeed.py rename to attic/gpu/modal_teacher_sadeed.py diff --git a/src/gpu/modal_teacher_thai.py b/attic/gpu/modal_teacher_thai.py similarity index 100% rename from src/gpu/modal_teacher_thai.py rename to attic/gpu/modal_teacher_thai.py diff --git a/src/gpu/modal_train.py b/attic/gpu/modal_train.py similarity index 100% rename from src/gpu/modal_train.py rename to attic/gpu/modal_train.py diff --git a/src/gpu/mtp.py b/attic/gpu/mtp.py similarity index 100% rename from src/gpu/mtp.py rename to attic/gpu/mtp.py diff --git a/src/gpu/muon.py b/attic/gpu/muon.py similarity index 100% rename from src/gpu/muon.py rename to attic/gpu/muon.py diff --git a/src/gpu/pkm.py b/attic/gpu/pkm.py similarity index 100% rename from src/gpu/pkm.py rename to attic/gpu/pkm.py diff --git a/attic/gpu/probe_heb_parity.py b/attic/gpu/probe_heb_parity.py new file mode 100644 index 00000000..5c1c8075 --- /dev/null +++ b/attic/gpu/probe_heb_parity.py @@ -0,0 +1,79 @@ +"""Probe: why did heb-diac-1.1-fp32 fail the parity gate? + +Runs the exact parity harness (torch reference vs ONNX kv decode) but +PRINTS the report numbers and sample outputs instead of raising. + + modal run --detach src/gpu/probe_heb_parity.py +""" + +from __future__ import annotations + +from pathlib import Path + +import modal + +REPO_ROOT = Path(__file__).resolve().parent.parent.parent + +IMAGE = ( + modal.Image.debian_slim(python_version="3.11") + .pip_install("torch==2.12.1", "transformers==5.14.1", "onnx==1.22.0", + "onnxruntime==1.23.2", "pyyaml>=6.0") + .add_local_dir(str(REPO_ROOT), "/root/interscript-ml", copy=True) + .workdir("/root/interscript-ml") +) + +CHECKPOINT_VOLUMES = {"/volumes/rababa-checkpoints": modal.Volume.from_name("rababa-checkpoints")} +DATASET_VOLUMES = {"/datasets/rababa": modal.Volume.from_name("rababa-datasets")} +MODELS_VOLUME = modal.Volume.from_name("secryst-models") + +app = modal.App("probe-heb-parity", image=IMAGE) + + +@app.function( + cpu=8, + memory=32 * 1024, + timeout=2 * 3600, + volumes={**CHECKPOINT_VOLUMES, **DATASET_VOLUMES, "/outputs": MODELS_VOLUME}, +) +def probe() -> dict: + import json + import sys + + sys.path.insert(0, "/root/interscript-ml/src") + + for v in list(CHECKPOINT_VOLUMES.values()) + list(DATASET_VOLUMES.values()) + [MODELS_VOLUME]: + v.reload() + + from imf.export import load_byte_seq2seq + from imf.parity import reference_decode, run_parity + + ckpt = Path("/volumes/rababa-checkpoints/rababa_hebrew/run-s46-phonikud-plus/run-002-gold-ft/best") + zip_path = Path("/outputs/imf/heb-diac/heb-diac-1.1-fp32.zip") + + model = load_byte_seq2seq(ckpt) + + pairs = [] + for line in Path("/datasets/rababa/nakdimon/test-imf.jsonl").read_text(encoding="utf-8").splitlines(): + if not line.strip(): + continue + row = json.loads(line) + pairs.append((row.get("input", row.get("src", "")), row.get("target", row.get("tgt", "")))) + pairs = [(s, t) for s, t in pairs if s][:40] + print(f"[probe] {len(pairs)} pairs", flush=True) + + reference = reference_decode(model, [s for s, _ in pairs], max_len=128) + for i in [0, 1, 2]: + print(f"[ref {i}] {reference[i][:90]!r}", flush=True) + + report = run_parity(model, zip_path, pairs, max_len=128, reference=reference) + print(f"REPORT: samples={report.samples} cer_ref={report.cer_reference}pp " + f"cer_onnx={report.cer_onnx}pp delta={report.cer_delta}pp " + f"mismatches={report.token_mismatches} passed={report.passed}", flush=True) + return {"samples": report.samples, "cer_ref": report.cer_reference, + "cer_onnx": report.cer_onnx, "delta": report.cer_delta, + "mismatches": report.token_mismatches} + + +@app.local_entrypoint() +def main(): + print(probe.remote()) diff --git a/src/gpu/ride.py b/attic/gpu/ride.py similarity index 100% rename from src/gpu/ride.py rename to attic/gpu/ride.py diff --git a/src/gpu/runstate.py b/attic/gpu/runstate.py similarity index 100% rename from src/gpu/runstate.py rename to attic/gpu/runstate.py diff --git a/src/gpu/sinkhorn_update.py b/attic/gpu/sinkhorn_update.py similarity index 100% rename from src/gpu/sinkhorn_update.py rename to attic/gpu/sinkhorn_update.py diff --git a/src/tasks/__init__.py b/attic/tasks/__init__.py similarity index 100% rename from src/tasks/__init__.py rename to attic/tasks/__init__.py diff --git a/src/tasks/rababa_arabic/__init__.py b/attic/tasks/rababa_arabic/__init__.py similarity index 100% rename from src/tasks/rababa_arabic/__init__.py rename to attic/tasks/rababa_arabic/__init__.py diff --git a/src/tasks/rababa_arabic/config.yaml b/attic/tasks/rababa_arabic/config.yaml similarity index 100% rename from src/tasks/rababa_arabic/config.yaml rename to attic/tasks/rababa_arabic/config.yaml diff --git a/src/tasks/rababa_arabic/data.py b/attic/tasks/rababa_arabic/data.py similarity index 100% rename from src/tasks/rababa_arabic/data.py rename to attic/tasks/rababa_arabic/data.py diff --git a/src/tasks/rababa_arabic/metrics.py b/attic/tasks/rababa_arabic/metrics.py similarity index 100% rename from src/tasks/rababa_arabic/metrics.py rename to attic/tasks/rababa_arabic/metrics.py diff --git a/src/tasks/rababa_arabic/student.py b/attic/tasks/rababa_arabic/student.py similarity index 100% rename from src/tasks/rababa_arabic/student.py rename to attic/tasks/rababa_arabic/student.py diff --git a/src/tasks/rababa_hebrew/__init__.py b/attic/tasks/rababa_hebrew/__init__.py similarity index 100% rename from src/tasks/rababa_hebrew/__init__.py rename to attic/tasks/rababa_hebrew/__init__.py diff --git a/src/tasks/rababa_hebrew/config.yaml b/attic/tasks/rababa_hebrew/config.yaml similarity index 100% rename from src/tasks/rababa_hebrew/config.yaml rename to attic/tasks/rababa_hebrew/config.yaml diff --git a/src/tasks/rababa_hebrew/data.py b/attic/tasks/rababa_hebrew/data.py similarity index 100% rename from src/tasks/rababa_hebrew/data.py rename to attic/tasks/rababa_hebrew/data.py diff --git a/src/tasks/rababa_hebrew/metrics.py b/attic/tasks/rababa_hebrew/metrics.py similarity index 100% rename from src/tasks/rababa_hebrew/metrics.py rename to attic/tasks/rababa_hebrew/metrics.py diff --git a/src/tasks/rababa_hebrew/student.py b/attic/tasks/rababa_hebrew/student.py similarity index 100% rename from src/tasks/rababa_hebrew/student.py rename to attic/tasks/rababa_hebrew/student.py diff --git a/src/tasks/secryst_thai_ipa/__init__.py b/attic/tasks/secryst_thai_ipa/__init__.py similarity index 100% rename from src/tasks/secryst_thai_ipa/__init__.py rename to attic/tasks/secryst_thai_ipa/__init__.py diff --git a/src/tasks/secryst_thai_ipa/config.yaml b/attic/tasks/secryst_thai_ipa/config.yaml similarity index 100% rename from src/tasks/secryst_thai_ipa/config.yaml rename to attic/tasks/secryst_thai_ipa/config.yaml diff --git a/src/tasks/secryst_thai_ipa/data.py b/attic/tasks/secryst_thai_ipa/data.py similarity index 100% rename from src/tasks/secryst_thai_ipa/data.py rename to attic/tasks/secryst_thai_ipa/data.py diff --git a/src/tasks/secryst_thai_ipa/metrics.py b/attic/tasks/secryst_thai_ipa/metrics.py similarity index 100% rename from src/tasks/secryst_thai_ipa/metrics.py rename to attic/tasks/secryst_thai_ipa/metrics.py diff --git a/src/tasks/secryst_thai_ipa/student.py b/attic/tasks/secryst_thai_ipa/student.py similarity index 100% rename from src/tasks/secryst_thai_ipa/student.py rename to attic/tasks/secryst_thai_ipa/student.py diff --git a/tests/test_config.py b/attic/tests/test_config.py similarity index 100% rename from tests/test_config.py rename to attic/tests/test_config.py diff --git a/tests/test_e2e_cpu.py b/attic/tests/test_e2e_cpu.py similarity index 100% rename from tests/test_e2e_cpu.py rename to attic/tests/test_e2e_cpu.py diff --git a/tests/test_engram.py b/attic/tests/test_engram.py similarity index 100% rename from tests/test_engram.py rename to attic/tests/test_engram.py diff --git a/tests/test_engram_attach.py b/attic/tests/test_engram_attach.py similarity index 100% rename from tests/test_engram_attach.py rename to attic/tests/test_engram_attach.py diff --git a/tests/test_gkd.py b/attic/tests/test_gkd.py similarity index 100% rename from tests/test_gkd.py rename to attic/tests/test_gkd.py diff --git a/tests/test_gpu_mtp.py b/attic/tests/test_gpu_mtp.py similarity index 100% rename from tests/test_gpu_mtp.py rename to attic/tests/test_gpu_mtp.py diff --git a/tests/test_gpu_pkm_muon.py b/attic/tests/test_gpu_pkm_muon.py similarity index 100% rename from tests/test_gpu_pkm_muon.py rename to attic/tests/test_gpu_pkm_muon.py diff --git a/tests/test_gpu_runstate.py b/attic/tests/test_gpu_runstate.py similarity index 100% rename from tests/test_gpu_runstate.py rename to attic/tests/test_gpu_runstate.py diff --git a/tests/test_muon_headwise.py b/attic/tests/test_muon_headwise.py similarity index 100% rename from tests/test_muon_headwise.py rename to attic/tests/test_muon_headwise.py diff --git a/tests/test_paired_bootstrap.py b/attic/tests/test_paired_bootstrap.py similarity index 100% rename from tests/test_paired_bootstrap.py rename to attic/tests/test_paired_bootstrap.py diff --git a/tests/test_parity_stage_skip.py b/attic/tests/test_parity_stage_skip.py similarity index 100% rename from tests/test_parity_stage_skip.py rename to attic/tests/test_parity_stage_skip.py diff --git a/tests/test_pipeline.py b/attic/tests/test_pipeline.py similarity index 100% rename from tests/test_pipeline.py rename to attic/tests/test_pipeline.py diff --git a/tests/test_rababa_arabic.py b/attic/tests/test_rababa_arabic.py similarity index 100% rename from tests/test_rababa_arabic.py rename to attic/tests/test_rababa_arabic.py diff --git a/tests/test_rababa_hebrew.py b/attic/tests/test_rababa_hebrew.py similarity index 100% rename from tests/test_rababa_hebrew.py rename to attic/tests/test_rababa_hebrew.py diff --git a/tests/test_registry.py b/attic/tests/test_registry.py similarity index 100% rename from tests/test_registry.py rename to attic/tests/test_registry.py diff --git a/tests/test_ride.py b/attic/tests/test_ride.py similarity index 100% rename from tests/test_ride.py rename to attic/tests/test_ride.py diff --git a/tests/test_secryst_thai_ipa.py b/attic/tests/test_secryst_thai_ipa.py similarity index 100% rename from tests/test_secryst_thai_ipa.py rename to attic/tests/test_secryst_thai_ipa.py diff --git a/tests/test_sinkhorn_update.py b/attic/tests/test_sinkhorn_update.py similarity index 100% rename from tests/test_sinkhorn_update.py rename to attic/tests/test_sinkhorn_update.py diff --git a/tests/test_stitch.py b/attic/tests/test_stitch.py similarity index 100% rename from tests/test_stitch.py rename to attic/tests/test_stitch.py diff --git a/tests/test_student_config.py b/attic/tests/test_student_config.py similarity index 100% rename from tests/test_student_config.py rename to attic/tests/test_student_config.py diff --git a/pyproject.toml b/pyproject.toml index 06dd0ea0..5395f53e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -58,7 +58,7 @@ isxml = "pipeline.cli:main" [tool.setuptools.packages.find] where = ["src"] -include = ["framework*", "tasks*", "imf*", "sadeedbench*", "pipeline*"] +include = ["imf*", "sadeedbench*", "pipeline*"] [tool.pytest.ini_options] testpaths = ["tests"] diff --git a/src/imf/parity.py b/src/imf/parity.py index 803ee16d..12a8004f 100644 --- a/src/imf/parity.py +++ b/src/imf/parity.py @@ -19,7 +19,6 @@ from dataclasses import dataclass from pathlib import Path -from framework.evaluator import char_error_rate from imf.export import ( BYTE_OFFSET, EOS_ID, @@ -29,6 +28,7 @@ onnx_greedy_kv, ) from imf.schema import ModelMetadata, Parity +from imf.text_metrics import char_error_rate @dataclass(frozen=True) diff --git a/src/imf/text_metrics.py b/src/imf/text_metrics.py new file mode 100644 index 00000000..444d61d2 --- /dev/null +++ b/src/imf/text_metrics.py @@ -0,0 +1,34 @@ +"""Character-level edit metrics for the IMF parity gate. + +Inlined from the retired framework module (WO56 attic move): the gate +needs CER and nothing else. Same definitions, one dependency-free +home. +""" + +from __future__ import annotations + +from collections.abc import Sequence + + +def edit_distance(a: Sequence[object], b: Sequence[object]) -> int: + """Levenshtein distance.""" + if a == b: + return 0 + if not a: + return len(b) + if not b: + return len(a) + prev = list(range(len(b) + 1)) + for i, ca in enumerate(a, 1): + cur = [i] + for j, cb in enumerate(b, 1): + cur.append(min(prev[j] + 1, cur[j - 1] + 1, prev[j - 1] + (ca != cb))) + prev = cur + return prev[-1] + + +def char_error_rate(pred: str, gold: str) -> float: + """CER = edit_distance / len(gold).""" + if not gold: + return 0.0 if not pred else 1.0 + return edit_distance(list(pred), list(gold)) / len(gold) diff --git a/src/pipeline/cli.py b/src/pipeline/cli.py index 7f5f81ab..5b212a59 100644 --- a/src/pipeline/cli.py +++ b/src/pipeline/cli.py @@ -100,6 +100,36 @@ def cmd_conformance(args: argparse.Namespace) -> int: return 0 if res.passed else 1 +def cmd_housekeeper(args: argparse.Namespace) -> int: + """Live bucket inventory + prune plan. Classify-only: this verb + cannot delete anything (WO56 law) — the plan it prints is the + input to a separate, owner-authorized execution step.""" + import os + + from huggingface_hub import HfFileSystem + + from pipeline.housekeeper import inventory, prune_plan + + fs = HfFileSystem(token=os.environ.get("HF_TOKEN")) + runs = {} + for f in fs.ls(args.bucket): + name = f["name"].rsplit("/", 1)[-1] + if name.startswith(args.prefix): + runs[name] = fs.ls(f["name"]) + inv = inventory(runs) + for r in inv: + status = "complete" if r.complete else "IN-FLIGHT" + notes = ("; ".join(r.notes)) if r.notes else "" + print(f"{r.name:40s} {status:10s} {r.files:4d} files " + f"{r.bytes / 1e9:6.2f} GB {notes}") + plan = prune_plan(inv) + print(f"\nprune plan: {len(plan)} candidate(s) " + "(DRY-RUN — execution is owner-authorized, this verb cannot delete):") + for p in plan: + print(" ", p) + return 0 + + def main(argv: list[str] | None = None) -> int: ap = argparse.ArgumentParser(prog="isxml") sub = ap.add_subparsers(dest="cmd", required=True) @@ -130,6 +160,12 @@ def main(argv: list[str] | None = None) -> int: c.add_argument("--zip", required=True, type=Path) c.set_defaults(fn=cmd_conformance) + h = sub.add_parser("housekeeper", + help="bucket inventory + prune plan (dry-run only)") + h.add_argument("--bucket", default="buckets/Interscript/isx-training") + h.add_argument("--prefix", default="run-") + h.set_defaults(fn=cmd_housekeeper) + args = ap.parse_args(argv) return args.fn(args) From 3d24240ea486f9f373ed7dc0d0a7bc90985dfb15 Mon Sep 17 00:00:00 2001 From: Ronald Tse Date: Mon, 19 Oct 2026 18:14:19 +0800 Subject: [PATCH 2/2] docs(cards): HF frontmatter (license/tags/language) on the shipped-model cards --- cards/fas-diac-base-1.0.md | 12 ++++++++++++ cards/urd-diac-base-1.0.md | 14 ++++++++++++++ cards/urd-g2p-base-1.0.md | 15 +++++++++++++++ 3 files changed, 41 insertions(+) diff --git a/cards/fas-diac-base-1.0.md b/cards/fas-diac-base-1.0.md index 2e5336b0..e9db69f1 100644 --- a/cards/fas-diac-base-1.0.md +++ b/cards/fas-diac-base-1.0.md @@ -1,3 +1,15 @@ +--- +license: bsd-3-clause +language: + - fa +tags: + - diacritization + - byt5 + - imf + - persian +metrics: + - cer +--- # fas-diac-base-1.0 Persian diacritization, base tier (run-077): byt5-small seq2seq on diff --git a/cards/urd-diac-base-1.0.md b/cards/urd-diac-base-1.0.md index e30d2d0e..e255b590 100644 --- a/cards/urd-diac-base-1.0.md +++ b/cards/urd-diac-base-1.0.md @@ -1,3 +1,17 @@ +--- +license: other +license_name: bsd-3-clause-with-data-dependency +license_link: https://github.com/interscript/interscript-models/blob/main/cards/urd-diac-base-1.0.md +language: + - ur +tags: + - diacritization + - byt5 + - imf + - urdu +metrics: + - cer +--- # urd-diac-base-1.0 Urdu diacritization, base tier (run-066): byt5-base seq2seq on the diff --git a/cards/urd-g2p-base-1.0.md b/cards/urd-g2p-base-1.0.md index 9109207f..6a0b49de 100644 --- a/cards/urd-g2p-base-1.0.md +++ b/cards/urd-g2p-base-1.0.md @@ -1,3 +1,18 @@ +--- +license: other +license_name: research-only-non-commercial-data +license_link: https://github.com/interscript/interscript-models/blob/main/cards/urd-g2p-base-1.0.md +language: + - ur +tags: + - g2p + - byt5 + - imf + - urdu + - research-only +metrics: + - cer +--- # urd-g2p-base-1.0 Urdu grapheme-to-phoneme, base tier (run-059): byt5-base seq2seq on