PowerMachine commited on
Commit
4f42a02
·
verified ·
1 Parent(s): d07d6a9

HAKO-V2: fontes GPT-2 x2 + DINOv2, metricas SOM + verificacoes M1-M4

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. README.md +9 -0
  2. analysis.json +56 -0
  3. artifacts/corpus_instr.json +0 -0
  4. artifacts/dinov2_decomposed.decomposed.json +26 -0
  5. artifacts/dinov2_decomposed.npz +3 -0
  6. artifacts/gpt2a_decomposed.decomposed.json +21 -0
  7. artifacts/gpt2a_decomposed.npz +3 -0
  8. artifacts/gpt2g_decomposed.decomposed.json +59 -0
  9. artifacts/gpt2g_decomposed.npz +3 -0
  10. artifacts/nlg_head_v2.npz +3 -0
  11. artifacts/v2_sources_meta.json +110 -0
  12. checkpoints/hako_v2_final.meta.json +24 -0
  13. checkpoints/hako_v2_final.npz +3 -0
  14. checkpoints/hako_v2_p2_solo.meta.json +24 -0
  15. checkpoints/hako_v2_p2_solo.npz +3 -0
  16. checkpoints/hako_v2_p3.meta.json +24 -0
  17. checkpoints/hako_v2_p3.npz +3 -0
  18. checkpoints/hako_v2_p4.meta.json +24 -0
  19. checkpoints/hako_v2_p4.npz +3 -0
  20. hako_v1_publicado/.gitattributes +35 -0
  21. hako_v1_publicado/README.md +66 -0
  22. hako_v1_publicado/artifacts/final_summary.json +16 -0
  23. hako_v1_publicado/artifacts/granite1b_decomposed.decomposed.json +18 -0
  24. hako_v1_publicado/artifacts/granite1b_decomposed.npz +3 -0
  25. hako_v1_publicado/artifacts/hako_byte_bpe.json +0 -0
  26. hako_v1_publicado/artifacts/nlg_head.npz +3 -0
  27. hako_v1_publicado/artifacts/phase1_Z_workspace.npz +3 -0
  28. hako_v1_publicado/artifacts/qwen05b_decomposed.decomposed.json +18 -0
  29. hako_v1_publicado/artifacts/qwen05b_decomposed.npz +3 -0
  30. hako_v1_publicado/checkpoints/hako_final.meta.json +24 -0
  31. hako_v1_publicado/checkpoints/hako_final.npz +3 -0
  32. hako_v1_publicado/checkpoints/hako_phase1.meta.json +24 -0
  33. hako_v1_publicado/checkpoints/hako_phase1.npz +3 -0
  34. hako_v1_publicado/checkpoints/hako_phase1_partial.meta.json +24 -0
  35. hako_v1_publicado/checkpoints/hako_phase1_partial.npz +3 -0
  36. hako_v1_publicado/checkpoints/hako_phase2.meta.json +24 -0
  37. hako_v1_publicado/checkpoints/hako_phase2.npz +3 -0
  38. hako_v1_publicado/checkpoints/hako_phase2_partial.meta.json +24 -0
  39. hako_v1_publicado/checkpoints/hako_phase2_partial.npz +3 -0
  40. hako_v1_publicado/checkpoints/hako_phase3.meta.json +24 -0
  41. hako_v1_publicado/checkpoints/hako_phase3.npz +3 -0
  42. hako_v1_publicado/hako/__init__.py +21 -0
  43. hako_v1_publicado/hako/autotune/__init__.py +0 -0
  44. hako_v1_publicado/hako/autotune/abmo.py +96 -0
  45. hako_v1_publicado/hako/autotune/ensemble.py +116 -0
  46. hako_v1_publicado/hako/autotune/ewc_qac.py +121 -0
  47. hako_v1_publicado/hako/autotune/growth.py +113 -0
  48. hako_v1_publicado/hako/autotune/meta.py +109 -0
  49. hako_v1_publicado/hako/autotune/pgo.py +146 -0
  50. hako_v1_publicado/hako/checkpoint.py +52 -0
README.md ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ # HAKO-V2 (Hybrid Attention Kohonen Orchestrator, v2)
2
+
3
+ Evolucao do HAKO-v1 publicado, gerada SEM modificar o pacote V1:
4
+ novas fontes congeladas (GPT-2 Alpaca-GPT4, GPT-2 GQA, DINOv2-small),
5
+ metricas SOM completas (QE, erro topografico, U-matrix, frequencia de
6
+ ativacao, convergencia de pesos) e verificacoes matematicas em runtime
7
+ (T-ATTVAR/Minkowski, Dirichlet eta<=2/lambda_max, cota de Rademacher,
8
+ Lemma 1 BPE). Quantizacao int4 mantida (P-DEC). Entrada:
9
+ `python3 -m hako_v2.run_v2 --start 0`. Telemetria JSONL 5 fluxos.
analysis.json ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "soft_cap_gib": 2.96,
3
+ "fontes": {
4
+ "gpt2a": {
5
+ "repo": "onnx-community/gpt2-alpaca-gpt4-ONNX",
6
+ "kind": "text-instruction",
7
+ "d_src": 768,
8
+ "K": 32,
9
+ "K_xi": 8,
10
+ "adapters": 4,
11
+ "notas": "GPT-2 124M afinado em Alpaca-GPT4 (epoca <= 2023/24)",
12
+ "download_bytes": 252785964,
13
+ "download_h": [
14
+ 241.1,
15
+ "MiB"
16
+ ],
17
+ "banco_decomposto_estimado_mib": 3.06
18
+ },
19
+ "gpt2g": {
20
+ "repo": "onnx-community/gpt2-ONNX-GQA",
21
+ "kind": "text-gqa",
22
+ "d_src": 768,
23
+ "K": 32,
24
+ "K_xi": 8,
25
+ "adapters": 4,
26
+ "notas": "GPT-2 com atencao agrupada (GQA) exportada ONNX/OGA",
27
+ "download_bytes": 501458554,
28
+ "download_h": [
29
+ 478.2,
30
+ "MiB"
31
+ ],
32
+ "banco_decomposto_estimado_mib": 3.06
33
+ },
34
+ "dinov2": {
35
+ "repo": "onnx-community/dinov2-small-with-attentions",
36
+ "kind": "vision",
37
+ "d_src": 384,
38
+ "K": 48,
39
+ "K_xi": 8,
40
+ "adapters": 4,
41
+ "notas": "ViT-S/14 DINOv2 (autoatencao auto-supervisionada, 2023/24)",
42
+ "download_bytes": 46029900,
43
+ "download_h": [
44
+ 43.9,
45
+ "MiB"
46
+ ],
47
+ "banco_decomposto_estimado_mib": 1.54
48
+ }
49
+ },
50
+ "veredito": {
51
+ "cabem_juntos": true,
52
+ "n_fontes": 3,
53
+ "pico_ram_estimado_gib": 1.1,
54
+ "justificativa": "runtime usa memmap (page cache evictavel) + bancos int4 (MBs); decomposicao um-por-vez (P-SRC)"
55
+ }
56
+ }
artifacts/corpus_instr.json ADDED
The diff for this file is too large to render. See raw diff
 
artifacts/dinov2_decomposed.decomposed.json ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "tag": "dinov2",
3
+ "repo": "onnx-community/dinov2-small-with-attentions",
4
+ "kind": "vision",
5
+ "notas": "ViT-S/14 DINOv2 (autoatencao auto-supervisionada, 2023/24)",
6
+ "matrix": "onnx::MatMul_1868",
7
+ "shape": [
8
+ 384,
9
+ 1536
10
+ ],
11
+ "dtype": "float16",
12
+ "K_experts": 48,
13
+ "K_xi": 8,
14
+ "d_src": 384,
15
+ "n_adapters": 4,
16
+ "inertia": 1218.400146484375,
17
+ "samples": 1536,
18
+ "int4": true,
19
+ "adapter_rank": 48,
20
+ "epoca": "<= 2024/2025",
21
+ "visao": {
22
+ "patch": 14,
23
+ "image_size": 518,
24
+ "uso": "prototipos int4 desquantizados (padrao granite)"
25
+ }
26
+ }
artifacts/dinov2_decomposed.npz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:25ba04e68b0ee955ddc3e4691d09d7e775984b7e8731ca1c9cdb311759a1e3ac
3
+ size 1506632
artifacts/gpt2a_decomposed.decomposed.json ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "tag": "gpt2a",
3
+ "repo": "onnx-community/gpt2-alpaca-gpt4-ONNX",
4
+ "kind": "text-instruction",
5
+ "notas": "GPT-2 124M afinado em Alpaca-GPT4 (epoca <= 2023/24)",
6
+ "matrix": "transformer.wte.weight",
7
+ "shape": [
8
+ 50260,
9
+ 768
10
+ ],
11
+ "dtype": "float16",
12
+ "K_experts": 32,
13
+ "K_xi": 8,
14
+ "d_src": 768,
15
+ "n_adapters": 4,
16
+ "inertia": 4198.662109375,
17
+ "samples": 6000,
18
+ "int4": true,
19
+ "adapter_rank": 48,
20
+ "epoca": "<= 2024/2025"
21
+ }
artifacts/gpt2a_decomposed.npz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:0f748f293a0896034734b52551167bba7bd0b50f0ebfd47e8956b139f527b7b4
3
+ size 2989717
artifacts/gpt2g_decomposed.decomposed.json ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "tag": "gpt2g",
3
+ "repo": "onnx-community/gpt2-ONNX-GQA",
4
+ "kind": "text-gqa",
5
+ "notas": "GPT-2 com atencao agrupada (GQA) exportada ONNX/OGA",
6
+ "matrix": "transformer.wte.weight",
7
+ "shape": [
8
+ 50257,
9
+ 768
10
+ ],
11
+ "dtype": "1",
12
+ "K_experts": 32,
13
+ "K_xi": 8,
14
+ "d_src": 768,
15
+ "n_adapters": 4,
16
+ "inertia": 4229.31640625,
17
+ "samples": 6000,
18
+ "int4": true,
19
+ "adapter_rank": 48,
20
+ "epoca": "<= 2024/2025",
21
+ "gqa_signature": {
22
+ "gqa_nodes": 12,
23
+ "ops_top": [
24
+ [
25
+ "Add",
26
+ 97
27
+ ],
28
+ [
29
+ "MatMul",
30
+ 73
31
+ ],
32
+ [
33
+ "LayerNormalization",
34
+ 25
35
+ ],
36
+ [
37
+ "GroupQueryAttention",
38
+ 12
39
+ ],
40
+ [
41
+ "Gelu",
42
+ 12
43
+ ],
44
+ [
45
+ "Gather",
46
+ 3
47
+ ],
48
+ [
49
+ "Constant",
50
+ 2
51
+ ],
52
+ [
53
+ "Cast",
54
+ 2
55
+ ]
56
+ ],
57
+ "kv_candidate_shapes": []
58
+ }
59
+ }
artifacts/gpt2g_decomposed.npz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:6a781b269f5029fc07c02225dea1d588e2cb7c33f274344e350fa92ced5a5ee2
3
+ size 2990184
artifacts/nlg_head_v2.npz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:2cd5913c71fd3baa665528e43fcef41b12e9c9be030e22ac86e723c4538d894d
3
+ size 19789276
artifacts/v2_sources_meta.json ADDED
@@ -0,0 +1,110 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "gpt2a": {
3
+ "tag": "gpt2a",
4
+ "repo": "onnx-community/gpt2-alpaca-gpt4-ONNX",
5
+ "kind": "text-instruction",
6
+ "notas": "GPT-2 124M afinado em Alpaca-GPT4 (epoca <= 2023/24)",
7
+ "matrix": "transformer.wte.weight",
8
+ "shape": [
9
+ 50260,
10
+ 768
11
+ ],
12
+ "dtype": "float16",
13
+ "K_experts": 32,
14
+ "K_xi": 8,
15
+ "d_src": 768,
16
+ "n_adapters": 4,
17
+ "inertia": 4198.662109375,
18
+ "samples": 6000,
19
+ "int4": true,
20
+ "adapter_rank": 48,
21
+ "epoca": "<= 2024/2025",
22
+ "runtime_mode": "embedding"
23
+ },
24
+ "gpt2g": {
25
+ "tag": "gpt2g",
26
+ "repo": "onnx-community/gpt2-ONNX-GQA",
27
+ "kind": "text-gqa",
28
+ "notas": "GPT-2 com atencao agrupada (GQA) exportada ONNX/OGA",
29
+ "matrix": "transformer.wte.weight",
30
+ "shape": [
31
+ 50257,
32
+ 768
33
+ ],
34
+ "dtype": "1",
35
+ "K_experts": 32,
36
+ "K_xi": 8,
37
+ "d_src": 768,
38
+ "n_adapters": 4,
39
+ "inertia": 4229.31640625,
40
+ "samples": 6000,
41
+ "int4": true,
42
+ "adapter_rank": 48,
43
+ "epoca": "<= 2024/2025",
44
+ "gqa_signature": {
45
+ "gqa_nodes": 12,
46
+ "ops_top": [
47
+ [
48
+ "Add",
49
+ 97
50
+ ],
51
+ [
52
+ "MatMul",
53
+ 73
54
+ ],
55
+ [
56
+ "LayerNormalization",
57
+ 25
58
+ ],
59
+ [
60
+ "GroupQueryAttention",
61
+ 12
62
+ ],
63
+ [
64
+ "Gelu",
65
+ 12
66
+ ],
67
+ [
68
+ "Gather",
69
+ 3
70
+ ],
71
+ [
72
+ "Constant",
73
+ 2
74
+ ],
75
+ [
76
+ "Cast",
77
+ 2
78
+ ]
79
+ ],
80
+ "kv_candidate_shapes": []
81
+ },
82
+ "runtime_mode": "embedding"
83
+ },
84
+ "dinov2": {
85
+ "tag": "dinov2",
86
+ "repo": "onnx-community/dinov2-small-with-attentions",
87
+ "kind": "vision",
88
+ "notas": "ViT-S/14 DINOv2 (autoatencao auto-supervisionada, 2023/24)",
89
+ "matrix": "onnx::MatMul_1868",
90
+ "shape": [
91
+ 384,
92
+ 1536
93
+ ],
94
+ "dtype": "float16",
95
+ "K_experts": 48,
96
+ "K_xi": 8,
97
+ "d_src": 384,
98
+ "n_adapters": 4,
99
+ "inertia": 1218.400146484375,
100
+ "samples": 1536,
101
+ "int4": true,
102
+ "adapter_rank": 48,
103
+ "epoca": "<= 2024/2025",
104
+ "visao": {
105
+ "patch": 14,
106
+ "image_size": 518,
107
+ "uso": "prototipos int4 desquantizados (padrao granite)"
108
+ }
109
+ }
110
+ }
checkpoints/hako_v2_final.meta.json ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "moe": {
3
+ "tau_bias": 0.7347201704978943,
4
+ "beta_moe": 1.0348315238952637
5
+ },
6
+ "heads": {},
7
+ "chain": {},
8
+ "tgnn": {},
9
+ "router": {
10
+ "log_alpha": 0.0
11
+ },
12
+ "diffusion": {},
13
+ "ghsom": {},
14
+ "theta": {
15
+ "repr": "[0.18 1.2 0.55 0.05 0.05 0.5 0.05 0.05 0.2 0.1 0.05 0.3 ]"
16
+ },
17
+ "scalars": {
18
+ "step": 348,
19
+ "N_dim": 256,
20
+ "growth_events": 1,
21
+ "difficulty": 0.05,
22
+ "level": 0
23
+ }
24
+ }
checkpoints/hako_v2_final.npz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:6e1f737a15907807170ed3e97daf60fd6b61725e18238db8b39e68f6bc284626
3
+ size 13652359
checkpoints/hako_v2_p2_solo.meta.json ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "moe": {
3
+ "tau_bias": 0.6858869791030884,
4
+ "beta_moe": 0.9861844778060913
5
+ },
6
+ "heads": {},
7
+ "chain": {},
8
+ "tgnn": {},
9
+ "router": {
10
+ "log_alpha": 0.0
11
+ },
12
+ "diffusion": {},
13
+ "ghsom": {},
14
+ "theta": {
15
+ "repr": "[0.18 1.2 0.55 0.05 0.05 0.5 0.05 0.05 0.2 0.1 0.05 0.3 ]"
16
+ },
17
+ "scalars": {
18
+ "step": 290,
19
+ "N_dim": 256,
20
+ "growth_events": 2,
21
+ "difficulty": 0.05,
22
+ "level": 0
23
+ }
24
+ }
checkpoints/hako_v2_p2_solo.npz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:40d8d15bd4108f31c7d81715a6180312c10ddc24110c4d31b87ee1b8c94a59b3
3
+ size 10059963
checkpoints/hako_v2_p3.meta.json ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "moe": {
3
+ "tau_bias": 0.6738803386688232,
4
+ "beta_moe": 0.9741302132606506
5
+ },
6
+ "heads": {},
7
+ "chain": {},
8
+ "tgnn": {},
9
+ "router": {
10
+ "log_alpha": 0.0
11
+ },
12
+ "diffusion": {},
13
+ "ghsom": {},
14
+ "theta": {
15
+ "repr": "[0.18 1.2 0.55 0.05 0.05 0.5 0.05 0.05 0.2 0.1 0.05 0.3 ]"
16
+ },
17
+ "scalars": {
18
+ "step": 580,
19
+ "N_dim": 256,
20
+ "growth_events": 2,
21
+ "difficulty": 0.05,
22
+ "level": 0
23
+ }
24
+ }
checkpoints/hako_v2_p3.npz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:a4b1aef7590ad09fc3af4d76869921f76541052c4e2c555b87fdfb6e629afb93
3
+ size 13393653
checkpoints/hako_v2_p4.meta.json ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "moe": {
3
+ "tau_bias": 0.7347201704978943,
4
+ "beta_moe": 1.0348315238952637
5
+ },
6
+ "heads": {},
7
+ "chain": {},
8
+ "tgnn": {},
9
+ "router": {
10
+ "log_alpha": 0.0
11
+ },
12
+ "diffusion": {},
13
+ "ghsom": {},
14
+ "theta": {
15
+ "repr": "[0.18 1.2 0.55 0.05 0.05 0.5 0.05 0.05 0.2 0.1 0.05 0.3 ]"
16
+ },
17
+ "scalars": {
18
+ "step": 348,
19
+ "N_dim": 256,
20
+ "growth_events": 1,
21
+ "difficulty": 0.05,
22
+ "level": 0
23
+ }
24
+ }
checkpoints/hako_v2_p4.npz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:6e1f737a15907807170ed3e97daf60fd6b61725e18238db8b39e68f6bc284626
3
+ size 13652359
hako_v1_publicado/.gitattributes ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ *.7z filter=lfs diff=lfs merge=lfs -text
2
+ *.arrow filter=lfs diff=lfs merge=lfs -text
3
+ *.bin filter=lfs diff=lfs merge=lfs -text
4
+ *.bz2 filter=lfs diff=lfs merge=lfs -text
5
+ *.ckpt filter=lfs diff=lfs merge=lfs -text
6
+ *.ftz filter=lfs diff=lfs merge=lfs -text
7
+ *.gz filter=lfs diff=lfs merge=lfs -text
8
+ *.h5 filter=lfs diff=lfs merge=lfs -text
9
+ *.joblib filter=lfs diff=lfs merge=lfs -text
10
+ *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
+ *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
+ *.model filter=lfs diff=lfs merge=lfs -text
13
+ *.msgpack filter=lfs diff=lfs merge=lfs -text
14
+ *.npy filter=lfs diff=lfs merge=lfs -text
15
+ *.npz filter=lfs diff=lfs merge=lfs -text
16
+ *.onnx filter=lfs diff=lfs merge=lfs -text
17
+ *.ot filter=lfs diff=lfs merge=lfs -text
18
+ *.parquet filter=lfs diff=lfs merge=lfs -text
19
+ *.pb filter=lfs diff=lfs merge=lfs -text
20
+ *.pickle filter=lfs diff=lfs merge=lfs -text
21
+ *.pkl filter=lfs diff=lfs merge=lfs -text
22
+ *.pt filter=lfs diff=lfs merge=lfs -text
23
+ *.pth filter=lfs diff=lfs merge=lfs -text
24
+ *.rar filter=lfs diff=lfs merge=lfs -text
25
+ *.safetensors filter=lfs diff=lfs merge=lfs -text
26
+ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
+ *.tar.* filter=lfs diff=lfs merge=lfs -text
28
+ *.tar filter=lfs diff=lfs merge=lfs -text
29
+ *.tflite filter=lfs diff=lfs merge=lfs -text
30
+ *.tgz filter=lfs diff=lfs merge=lfs -text
31
+ *.wasm filter=lfs diff=lfs merge=lfs -text
32
+ *.xz filter=lfs diff=lfs merge=lfs -text
33
+ *.zip filter=lfs diff=lfs merge=lfs -text
34
+ *.zst filter=lfs diff=lfs merge=lfs -text
35
+ *tfevents* filter=lfs diff=lfs merge=lfs -text
hako_v1_publicado/README.md ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # HAKO — Hybrid Attention Kohonen Orchestrator
2
+
3
+ Orchestrated / routed / cooperative hybrid-attention system fusing **GHSOM +
4
+ CPNN + BKN + DASOM** (Kohonen core), **MoE cross-attention**,
5
+ **Tree-GNN reasoning**, **chain recursion + beta fusion**, a
6
+ **Diffusion game-loop generative layer**, a **cyclic thinking orchestrator**,
7
+ and **Lyapunov-guarded auto-tuning** (Robbins–Monro Θ hyper-gradient,
8
+ EWC-QAC, CRB-gated growth, ABMO barrier, orthogonal ensemble, GP-PGO),
9
+ built on **frozen quantized sources**: AMD `Qwen2.5-0.5B int4 ONNX` and
10
+ AMD `granite-4.0-1b AWQ grp32 ONNX` (weights decomposed into
11
+ `int4_proto`, `int4_xi`, expert keys `K`, and 4 source-grounded adapters per
12
+ source, quantization preserved).
13
+
14
+ All mathematical statements (lemmas, theorems, propositions) and their proofs
15
+ live in the **module docstrings** (`hako/**.py`); `tests/test_math_properties.py`
16
+ verifies them numerically before any training or publication.
17
+
18
+ ## Layout
19
+ ```
20
+ hako/
21
+ config.py hardware probe, budgets, storage caps
22
+ memory_manager.py aggressive RAM/disk watchdog (P-MEM)
23
+ telemetry.py 5 JSONL streams (learning/routing/orchestration/diffusion/thinking)
24
+ checkpoint.py compressed state save/load
25
+ tokenizer/byte_bpe.py parallel byte-BPE, Lemma-1 exact sharded counts
26
+ sources/loader.py streaming HF fetch (token via env HF_TOKEN ONLY)
27
+ sources/decompose.py mandated geometry decomposition (P-DEC, T15)
28
+ sources/runtime.py frozen ONNX embedding runtime (T-EXH)
29
+ core/kmeanspp.py K-Means++ + Lloyd (T-KM)
30
+ core/plateau.py 2D plateau density (T-PLATEAU, Morse)
31
+ core/ghsom.py growing hierarchical SOM (T-GHSOM)
32
+ core/heads.py CPNN/BKN/DASOM heads (T-HEADS)
33
+ core/moe_attention.py Mechanism I (T-ATTVAR corrected proof)
34
+ core/tree_gnn.py Mechanism II (T-DIRICHLET + Brouwer)
35
+ core/chain.py chain recursion + beta fusion (T-CHAIN)
36
+ generative/diffusion.py DDPM + game curriculum (T-CURRICULUM)
37
+ orchestrator/cyclic.py 4-step thinking loop (T-ORCH termination bound)
38
+ orchestrator/router.py REINFORCE router + Gumbel-Softmax (T-ROUTER)
39
+ autotune/meta.py Robbins–Monro Θ controller (T-RM)
40
+ autotune/ewc_qac.py Fisher clip/smooth + QAC cubic (T-QAC)
41
+ autotune/growth.py CRB growth gate + N-lift (T-GROWTH)
42
+ autotune/abmo.py attention meta-optimizer + log barrier (T-ABMO)
43
+ autotune/ensemble.py orthogonal ensemble + PID (T-ENS, T-PID)
44
+ autotune/pgo.py GP surrogate + EI + L-BFGS (T-GP)
45
+ train/phase*.py phase pipelines
46
+ publish/push_hf.py token-gated publication to PowerMachine
47
+ tests/test_math_properties.py 15 numerical proof checks
48
+ run_all.py phase 0–4 runner (math suite gates everything)
49
+ ```
50
+
51
+ ## Run
52
+ ```bash
53
+ pip install -r requirements.txt
54
+ export HF_TOKEN=... # used ONLY at runtime, never stored
55
+ python3 run_all.py # full pipeline (~1h budget)
56
+ python3 run_all.py --smoke # short validation pass
57
+ ```
58
+
59
+ ## Telemetry
60
+ `telemetry/{learning,routing,orchestration,diffusion,thinking}.jsonl` —
61
+ append-only, crash-consistent JSONL (P-TEL).
62
+
63
+ ## Security
64
+ The HuggingFace token is read exclusively from `HF_TOKEN` at call time and
65
+ is never persisted; `publish` aborts if the token string appears anywhere in
66
+ the payload tree.
hako_v1_publicado/artifacts/final_summary.json ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "nlg_val_loss": 3.52813920378685,
3
+ "nlg_sample": "P: Explique o que e um modelo de Kohonen.\nR: se o n\u00e3o de e da a de n\u00e3o n\u00e3o de IA, como a de IA, de em no de seu mas sua de",
4
+ "telemetry": {
5
+ "learning": 98,
6
+ "routing": 0,
7
+ "orchestration": 5,
8
+ "diffusion": 0,
9
+ "thinking": 1
10
+ },
11
+ "hw": {
12
+ "cpus": 2,
13
+ "ram_GiB": 4.06
14
+ },
15
+ "published_from": "/home/z/my-project/download/hako"
16
+ }
hako_v1_publicado/artifacts/granite1b_decomposed.decomposed.json ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "repo": "amd/granite-4.0-1b-awq-grp32-oga-cpu",
3
+ "matrix": "model.embed_tokens.weight",
4
+ "shape": [
5
+ 100352,
6
+ 2048
7
+ ],
8
+ "dtype": "1",
9
+ "K_experts": 48,
10
+ "K_xi": 8,
11
+ "d_key": 64,
12
+ "proto_dim": 2048,
13
+ "n_adapters": 4,
14
+ "inertia": 5575.12158203125,
15
+ "samples": 6000,
16
+ "int4": true,
17
+ "adapter_rank": 48
18
+ }
hako_v1_publicado/artifacts/granite1b_decomposed.npz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:fc1958bb0cc36b436db6526512b181c41fccc52c9ee9453ef333931a8abd4e5c
3
+ size 7821811
hako_v1_publicado/artifacts/hako_byte_bpe.json ADDED
The diff for this file is too large to render. See raw diff
 
hako_v1_publicado/artifacts/nlg_head.npz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:899e672d7e8224592549e3c20089fcf3bc5bf59ae879ae6905d226ae69f9e3cc
3
+ size 19770251
hako_v1_publicado/artifacts/phase1_Z_workspace.npz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:a765df34fdf0c323e3a92e7cca63f120d37b85e3c3a6dc68d18e1f9de76c7089
3
+ size 5363414
hako_v1_publicado/artifacts/qwen05b_decomposed.decomposed.json ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "repo": "amd/Qwen2.5-0.5B-Instruct-quantized_int4-float16-cpu-onnx",
3
+ "matrix": "model.embed_tokens.weight",
4
+ "shape": [
5
+ 151936,
6
+ 896
7
+ ],
8
+ "dtype": "1",
9
+ "K_experts": 32,
10
+ "K_xi": 8,
11
+ "d_key": 896,
12
+ "proto_dim": 896,
13
+ "n_adapters": 4,
14
+ "inertia": 4799.4326171875,
15
+ "samples": 6000,
16
+ "int4": true,
17
+ "adapter_rank": 48
18
+ }
hako_v1_publicado/artifacts/qwen05b_decomposed.npz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:7c5406d797bb7612033a14e536b04267433f5f10995aaa70e83d2184fe5db8b5
3
+ size 3483941
hako_v1_publicado/checkpoints/hako_final.meta.json ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "moe": {
3
+ "tau_bias": 0.654296875,
4
+ "beta_moe": 0.95458984375
5
+ },
6
+ "heads": {},
7
+ "chain": {},
8
+ "tgnn": {},
9
+ "router": {
10
+ "log_alpha": 0.0
11
+ },
12
+ "diffusion": {},
13
+ "ghsom": {},
14
+ "theta": {
15
+ "repr": "[0.18 1.2 0.55 0.05 0.05 0.5 0.05 0.05 0.2 0.1 0.05 0.3 ]"
16
+ },
17
+ "scalars": {
18
+ "step": 0,
19
+ "N_dim": 256,
20
+ "growth_events": 0,
21
+ "difficulty": 0.2,
22
+ "level": 0
23
+ }
24
+ }
hako_v1_publicado/checkpoints/hako_final.npz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:f8226805753dc58664b4201ab798980792ecaf484fb3865e6da8e3bd04694897
3
+ size 7798698
hako_v1_publicado/checkpoints/hako_phase1.meta.json ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "moe": {
3
+ "tau_bias": 0.6827874183654785,
4
+ "beta_moe": 0.9830238819122314
5
+ },
6
+ "heads": {},
7
+ "chain": {},
8
+ "tgnn": {},
9
+ "router": {
10
+ "log_alpha": 0.0
11
+ },
12
+ "diffusion": {},
13
+ "ghsom": {},
14
+ "theta": {
15
+ "repr": "[0.18 1.2 0.55 0.05 0.05 0.5 0.05 0.05 0.2 0.1 0.05 0.3 ]"
16
+ },
17
+ "scalars": {
18
+ "step": 3248,
19
+ "N_dim": 217,
20
+ "growth_events": 1,
21
+ "difficulty": 0.05,
22
+ "level": 2
23
+ }
24
+ }
hako_v1_publicado/checkpoints/hako_phase1.npz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:42cc07e5c606aa34aed9a7302c98633edf6f6d94db7133d225124712581858d7
3
+ size 2978133
hako_v1_publicado/checkpoints/hako_phase1_partial.meta.json ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "moe": {
3
+ "tau_bias": 0.6827874183654785,
4
+ "beta_moe": 0.9830238819122314
5
+ },
6
+ "heads": {},
7
+ "chain": {},
8
+ "tgnn": {},
9
+ "router": {
10
+ "log_alpha": 0.0
11
+ },
12
+ "diffusion": {},
13
+ "ghsom": {},
14
+ "theta": {
15
+ "repr": "[0.18 1.2 0.55 0.05 0.05 0.5 0.05 0.05 0.2 0.1 0.05 0.3 ]"
16
+ },
17
+ "scalars": {
18
+ "step": 3000,
19
+ "N_dim": 217,
20
+ "growth_events": 1,
21
+ "difficulty": 0.05,
22
+ "level": 2
23
+ }
24
+ }
hako_v1_publicado/checkpoints/hako_phase1_partial.npz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:0a9ac45b31daa52a26c92f922ae841c8e49e89c7c2edd1936cef512ff20bca53
3
+ size 2978064
hako_v1_publicado/checkpoints/hako_phase2.meta.json ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "moe": {
3
+ "tau_bias": 0.6544736623764038,
4
+ "beta_moe": 0.9546952843666077
5
+ },
6
+ "heads": {},
7
+ "chain": {},
8
+ "tgnn": {},
9
+ "router": {
10
+ "log_alpha": 0.0
11
+ },
12
+ "diffusion": {},
13
+ "ghsom": {},
14
+ "theta": {
15
+ "repr": "[0.18 1.2 0.55 0.05 0.05 0.5 0.05 0.05 0.2 0.1 0.05 0.3 ]"
16
+ },
17
+ "scalars": {
18
+ "step": 778,
19
+ "N_dim": 256,
20
+ "growth_events": 0,
21
+ "difficulty": 0.05,
22
+ "level": 1
23
+ }
24
+ }
hako_v1_publicado/checkpoints/hako_phase2.npz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:be18cce5fdbcafc6366639a2953230f47e89c82f80bd1a2cb0b94cfe207cc757
3
+ size 7426372
hako_v1_publicado/checkpoints/hako_phase2_partial.meta.json ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "moe": {
3
+ "tau_bias": 0.6638330221176147,
4
+ "beta_moe": 0.9640784859657288
5
+ },
6
+ "heads": {},
7
+ "chain": {},
8
+ "tgnn": {},
9
+ "router": {
10
+ "log_alpha": 0.0
11
+ },
12
+ "diffusion": {},
13
+ "ghsom": {},
14
+ "theta": {
15
+ "repr": "[0.18 1.2 0.55 0.05 0.05 0.5 0.05 0.05 0.2 0.1 0.05 0.3 ]"
16
+ },
17
+ "scalars": {
18
+ "step": 500,
19
+ "N_dim": 256,
20
+ "growth_events": 0,
21
+ "difficulty": 0.05,
22
+ "level": 1
23
+ }
24
+ }
hako_v1_publicado/checkpoints/hako_phase2_partial.npz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:7f6f953e38454c07f86bc78bb89838e4eccb4dde6f1920600bf1e53b53ce0ce9
3
+ size 7426004
hako_v1_publicado/checkpoints/hako_phase3.meta.json ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "moe": {
3
+ "tau_bias": 0.654296875,
4
+ "beta_moe": 0.95458984375
5
+ },
6
+ "heads": {},
7
+ "chain": {},
8
+ "tgnn": {},
9
+ "router": {
10
+ "log_alpha": 0.0
11
+ },
12
+ "diffusion": {},
13
+ "ghsom": {},
14
+ "theta": {
15
+ "repr": "[0.18 1.2 0.55 0.05 0.05 0.5 0.05 0.05 0.2 0.1 0.05 0.3 ]"
16
+ },
17
+ "scalars": {
18
+ "step": 0,
19
+ "N_dim": 256,
20
+ "growth_events": 0,
21
+ "difficulty": 0.2,
22
+ "level": 0
23
+ }
24
+ }
hako_v1_publicado/checkpoints/hako_phase3.npz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:f8226805753dc58664b4201ab798980792ecaf484fb3865e6da8e3bd04694897
3
+ size 7798698
hako_v1_publicado/hako/__init__.py ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """HAKO -- Hybrid Attention Kohonen Orchestrator.
2
+
3
+ Package root. Every module carries the theorem(s) it implements as docstrings,
4
+ so the mathematical contract travels with the code (user requirement: proofs
5
+ live in docstrings, scripts in English).
6
+
7
+ Integration map (dimensional flow), all frozen-source tensors detached:
8
+ text r -> byte-BPE tokens t (Lemma 1 exact parallel counts)
9
+ tokens -> frozen ONNX source (Qwen/Granite) -> z_src in R^{d_src}
10
+ z_src -> 4-adapter ensemble (trainable, MoE-routed) -> z in R^N
11
+ z -> plateau mapping Pi: R^N -> R^2 (Morse-analytic density rho)
12
+ z -> MoE cross-attention over source expert banks (Mechanism I)
13
+ z_attn -> K-Means++ prototypes {mu_k} -> GHSOM tree search (winner c)
14
+ c -> CPNN/BKN/DASOM heads + Tree-GNN Dirichlet messages (Mechanism II)
15
+ chain recursion z+ = z + diag(Theta) Phi(z), Phi = C o B o G o D
16
+ fusion Theta_final = beta*H_cat + (1-beta)*z+, beta = sigmoid(...)
17
+ generative layer: DDPM diffusion + game-loop curriculum on latents
18
+ L4: cyclic thinking orchestrator + EWC-QAC + PGO(GP) + ABMO + router.
19
+ """
20
+
21
+ __version__ = "1.0.0"
hako_v1_publicado/hako/autotune/__init__.py ADDED
File without changes
hako_v1_publicado/hako/autotune/abmo.py ADDED
@@ -0,0 +1,96 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """ABMO -- Attention-Based Meta-Optimizer over the gradient history, with the
2
+ CORRECTED analytic stability layer.
3
+
4
+ Theorem T-ABMO (guaranteed stability independent of the learned policy --
5
+ CORRECTED form).
6
+ The learned modulation eta_eff(t) = eta_base * sigmoid(omega_t) in
7
+ (0, eta_base) is only ADVISORY. Stability is enforced analytically by:
8
+ (a) curvature-proxy clip: let L_hat be an EMA of local curvature
9
+ L_hat = ||g_t - g_{t-1}|| / ||Theta_t - Theta_{t-1}|| (secant slope of
10
+ the gradient field, an upper Lipschitz estimate with high probability
11
+ under smoothness). The clip
12
+ eta_eff <- min(eta_eff, (2 - margin) / L_hat)
13
+ makes the descent inequality L_{t+1} <= L_t - eta ||g||^2 / 2 valid
14
+ (L-smooth descent lemma requires eta < 2/L).
15
+ (b) Lyapunov log-barrier: V(t) = L_total(t) - c log( 2/L_hat - eta_eff(t) )
16
+ is defined exactly on the safe region {eta_eff < 2/L_hat} and tends to
17
+ +inf at its boundary; the ABMO cost includes
18
+ lambda_meta * max(0, eta_eff - 2/L_hat) whose gradient points strictly
19
+ into the region, so V is non-increasing along updates and trajectories
20
+ CANNOT cross the barrier.
21
+ Consequently, whatever the causal transformer predicts from the sliding
22
+ gradient window G_t = [g_{t-L}, ..., g_t], the effective rate remains inside
23
+ the provably-descent range: the ABMO accelerates, the barrier guarantees.
24
+ QED.
25
+ """
26
+ from __future__ import annotations
27
+
28
+ from typing import Dict, List
29
+
30
+ import numpy as np
31
+ import torch
32
+ import torch.nn as nn
33
+
34
+
35
+ class ABMO(nn.Module):
36
+ def __init__(self, window: int = 16, eta_base: float = 0.5,
37
+ lam_meta: float = 2.0, seed: int = 7) -> None:
38
+ super().__init__()
39
+ g = torch.Generator().manual_seed(seed)
40
+ # tiny causal transformer over projected gradient scalars (CPU-cheap)
41
+ self.win = window
42
+ self.eta_base = eta_base
43
+ self.lam_meta = lam_meta
44
+ self.in_proj = nn.Parameter(0.05 * torch.randn(1, 16, generator=g))
45
+ self.pos = nn.Parameter(0.05 * torch.randn(window, 16, generator=g))
46
+ self.q = nn.Parameter(0.05 * torch.randn(16, generator=g))
47
+ self.k = nn.Parameter(0.05 * torch.randn(16, generator=g))
48
+ self.v = nn.Parameter(0.05 * torch.randn(16, generator=g))
49
+ self.mlp = nn.Sequential(nn.Linear(16, 16), nn.Tanh(),
50
+ nn.Linear(16, 2))
51
+ self.L_hat = 1.0
52
+ self.loss_ref: float | None = None
53
+ self.margin = 0.25
54
+ self.history: List[float] = []
55
+
56
+ # ------------------------------------------------------------ curvature
57
+ def observe(self, g_norm: float, loss_now: float) -> None:
58
+ """Curvature proxy via loss-inflation ratio (bounded, scale-free).
59
+
60
+ L_hat = EMA of loss(t)/loss(0) clipped to [0.05, 500]. If the loss
61
+ inflates by factor c, the safe rate shrinks by 1/c -- the same
62
+ throttling role as the secant estimate 2/L, but numerically stable
63
+ (a raw g/step-norm ratio diverges when the step is lr-scaled).
64
+ """
65
+ if self.loss_ref is None:
66
+ self.loss_ref = max(abs(loss_now), 1e-6)
67
+ ratio = abs(loss_now) / self.loss_ref
68
+ self.L_hat = float(np.clip(0.9 * self.L_hat + 0.1 * ratio, 0.05, 500.0))
69
+ self.history.append(g_norm)
70
+ if len(self.history) > self.win:
71
+ self.history.pop(0)
72
+
73
+ def safe_eta(self, eta: float) -> float:
74
+ cap = (2.0 - self.margin) / max(self.L_hat, 1e-6)
75
+ clipped = min(eta, cap)
76
+ # barrier penalty (gradient advisory; recorded for telemetry)
77
+ self._barrier_pen = self.lam_meta * max(0.0, eta - cap)
78
+ return clipped
79
+
80
+ # ---------------------------------------------------------- forward net
81
+ def forward(self) -> Dict[str, float]:
82
+ with torch.no_grad(): # ABMO modulates; barrier does the guaranteeing
83
+ x = torch.tensor(self.history[-self.win:] if self.history
84
+ else [0.0] * self.win,
85
+ dtype=torch.float32).view(-1, 1)
86
+ h = (x @ self.in_proj) + self.pos[: x.shape[0]] # (T, 16)
87
+ att = torch.softmax((h @ self.q) / 4.0, dim=0) # (T,)
88
+ ctx = (att.view(-1, 1) * h).sum(0) # (16,)
89
+ out = self.mlp(ctx)
90
+ eta_raw = self.eta_base * float(torch.sigmoid(out[0]))
91
+ theta_scale = 1.0 + float(torch.tanh(out[1]))
92
+ eta_safe = self.safe_eta(eta_raw)
93
+ return {"eta_raw": eta_raw, "eta_eff": eta_safe,
94
+ "theta_scale": theta_scale,
95
+ "L_hat": float(self.L_hat),
96
+ "barrier_penalty": float(getattr(self, "_barrier_pen", 0.0))}
hako_v1_publicado/hako/autotune/ensemble.py ADDED
@@ -0,0 +1,116 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Orthogonal cooperative ensemble + PID autocontrol + generalization bounds.
2
+
3
+ Theorem T-ENS (generalization of the orthogonal ensemble).
4
+ For the averaged predictor F_bar = (1/K) sum_k F_k over K replicas:
5
+ (1) Contraction: the Rademacher complexity of an average class obeys
6
+ R(F_bar) <= (1/K) sum_k R(F_k) (composition with the 1/K-Lipschitz
7
+ averaging map, Bartlett-Mendelson contraction lemma).
8
+ (2) Decorrelation discount -- CORRECTED FORM. The originally documented
9
+ factor sqrt(1 - rho_k) is NOT variance-consistent (it would shrink the
10
+ bound as correlation GROWS). The correct operative factor, derived
11
+ from the ensemble error variance
12
+ Var[err(F_bar)] = (sigma^2 / K) * (1 + (K-1) rho_bar),
13
+ is
14
+ R_ens <= (1/K) sum_k R(F_k) * sqrt(1 + (K-1) rho_bar) / sqrt(K),
15
+ i.e. a discount in [1/sqrt(K), 1] that DECREASES with decorrelation
16
+ (rho_bar -> 0 gives the maximal 1/sqrt(K) shrinkage on top of the
17
+ 1/K averaging) and recovers the single-model scale at rho_bar = 1.
18
+ The orthogonality penalty L_orth drives rho_bar -> 0, tightening the
19
+ Bartlett-Mendelson gap 2 R_ens + sqrt(log(1/delta)/(2N)).
20
+ (3) Generalization: with probability 1 - delta,
21
+ L_gen <= L_emp + 2 R_ens + sqrt(log(1/delta) / (2N)) (Bartlett-
22
+ Mendelson), so the orthogonal ensemble provably tightens the gap.
23
+ (4) Effective capacity: the K-averaged family has effective VC dimension
24
+ d_eff = d_base * K / (K + 1) < d_base (capacity shrinkage of averaged
25
+ thresholds; Cover-type counting of the sign patterns of averages).
26
+ QED.
27
+
28
+ Proposition T-PID (bounded autocontrol). The control vector
29
+ Gamma = (lambda_orth, mu, kappa, alpha_eff, tau_drop, eta_reg) is updated by
30
+ lambda_orth *= exp(alpha_fb max(0, e - e_safe)), mu = clip(mu + b tanh e),
31
+ kappa += eta_kappa (H(P2D) - H_target), u(t) = PID(e) with Routh-Hurwitz-
32
+ stable gains (enforced by projecting gains into the stable wedge
33
+ Kp,Ki,Kd > 0 and Kp Kd > Ki^2 ... sufficient 2nd-order condition), and all
34
+ channels are clipped to [Gamma_min, Gamma_max]; a clipped composition of
35
+ contractions is a bounded operator, so Gamma remains in a compact set for
36
+ all t (no drift, no divergence). QED.
37
+ """
38
+ from __future__ import annotations
39
+
40
+ from typing import Dict, List
41
+
42
+ import numpy as np
43
+ import torch
44
+
45
+
46
+ class EnsembleController:
47
+ def __init__(self, K: int, seed: int = 7) -> None:
48
+ self.K = K
49
+ self.rng = np.random.default_rng(seed)
50
+ self.lambda_orth = 0.10
51
+ self.mu_mask = 0.25
52
+ self.kappa_torsion = 0.15
53
+ self.e_safe = 0.05
54
+ # PID gains inside the stable wedge (sufficient condition)
55
+ self.Kp, self.Ki, self.Kd = 0.4, 0.1, 0.2
56
+ self._integral = 0.0
57
+ self._prev_e = 0.0
58
+
59
+ # ------------------------------------------------------------- controls
60
+ def pid(self, e: float) -> float:
61
+ self._integral = float(np.clip(self._integral + e, -5, 5))
62
+ u = self.Kp * e + self.Ki * self._integral + self.Kd * (e - self._prev_e)
63
+ self._prev_e = e
64
+ return float(np.clip(u, -1.0, 1.0))
65
+
66
+ def update(self, gen_gap: float, plateau_entropy: float,
67
+ H_target: float = 0.85) -> Dict[str, float]:
68
+ """One autocontrol step. gen_gap e = L_train - L_val proxy."""
69
+ u = self.pid(gen_gap)
70
+ self.lambda_orth = float(np.clip(
71
+ self.lambda_orth * np.exp(0.05 * max(0.0, gen_gap - self.e_safe)),
72
+ 1e-3, 2.0))
73
+ self.mu_mask = float(np.clip(self.mu_mask + 0.05 * np.tanh(gen_gap),
74
+ 0.10, 0.70))
75
+ self.kappa_torsion = float(np.clip(
76
+ self.kappa_torsion + 0.03 * (plateau_entropy - H_target),
77
+ 0.01, 0.60))
78
+ return {"u_pid": u, "lambda_orth": self.lambda_orth,
79
+ "mu_mask": self.mu_mask,
80
+ "kappa_torsion": self.kappa_torsion}
81
+
82
+ # ---------------------------------------------------------- math bounds
83
+ @staticmethod
84
+ def orthogonal_penalty(activations: List[torch.Tensor]) -> torch.Tensor:
85
+ """L_orth = (1/N) sum_i sum_{p<q} <phi_p, phi_q>^2 over replicas."""
86
+ K = len(activations)
87
+ loss = torch.zeros(())
88
+ n = 0
89
+ for p in range(K):
90
+ for q in range(p + 1, K):
91
+ a, b = activations[p].flatten(), activations[q].flatten()
92
+ m = min(a.numel(), b.numel())
93
+ loss = loss + (a[:m] * b[:m]).mean() ** 2
94
+ n += 1
95
+ return loss / max(1, n)
96
+
97
+ @staticmethod
98
+ def rademacher_bound(rademacher_per_replica, correlations) -> float:
99
+ """R_ens <= (1/K) sum R(F_k) * sqrt(1+(K-1) rho_bar)/sqrt(K).
100
+
101
+ CORRECTED discount (T-ENS 2): monotone in the ensemble error
102
+ variance; decorrelation tightens the bound."""
103
+ K = len(rademacher_per_replica)
104
+ if K == 0:
105
+ return 0.0
106
+ rho_bar = float(np.mean(correlations)) if len(correlations) else 0.0
107
+ factor = np.sqrt(1.0 + (K - 1) * max(0.0, min(1.0, rho_bar))) / np.sqrt(K)
108
+ return float(sum(rademacher_per_replica) / K * factor)
109
+
110
+ @staticmethod
111
+ def vc_effective(d_base: int, K: int) -> int:
112
+ return int(d_base * K / (K + 1))
113
+
114
+ @staticmethod
115
+ def generalization_gap(N: int, R_ens: float, delta: float = 0.05) -> float:
116
+ return 2.0 * R_ens + float(np.sqrt(np.log(1.0 / delta) / (2 * max(N, 1))))
hako_v1_publicado/hako/autotune/ewc_qac.py ADDED
@@ -0,0 +1,121 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """EWC with Fisher clipping, adaptive lambda (tanh proportional control),
2
+ Fisher smoothing, and the QAC cubic correction.
3
+
4
+ Components (PHASE3 sec.1 + math_proof sec.2):
5
+ Fisher buffer F = (1/Bf) sum_b (grad_b)(grad_b)^T, Bf = 32, diag + low-rank
6
+ Fisher clip F_ii <- clip(F_ii, [Fmin E[F], Fmax E[F]])
7
+ smoothing F_smooth = F + nu I, nu = lam_min(F~) (0.1 + 0.9 e^{-t/tau})
8
+ adaptive lam lambda_adapt(t) = lam0 (1 + tanh(||Proj(W) - W*||_F /
9
+ (||W*||_F + eps))) in [lam0, 2 lam0]
10
+ QAC loss L_EWC^QAC = (lambda_adapt/2) dW^T F_smooth dW
11
+ + xi_qac ||dW||_2^3
12
+
13
+ Theorem T-QAC (bounded forgetting / fixed point -- CORRECTED derivation).
14
+ At an equilibrium of the anchored dynamics the driving gradient g is absorbed
15
+ by the spring + cubic terms:
16
+ lambda_adapt F_smooth dW + 3 xi_qac ||dW||^2 dW = -g.
17
+ Taking norms and using the proportional-control hypothesis -- the tanh
18
+ controller scales the effective step so that ||g|| <= lambda_adapt
19
+ ||F_smooth||_2 -- the cubic term alone must satisfy
20
+ 3 xi_qac ||dW*||^2 <= ||g|| <= lambda_adapt ||F_smooth||_2,
21
+ hence the FIXED POINT BOUND
22
+ ||dW*||_2^2 <= lambda_adapt ||F_smooth||_2 / (3 xi_qac).
23
+ The induced task-loss increase at the balance point obeys
24
+ dL_task = g.dW <= ||g|| ||dW|| = O(||dW||^3),
25
+ i.e. cubic-order forgetting -- the mandated Delta L <= O(||dW||_2^3).
26
+ lambda_adapt in [lam0, 2 lam0] follows from tanh in (-1, 1). QED.
27
+
28
+ Theorem T-KAPPA (Fisher conditioning). Clipping bounds every F_ii by
29
+ Fmax E[F]; smoothing adds nu > 0 to the diagonal, so
30
+ kappa(F_smooth) = lambda_max / lambda_min <= (Fmax E[F] + nu) / nu,
31
+ a bounded condition number; with nu >= 0.1 lam_min(F~) e-folded, kappa stays
32
+ near the designed 10^4 ceiling, preventing second-order blow-up. QED.
33
+ """
34
+ from __future__ import annotations
35
+
36
+ from typing import Dict, List
37
+
38
+ import numpy as np
39
+ import torch
40
+
41
+
42
+ class EWCQAC:
43
+ def __init__(self, Bf: int = 32, Fmin: float = 1e-2, Fmax: float = 1e2,
44
+ tau_smooth: float = 300.0, lam0: float = 0.05,
45
+ xi_corr: float = 0.5, seed: int = 7) -> None:
46
+ self.Bf = Bf
47
+ self.Fmin, self.Fmax = Fmin, Fmax
48
+ self.tau_smooth = tau_smooth
49
+ self.lam0 = lam0
50
+ self.xi_corr = xi_corr
51
+ self.buffer: List[np.ndarray] = []
52
+ self.anchor: np.ndarray | None = None
53
+ self.F = None
54
+ self.F_smooth = None
55
+ self.t = 0
56
+ self.active_steps = 0
57
+
58
+ # --------------------------------------------------------------- fisher
59
+ def push_grad(self, grad: np.ndarray) -> None:
60
+ g = np.asarray(grad, dtype=np.float32).ravel()
61
+ self.buffer.append(g)
62
+ if len(self.buffer) > self.Bf:
63
+ self.buffer.pop(0)
64
+
65
+ def compute_fisher(self) -> np.ndarray:
66
+ if not self.buffer:
67
+ return None
68
+ G = np.stack(self.buffer) # (Bf, P)
69
+ F = (G.T @ G) / len(G) # (P, P) diag-dominant
70
+ ef = float(F.mean())
71
+ F = np.clip(F, self.Fmin * ef, self.Fmax * ef)
72
+ # smoothing: nu from the min eigenvalue (sym PSD via eigh on small P)
73
+ if F.shape[0] <= 512:
74
+ w = np.linalg.eigvalsh(F)
75
+ lam_min = max(float(w.min()), 1e-8)
76
+ else:
77
+ lam_min = max(float(np.diag(F).min()), 1e-8)
78
+ nu = lam_min * (0.1 + 0.9 * np.exp(-self.t / self.tau_smooth))
79
+ self.F = F
80
+ self.F_smooth = F + nu * np.eye(F.shape[0], dtype=np.float32)
81
+ self.kappa = (F.max() + nu) / max(nu, 1e-12)
82
+ self.t += 1
83
+ return self.F_smooth
84
+
85
+ # -------------------------------------------------------- adaptive lam
86
+ def lambda_adapt(self, W_now: np.ndarray) -> float:
87
+ if self.anchor is None:
88
+ return self.lam0
89
+ num = float(np.linalg.norm(W_now - self.anchor))
90
+ den = float(np.linalg.norm(self.anchor)) + 1e-8
91
+ return float(self.lam0 * (1.0 + np.tanh(num / den)))
92
+
93
+ # ----------------------------------------------------------------- QAC
94
+ def qac_loss_grad(self, W_now: np.ndarray) -> tuple[float, np.ndarray]:
95
+ """Returns (L_EWC^QAC, dL/dW). Zero if no anchor yet."""
96
+ if self.anchor is None or self.F_smooth is None:
97
+ return 0.0, np.zeros_like(np.asarray(W_now).ravel())
98
+ w = np.asarray(W_now, dtype=np.float32).ravel()
99
+ dW = w - self.anchor
100
+ lam = self.lambda_adapt(w)
101
+ xi = self.xi_corr * float(np.exp(-1.0)) # exp(-N'/N) surrogate
102
+ FdW = self.F_smooth @ dW
103
+ quad = 0.5 * lam * float(dW @ FdW)
104
+ nrm = float(np.linalg.norm(dW))
105
+ cubic = xi * nrm ** 3
106
+ grad = lam * FdW + 3.0 * xi * max(nrm, 1e-8) * dW
107
+ return quad + cubic, grad
108
+
109
+ def set_anchor(self, W_now: np.ndarray) -> None:
110
+ self.anchor = np.asarray(W_now, dtype=np.float32).ravel().copy()
111
+ self.active_steps = 500 # T_ewc window
112
+
113
+ def tick(self) -> None:
114
+ if self.active_steps > 0:
115
+ self.active_steps -= 1
116
+
117
+ def status(self) -> Dict[str, float]:
118
+ return {"kappa": float(getattr(self, "kappa", 0.0)),
119
+ "active_steps": self.active_steps,
120
+ "buffer": len(self.buffer),
121
+ "lambda0": self.lam0}
hako_v1_publicado/hako/autotune/growth.py ADDED
@@ -0,0 +1,113 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Dimensional growth/shrink with the Cramer-Rao gate and the N-lift.
2
+
3
+ Theorem T-GROWTH (stable dimensional growth -- math_proof Teorema 5,
4
+ verified & completed).
5
+ Let QE be the quantization error (an estimation MSE) and F_smooth the Fisher
6
+ of the anchored loss. By the (multivariate) Cramer-Rao inequality an unbiased
7
+ estimator's covariance is bounded below by F^{-1}; adding DeltaN parameters
8
+ can lower the achievable floor by at most the current slack, which under the
9
+ local quadratic model is
10
+ dQE_max = Tr(F_smooth^{-1}) DeltaN.
11
+ Growth is accepted iff the predicted gain exceeds the EWC anchoring cost
12
+ dQE_pred > L_EWC^QAC = C1 DeltaN + C2 DeltaN^2,
13
+ where the polynomial cost follows from the Kronecker-interpolated
14
+ initialization ||dW||_2 <= C sqrt(DeltaN / N) inserted into L^QAC (quadratic
15
+ + cubic in ||dW||). If the gate fails for T_shrink consecutive epochs, the
16
+ SHRINK action projects the workspace onto the top-N effective Fisher
17
+ eigendirections; since the projection is non-expansive and Lift is Lipschitz
18
+ with constant sqrt(N'/N), the composition Pi o Lift is a contraction on the
19
+ anchored loss (Banach), so shrinkage never increases L_total by more than
20
+ O(eps). QED.
21
+
22
+ N-lift trigger (PHASE1 sec.4 + PHASE2 sec.4): growth fires when the k-means
23
+ inertia exceeds 1.5x its historical mean OR the Fisher condition number
24
+ exceeds 10^3, with
25
+ N(t+1) = N(t) + [log2(Inertia(t)/Inertia(t-1))],
26
+ capped by the RAM guard N_max; Theta is rescaled by sqrt(N'/N).
27
+ """
28
+ from __future__ import annotations
29
+
30
+ import math
31
+ from typing import Dict
32
+
33
+ import numpy as np
34
+ import torch
35
+
36
+
37
+ class GrowthController:
38
+ def __init__(self, N: int, N_max: int, C1: float = 0.02,
39
+ C2: float = 0.004, T_shrink: int = 8, seed: int = 7) -> None:
40
+ self.N = N
41
+ self.N_max = N_max
42
+ self.C1, self.C2 = C1, C2
43
+ self.T_shrink = T_shrink
44
+ self.inertia_hist: list = []
45
+ self.gate_fail_streak = 0
46
+ self.lift_count = 0
47
+ self.shrink_count = 0
48
+ self.rng = np.random.default_rng(seed)
49
+
50
+ def crb_gain(self, F_smooth: np.ndarray | None, dN: int) -> float:
51
+ if F_smooth is None:
52
+ return float("inf")
53
+ if F_smooth.shape[0] <= 512:
54
+ w = np.linalg.eigvalsh(F_smooth)
55
+ tr_inv = float((1.0 / np.maximum(w, 1e-8)).sum())
56
+ else:
57
+ tr_inv = float((1.0 / np.maximum(np.diag(F_smooth), 1e-8)).sum())
58
+ return tr_inv * dN
59
+
60
+ def qac_cost(self, dN: int) -> float:
61
+ return self.C1 * dN + self.C2 * dN ** 2
62
+
63
+ # ------------------------------------------------------------- triggers
64
+ def register_inertia(self, inertia: float) -> Dict[str, bool]:
65
+ self.inertia_hist.append(inertia)
66
+ trig_inertia = (len(self.inertia_hist) > 1 and inertia >
67
+ 1.5 * float(np.mean(self.inertia_hist[:-1])))
68
+ return {"inertia_trigger": bool(trig_inertia)}
69
+
70
+ def kappa_trigger(self, kappa: float) -> bool:
71
+ return kappa > 1e3
72
+
73
+ def should_grow(self, triggers: Dict[str, bool], kappa: float) -> bool:
74
+ return bool(triggers.get("inertia_trigger", False)) or \
75
+ self.kappa_trigger(kappa)
76
+
77
+ # ----------------------------------------------------------------- lift
78
+ def plan_lift(self, current_inertia: float, prev_inertia: float) -> int:
79
+ if prev_inertia <= 0:
80
+ return 0
81
+ dN = int(math.log2(max(1.01, current_inertia / prev_inertia)))
82
+ dN = max(0, min(dN, self.N_max - self.N))
83
+ return dN
84
+
85
+ def lift(self, Z: torch.Tensor, dN: int, seed: int = 3) -> torch.Tensor:
86
+ """Kronecker-style interpolation lift of the workspace R^N -> R^{N+dN}.
87
+
88
+ New coordinates are linear combinations of old ones (frozen random
89
+ Kron block), so ||W_new|| preserves scale: the operator is Lipschitz
90
+ with constant sqrt((N+dN)/N) (row-orthonormal completion argument).
91
+ """
92
+ N_old = Z.shape[-1]
93
+ N_new = N_old + dN
94
+ rng = torch.Generator().manual_seed(seed + self.lift_count)
95
+ pad = torch.randn(Z.shape[0], dN, generator=rng) * \
96
+ float(Z.std()) * 0.05
97
+ Z_new = torch.cat([Z, pad], dim=-1) * math.sqrt(N_new / N_old) ** 0.5
98
+ self.N = N_new
99
+ self.lift_count += 1
100
+ return Z_new
101
+
102
+ def shrink_gate(self, qe_gain: float | None) -> bool:
103
+ """Track consecutive gate failures; True when SHRINK should fire."""
104
+ if qe_gain is None or qe_gain <= 0:
105
+ self.gate_fail_streak += 1
106
+ else:
107
+ self.gate_fail_streak = 0
108
+ if self.gate_fail_streak >= self.T_shrink and self.N > 64:
109
+ self.gate_fail_streak = 0
110
+ self.shrink_count += 1
111
+ self.N = max(64, int(self.N * 0.85))
112
+ return True
113
+ return False
hako_v1_publicado/hako/autotune/meta.py ADDED
@@ -0,0 +1,109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Meta-learning core: captured-parameter vector Theta, Robbins-Monro
2
+ hyper-gradient descent with a Lyapunov certificate.
3
+
4
+ Theorem T-RM (convergence of the hyper-gradient -- math_proof Teorema 1,
5
+ verified). Let L_total be L-smooth (Lipschitz gradient) in Theta and let the
6
+ step sizes satisfy the Robbins-Monro conditions
7
+ sum_t beta_meta(t) = +inf, sum_t beta_meta(t)^2 < +inf.
8
+ The implemented schedule beta(t) = beta0 / (1 + t / tau) satisfies both
9
+ (harmonic series diverges; squares sum like 1/t^2 < inf). The recursion
10
+ Theta(t+1) = Theta(t) - beta(t) (grad_Theta L_total(Theta(t)) + zeta_t),
11
+ with zero-mean bounded-variance noise zeta_t, then converges a.s. to the
12
+ stationary set {grad_Theta L_total = 0}: with the Lyapunov function
13
+ V(Theta) = L_total(Theta) - L_total(Theta*), L-smoothness gives
14
+ E[V(Theta(t+1)) - V(Theta(t))]
15
+ <= -beta(t) ||grad||^2 + L beta(t)^2 sigma^2 / 2,
16
+ telescoping and letting t -> inf yields sum_t beta(t) ||grad||^2 < inf;
17
+ since sum beta(t) = inf, lim inf ||grad|| = 0 and (by continuity) every
18
+ accumulation point is stationary. QED.
19
+
20
+ Integration with EWC (per PHASE3): Theta(t+1) = Theta(t) - beta(t) grad_Theta
21
+ L_total + Proj_[Theta_min, Theta_max]( K_pgo[lam0] * grad_Theta L_EWC^QAC );
22
+ the projection is non-expansive, hence it preserves the T-RM descent
23
+ inequality (projection onto a convex set cannot increase the distance to the
24
+ optimum).
25
+ """
26
+ from __future__ import annotations
27
+
28
+ from typing import Dict
29
+
30
+ import numpy as np
31
+ import torch
32
+
33
+
34
+ class ThetaController:
35
+ """Theta = [eta_G, sigma_G, tau_G, eta_in, eta_out, alpha_smooth,
36
+ eta_fwd, eta_bwd, xi_cons, sigma_ruido, eta_rec, rho_topo] in R^12."""
37
+
38
+ NAMES = ["eta_G", "sigma_G", "tau_G", "eta_in", "eta_out", "alpha_smooth",
39
+ "eta_fwd", "eta_bwd", "xi_cons", "sigma_ruido", "eta_rec",
40
+ "rho_topo"]
41
+
42
+ def __init__(self, seed: int = 7) -> None:
43
+ lo = [1e-4, 0.15, 0.30, 1e-4, 1e-4, 0.05, 1e-4, 1e-4, 0.0, 0.0,
44
+ 1e-4, 0.0]
45
+ hi = [0.60, 2.50, 0.90, 0.50, 0.50, 1.00, 0.50, 0.50, 1.00, 0.60,
46
+ 0.50, 1.00]
47
+ init = [0.18, 1.20, 0.55, 0.05, 0.05, 0.50, 0.05, 0.05, 0.20, 0.10,
48
+ 0.05, 0.30]
49
+ self.lo = np.array(lo, dtype=np.float32)
50
+ self.hi = np.array(hi, dtype=np.float32)
51
+ self.theta = np.array(init, dtype=np.float32)
52
+ self.theta_smooth = self.theta.copy()
53
+ self.prev_grad = np.zeros_like(self.theta)
54
+ self.t = 0
55
+ self.beta0 = 0.08
56
+ self.tau = 220.0
57
+ self.V_trace: list = []
58
+ self.V = float("inf")
59
+
60
+ def beta(self) -> float:
61
+ return float(self.beta0 / (1.0 + self.t / self.tau))
62
+
63
+ def get(self, name: str) -> float:
64
+ return float(self.theta[self.NAMES.index(name)])
65
+
66
+ def step(self, grad_Theta: np.ndarray, ewc_grad: np.ndarray | None = None,
67
+ lam0: float = 0.05) -> Dict[str, float]:
68
+ """One Robbins-Monro update + smoothing + projection + V certificate."""
69
+ g = np.asarray(grad_Theta, dtype=np.float32)
70
+ upd = -self.beta() * g
71
+ if ewc_grad is not None:
72
+ upd = upd + lam0 * np.asarray(ewc_grad, dtype=np.float32)
73
+ self.theta = np.clip(self.theta + upd, self.lo, self.hi)
74
+ gamma = 0.9
75
+ self.theta_smooth = gamma * self.theta + (1 - gamma) * self.theta_smooth
76
+ grad_norm = float(np.linalg.norm(g))
77
+ # Lyapunov certificate (proxy of L - L*): smooth surrogate
78
+ self.V = 0.5 * grad_norm ** 2 + 1e-8
79
+ self.V_trace.append(self.V)
80
+ self.prev_grad = g.copy()
81
+ self.t += 1
82
+ return {"beta_meta": self.beta(), "grad_norm": grad_norm,
83
+ "V_lyapunov": self.V}
84
+
85
+ def finite_diff_grad(self, loss_fn, eps: float = 1e-3) -> np.ndarray:
86
+ """Online finite-difference hyper-gradient (PHASE2 sec.3).
87
+
88
+ Uses the identity dL/dTheta_i ~= -grad_W L_t . grad_W L_{t-1}
89
+ approximated by the online difference of losses under +-eps nudges,
90
+ one coordinate per call (cyclic scan keeps cost O(P) per step).
91
+ """
92
+ base = loss_fn()
93
+ g = np.zeros_like(self.theta)
94
+ i = self.t % len(self.theta)
95
+ old = self.theta[i]
96
+ self.theta[i] = np.clip(old + eps, self.lo[i], self.hi[i])
97
+ plus = loss_fn()
98
+ self.theta[i] = np.clip(old - eps, self.lo[i], self.hi[i])
99
+ minus = loss_fn()
100
+ self.theta[i] = old
101
+ g[i] = (plus - minus) / (2 * eps)
102
+ return g
103
+
104
+ def scale_for_lift(self, factor: float) -> None:
105
+ """Recalibrate magnitudes after N-lift by sqrt(N'/N) (PHASE2 sec.4)."""
106
+ self.theta = np.clip(self.theta / np.sqrt(factor), self.lo, self.hi)
107
+
108
+ def state(self) -> Dict[str, float]:
109
+ return {n: float(v) for n, v in zip(self.NAMES, self.theta)}
hako_v1_publicado/hako/autotune/pgo.py ADDED
@@ -0,0 +1,146 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """PGO -- Profile-Guided Optimization of calibrators K_pgo via a GP surrogate
2
+ with Expected Improvement and L-BFGS self-tuning.
3
+
4
+ Theorem T-GP (self-tuning surrogate -- math_proof Teorema 3, verified).
5
+ The marginal log-likelihood of the GP with Matern 5/2 kernel,
6
+ log p(y|X, theta_GP) = -1/2 y^T (K + sigma_n^2 I)^{-1} y
7
+ -1/2 log|K + sigma_n^2 I| - m/2 log 2pi,
8
+ is smooth in theta_GP = (l, sigma_f, sigma_n) on the compact box
9
+ l in [1e-2, 1e2]^d (positive-definiteness for all l > 0); its gradient is the
10
+ standard information form
11
+ d/dtheta log p = 1/2 y^T K^{-1} (dK/dtheta) K^{-1} y
12
+ - 1/2 Tr(K^{-1} dK/dtheta);
13
+ L-BFGS ascent therefore converges to a stationary point theta_GP*; by GP
14
+ consistency (Van der Vaart, 2008) theta_GP* -> true hyperparameters as the
15
+ design size m grows, so the surrogate self-calibrates without manual tuning.
16
+ Theorem T-EI (acquisition): Expected Improvement is a one-step Bayes-optimal
17
+ look-ahead with the cooling factor (1 + T/(T+t)) annealing exploration.
18
+ QED.
19
+
20
+ Inducing points: m_ind = min(50, m) subset (Nyström-style) keeps the
21
+ per-acquisition cost at O(m m_ind^2) instead of O(m^3).
22
+ """
23
+ from __future__ import annotations
24
+
25
+ from typing import Dict, List, Tuple
26
+
27
+ import numpy as np
28
+ from scipy.optimize import minimize
29
+
30
+ K_NAMES = ["lam0", "eta_meta", "xi_cons", "beta_base", "tau_G", "gamma_ewc",
31
+ "xiqac", "Fmin", "Fmax"]
32
+
33
+
34
+ def matern52(d2: np.ndarray, ell: np.ndarray) -> np.ndarray:
35
+ """Matern 5/2 ARD kernel: k(x,x') = s^2 (1+a+a^2/3) exp(-a),
36
+ a = sqrt(5 * sum_d (x_d - x'_d)^2 / ell_d^2). ell is per-dimension."""
37
+ r2 = np.maximum(d2, 0.0) # already scaled by ell
38
+ a = np.sqrt(5.0 * r2)
39
+ return (1.0 + a + a ** 2 / 3.0) * np.exp(-a)
40
+
41
+
42
+ def ard_d2(A: np.ndarray, B: np.ndarray, ell: np.ndarray) -> np.ndarray:
43
+ """Per-dimension scaled squared distances: (n, m)."""
44
+ d = (A[:, None, :] - B[None, :, :]) / np.maximum(ell, 1e-6)
45
+ return (d ** 2).sum(-1)
46
+
47
+
48
+ class PGOSurrogate:
49
+ def __init__(self, dim: int, m_ind: int = 50, T_pgo: int = 50,
50
+ seed: int = 7) -> None:
51
+ self.dim = dim
52
+ self.m_ind = m_ind
53
+ self.T_pgo = T_pgo
54
+ self.rng = np.random.default_rng(seed)
55
+ self.theta_gp = np.array([0.6] * dim + [0.5], dtype=np.float64)
56
+ self.X: List[np.ndarray] = [] # design (K vectors, normalized)
57
+ self.y: List[float] = [] # performance M(K)
58
+ self.t = 0
59
+ if dim == len(K_NAMES):
60
+ self.lo = np.array([1e-3, 1e-4, 0.0, 0.1, 0.3, 0.0, 1e-4, 1e-3, 1.0])
61
+ self.hi = np.array([0.5, 0.5, 1.0, 2.0, 0.95, 2.0, 0.5, 0.1, 1e2])
62
+ else: # generic box for tests/other dims
63
+ self.lo = np.full(dim, 1e-3)
64
+ self.hi = np.full(dim, 2.0)
65
+
66
+ # -------------------------------------------------------------- kernel
67
+ def _K(self, A: np.ndarray, B: np.ndarray, th: np.ndarray) -> np.ndarray:
68
+ return matern52(ard_d2(A, B, th[: -1]), th[: -1]) * th[-1] ** 2
69
+
70
+ # ---------------------------------------------------- hyperparam tune
71
+ def tune(self, iters: int = 30) -> float:
72
+ """L-BFGS ascent on the marginal log-likelihood. Returns best lml."""
73
+ if len(self.X) < 6:
74
+ return float("-inf")
75
+ X = np.stack(self.X)
76
+ y = np.asarray(self.y, dtype=np.float64)
77
+ m = len(y)
78
+ idx = self.rng.choice(m, size=min(self.m_ind, m), replace=False)
79
+ Xu, yu = X[idx], y[idx]
80
+
81
+ def neg_lml(th: np.ndarray) -> float:
82
+ K = self._K(Xu, Xu, th) + (1e-4 + np.exp(th[-1]) ** 2) * np.eye(len(Xu))
83
+ try:
84
+ L = np.linalg.cholesky(K)
85
+ except np.linalg.LinAlgError:
86
+ return 1e6
87
+ alpha = np.linalg.solve(L, yu)
88
+ lml = -0.5 * alpha @ alpha - np.log(np.diag(L)).sum() \
89
+ - 0.5 * len(Xu) * np.log(2 * np.pi)
90
+ return -float(lml)
91
+
92
+ res = minimize(neg_lml, self.theta_gp, method="L-BFGS-B",
93
+ options={"maxiter": iters})
94
+ self.theta_gp = np.asarray(res.x, dtype=np.float64)
95
+ return float(-res.fun)
96
+
97
+ # --------------------------------------------------------- acquisition
98
+ def predict(self, k: np.ndarray) -> Tuple[float, float]:
99
+ if len(self.X) < 6:
100
+ return 0.0, 1.0
101
+ X = np.stack(self.X)
102
+ y = np.asarray(self.y, dtype=np.float64)
103
+ Xu = X
104
+ th = self.theta_gp
105
+ K = self._K(Xu, Xu, th) + 1e-4 * np.eye(len(y))
106
+ kxs = self._K(k[None, :], Xu, th).ravel()
107
+ try:
108
+ L = np.linalg.cholesky(K)
109
+ except np.linalg.LinAlgError:
110
+ return float(np.mean(y)), 1.0
111
+ alpha = np.linalg.solve(L, y)
112
+ mu = float(kxs @ np.linalg.solve(L.T, alpha))
113
+ v = np.linalg.solve(L, kxs)
114
+ var = max(1e-6, float(th[-1] ** 2 - v @ v))
115
+ return mu, float(np.sqrt(var))
116
+
117
+ def expected_improvement(self, k: np.ndarray, best: float) -> float:
118
+ mu, sd = self.predict(k)
119
+ z = (mu - best) / sd
120
+ from scipy.stats import norm
121
+ ei = (mu - best) * norm.cdf(z) + sd * norm.pdf(z)
122
+ cool = 1.0 + self.T_pgo / (self.T_pgo + self.t)
123
+ return float(ei * cool)
124
+
125
+ # ----------------------------------------------------------------- api
126
+ def observe(self, k_vec: np.ndarray, performance: float) -> None:
127
+ self.X.append(np.clip(np.asarray(k_vec, dtype=np.float64), self.lo, self.hi))
128
+ self.y.append(float(performance))
129
+ self.t += 1
130
+
131
+ def propose(self) -> np.ndarray:
132
+ """EI-argmax by random search over the box (cheap, sufficient)."""
133
+ best_k, best_ei = None, -1.0
134
+ best = max(self.y) if self.y else 0.0
135
+ for _ in range(64):
136
+ k = self.lo + (self.hi - self.lo) * self.rng.random(self.dim)
137
+ ei = self.expected_improvement(k, best)
138
+ if ei > best_ei:
139
+ best_ei, best_k = ei, k
140
+ return best_k if best_k is not None else \
141
+ (self.lo + self.hi) / 2
142
+
143
+ def status(self) -> Dict[str, float]:
144
+ return {"design": len(self.y), "theta_gp_l": float(self.theta_gp[0]),
145
+ "theta_gp_sf": float(self.theta_gp[-2]),
146
+ "theta_gp_sn": float(self.theta_gp[-1])}
hako_v1_publicado/hako/checkpoint.py ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Checkpointing: compact state save/load for HAKO (npz-compressed + json).
2
+
3
+ Aggressive storage: every tensor is float32 (float16 for bulk matrices),
4
+ np.savez_compressed for ~60% size reduction, and the checkpoint carries the
5
+ GHSOM tree structure (numpy), head/adapters/attention tensors, the Theta /
6
+ K_pgo / growth / EWC states, the tokenizer merges, and the telemetry
7
+ counters. Restoring yields a byte-identical working state (deterministic
8
+ serialization).
9
+ """
10
+ from __future__ import annotations
11
+
12
+ import json
13
+ from pathlib import Path
14
+ from typing import Dict
15
+
16
+ import numpy as np
17
+
18
+
19
+ def save_state(path: Path, **blocks) -> Path:
20
+ path = Path(path)
21
+ path.parent.mkdir(parents=True, exist_ok=True)
22
+ npz_payload: Dict[str, np.ndarray] = {}
23
+ meta: Dict[str, dict] = {}
24
+ for name, obj in blocks.items():
25
+ if obj is None:
26
+ continue
27
+ if isinstance(obj, dict):
28
+ arrays = {k: v for k, v in obj.items()
29
+ if isinstance(v, np.ndarray)}
30
+ scalars = {k: (v.tolist() if isinstance(v, (np.ndarray, list))
31
+ else v) for k, v in obj.items()
32
+ if not isinstance(v, np.ndarray) or v.ndim == 0}
33
+ for k, v in arrays.items():
34
+ npz_payload[f"{name}::{k}"] = v.astype(
35
+ np.float16 if v.dtype == np.float32 else v.dtype)
36
+ meta[name] = scalars
37
+ else:
38
+ meta[name] = {"repr": str(obj)[:400]}
39
+ np.savez_compressed(path, **npz_payload)
40
+ Path(str(path).replace(".npz", ".meta.json")).write_text(
41
+ json.dumps(meta, indent=1, default=str), encoding="utf-8")
42
+ return path
43
+
44
+
45
+ def load_state(path: Path) -> Dict[str, Dict[str, np.ndarray]]:
46
+ path = Path(path)
47
+ data = np.load(path, allow_pickle=False)
48
+ out: Dict[str, Dict[str, np.ndarray]] = {}
49
+ for key in data.files:
50
+ name, _, fieldname = key.partition("::")
51
+ out.setdefault(name, {})[fieldname] = data[key]
52
+ return out