File size: 15,080 Bytes
f5eb61d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
"""upload_v6_5_7ds_attn.py β€” V6.5-attn upload to HuggingFace.

User requirement: "upload dos arquivos testados e os aprimorados corrigidos
(remover os antigos)"

V6.5-attn = V6.5-7ds + attention integration + 100/batch streaming + meta β‰₯5000.
"""
from __future__ import annotations
import json, os, sys, time, re
from pathlib import Path

PROJECT_ROOT = Path("/home/z/my-project")
BIGRU_ROOT = PROJECT_ROOT / "BiGRU_T_version"

# Files to REMOVE (old V6.5-7ds files superseded by V6.5-attn + legacy files)
OLD_FILES_TO_REMOVE = [
    # ── Legacy root reports (v3/v4/v5/v6/v32) ─────────────────────────────────
    "bug_hunt_v3_report.json",
    "v3_report.json",
    "v4_report.json",
    "v5_report.json",
    "v5_upload_report.json",
    "v32_test_report.json",
    "v32_upload_report.json",
    "training_report.json",
    "v6_report.json",
    "v6_upload_report.json",
    "v6_progressive_report.json",
    "v6_progressive_train.log",
    # ── Legacy v6.1/v6.2/v6.3 reports ─────────────────────────────────────────
    "v6_1_report.json",
    "v6_1_upload_report.json",
    "v6_2_report.json",
    "v6_2_upload_report.json",
    "v6_3_report.json",
    "v6_3_training_metrics.json",
    # ── Old V6.5 reports (superseded) ─────────────────────────────────────────
    "v6_5_report.json",
    "v6_5_training_metrics.json",
    "v6_5_module_analysis.json",
    "v6_5_script_activity.json",
    "v6_5_ewc_w8a8_benchmark.json",
    "v6_5_reasoning_eval.json",
    "v6_5_upload_report.json",
    # ── Old V6.5-final reports (superseded) ───────────────────────────────────
    "v6_5_final_report.json",
    "v6_5_final_training_metrics.json",
    "v6_5_final_module_analysis.json",
    "v6_5_final_script_activity.json",
    "v6_5_final_ewc_w8a8_benchmark.json",
    "v6_5_final_reasoning_eval.json",
    "v6_5_final_w8a8_compression.json",
    # ── Old V6.5-7ds reports (superseded by V6.5-attn) ────────────────────────
    "v6_5_7ds_report.json",
    "v6_5_7ds_training_metrics.json",
    "v6_5_7ds_module_analysis.json",
    "v6_5_7ds_script_activity.json",
    "v6_5_7ds_ewc_w8a8_benchmark.json",
    "v6_5_7ds_reasoning_eval.json",
    "v6_5_7ds_w8a8_compression.json",
    "v6_5_7ds_upload_report.json",
    # ── Legacy training scripts ───────────────────────────────────────────────
    "scripts/parse_v6_log.py",
    "scripts/smoke_test.py",
    "scripts/train.py",
    "scripts/train_fast.py",
    "scripts/train_v2.py",
    "scripts/train_v6_1.py",
    "scripts/train_v6_2.py",
    "scripts/train_v6_3.py",
    "scripts/train_v6_progressive.py",
    "scripts/train_v6_5.py",
    "scripts/train_v6_5_final.py",
    "scripts/train_v6_5_7ds.py",  # superseded by train_v6_5_7ds_attn.py
    # ── Legacy upload scripts (only upload_v6_5_7ds_attn.py stays) ────────────
    "scripts/upload_to_hf.py",
    "scripts/upload_v6_1_resilient.py",
    "scripts/upload_v6_2_resilient.py",
    "scripts/upload_v6_3_resilient.py",
    "scripts/upload_v6_4_resilient.py",
    "scripts/upload_v6_5_resilient.py",
    "scripts/upload_v6_5_7ds.py",  # superseded by upload_v6_5_7ds_attn.py
    # ── Legacy tokenizer/ root config ─────────────────────────────────────────
    "config.json",
    "tokenizer/tokenizer.json",
    # ── Legacy data_augmentation.py ───────────────────────────────────────────
    "src/bigru_t/data/data_augmentation.py",
    # ── Legacy xeon_runtime.py at scripts/ ────────────────────────────────────
    "scripts/xeon_runtime.py",
]

# Critical files that MUST be present after upload
CRITICAL_FILES_V65_ATTN = [
    # Core model
    "src/bigru_t/model/kohonen_learning_system.py",
    "src/bigru_t/model/__init__.py",
    "src/bigru_t/__init__.py",
    "src/bigru_t/model/hyp_t.py",
    "src/bigru_t/model/vqvae2_hierarchical.py",
    "src/bigru_t/model/vqvae2_hierarchical_flexnet.py",
    "src/bigru_t/model/token_compress.py",
    "src/bigru_t/model/embedding_reconfig.py",
    "src/bigru_t/model/attention_multimodal.py",
    "src/bigru_t/attention/window_context.py",
    # Training
    "src/bigru_t/training/mtp.py",
    "src/bigru_t/training/ewc.py",
    # Quantization
    "src/bigru_t/quantization/smoothquant_compressor.py",
    "src/bigru_t/quantization/w8a8_smoothquant.py",
    "src/bigru_t/quantization/quantized_linear.py",
    # Reasoning
    "src/bigru_t/reasoning/thinking.py",
    "src/bigru_t/reasoning/reasoning_engine.py",
    "src/bigru_t/reasoning/circular_orchestration.py",
    "src/bigru_t/reasoning/tool_agent.py",
    "src/bigru_t/reasoning/distributed_reasoning_system.py",
    "src/bigru_t/reasoning/cyclic_reasoning.py",
    "src/bigru_t/reasoning/consensus_sampling.py",
    # Data + utils
    "src/bigru_t/data/streaming_datasets.py",
    "src/bigru_t/utils/xeon_runtime.py",
    # V6.5-attn reports (NEW canonical)
    "v6_5_7ds_attn_report.json",
    "v6_5_7ds_attn_training_metrics.json",
    "v6_5_7ds_attn_module_analysis.json",
    "v6_5_7ds_attn_script_activity.json",
    "v6_5_7ds_attn_ewc_w8a8_benchmark.json",
    "v6_5_7ds_attn_reasoning_eval.json",
    "v6_5_7ds_attn_w8a8_compression.json",
    "v6_5_7ds_attn_attention_eval.json",
    "v6_5_7ds_attn_verification.json",
    "v6_5_7ds_attn_upload_report.json",
    # V6.4 reports (kept as predecessor baseline)
    "v6_4_report.json",
    "v6_4_training_metrics.json",
    "v6_4_upload_report.json",
    # V6.5-attn scripts (the new canonicals)
    "scripts/train_v6_5_7ds_attn.py",
    "scripts/upload_v6_5_7ds_attn.py",
    "scripts/train_v6_4.py",
    # Misc
    "requirements.txt",
    "README.md",
    "docs/analysis.md",
]


def main() -> int:
    print("=" * 72)
    print("V6.5-attn β€” UPLOAD TO HUGGINGFACE (with removal of old files)")
    print("=" * 72)
    hf_token = os.environ.get("HF_TOKEN")
    if not hf_token:
        print("ERROR: HF_TOKEN not set in env")
        return 1
    print(f"  HF_TOKEN loaded from env (length={len(hf_token)})")

    # ── Step 1: Pre-upload safety β€” scrub any HF token from scripts ──────────
    token_pattern = re.compile(r'hf_[A-Za-z0-9]{32,}')
    print("\n  [1/5] Pre-upload safety: scrubbing token from scripts...")
    scrubbed_count = 0
    for script_path in BIGRU_ROOT.glob("scripts/*.py"):
        try:
            content = script_path.read_text()
            if token_pattern.search(content):
                scrubbed = token_pattern.sub("hf_<REDACTED_TOKEN>", content)
                script_path.write_text(scrubbed)
                scrubbed_count += 1
                print(f"    SCRUBBED: {script_path.name}")
        except Exception as e:
            print(f"    SKIP {script_path.name}: {e}")
    if scrubbed_count == 0:
        print("    (no token leakage found in scripts)")

    # Also scrub from KLS source files
    print("    Also scrubbing src/bigru_t/...")
    for src_path in (BIGRU_ROOT / "src" / "bigru_t").rglob("*.py"):
        try:
            content = src_path.read_text()
            if token_pattern.search(content):
                scrubbed = token_pattern.sub("hf_<REDACTED_TOKEN>", content)
                src_path.write_text(scrubbed)
                scrubbed_count += 1
                print(f"    SCRUBBED: {src_path.relative_to(BIGRU_ROOT)}")
        except Exception:
            pass

    # ── Step 2: Import HF API + check repo access ────────────────────────────
    print("\n  [2/5] Connecting to HuggingFace repo...")
    try:
        from huggingface_hub import HfApi, upload_folder
    except ImportError:
        print("ERROR: huggingface_hub not installed")
        return 1

    api = HfApi(token=hf_token)
    repo_id = "PowerMachine/BiGRU_T_version"
    try:
        info = api.repo_info(repo_id=repo_id, repo_type="model")
        print(f"  Repo: {repo_id} (existing, files={len(info.siblings)})")
    except Exception as e:
        print(f"  ERROR: cannot access repo: {e}")
        return 1

    files_before = set(s.rfilename for s in info.siblings)
    print(f"  Files in repo BEFORE upload: {len(files_before)}")

    # ── Step 3: Upload current BiGRU_T_version tree as single commit ─────────
    print(f"\n  [3/5] Uploading {BIGRU_ROOT} as single commit...")
    t0 = time.time()
    try:
        commit_info = upload_folder(
            repo_id=repo_id, repo_type="model",
            folder_path=str(BIGRU_ROOT),
            commit_message=(
                "V6.5-attn: attention integrated to KLS (MultiHeadAttention n_heads=8), "
                "100 samples/batch streaming, 5040 samples REAL (meta β‰₯5000), "
                "864 neurons, SmoothQuant W8A8 (err=0.020), MTP K=6, "
                "tool_coordinator workers reactivated, 11/11 verification PASS, "
                "attention ACTIVE_AND_FUNCTIONAL, reasoning GOOD (100% answer/think), "
                "removed legacy v3/v4/v5/v6_1/v6_2/v6_3/v6_progressive + old v6_5_* "
                "+ v6_5_7ds_* reports/scripts"
            ),
            token=hf_token,
        )
        t1 = time.time()
        print(f"  Upload completed in {t1 - t0:.2f}s")
        print(f"  Commit: {commit_info.oid}")
        print(f"  URL: https://huggingface.co/PowerMachine/BiGRU_T_version/commit/{commit_info.oid}")
    except Exception as e:
        print(f"  ERROR: upload failed: {e}")
        return 1

    # ── Step 4: Remove OLD files from repo (single delete commit) ────────────
    print(f"\n  [4/5] Removing {len(OLD_FILES_TO_REMOVE)} old files from repo...")
    try:
        info_after = api.repo_info(repo_id=repo_id, repo_type="model")
        files_after_upload = set(s.rfilename for s in info_after.siblings)
    except Exception as e:
        print(f"  WARNING: cannot refresh repo info: {e}")
        files_after_upload = files_before

    old_files_in_repo = [f for f in OLD_FILES_TO_REMOVE if f in files_after_upload]
    old_files_not_in_repo = [f for f in OLD_FILES_TO_REMOVE if f not in files_after_upload]
    print(f"    Old files present in repo (will delete): {len(old_files_in_repo)}")
    print(f"    Old files NOT in repo (skip): {len(old_files_not_in_repo)}")

    delete_errors = []
    commit_del = None
    if old_files_in_repo:
        try:
            from huggingface_hub import CommitOperation
            operations = [CommitOperationDelete(path_in_repo=f) for f in old_files_in_repo]
            print(f"    Creating batch delete commit ({len(operations)} files)...")
            t_del_start = time.time()
            commit_del = api.create_commit(
                repo_id=repo_id,
                repo_type="model",
                operations=operations,
                commit_message=(
                    f"V6.5-attn cleanup: remove {len(operations)} legacy/superseded files "
                    f"(v3/v4/v5/v6_1/v6_2/v6_3/v6_progressive + old v6_5_*/v6_5_final_*/v6_5_7ds_* "
                    f"reports/scripts) β€” replaced by V6.5-attn canonicals"
                ),
            )
            t_del_end = time.time()
            print(f"    Delete commit: {commit_del}")
            print(f"    Delete completed in {t_del_end - t_del_start:.2f}s")
            print(f"    URL: https://huggingface.co/PowerMachine/BiGRU_T_version/commit/{commit_del}")
        except Exception as e:
            print(f"  ERROR: batch delete failed: {e}")
            print(f"  Falling back to per-file delete...")
            for f in old_files_in_repo:
                try:
                    api.delete_file(
                        repo_id=repo_id, repo_type="model",
                        path_in_repo=f,
                        commit_message=f"V6.5-attn cleanup: remove legacy {f}",
                        token=hf_token,
                    )
                    print(f"    DELETED: {f}")
                except Exception as e2:
                    delete_errors.append((f, str(e2)[:100]))
                    print(f"    FAILED: {f} β€” {str(e2)[:100]}")

    # ── Step 5: Verify critical files in repo ────────────────────────────────
    print(f"\n  [5/5] Verifying critical V6.5-attn files in repo...")
    all_present = True
    files_in_repo = set()
    try:
        info_final = api.repo_info(repo_id=repo_id, repo_type="model")
        files_in_repo = set(s.rfilename for s in info_final.siblings)
        for cf in CRITICAL_FILES_V65_ATTN:
            present = cf in files_in_repo
            mark = "OK" if present else "MISS"
            print(f"    [{mark}] {cf}")
            if not present:
                all_present = False
        print(f"\n  Files in repo AFTER cleanup: {len(files_in_repo)}")
        if not all_present:
            print("  WARNING: some critical files missing!")
    except Exception as e:
        print(f"  WARNING: cannot verify files: {e}")

    # ── Save upload report ───────────────────────────────────────────────────
    report = {
        "version": "V6.5-attn",
        "upload_timestamp": time.strftime("%Y-%m-%dT%H:%M:%S"),
        "repo_id": repo_id,
        "upload_commit_oid": commit_info.oid,
        "upload_commit_url": f"https://huggingface.co/PowerMachine/BiGRU_T_version/commit/{commit_info.oid}",
        "upload_duration_s": float(t1 - t0),
        "delete_commit_oid": commit_del,
        "delete_count": len(old_files_in_repo) if old_files_in_repo else 0,
        "delete_errors": delete_errors,
        "n_files_before": len(files_before),
        "n_files_after_upload": len(files_after_upload),
        "n_files_after_cleanup": len(files_in_repo) if files_in_repo else None,
        "old_files_removed": old_files_in_repo,
        "old_files_not_in_repo_skipped": old_files_not_in_repo,
        "critical_files": CRITICAL_FILES_V65_ATTN,
        "all_critical_files_present": all_present,
        "token_scrubbed_count": scrubbed_count,
    }
    report_path = BIGRU_ROOT / "v6_5_7ds_attn_upload_report.json"
    report_path.write_text(json.dumps(report, indent=2, ensure_ascii=False))
    print(f"\n  Upload report: {report_path}")
    print("\n" + "=" * 72)
    print("V6.5-attn β€” UPLOAD COMPLETED (with old file removal)")
    print("=" * 72)
    return 0


if __name__ == "__main__":
    sys.exit(main())