anima-python 0.13.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- anima_py/README.md +39 -0
- anima_py/__init__.py +28 -0
- anima_py/__main__.py +7 -0
- anima_py/cli/__init__.py +1 -0
- anima_py/cli/anima.py +271 -0
- anima_py/cli/corpus.py +150 -0
- anima_py/cli/evaluate.py +1350 -0
- anima_py/cli/rho_axon.py +801 -0
- anima_py/cli/serialize.py +174 -0
- anima_py/cli/serialize_bind.py +100 -0
- anima_py/cli/sweep.py +509 -0
- anima_py/cli/train.py +1667 -0
- anima_py/core/__init__.py +1 -0
- anima_py/core/brain.py +601 -0
- anima_py/core/clm_serialize_v2.py +486 -0
- anima_py/core/clml.py +155 -0
- anima_py/core/decode.py +1386 -0
- anima_py/core/engine_cli.py +10307 -0
- anima_py/core/engine_g.py +129 -0
- anima_py/core/generator.py +318 -0
- anima_py/core/hippo_lane.py +133 -0
- anima_py/core/model.py +462 -0
- anima_py/core/pure_field.py +334 -0
- anima_py/core/rho_fan.py +442 -0
- anima_py/core/serialize.py +826 -0
- anima_py/core/serialize_standalone.py +186 -0
- anima_py/core/slw.py +211 -0
- anima_py/core/verify_clm_v2.py +844 -0
- anima_python-0.13.1.dist-info/METADATA +52 -0
- anima_python-0.13.1.dist-info/RECORD +34 -0
- anima_python-0.13.1.dist-info/WHEEL +5 -0
- anima_python-0.13.1.dist-info/entry_points.txt +2 -0
- anima_python-0.13.1.dist-info/licenses/LICENSE +21 -0
- anima_python-0.13.1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# ==========================================================================
|
|
2
|
+
# ⛔ ENGINE-INTERNAL / DEPRECATED py-MIRROR — DO NOT RUN OR SCORE DIRECTLY
|
|
3
|
+
# 측정/학습/서빙/직렬화는 cli/ 단일진입만: anima eval | train | serialize
|
|
4
|
+
# (canonical = hexa core/*.hexa 단일 SSOT; py 미러는 2026-06-28 폐기, DIRECTIONAL).
|
|
5
|
+
# 이 파일을 `python3 core/engine_g.py` 로 직접 실행하거나 side-harness로 import-채점하면
|
|
6
|
+
# = 단일진입 우회(#2603 위반) + terminal verdict 불가. cli/가 import하는 경로만 허용.
|
|
7
|
+
# ==========================================================================
|
|
8
|
+
import sys as _anima_entry_guard
|
|
9
|
+
if __name__ == "__main__":
|
|
10
|
+
_anima_entry_guard.exit("⛔ engine_g.py 직접 실행 금지 — cli/ 단일진입(anima eval/train/serialize, canonical=hexa) 경유. #2603")
|
|
11
|
+
|
|
12
|
+
"""core/engine_g.py — PY PRODUCTION ENGINE: byte-faithful 1:1 port of
|
|
13
|
+
core/engine_g.hexa (Engine G — motivation + emit gate).
|
|
14
|
+
|
|
15
|
+
Per CLAUDE.md a_two_production_mirror. Closed-form spontaneous machinery: the
|
|
16
|
+
8-factor weighted motivation_score + emit/safety predicates. Values are
|
|
17
|
+
byte-identical to the anima_alive PROACTIVE_THRESHOLD / weights (sum=1.0) lineage,
|
|
18
|
+
so CORE and the chat daemon share one behaviour. brain.py couples this (G) with
|
|
19
|
+
Engine A (pure_field.py). No external math builtins — pure float arithmetic.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
# ── thresholds (anima_alive carry) ──
|
|
23
|
+
def spont_im_threshold():
|
|
24
|
+
return 0.3 # PROACTIVE_THRESHOLD
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def spont_interrupt_threshold():
|
|
28
|
+
return 0.6 # talker interrupt
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def spont_idle_speak_after():
|
|
32
|
+
return 30.0 # IDLE_SPEAK_AFTER
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def spont_min_emit_interval():
|
|
36
|
+
return 30.0 # rate-limit convention
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
# ── 8 weights (sum = 1.00 closed conservation) ──
|
|
40
|
+
def spont_weight_relevance():
|
|
41
|
+
return 0.20
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def spont_weight_info_gap():
|
|
45
|
+
return 0.10
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def spont_weight_curiosity():
|
|
49
|
+
return 0.15
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def spont_weight_pain():
|
|
53
|
+
return 0.10
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def spont_weight_coherence():
|
|
57
|
+
return 0.10
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def spont_weight_originality():
|
|
61
|
+
return 0.10
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def spont_weight_balance():
|
|
65
|
+
return 0.15
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def spont_weight_dynamics():
|
|
69
|
+
return 0.10
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
# ── motivation_score (linear weighted sum) ──
|
|
73
|
+
def motivation_score(rel, gap, cur, pain, coh, orig, bal, dyn_v):
|
|
74
|
+
return (spont_weight_relevance() * rel
|
|
75
|
+
+ spont_weight_info_gap() * gap
|
|
76
|
+
+ spont_weight_curiosity() * cur
|
|
77
|
+
+ spont_weight_pain() * pain
|
|
78
|
+
+ spont_weight_coherence() * coh
|
|
79
|
+
+ spont_weight_originality() * orig
|
|
80
|
+
+ spont_weight_balance() * bal
|
|
81
|
+
+ spont_weight_dynamics() * dyn_v)
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
# ── emission predicates ──
|
|
85
|
+
def should_emit(score):
|
|
86
|
+
return score > spont_im_threshold()
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def should_interrupt(score):
|
|
90
|
+
return score > spont_interrupt_threshold()
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
# ── safety predicates (4-way AND closure) ──
|
|
94
|
+
def safety_kill_switch_on(env_off):
|
|
95
|
+
return env_off == False
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def safety_rate_limit_ok(seconds_since_last):
|
|
99
|
+
return seconds_since_last >= spont_min_emit_interval()
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def safety_phi_ratchet_ok(phi, ratchet):
|
|
103
|
+
"""Engine A's live Φ vs its ratchet peak (the A->G coupling gate)."""
|
|
104
|
+
return phi > ratchet / 2.0
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def safety_content_ok(content_clean):
|
|
108
|
+
return content_clean
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def safety_combined(kill, rate, phi_r, content):
|
|
112
|
+
return kill and rate and phi_r and content
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
if __name__ == "__main__":
|
|
116
|
+
# smoke: 8-factor score + predicates (matches _eg_parity.hexa oracle).
|
|
117
|
+
lo = motivation_score(0.1, 0.0, 0.0, 0.0, 0.1, 0.0, 0.1, 0.0)
|
|
118
|
+
hi = motivation_score(0.9, 0.6, 0.8, 0.0, 0.7, 0.5, 0.6, 1.0)
|
|
119
|
+
mid = motivation_score(0.5, 0.3, 0.2, 0.0, 0.4, 0.2, 0.3, 0.2)
|
|
120
|
+
print("score_lo=%.17g" % lo)
|
|
121
|
+
print("score_hi=%.17g" % hi)
|
|
122
|
+
print("score_mid=%.17g" % mid)
|
|
123
|
+
print("emit_lo=%s" % str(should_emit(lo)).lower())
|
|
124
|
+
print("emit_hi=%s" % str(should_emit(hi)).lower())
|
|
125
|
+
print("interrupt_hi=%s" % str(should_interrupt(hi)).lower())
|
|
126
|
+
print("rate_5=%s" % str(safety_rate_limit_ok(5.0)).lower())
|
|
127
|
+
print("rate_60=%s" % str(safety_rate_limit_ok(60.0)).lower())
|
|
128
|
+
print("phi_ratchet=%s" % str(safety_phi_ratchet_ok(0.118, 0.148)).lower())
|
|
129
|
+
print("combined=%s" % str(safety_combined(True, True, True, True)).lower())
|
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
# ==========================================================================
|
|
2
|
+
# ⛔ ENGINE-INTERNAL / DEPRECATED py-MIRROR — DO NOT RUN OR SCORE DIRECTLY
|
|
3
|
+
# 측정/학습/서빙/직렬화는 cli/ 단일진입만: anima eval | train | serialize
|
|
4
|
+
# (canonical = hexa core/*.hexa 단일 SSOT; py 미러는 2026-06-28 폐기, DIRECTIONAL).
|
|
5
|
+
# 이 파일을 `python3 core/generator.py` 로 직접 실행하거나 side-harness로 import-채점하면
|
|
6
|
+
# = 단일진입 우회(#2603 위반) + terminal verdict 불가. cli/가 import하는 경로만 허용.
|
|
7
|
+
# ==========================================================================
|
|
8
|
+
import sys as _anima_entry_guard
|
|
9
|
+
if __name__ == "__main__":
|
|
10
|
+
_anima_entry_guard.exit("⛔ generator.py 직접 실행 금지 — cli/ 단일진입(anima eval/train/serialize, canonical=hexa) 경유. #2603")
|
|
11
|
+
|
|
12
|
+
"""core/generator.py — PY PRODUCTION ENGINE: byte-faithful 1:1 mirror of the
|
|
13
|
+
L3 MOUTH-DISPATCH surface of core/generator.hexa.
|
|
14
|
+
|
|
15
|
+
Per CLAUDE.md a_two_production_mirror / a_core_engine_map: hexa + py are TWO
|
|
16
|
+
co-equal production engines kept at byte-parity. generator.hexa is the SINGLE L3
|
|
17
|
+
typed mouth slot — it sniffs a ckpt header and dispatches to ONE of two mouth
|
|
18
|
+
ARCHITECTURES (conv .clm via the CONV mouth, ByteGPT .bin via the BYTE mouth). This
|
|
19
|
+
module is the py mirror of that dispatcher; it routes to the already-parity-proven
|
|
20
|
+
core/decode.py (the unified decoder that merges the former clm_decode.py +
|
|
21
|
+
bytegpt_decode.py 1:1, itself a port of core/decode.hexa). NO torch in the path —
|
|
22
|
+
stdlib + numpy (via the decoder) only.
|
|
23
|
+
|
|
24
|
+
Scope: this mirrors generator.hexa's PUBLIC dispatch surface (a_core_engine_map):
|
|
25
|
+
gen_mouth_kind generator.hexa:628 header-sniff CLM\\x01 / 5xu32 / unknown
|
|
26
|
+
gen_auto_backend generator.hexa:641 -> gen_bytegpt_backend | gen_clm_backend
|
|
27
|
+
gen_auto_chat generator.hexa:684 -> gen_bytegpt_chat | gen_clm_chat
|
|
28
|
+
gen_auto_ideate generator.hexa:750 -> gen_bytegpt_ideate | gen_clm_ideate
|
|
29
|
+
plus the per-architecture single entries each dispatcher picks between:
|
|
30
|
+
gen_null_backend :74 gen_clm_backend :101 gen_bytegpt_backend :175
|
|
31
|
+
gen_clm_chat :599 gen_bytegpt_chat :664
|
|
32
|
+
gen_clm_ideate :697 gen_clm_ideate_W :713 gen_bytegpt_ideate :728
|
|
33
|
+
and the header helpers they reuse:
|
|
34
|
+
_gen_is_bytegpt :148 _gen_clm_probe_header :224 _gen_rd_u32 :792
|
|
35
|
+
|
|
36
|
+
NOTE the sniff is reproduced VERBATIM from generator.hexa (NOT the looser ranges
|
|
37
|
+
in decode.bg_is_bytegpt): generator.hexa::_gen_is_bytegpt requires
|
|
38
|
+
vocab==256, n_layer in 1..64, n_head divides d, block in 1..8192 — these tighter
|
|
39
|
+
bounds are the dispatcher's actual edge-case behavior and must be mirrored exactly.
|
|
40
|
+
|
|
41
|
+
The VERDICT path stays engine-native (hexa); this is the parity-proven py mirror.
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
import os
|
|
45
|
+
import sys
|
|
46
|
+
|
|
47
|
+
_HERE = os.path.dirname(os.path.abspath(__file__))
|
|
48
|
+
if _HERE not in sys.path:
|
|
49
|
+
sys.path.insert(0, _HERE)
|
|
50
|
+
|
|
51
|
+
import decode as _clm # core/decode.py (unified) — ConvMoE .clm mouth API
|
|
52
|
+
import decode as _bg # same module; both aliases resolve the union public API (ByteGPT .bin mouth)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
# ════════════════════════════════════════════════════════════════════════
|
|
56
|
+
# header helpers — 1:1 from generator.hexa
|
|
57
|
+
# ════════════════════════════════════════════════════════════════════════
|
|
58
|
+
|
|
59
|
+
def _gen_rd_u32(rb, off):
|
|
60
|
+
"""generator.hexa:792 _gen_rd_u32 — little-endian u32 from a byte buffer."""
|
|
61
|
+
return rb[off] + rb[off + 1] * 0x100 + rb[off + 2] * 0x10000 + rb[off + 3] * 0x1000000
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def _gen_path_is_file(p):
|
|
65
|
+
"""generator.hexa:245 _gen_path_is_file — empty path -> false, else isfile."""
|
|
66
|
+
if len(p) == 0:
|
|
67
|
+
return False
|
|
68
|
+
return os.path.isfile(p)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def _gen_is_bytegpt(p):
|
|
72
|
+
"""generator.hexa:148 _gen_is_bytegpt — true iff `p` is a ByteGPT flat binary,
|
|
73
|
+
NOT a .clm. Reject the CLM\\x01 magic; then require a SANE 5xu32 header:
|
|
74
|
+
vocab==256, n_layer in 1..64, n_head divides d, block in 1..8192. Edge-safe
|
|
75
|
+
(missing/short file -> false). Bounds are tighter than decode.bg_is_bytegpt;
|
|
76
|
+
these are the dispatcher's verbatim discriminator (mirror exactly)."""
|
|
77
|
+
if len(p) == 0:
|
|
78
|
+
return False
|
|
79
|
+
if not _gen_path_is_file(p):
|
|
80
|
+
return False
|
|
81
|
+
try:
|
|
82
|
+
rb = open(p, 'rb').read()
|
|
83
|
+
except Exception:
|
|
84
|
+
return False
|
|
85
|
+
if len(rb) < 20:
|
|
86
|
+
return False
|
|
87
|
+
# reject the .clm magic outright (CLM\x01 = 67,76,77,1)
|
|
88
|
+
if rb[0] == 67 and rb[1] == 76 and rb[2] == 77 and rb[3] == 1:
|
|
89
|
+
return False
|
|
90
|
+
vocab = _gen_rd_u32(rb, 0)
|
|
91
|
+
d = _gen_rd_u32(rb, 4)
|
|
92
|
+
nlay = _gen_rd_u32(rb, 8)
|
|
93
|
+
nh = _gen_rd_u32(rb, 12)
|
|
94
|
+
block = _gen_rd_u32(rb, 16)
|
|
95
|
+
if vocab != 256:
|
|
96
|
+
return False
|
|
97
|
+
if nlay < 1 or nlay > 64:
|
|
98
|
+
return False
|
|
99
|
+
if nh < 1 or d < 1:
|
|
100
|
+
return False
|
|
101
|
+
if (d // nh) * nh != d: # n_head must divide d
|
|
102
|
+
return False
|
|
103
|
+
if block < 1 or block > 8192:
|
|
104
|
+
return False
|
|
105
|
+
return True
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def _gen_clm_probe_header(p):
|
|
109
|
+
"""generator.hexa:224 _gen_clm_probe_header — verify the CLM\\x01 header.
|
|
110
|
+
Returns {exists, valid, nblocks}. Edge-safe: missing/empty/truncated -> valid=False."""
|
|
111
|
+
if len(p) == 0:
|
|
112
|
+
return {"exists": False, "valid": False, "nblocks": 0}
|
|
113
|
+
if not _gen_path_is_file(p):
|
|
114
|
+
return {"exists": False, "valid": False, "nblocks": 0}
|
|
115
|
+
rb = open(p, 'rb').read()
|
|
116
|
+
# need at least MAGIC(4) + nblocks(1) = 5 bytes
|
|
117
|
+
if len(rb) < 5:
|
|
118
|
+
return {"exists": True, "valid": False, "nblocks": 0}
|
|
119
|
+
magic_ok = rb[0] == 67 and rb[1] == 76 and rb[2] == 77 and rb[3] == 1
|
|
120
|
+
if not magic_ok:
|
|
121
|
+
return {"exists": True, "valid": False, "nblocks": 0}
|
|
122
|
+
nblocks = rb[4]
|
|
123
|
+
return {"exists": True, "valid": True, "nblocks": nblocks}
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
# ════════════════════════════════════════════════════════════════════════
|
|
127
|
+
# §1 backend constructors (the pluggable "vtable" records)
|
|
128
|
+
# ════════════════════════════════════════════════════════════════════════
|
|
129
|
+
|
|
130
|
+
def gen_null_backend():
|
|
131
|
+
"""generator.hexa:74 gen_null_backend — always-ready deterministic placeholder."""
|
|
132
|
+
return {"kind": "null", "loaded": True, "ckpt": ""}
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def gen_clm_backend(ckpt_path):
|
|
136
|
+
"""generator.hexa:101 gen_clm_backend — parse the .clm header at the single L3
|
|
137
|
+
entry; surface loaded (header admit) + decodable (v0.2 CLMX trailer present)."""
|
|
138
|
+
probe = _gen_clm_probe_header(ckpt_path)
|
|
139
|
+
exists = probe["exists"]
|
|
140
|
+
valid = probe["valid"]
|
|
141
|
+
nblk = probe["nblocks"]
|
|
142
|
+
loaded = valid
|
|
143
|
+
decodable = valid and _clm.clm_decodable(ckpt_path)
|
|
144
|
+
if not exists:
|
|
145
|
+
reason = "no ckpt at path"
|
|
146
|
+
elif not valid:
|
|
147
|
+
reason = "file present but not a valid .clm (bad CLM\\x01 magic)"
|
|
148
|
+
else:
|
|
149
|
+
reason = ("valid .clm admitted + LOADED (magic+structure OK, nblocks="
|
|
150
|
+
+ str(nblk)
|
|
151
|
+
+ "); decode forward LANDED + descends CORE-mounted at d=768 (loaded=valid)")
|
|
152
|
+
return {"kind": "clm", "loaded": loaded, "decodable": decodable, "valid": valid,
|
|
153
|
+
"ckpt": ckpt_path, "ckpt_exists": exists, "nblocks": nblk, "reason": reason}
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
def gen_bytegpt_backend(ckpt_path):
|
|
157
|
+
"""generator.hexa:175 gen_bytegpt_backend — parse the 5xu32 ByteGPT header at the
|
|
158
|
+
single L3 entry. ByteGPT-format file => valid+loaded+decodable=True; else honest
|
|
159
|
+
rejection (valid=False) so generate() falls through to null (no garbage)."""
|
|
160
|
+
if not _gen_is_bytegpt(ckpt_path):
|
|
161
|
+
exists = _gen_path_is_file(ckpt_path)
|
|
162
|
+
reason = ("no ckpt at path" if not exists
|
|
163
|
+
else "file present but not a ByteGPT flat binary (bad 5xu32 header)")
|
|
164
|
+
return {"kind": "bytegpt", "loaded": False, "decodable": False, "valid": False,
|
|
165
|
+
"ckpt": ckpt_path, "ckpt_exists": exists, "nlayer": 0, "d": 0, "reason": reason}
|
|
166
|
+
rb = open(ckpt_path, 'rb').read()
|
|
167
|
+
vocab = _gen_rd_u32(rb, 0); d = _gen_rd_u32(rb, 4)
|
|
168
|
+
nlay = _gen_rd_u32(rb, 8); nh = _gen_rd_u32(rb, 12)
|
|
169
|
+
block = _gen_rd_u32(rb, 16)
|
|
170
|
+
reason = ("valid ByteGPT flat binary admitted + LOADED (vocab=" + str(vocab)
|
|
171
|
+
+ " d=" + str(d) + " n_layer=" + str(nlay) + " n_head=" + str(nh)
|
|
172
|
+
+ " block=" + str(block) + "); decode forward = full-24-layer BYTE-EXACT-argmax "
|
|
173
|
+
+ "parity with torch ByteGPT (H_1157 R1, G1 inherited)")
|
|
174
|
+
return {"kind": "bytegpt", "loaded": True, "decodable": True, "valid": True,
|
|
175
|
+
"ckpt": ckpt_path, "ckpt_exists": True, "vocab": vocab, "d": d,
|
|
176
|
+
"nlayer": nlay, "nhead": nh, "block": block, "reason": reason}
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
# ════════════════════════════════════════════════════════════════════════
|
|
180
|
+
# MOUTH-TYPE DISPATCHER — generator.hexa §"MOUTH-TYPE DISPATCHER" (609+)
|
|
181
|
+
# ════════════════════════════════════════════════════════════════════════
|
|
182
|
+
|
|
183
|
+
def gen_mouth_kind(ckpt_path):
|
|
184
|
+
"""generator.hexa:628 gen_mouth_kind — sniff a ckpt and report the mouth
|
|
185
|
+
ARCHITECTURE: "bytegpt" | "clm" | "unknown". ByteGPT checked FIRST (its magic
|
|
186
|
+
is the ABSENCE of CLM\\x01 + a sane 5xu32 header, strictly disjoint from a .clm)."""
|
|
187
|
+
if _gen_is_bytegpt(ckpt_path):
|
|
188
|
+
return "bytegpt"
|
|
189
|
+
probe = _gen_clm_probe_header(ckpt_path)
|
|
190
|
+
if probe["valid"]:
|
|
191
|
+
return "clm"
|
|
192
|
+
return "unknown"
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
def gen_auto_backend(ckpt_path):
|
|
196
|
+
"""generator.hexa:641 gen_auto_backend — THE mouth dispatcher. Sniff and return
|
|
197
|
+
the right backend record; "clm"/"unknown" both go to gen_clm_backend (it self-
|
|
198
|
+
reports valid=False for a non-.clm/absent file -> generate() falls through to null)."""
|
|
199
|
+
kind = gen_mouth_kind(ckpt_path)
|
|
200
|
+
if kind == "bytegpt":
|
|
201
|
+
return gen_bytegpt_backend(ckpt_path)
|
|
202
|
+
return gen_clm_backend(ckpt_path)
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
# ════════════════════════════════════════════════════════════════════════
|
|
206
|
+
# CHAT entries — greedy byte-continuation of a composed dialogue seed
|
|
207
|
+
# ════════════════════════════════════════════════════════════════════════
|
|
208
|
+
|
|
209
|
+
def gen_clm_chat(ckpt_path, seed, max_new):
|
|
210
|
+
"""generator.hexa:599 gen_clm_chat — thin caller of the ONE .clm decode mouth
|
|
211
|
+
(clm_decode_argmax). ok=False with reason for a v0.1 (non-decodable) file."""
|
|
212
|
+
if not _clm.clm_decodable(ckpt_path):
|
|
213
|
+
return {"ok": False, "text": "",
|
|
214
|
+
"reason": "ckpt not v0.2-decodable (no CLMX trailer; embed/GN absent)"}
|
|
215
|
+
r = _clm.clm_decode_argmax(ckpt_path, seed, max_new)
|
|
216
|
+
return {"ok": r["ok"], "text": r["text"],
|
|
217
|
+
"reason": "decoded via clm_decode_argmax (CLMConvMoE int4 forward)"}
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
def gen_bytegpt_chat(ckpt_path, seed, max_new):
|
|
221
|
+
"""generator.hexa:664 gen_bytegpt_chat — thin caller of the ONE ByteGPT decode
|
|
222
|
+
mouth (bytegpt_decode_argmax_ranged, OOM-safe ranged load). seed string -> byte
|
|
223
|
+
ids (vocab256 byte LM), exactly as the hexa builds sids via ord(substring(...))."""
|
|
224
|
+
if gen_mouth_kind(ckpt_path) != "bytegpt":
|
|
225
|
+
return {"ok": False, "text": "",
|
|
226
|
+
"reason": "ckpt not a ByteGPT flat binary (bad 5xu32 [256,d,L,H,block] header)"}
|
|
227
|
+
sids = list(seed.encode('utf-8', 'surrogateescape'))
|
|
228
|
+
r = _bg.bytegpt_decode_argmax_ranged(ckpt_path, sids, max_new)
|
|
229
|
+
return {"ok": r["ok"], "text": r["text"],
|
|
230
|
+
"reason": "decoded via bytegpt_decode_argmax_ranged (24-layer GPT-2-class byte forward)"}
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
def gen_auto_chat(ckpt_path, seed, max_new):
|
|
234
|
+
"""generator.hexa:684 gen_auto_chat — mouth-dispatched chat. Same {ok,text,reason}
|
|
235
|
+
shape for both mouths so the chat loop is mouth-agnostic."""
|
|
236
|
+
if gen_mouth_kind(ckpt_path) == "bytegpt":
|
|
237
|
+
return gen_bytegpt_chat(ckpt_path, seed, max_new)
|
|
238
|
+
return gen_clm_chat(ckpt_path, seed, max_new)
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
# ════════════════════════════════════════════════════════════════════════
|
|
242
|
+
# IDEATE entries — the seeded-sampling siblings (ρ·fan best-of-K source · ideation · former G6)
|
|
243
|
+
# ════════════════════════════════════════════════════════════════════════
|
|
244
|
+
|
|
245
|
+
def gen_clm_ideate(ckpt_path, seed, max_new, top_k, temp, seed_rng):
|
|
246
|
+
"""generator.hexa:697 gen_clm_ideate — seeded top-k sampler on the .clm mouth
|
|
247
|
+
(clm_decode_topk_sampled). HARD-BOUNDED by max_new."""
|
|
248
|
+
if not _clm.clm_decodable(ckpt_path):
|
|
249
|
+
return {"ok": False, "text": "",
|
|
250
|
+
"reason": "ckpt not v0.2-decodable (no CLMX trailer; embed/GN absent)"}
|
|
251
|
+
r = _clm.clm_decode_topk_sampled(ckpt_path, seed, max_new, top_k, temp, seed_rng)
|
|
252
|
+
return {"ok": r["ok"], "text": r["text"],
|
|
253
|
+
"reason": "ideated via clm_decode_topk_sampled (seeded top-k, best-of-K source)"}
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
def gen_clm_ideate_W(W, seed, max_new, top_k, temp, seed_rng):
|
|
257
|
+
"""generator.hexa:713 gen_clm_ideate_W — SAME mouth off a PRE-LOADED weight map
|
|
258
|
+
(clm_load_weights) so a multi-decode driver loads the 303M ConvMoE ONCE."""
|
|
259
|
+
r = _clm.clm_decode_topk_sampled_W(W, seed, max_new, top_k, temp, seed_rng)
|
|
260
|
+
return {"ok": r["ok"], "text": r["text"],
|
|
261
|
+
"reason": "ideated via clm_decode_topk_sampled_W (loaded-W, seeded top-k)"}
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
def gen_bytegpt_ideate(ckpt_path, seed, max_new, top_k, temp, seed_rng):
|
|
265
|
+
"""generator.hexa:728 gen_bytegpt_ideate — seeded top-k sampler on the ByteGPT
|
|
266
|
+
mouth (bytegpt_decode_topk_sampled_ranged, OOM-safe). HARD-BOUNDED by max_new."""
|
|
267
|
+
if gen_mouth_kind(ckpt_path) != "bytegpt":
|
|
268
|
+
return {"ok": False, "text": "",
|
|
269
|
+
"reason": "ckpt not a ByteGPT flat binary (bad 5xu32 [256,d,L,H,block] header)"}
|
|
270
|
+
sids = list(seed.encode('utf-8', 'surrogateescape'))
|
|
271
|
+
r = _bg.bytegpt_decode_topk_sampled_ranged(ckpt_path, sids, max_new, top_k, temp, seed_rng)
|
|
272
|
+
return {"ok": r["ok"], "text": r["text"],
|
|
273
|
+
"reason": "ideated via bytegpt_decode_topk_sampled_ranged (seeded top-k, OOM-safe)"}
|
|
274
|
+
|
|
275
|
+
|
|
276
|
+
def gen_auto_ideate(ckpt_path, seed, max_new, top_k, temp, seed_rng):
|
|
277
|
+
"""generator.hexa:750 gen_auto_ideate — mouth-dispatched ideate (the seeded-sampling
|
|
278
|
+
sibling of gen_auto_chat). Same {ok,text,reason} contract for both mouths so the
|
|
279
|
+
ρ-AXON reach scorers (former G0-G6) run on EITHER mouth via this ONE typed entry (mouth-agnostic)."""
|
|
280
|
+
if gen_mouth_kind(ckpt_path) == "bytegpt":
|
|
281
|
+
return gen_bytegpt_ideate(ckpt_path, seed, max_new, top_k, temp, seed_rng)
|
|
282
|
+
return gen_clm_ideate(ckpt_path, seed, max_new, top_k, temp, seed_rng)
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
# ════════════════════════════════════════════════════════════════════════
|
|
286
|
+
# CLI — for the byte-parity harness (mirror of a hexa main calling the same)
|
|
287
|
+
# ════════════════════════════════════════════════════════════════════════
|
|
288
|
+
|
|
289
|
+
def _main(argv):
|
|
290
|
+
if len(argv) < 2:
|
|
291
|
+
print("usage: generator.py <cmd> ...", file=sys.stderr)
|
|
292
|
+
return 2
|
|
293
|
+
cmd = argv[1]
|
|
294
|
+
if cmd == "kind":
|
|
295
|
+
print("KIND:" + gen_mouth_kind(argv[2]))
|
|
296
|
+
return 0
|
|
297
|
+
if cmd == "ideate":
|
|
298
|
+
# ideate <ckpt> <seed> <gen> <top_k> <temp> <seed_rng>
|
|
299
|
+
ck, seed, gen = argv[2], argv[3], int(argv[4])
|
|
300
|
+
top_k = int(argv[5]); temp = float(argv[6]); rng = int(argv[7])
|
|
301
|
+
r = gen_auto_ideate(ck, seed, gen, top_k, temp, rng)
|
|
302
|
+
sys.stdout.buffer.write(b"KIND:" + gen_mouth_kind(ck).encode() + b"\n")
|
|
303
|
+
sys.stdout.buffer.write(b"OK:" + (b"true" if r["ok"] else b"false") + b"\n")
|
|
304
|
+
sys.stdout.buffer.write(b"TEXT:" + r["text"].encode('utf-8', 'surrogateescape') + b"\n")
|
|
305
|
+
return 0
|
|
306
|
+
if cmd == "chat":
|
|
307
|
+
ck, seed, gen = argv[2], argv[3], int(argv[4])
|
|
308
|
+
r = gen_auto_chat(ck, seed, gen)
|
|
309
|
+
sys.stdout.buffer.write(b"KIND:" + gen_mouth_kind(ck).encode() + b"\n")
|
|
310
|
+
sys.stdout.buffer.write(b"OK:" + (b"true" if r["ok"] else b"false") + b"\n")
|
|
311
|
+
sys.stdout.buffer.write(b"TEXT:" + r["text"].encode('utf-8', 'surrogateescape') + b"\n")
|
|
312
|
+
return 0
|
|
313
|
+
print("unknown cmd", cmd, file=sys.stderr)
|
|
314
|
+
return 2
|
|
315
|
+
|
|
316
|
+
|
|
317
|
+
if __name__ == "__main__":
|
|
318
|
+
sys.exit(_main(sys.argv))
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# ==========================================================================
|
|
3
|
+
# core/hippo_lane.py — L5 HIPPOCAMPAL ASSOCIATIVE-STORE lane (numpy 2-production).
|
|
4
|
+
#
|
|
5
|
+
# H_9129 rung-3. A DISJOINT store-side lane over the .kosmos anchor store:
|
|
6
|
+
# pattern-separated (DG kWTA) sparse coding of anima representations + a CA3
|
|
7
|
+
# heteroassociative store that does MULTI-STEP pattern completion (transitive
|
|
8
|
+
# chaining). This is a READ-ONLY relatedness READOUT — it never mutates the
|
|
9
|
+
# emit-drive lane (Ψ / motivation / recall_thr / generator). Adding/consulting
|
|
10
|
+
# it therefore cannot change generation bytes (a_substrate_disjoint: separation
|
|
11
|
+
# = preservation). The byte-parity hexa twin lives in core/kosmos_io.hexa
|
|
12
|
+
# (hippo_kwta / hippo_build_store / hippo_relatedness).
|
|
13
|
+
#
|
|
14
|
+
# This module is a pure library (NO __main__ execution of the engine) — the
|
|
15
|
+
# rep→code encoding uses the real ByteGPT-303M forward via core/decode.py in the
|
|
16
|
+
# py-canonical measurement path (== anima-python evaluate ops, a_eval_py_canonical);
|
|
17
|
+
# the store + completion here is arch-independent arithmetic (no FFI, no torch).
|
|
18
|
+
# ==========================================================================
|
|
19
|
+
import numpy as np
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
# ── DG de-anisotropy (rung-2 GREEN lens: center_zscore) ─────────────────────
|
|
23
|
+
def dg_decorrelate(reps, mode="center_zscore"):
|
|
24
|
+
"""Whiten anisotropic anima reps before pattern separation. Raw single-token
|
|
25
|
+
303M reps are near-collinear (a dominant shared direction) which masquerades
|
|
26
|
+
as a substrate wall; center/z-score removes it (rung-2 pre-registered lens)."""
|
|
27
|
+
R = np.asarray(reps, dtype=np.float64)
|
|
28
|
+
if mode == "raw":
|
|
29
|
+
return R
|
|
30
|
+
mu = R.mean(axis=0, keepdims=True)
|
|
31
|
+
Rc = R - mu
|
|
32
|
+
if mode == "center":
|
|
33
|
+
return Rc
|
|
34
|
+
if mode == "center_zscore":
|
|
35
|
+
sd = Rc.std(axis=0, keepdims=True) + 1e-6
|
|
36
|
+
return Rc / sd
|
|
37
|
+
raise ValueError(mode)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
# ── DG pattern separation: fixed (untrained) random projection → kWTA sparse code ──
|
|
41
|
+
def hippo_kwta(v, k):
|
|
42
|
+
"""k-winners-take-all cleanup → sparse binary attractor state (CA3 cleanup)."""
|
|
43
|
+
v = np.asarray(v, dtype=np.float64)
|
|
44
|
+
if k >= v.size:
|
|
45
|
+
return (v > 0).astype(np.float32)
|
|
46
|
+
idx = np.argpartition(v, -k)[-k:]
|
|
47
|
+
out = np.zeros_like(v, dtype=np.float32)
|
|
48
|
+
pos = idx[v[idx] > 0]
|
|
49
|
+
out[pos] = 1.0
|
|
50
|
+
return out
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def dg_codes(reps, dim, active, seed):
|
|
54
|
+
"""Pattern separation. Fixed seeded random projection (DG expansion) of each
|
|
55
|
+
rep → kWTA sparse binary code. Projection is UNTRAINED (no handed advantage);
|
|
56
|
+
correlated reps → overlapping codes (crosstalk preserved = honest test)."""
|
|
57
|
+
reps = np.asarray(reps, dtype=np.float64)
|
|
58
|
+
n, dm = reps.shape
|
|
59
|
+
rng = np.random.default_rng(seed)
|
|
60
|
+
P = rng.standard_normal((dim, dm)).astype(np.float32) / np.sqrt(dm)
|
|
61
|
+
R = reps / (np.linalg.norm(reps, axis=1, keepdims=True) + 1e-9)
|
|
62
|
+
drive = R @ P.T
|
|
63
|
+
return np.stack([hippo_kwta(drive[i], active) for i in range(n)])
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
# ── CA3 heteroassociative store + multi-step pattern completion ─────────────
|
|
67
|
+
def hippo_build_store(codes, edges, dim):
|
|
68
|
+
"""Heteroassociative CA3 store: W = Σ outer(code[nxt], code[cur]) over the
|
|
69
|
+
DIRECTED premise edges only. edges = list of (cur, nxt) index pairs."""
|
|
70
|
+
W = np.zeros((dim, dim), dtype=np.float32)
|
|
71
|
+
codes = np.asarray(codes, dtype=np.float32)
|
|
72
|
+
for cur, nxt in edges:
|
|
73
|
+
W += np.outer(codes[nxt], codes[cur])
|
|
74
|
+
return W
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def hippo_relatedness(W, codes, i, j, steps, kwta):
|
|
78
|
+
"""READ-OUT (no mouth): seed the lane with code[i], run CA3 completion `steps`
|
|
79
|
+
times, return the max overlap between any visited attractor state and code[j].
|
|
80
|
+
Multi-step ⇒ transitive chaining i→i+1→…→j iff a stored relation path exists."""
|
|
81
|
+
codes = np.asarray(codes, dtype=np.float32)
|
|
82
|
+
x = codes[i].copy().astype(np.float64)
|
|
83
|
+
cj = codes[j].astype(np.float64)
|
|
84
|
+
cjn = np.linalg.norm(cj) + 1e-9
|
|
85
|
+
best = 0.0
|
|
86
|
+
for _ in range(steps):
|
|
87
|
+
x = hippo_kwta(W @ x, kwta).astype(np.float64)
|
|
88
|
+
ov = float(x @ cj) / ((np.linalg.norm(x) + 1e-9) * cjn)
|
|
89
|
+
if ov > best:
|
|
90
|
+
best = ov
|
|
91
|
+
return best
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
# ── deterministic fixture (byte-parity oracle for the kosmos_io.hexa twin) ──
|
|
95
|
+
def fixture_codes(n, dim, active, seed):
|
|
96
|
+
"""Deterministic sparse binary codes WITHOUT any float RNG divergence across
|
|
97
|
+
languages: bit b is active for item i iff ((i*step + b*mul) % dim) < active
|
|
98
|
+
band — a pure integer construction so hexa and py agree byte-for-byte."""
|
|
99
|
+
codes = np.zeros((n, dim), dtype=np.float32)
|
|
100
|
+
for i in range(n):
|
|
101
|
+
picked = set()
|
|
102
|
+
b = 0
|
|
103
|
+
h = (i * 2654435761 + seed) & 0xFFFFFFFF
|
|
104
|
+
while len(picked) < active:
|
|
105
|
+
h = (h * 1664525 + 1013904223) & 0xFFFFFFFF
|
|
106
|
+
picked.add(h % dim)
|
|
107
|
+
b += 1
|
|
108
|
+
for idx in picked:
|
|
109
|
+
codes[i, idx] = 1.0
|
|
110
|
+
return codes
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def _fixture_report():
|
|
114
|
+
"""Print a deterministic small-scale CA3 report for hexa byte-parity.
|
|
115
|
+
8 items in one chain 0→1→…→7; reachable = (0,k) k>=2 chain via completion;
|
|
116
|
+
unreachable = a disconnected item. Also a lesion (remove edge 3→4)."""
|
|
117
|
+
N, DIM, ACTIVE, STEPS, KWTA = 8, 64, 4, 8, 4
|
|
118
|
+
codes = fixture_codes(N, DIM, ACTIVE, 20260705)
|
|
119
|
+
edges = [(p, p + 1) for p in range(N - 1)] # chain 0→1→...→7
|
|
120
|
+
W = hippo_build_store(codes, edges, DIM)
|
|
121
|
+
# reachable 2-hop (0,2) and 3-hop (0,3); adjacent stored (0,1); self-far (0,7)
|
|
122
|
+
for (i, j, tag) in [(0, 1, "recall_1hop"), (0, 2, "novel_2hop"),
|
|
123
|
+
(0, 3, "novel_3hop"), (0, 7, "novel_7hop")]:
|
|
124
|
+
r = hippo_relatedness(W, codes, i, j, STEPS, KWTA)
|
|
125
|
+
print("py %s(0,%d)=%.6f" % (tag, j, r))
|
|
126
|
+
# lesion: remove edge 3→4 ; pair (0,5) path crosses it → must collapse
|
|
127
|
+
Wl = hippo_build_store(codes, [(p, p + 1) for p in range(N - 1) if p != 3], DIM)
|
|
128
|
+
print("py lesion_broken(0,5)=%.6f" % hippo_relatedness(Wl, codes, 0, 5, STEPS, KWTA))
|
|
129
|
+
print("py lesion_intact(0,2)=%.6f" % hippo_relatedness(Wl, codes, 0, 2, STEPS, KWTA))
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
if __name__ == "__main__":
|
|
133
|
+
_fixture_report()
|