Mr-DS-ML-85 commited on
Commit
5aa6962
Β·
verified Β·
1 Parent(s): 33892ad

Build instructions: BUILDING.md + make sync-so

Browse files

Full build/test/run/rebuild instructions, verified by running each command. Adds a make sync-so target that builds the shared library AND copies it to the repo-root build/ dir the ctypes bridge actually loads -- the stale-library trap that broke from_pretrained is now impossible to miss.

Files changed (4) hide show
  1. .gitattributes +0 -5
  2. BUILDING.md +193 -0
  3. README.md +12 -0
  4. engine/Makefile +13 -0
.gitattributes CHANGED
@@ -1,7 +1,2 @@
1
  *.bin filter=lfs diff=lfs merge=lfs -text
2
  model/*/substrate.bin filter=lfs diff=lfs merge=lfs -text
3
- build/libsyfox_core.so filter=lfs diff=lfs merge=lfs -text
4
- engine/build/libsyfox_core.so filter=lfs diff=lfs merge=lfs -text
5
- engine/build/rebuild_sem filter=lfs diff=lfs merge=lfs -text
6
- engine/build/syfox filter=lfs diff=lfs merge=lfs -text
7
- engine/build/syfox-test filter=lfs diff=lfs merge=lfs -text
 
1
  *.bin filter=lfs diff=lfs merge=lfs -text
2
  model/*/substrate.bin filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
BUILDING.md ADDED
@@ -0,0 +1,193 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Building SyFox
2
+
3
+ The decision engine is **C++17 with no runtime dependencies** beyond a C++
4
+ compiler. There is no neural network, no transformer, and no Python needed for
5
+ inference from the CLI.
6
+
7
+ ```
8
+ engine/ the C++ SI-substrate core (core/*.hpp + src/*.cpp) + its Makefile
9
+ server/ optional HTTP bridge (FastAPI) and the ctypes bridge
10
+ inference.py thin python wrapper over the bridge
11
+ model/ the fabrics (prebuilt substrates, no training required to use them)
12
+ ```
13
+
14
+ ---
15
+
16
+ ## 1. Build the core
17
+
18
+ ```bash
19
+ cd engine
20
+ make all # -> build/syfox, build/syfox-test, build/libsyfox_core.so,
21
+ # build/rebuild_sem
22
+ ```
23
+
24
+ Requires `g++` (C++17) and `make`. On Debian/Ubuntu:
25
+
26
+ ```bash
27
+ sudo apt-get install build-essential
28
+ ```
29
+
30
+ There is **no top-level `Makefile`** β€” the `cd engine` is required, not optional.
31
+
32
+ ## 2. Run the tests
33
+
34
+ ```bash
35
+ cd engine
36
+ make test # builds and runs build/syfox-test
37
+ ./build/syfox-test # expected: "all tests passed"
38
+ ```
39
+
40
+ ## 3. Build the Python bridge library β€” **read this**
41
+
42
+ ```bash
43
+ cd engine
44
+ make sync-so # builds the .so AND copies it to ../build/
45
+ ```
46
+
47
+ `server/syfox_bridge.py` loads the shared library with `ctypes` from the
48
+ **repo-root** `build/` directory:
49
+
50
+ ```python
51
+ _LIB = ... / "build" / "libsyfox_core.so" # NOT engine/build/
52
+ ```
53
+
54
+ So if you only run `make all`, the CLI and the test suite pass while
55
+ `from inference import SyFox` fails with:
56
+
57
+ ```
58
+ AttributeError: ... undefined symbol: syfox_engine_set_semantics
59
+ ```
60
+
61
+ That happens because the bridge keeps loading an **older** `build/` copy that
62
+ happens to be present. A prebuilt `build/libsyfox_core.so` ships in this repo,
63
+ so it will look like everything works β€” right up until it silently uses the
64
+ stale core. `make sync-so` exists so this cannot be forgotten.
65
+
66
+ For a clean environment, delete it first so the failure is loud:
67
+
68
+ ```bash
69
+ rm -f build/libsyfox_core.so && cd engine && make sync-so
70
+ ```
71
+
72
+ ## 4. Optional: OpenMP build
73
+
74
+ Parallel settle, deterministic by construction (fixed reduction order) and
75
+ bit-identical to the sequential build:
76
+
77
+ ```bash
78
+ cd engine && make build/syfox-omp
79
+ ```
80
+
81
+ ## 5. Run it
82
+
83
+ **CLI** β€” no Python needed:
84
+
85
+ ```bash
86
+ ./engine/build/syfox stats --model model/sst2
87
+
88
+ ./engine/build/syfox decide --model model/sst2 \
89
+ --state "a hollow, inert picture that never risks anything" \
90
+ --questions '{"q":{"type":"choice","instructions":"sentiment",
91
+ "criteria":{"negative":"negative","positive":"positive"}}}'
92
+ ```
93
+
94
+ Every response carries `choice`, `confidence`, `deferred`, `probabilities`, and
95
+ a `reason` when it abstains. **`deferred: true` is the engine declining to
96
+ answer, not an error** β€” see [Abstention](#abstention-is-a-feature).
97
+
98
+ **Python**:
99
+
100
+ ```bash
101
+ pip install fastapi uvicorn # only needed for the HTTP server
102
+ python -c "
103
+ from inference import SyFox
104
+ m = SyFox()
105
+ r = m.decide('I was charged twice on my last invoice, please refund.')
106
+ print(r['answers']['domain'])"
107
+ ```
108
+
109
+ **HTTP server** (the HuggingFace Spaces entrypoint):
110
+
111
+ ```bash
112
+ python server/app.py --model model/giant --lang auto --energy-norm \
113
+ --host 0.0.0.0 --port 7860
114
+ ```
115
+
116
+ ## 6. Docker / Spaces
117
+
118
+ The `Dockerfile` builds the core in a throwaway stage and copies only the
119
+ stripped `.so` into a slim runtime image β€” it handles the `sync-so` step for
120
+ you. It serves on port **7860**, which Spaces expects.
121
+
122
+ ```bash
123
+ docker build -t syfox .
124
+ docker run -p 7860:7860 syfox
125
+ ```
126
+
127
+ ## 7. Retraining a fabric
128
+
129
+ Not needed to *use* the models. To train your own:
130
+
131
+ ```bash
132
+ ./engine/build/syfox learn --model my-model --examples train.jsonl \
133
+ --energy-norm --ngrams on
134
+ ./engine/build/syfox calibrate --model my-model --examples cal.jsonl \
135
+ --energy-norm --ngrams on
136
+ ```
137
+
138
+ Always calibrate on a split the model never trained on, and score **once** on a
139
+ held-out split. Fabric size grows with lesson count: ~4,200 rows β†’ ~78k nodes /
140
+ ~949k lanes / ~23 MB.
141
+
142
+ ### Admission gate
143
+
144
+ A model should be checked on handcrafted novel questions before publishing,
145
+ because held-out accuracy shares its generator with training and rewards
146
+ memorising n-grams:
147
+
148
+ ```bash
149
+ python tools/novel_gate.py --sweep path/to/candidate/dir
150
+ ```
151
+
152
+ Probes live in `datasets/novel_probes/`. A model is admitted only if it clears
153
+ both the majority baseline and uniform chance + 0.15, with no single class
154
+ answering more than 60% of probes.
155
+
156
+ ---
157
+
158
+ ## Platform support
159
+
160
+ **The prebuilt `build/libsyfox_core.so` is linux-x86_64.** On macOS or ARM
161
+ (Apple Silicon, ARM servers) it will not load β€” rebuild instead:
162
+
163
+ ```bash
164
+ cd engine && make clean && make sync-so
165
+ ```
166
+
167
+ That produces a library for *your* machine. Do not ship it to users on other
168
+ platforms; the repository copy is a convenience for linux-x86_64 only.
169
+
170
+ ## Troubleshooting
171
+
172
+ | symptom | cause | fix |
173
+ |---|---|---|
174
+ | `undefined symbol: syfox_engine_set_*` on import | bridge loaded a stale `.so` | `cd engine && make sync-so` |
175
+ | `command not found: make` | no toolchain | `apt-get install build-essential` |
176
+ | `make: *** No rule to make target` | wrong directory | you are in the repo root, not `engine/` |
177
+ | CLI and tests pass but Python fails | see row 1 | stale `.so` |
178
+ | every answer has `deferred: true` | honesty gate firing, working as designed | inspect `reason` in the response |
179
+
180
+ ## Abstention is a feature
181
+
182
+ SyFox returns `deferred: true` with a `reason` rather than guessing. Reported
183
+ accuracy is always meaningless without the paired defer rate β€” the honest
184
+ metric is `accuracy Γ— answered/total`. See
185
+ [docs/HONEST_TOTAL.md](../docs/HONEST_TOTAL.md) in the upstream project for the
186
+ protocol, and `docs/ENGINE_PORT.md` for what changed in the v3.9.1 port.
187
+
188
+ ## Related
189
+
190
+ - [`docs/ENGINE_PORT.md`](ENGINE_PORT.md) β€” the v3.2.0 β†’ v3.9.1 port, ABI
191
+ verification, and the stale-numbers caveat
192
+ - [`docs/EVALUATION.md`](EVALUATION.md) β€” measured evaluation
193
+ - [`docs/ZEROSHOT.md`](ZEROSHOT.md) β€” zero-shot and coverage probes
README.md CHANGED
@@ -154,6 +154,18 @@ examples/ JSON payloads + curl + python usage
154
  Dockerfile HuggingFace Spaces (builds engine, serves on 7860)
155
  ```
156
 
 
 
 
 
 
 
 
 
 
 
 
 
157
  ## Usage (python)
158
 
159
  ```python
 
154
  Dockerfile HuggingFace Spaces (builds engine, serves on 7860)
155
  ```
156
 
157
+ ## Build
158
+
159
+ ```bash
160
+ cd engine && make all && make sync-so && cd ..
161
+ ```
162
+
163
+ `make sync-so` is **required** for the Python bridge: it loads
164
+ `build/libsyfox_core.so` from the **repo root**, not `engine/build/`, so a
165
+ plain `make all` leaves a stale library in place and `from inference import
166
+ SyFox` fails with `undefined symbol`. Full instructions, Docker, retraining
167
+ and troubleshooting: **[BUILDING.md](BUILDING.md)**.
168
+
169
  ## Usage (python)
170
 
171
  ```python
engine/Makefile CHANGED
@@ -5,6 +5,19 @@ BUILD := build
5
 
6
  all: build/syfox build/syfox-test build/libsyfox_core.so build/rebuild_sem
7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
  build:
9
  mkdir -p build
10
 
 
5
 
6
  all: build/syfox build/syfox-test build/libsyfox_core.so build/rebuild_sem
7
 
8
+ # Copy the shared library to the REPO-ROOT build/ dir, which is where
9
+ # server/syfox_bridge.py looks for it (ctypes: ../build/libsyfox_core.so).
10
+ # Skipping this is the single most common setup failure: the CLI and the tests
11
+ # pass, then `from inference import SyFox` dies with
12
+ # undefined symbol: syfox_engine_set_*
13
+ # because the bridge silently keeps loading a stale core.
14
+ sync-so: build/libsyfox_core.so
15
+ mkdir -p ../build
16
+ cp $< ../build/libsyfox_core.so
17
+ @echo "synced -> ../build/libsyfox_core.so"
18
+
19
+ .PHONY: sync-so
20
+
21
  build:
22
  mkdir -p build
23