Agent-Guided-Quantum-MLLM / QH024 /code /scripts /lock_qh024_wikitext_distillation.py
QuSpect
Initial Hugging Face release
47709ed
Raw History Blame Contribute Delete
6 kB
#!/usr/bin/env python3
"""Lock QH-024 train/eval blocks and hyperparameters before formal runs."""
from __future__ import annotations
import hashlib
import json
from datetime import datetime, timezone
from pathlib import Path
import numpy as np
import torch
PROJECT = Path(__file__).resolve().parents[2]
ARTIFACTS = PROJECT / "artifacts"
STAGE_A = ARTIFACTS / "wikitext_stage_a"
TRAIN = PROJECT / "datasets/processed/wikitext2_qwen38/train-tokens.pt"
VALIDATION = PROJECT / "datasets/processed/wikitext2_qwen38/validation-tokens.pt"
PARENT_LOCK = ARTIFACTS / "wikitext-replacement-screen-lock.json"
SCREEN = ARTIFACTS / "wikitext-svd-value-replacement-screen.json"
OUTPUT = ARTIFACTS / "wikitext-qh024-distillation-lock.json"
SEED = 20260838
SEQUENCE_LENGTH = 256
TRAIN_COUNT = 512
EVAL_COUNT = 32
def sha256(path: Path) -> str:
digest = hashlib.sha256()
with path.open("rb") as handle:
for chunk in iter(lambda: handle.read(8 << 20), b""):
digest.update(chunk)
return digest.hexdigest()
def prior_train_indices() -> set[int]:
paths = [
STAGE_A / "wikitext-qh010-s20260829-n256-l256.json",
STAGE_A / "wikitext-cc010-s20260829-n256-l256.json",
STAGE_A / "wikitext-qh022-unused-complement-s20260829-n256-l256.json",
STAGE_A / "wikitext-cc022-unused-complement-s20260829-n256-l256.json",
]
values: set[int] = set()
for path in paths:
if path.exists():
payload = json.loads(path.read_text(encoding="utf-8"))
values.update(int(index) for index in payload["dataset"]["train_indices"])
return values
def main() -> None:
parent = json.loads(PARENT_LOCK.read_text(encoding="utf-8"))
if parent["status"] != "locked_before_any_replacement_performance_result":
raise RuntimeError("invalid parent replacement lock")
if not SCREEN.exists():
raise RuntimeError("SVD screen record is required before architecture locking")
eval_indices = [int(value) for value in parent["indices"][32:64]]
if len(eval_indices) != EVAL_COUNT:
raise RuntimeError("parent lock does not contain the reserved holdout")
screen_payload = json.loads(SCREEN.read_text(encoding="utf-8"))
screened_indices = {
int(row["block_index"]) for row in screen_payload["base"]["rows"]
}
if screened_indices & set(eval_indices):
raise RuntimeError("QH-024 holdout overlaps the SVD selection blocks")
train_tokens = torch.load(TRAIN, map_location="cpu", weights_only=True)
complete_train = len(train_tokens) // SEQUENCE_LENGTH
excluded_train = prior_train_indices()
available = np.array(sorted(set(range(complete_train)) - excluded_train), dtype=np.int64)
train_indices = np.random.default_rng(SEED).permutation(available)[:TRAIN_COUNT].tolist()
if len(train_indices) != TRAIN_COUNT or set(train_indices) & excluded_train:
raise RuntimeError("failed to create disjoint QH-024 training blocks")
payload = {
"status": "locked_before_qh024_qh_cc_base_performance_results",
"candidate": "QH-024 true v_proj replacement",
"architecture": {
"layer_index": 7,
"target": "v_proj",
"svd_rank": 512,
"qubits": 10,
"depth": 2,
"quantum_trainable_parameters": 112701,
"original_projection_parameters": 5242880,
"deployed_replacement_parameters": 3258429,
"net_model_parameter_reduction": 1984451,
},
"selection_basis": {
"screen_record": str(SCREEN),
"screen_sha256": sha256(SCREEN),
"selected_candidate": "svd-v-l7-r512",
"selection_rule": (
"largest tested parameter reduction among candidates with development-screen "
"mean NLL increase <= 0.005"
),
},
"dataset": "Salesforce/wikitext wikitext-2-raw-v1",
"source_revision": "b08601e04326c79dfdd32d625aee71d232d685c3",
"license": "CC BY-SA 4.0",
"sequence_length": SEQUENCE_LENGTH,
"seed": SEED,
"train_indices": train_indices,
"train_count": TRAIN_COUNT,
"excluded_prior_train_indices_count": len(excluded_train),
"train_overlap_with_excluded": len(set(train_indices) & excluded_train),
"eval_indices": eval_indices,
"eval_count": EVAL_COUNT,
"eval_overlap_with_svd_selection_blocks": len(screened_indices & set(eval_indices)),
"parent_lock": str(PARENT_LOCK),
"parent_lock_sha256": sha256(PARENT_LOCK),
"train_tokens_sha256": sha256(TRAIN),
"validation_tokens_sha256": sha256(VALIDATION),
"training_protocol": {
"objective": "relative MSE distillation of the deleted dense v_proj output",
"optimizer": "AdamW",
"learning_rate": 0.001,
"weight_decay": 0.0,
"gradient_clip_norm": 1.0,
"epochs": 1,
"all_original_model_parameters_frozen": True,
"teacher_dense_weight_is_training_only_nonpersistent_buffer": True,
},
"evaluation_protocol": {
"primary_metric": "mean token NLL",
"compression_noninferiority_margin_nll": 0.005,
"paired_bootstrap_samples": 20000,
"required_controls": ["frozen_dense_base", "svd512_zero_branch", "CC-024"],
},
"test_rows_inspected_or_used_for_fitness": 0,
"created_at": datetime.now(timezone.utc).isoformat(),
}
OUTPUT.write_text(json.dumps(payload, indent=2), encoding="utf-8")
print(json.dumps({
"status": payload["status"],
"train_count": TRAIN_COUNT,
"eval_count": EVAL_COUNT,
"train_overlap": payload["train_overlap_with_excluded"],
"eval_overlap": payload["eval_overlap_with_svd_selection_blocks"],
"record": str(OUTPUT),
"sha256": sha256(OUTPUT),
}, indent=2))
if __name__ == "__main__":
main()