| |
| """One-command verification of this release package. |
| |
| python verify_package.py # full check (1024 dev rows, both variants) |
| python verify_package.py --quick # 128 dev rows (fast, on CPU) |
| |
| Checks, in order: |
| 1. architecture in config.json rebuilds a model with the documented parameter count |
| 2. every packaged variant reproduces the documented dev protocol numbers |
| (top-1 / top-5 / CE on 1024 fixed rows, tolerance 5e-4) |
| 3. a real example state produces tactics (inference wiring works end to end) |
| 4. SHA256SUMS verifies the big files byte-for-byte |
| Exit code 0 only if every check passes. |
| """ |
| import argparse |
| import hashlib |
| import json |
| import os |
| import sys |
|
|
| from common import ROOT, VARIANTS, load_config, load_model, load_tokenizer, pick_device, \ |
| encode_state, whitelist, specials |
| from eval_dev import dev_eval, documented |
|
|
|
|
| def sha256(path, chunk=1 << 22): |
| h = hashlib.sha256() |
| with open(path, 'rb') as fh: |
| while True: |
| b = fh.read(chunk) |
| if not b: |
| break |
| h.update(b) |
| return h.hexdigest() |
|
|
|
|
| def check_sums(): |
| p = os.path.join(ROOT, 'SHA256SUMS') |
| if not os.path.exists(p): |
| return 'SHA256SUMS 不存在(跳过)', False |
| bad, n = [], 0 |
| for line in open(p): |
| line = line.strip() |
| if not line or line.startswith('#'): |
| continue |
| want, name = line.split(None, 1) |
| name = name.lstrip('*') |
| f = os.path.join(ROOT, name) |
| if not os.path.exists(f): |
| bad.append(f'{name} 缺失') |
| continue |
| n += 1 |
| if sha256(f) != want: |
| bad.append(f'{name} 校验和不符') |
| return ('SHA256SUMS:%d 个文件全部匹配' % n if not bad else ';'.join(bad)), not bad |
|
|
|
|
| def main(): |
| ap = argparse.ArgumentParser() |
| ap.add_argument('--quick', action='store_true', help='128 dev rows instead of 1024') |
| ap.add_argument('--device', default=None) |
| ap.add_argument('--skip-sums', action='store_true') |
| a = ap.parse_args() |
| rows = 128 if a.quick else 1024 |
| device = pick_device(a.device) |
| cfg = load_config() |
| ok_all = True |
| print(f'package : {ROOT}') |
| print(f'device : {device} dev rows: {rows}\n') |
|
|
| print('[1] 参数数量') |
| want = cfg['n_params'] |
| for ck in VARIANTS: |
| net, _, _ = load_model(ck, device) |
| got = sum(p.numel() for p in net.parameters()) |
| good = got == want |
| ok_all &= good |
| print(f' {ck:22s} {got:,} (config: {want:,}) {"OK" if good else "MISMATCH"}') |
| del net |
|
|
| print('\n[2] dev 协议复算(top-1 / top-5 / CE)') |
| for ck in VARIANTS: |
| net, _, device = load_model(ck, device) |
| r = dev_eval(net, device, rows=rows) |
| doc = documented(ck) |
| line = f' {ck:22s} top1={r["top1"]:.4f} top5={r["top5"]:.4f} ce={r["ce"]:.4f}' |
| if doc and rows == 1024: |
| d = max(abs(r['top1'] - doc['top1']), abs(r['top5'] - doc['top5']), |
| abs(r['ce'] - doc['ce'])) |
| good = d < 5e-4 |
| ok_all &= good |
| line += f' | documented {doc["top1"]:.4f}/{doc["top5"]:.4f}/{doc["ce"]:.4f} Δ={d:.5f} {"OK" if good else "MISMATCH"}' |
| elif doc: |
| line += f' | documented {doc["top1"]:.4f}/{doc["top5"]:.4f}/{doc["ce"]:.4f} (只用 1024 行才判定)' |
| print(line) |
| del net |
|
|
| print('\n[3] 推理连通性(示例样本 0)') |
| net, _, device = load_model(VARIANTS[0], device) |
| tok = load_tokenizer() |
| rec = [json.loads(l) for l in open(os.path.join(ROOT, 'examples/dev_sample.jsonl'))][0] |
| import torch |
| import torch.nn.functional as F |
| p = encode_state(tok, rec['state'], cfg) |
| ids = torch.tensor([p], device=device) |
| with torch.no_grad(): |
| lg = net(ids)['logits'][0, -1] |
| allow = torch.full_like(lg, float('-inf')) |
| allow[torch.tensor(whitelist(), device=device)] = 0.0 |
| top = int((lg + allow).argmax()) |
| sp = specials() |
| pred = tok.decode([top]) |
| truth = rec['true_first_token'] |
| hit = bool(pred.strip() == truth.strip()) |
| print(f' 状态: {rec["state"].strip().splitlines()[-1][:60]}') |
| print(f' 模型首个 token: {pred!r} | 该真实状态的 tactic 首 token: {truth!r} ' |
| f'{"命中" if hit else "未命中(正常:模型只有 0.31 的首 token 命中率,不影响本包可用性)"}') |
| del net |
|
|
| if not a.skip_sums: |
| print('\n[4] 校验和') |
| msg, good = check_sums() |
| ok_all &= good |
| print(f' {msg}') |
|
|
| print('\n=== ' + ('PASS:本包自洽,文档中的数字可复现' if ok_all else 'FAIL:见上面标记')) |
| return 0 if ok_all else 1 |
|
|
|
|
| if __name__ == '__main__': |
| sys.exit(main()) |
|
|