File size: 4,683 Bytes
81cffe7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
"""Prepare one V4.4 ablation arm's frozen 20-epoch LM+chat mixture.

Derives the arm request from the frozen V4.1 mixture exactly as V4.2 did (same
joined banks, exclusion masks and crop minimum; conversion pool removed; 20
epochs), then overrides only the arm's seed, chat fraction or crop probability.
Request and manifest are written with LF newlines so the manifest SHA is the
same on Windows and Linux; a configured arm must reproduce its pinned SHA.

The 'control' arm rebuilds V4.2 itself: epochs 0-15 must equal frozen V4.1, and
all 20 must equal the V4.2 mixture when that directory is present.
"""
import argparse
import json
from pathlib import Path
import shutil
import sys
import tomllib

ROOT=Path(__file__).resolve().parents[2]
sys.path.insert(0,str(ROOT/'src'))
from vimeml.training.data import file_sha
from vimeml.training.joint_v44 import ARMS,MIXTURE_EPOCHS
from vimeml.training.v41_data import prepare_maps

OLD=ROOT/'artifacts/training-data/corpus-v41-mixed-c128'
V42=ROOT/'artifacts/training-data/corpus-v42-mixed-c128'


def directory(arm):
    return ROOT/f'artifacts/training-data/corpus-v44-{arm}-c128'


def request_for(arm):
    request=json.loads((OLD/'request.json').read_text('utf-8'))
    if request['epochs']!=16:
        raise ValueError('Unexpected V4.1 mixture shape')
    seed,chat,crop=ARMS[arm]
    for key in ('conversion_dir','conversion_manifest_sha256','conversion_keep',
                'conversion_keep_sha256','conversion_examples','numpy_version'):
        request.pop(key)
    request.update(arm=arm,epochs=MIXTURE_EPOCHS,seed=seed,chat_fraction=chat,crop_probability=crop,
        old_keep=directory(arm).relative_to(ROOT).as_posix()+'/old.keep.npy',
        derived_from='artifacts/training-data/corpus-v41-mixed-c128',
        derivation=('V4.2 request (V4.1 with epochs 16->20 and the conversion pool removed) '
                    f'with seed={seed}, chat_fraction={chat}, crop_probability={crop}'))
    return request


def write_lf(path,text):
    temporary=path.with_suffix(path.suffix+'.tmp')
    temporary.write_bytes(text.encode('utf-8'))
    temporary.replace(path)


def main():
    parser=argparse.ArgumentParser(description=__doc__)
    parser.add_argument('--arm',choices=sorted(ARMS),required=True)
    args=parser.parse_args()
    target=directory(args.arm)
    request=request_for(args.arm)
    if (target/'request.json').exists():
        if json.loads((target/'request.json').read_text('utf-8'))!=request:
            raise ValueError(f'{target} holds a different request')
    else:
        target.mkdir(parents=True,exist_ok=True)
        shutil.copyfile(OLD/'old.keep.npy',target/'old.keep.npy')
        write_lf(target/'request.json',json.dumps(request,ensure_ascii=False,indent=1)+'\n')
    result=prepare_maps(target,root=ROOT)
    manifest=target/'manifest.json'
    raw=manifest.read_bytes()
    if b'\r\n' in raw:
        write_lf(manifest,raw.decode('utf-8').replace('\r\n','\n'))
    if len(result['epochs'])!=MIXTURE_EPOCHS:
        raise ValueError('prepare_maps did not produce the 20-epoch plan')
    report={'arm':args.arm,'directory':target.relative_to(ROOT).as_posix(),'epochs':MIXTURE_EPOCHS,
        'dataset_sha256':file_sha(manifest),
        'chat_fraction':[round(r['chat_fraction'],6) for r in result['epochs'][:2]],
        'chat_effective_passes':round(result['epochs'][0]['chat_effective_passes'],3),
        'windows_epoch1':result['epochs'][0]['windows']}
    if args.arm=='control':
        old=json.loads((OLD/'manifest.json').read_text('utf-8'))['epochs']
        if result['epochs'][:16]!=old:
            raise ValueError('Control maps differ from frozen V4.1 epochs 0-15')
        report['identical_to_v41']='epochs 0-15'
        if (V42/'manifest.json').exists():
            if result['epochs']!=json.loads((V42/'manifest.json').read_text('utf-8'))['epochs']:
                raise ValueError('Control maps differ from frozen V4.2')
            report['identical_to_v42']='epochs 0-19'
    else:
        config=tomllib.loads((ROOT/f'configs/train-v44-{args.arm}.toml').read_text('utf-8'))
        if config['data_mixture']['directory']!=report['directory']:
            raise ValueError('Config points at another mixture directory')
        if config['dataset_sha256'] and config['dataset_sha256']!=report['dataset_sha256']:
            raise ValueError(f"{args.arm} mixture SHA {report['dataset_sha256']} differs from the pinned "
                             f"{config['dataset_sha256']}; do not train, report this mismatch")
        report['matches_pinned_sha']=bool(config['dataset_sha256'])
    print(json.dumps(report),flush=True)


if __name__=='__main__':
    main()