simthinkd 0.2.0__tar.gz → 0.2.1__tar.gz
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.
- {simthinkd-0.2.0/src/simthinkd.egg-info → simthinkd-0.2.1}/PKG-INFO +27 -17
- {simthinkd-0.2.0 → simthinkd-0.2.1}/README.md +26 -16
- {simthinkd-0.2.0 → simthinkd-0.2.1}/pyproject.toml +1 -1
- {simthinkd-0.2.0 → simthinkd-0.2.1}/src/simthinkd/__init__.py +1 -1
- {simthinkd-0.2.0 → simthinkd-0.2.1}/src/simthinkd/server.py +16 -1
- {simthinkd-0.2.0 → simthinkd-0.2.1/src/simthinkd.egg-info}/PKG-INFO +27 -17
- {simthinkd-0.2.0 → simthinkd-0.2.1}/src/simthinkd.egg-info/SOURCES.txt +1 -0
- simthinkd-0.2.1/tests/test_server_latency.py +30 -0
- {simthinkd-0.2.0 → simthinkd-0.2.1}/LICENSE +0 -0
- {simthinkd-0.2.0 → simthinkd-0.2.1}/NOTICE +0 -0
- {simthinkd-0.2.0 → simthinkd-0.2.1}/setup.cfg +0 -0
- {simthinkd-0.2.0 → simthinkd-0.2.1}/src/simthinkd/bench.py +0 -0
- {simthinkd-0.2.0 → simthinkd-0.2.1}/src/simthinkd/cli.py +0 -0
- {simthinkd-0.2.0 → simthinkd-0.2.1}/src/simthinkd/core.py +0 -0
- {simthinkd-0.2.0 → simthinkd-0.2.1}/src/simthinkd/data/doom_defend_states.json +0 -0
- {simthinkd-0.2.0 → simthinkd-0.2.1}/src/simthinkd/integrations/__init__.py +0 -0
- {simthinkd-0.2.0 → simthinkd-0.2.1}/src/simthinkd/integrations/langchain_tool.py +0 -0
- {simthinkd-0.2.0 → simthinkd-0.2.1}/src/simthinkd/integrations/mcp_server.py +0 -0
- {simthinkd-0.2.0 → simthinkd-0.2.1}/src/simthinkd/policy.py +0 -0
- {simthinkd-0.2.0 → simthinkd-0.2.1}/src/simthinkd/score.py +0 -0
- {simthinkd-0.2.0 → simthinkd-0.2.1}/src/simthinkd/toy.py +0 -0
- {simthinkd-0.2.0 → simthinkd-0.2.1}/src/simthinkd/train.py +0 -0
- {simthinkd-0.2.0 → simthinkd-0.2.1}/src/simthinkd/weights/SHA256SUMS +0 -0
- {simthinkd-0.2.0 → simthinkd-0.2.1}/src/simthinkd/weights/doom-corridor.npz +0 -0
- {simthinkd-0.2.0 → simthinkd-0.2.1}/src/simthinkd/weights/doom-defend.npz +0 -0
- {simthinkd-0.2.0 → simthinkd-0.2.1}/src/simthinkd.egg-info/dependency_links.txt +0 -0
- {simthinkd-0.2.0 → simthinkd-0.2.1}/src/simthinkd.egg-info/entry_points.txt +0 -0
- {simthinkd-0.2.0 → simthinkd-0.2.1}/src/simthinkd.egg-info/requires.txt +0 -0
- {simthinkd-0.2.0 → simthinkd-0.2.1}/src/simthinkd.egg-info/top_level.txt +0 -0
- {simthinkd-0.2.0 → simthinkd-0.2.1}/tests/test_factory_twin.py +0 -0
- {simthinkd-0.2.0 → simthinkd-0.2.1}/tests/test_notebook.py +0 -0
- {simthinkd-0.2.0 → simthinkd-0.2.1}/tests/test_package.py +0 -0
- {simthinkd-0.2.0 → simthinkd-0.2.1}/tests/test_score.py +0 -0
- {simthinkd-0.2.0 → simthinkd-0.2.1}/tests/test_space.py +0 -0
- {simthinkd-0.2.0 → simthinkd-0.2.1}/tests/test_web_page.py +0 -0
- {simthinkd-0.2.0 → simthinkd-0.2.1}/tests/test_web_parity.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: simthinkd
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Summary: A 265k-parameter decision model that picks one action in about 2 ms on one CPU core, inside real-time loops.
|
|
5
5
|
Author: Myeongseongsimjae AX Institute
|
|
6
6
|
License: Apache-2.0
|
|
@@ -28,7 +28,7 @@ Requires-Dist: onnx>=1.15; extra == "onnx"
|
|
|
28
28
|
Requires-Dist: onnxruntime>=1.17; extra == "onnx"
|
|
29
29
|
Dynamic: license-file
|
|
30
30
|
|
|
31
|
-
<p align="center"><img src="assets/
|
|
31
|
+
<p align="center"><img src="assets/banner_v2.png" alt="SimThink D: a local backup for cloud decisions" width="100%"></p>
|
|
32
32
|
|
|
33
33
|
<p align="center">
|
|
34
34
|
<a href="https://pypi.org/project/simthinkd/"><img src="https://img.shields.io/pypi/v/simthinkd" alt="PyPI"></a>
|
|
@@ -39,27 +39,23 @@ Dynamic: license-file
|
|
|
39
39
|
<a href="https://doi.org/10.5281/zenodo.23111615"><img src="https://zenodo.org/badge/DOI/10.5281/zenodo.23111615.svg" alt="DOI"></a>
|
|
40
40
|
</p>
|
|
41
41
|
|
|
42
|
-
<p align="center"><
|
|
42
|
+
<p align="center"><b>Network down. Decisions stay local.</b></p>
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
SimThink D is a small CPU model for offline backup decisions.
|
|
45
|
+
It has 265,665 parameters and takes about 2 ms per decision on one CPU core.
|
|
45
46
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
</p>
|
|
49
|
-
|
|
50
|
-
<p align="center"><sub>Same game, same seed, same 6-core CPU. Left: SimThink D, 1.9 ms per decision, 1 of 420 ticks missed. Right: Laya, a 421M-parameter open decision model, used as published without training on this game. It takes about 360 ms per decision and misses 390 of 420 ticks. A dark frame means the game moved on before the decider answered.</sub></p>
|
|
47
|
+
In the factory simulation, the internet was cut for 15 seconds.
|
|
48
|
+
The local backup got 59 of 63 parts right, with no late decisions.
|
|
51
49
|
|
|
52
|
-
<
|
|
50
|
+
<p align="center"><a href="assets/factory_fallback.mp4"><img src="assets/factory_fallback_poster.jpg" alt="Watch the factory simulation: local backup during a network outage" width="100%"></a></p>
|
|
53
51
|
|
|
54
|
-
|
|
52
|
+
<p align="center"><a href="https://mssj-ai-org.github.io/simthinkd/#demo">Try in your browser</a> · <a href="assets/factory_fallback.mp4">Watch the video (72 s)</a> · <a href="examples/factory_twin/">Factory code</a> · <a href="docs/PAPER.md">Paper</a></p>
|
|
55
53
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
<a href="assets/factory_fallback.mp4"><img src="assets/factory_fallback_poster.jpg" alt="Internet down. The line kept going." width="100%"></a>
|
|
54
|
+
```bash
|
|
55
|
+
pip install simthinkd
|
|
56
|
+
```
|
|
61
57
|
|
|
62
|
-
|
|
58
|
+
What makes the next decision when your network goes down?
|
|
63
59
|
|
|
64
60
|
## Words used here
|
|
65
61
|
|
|
@@ -181,6 +177,12 @@ The second line measures any server that accepts the [decision request](docs/PRO
|
|
|
181
177
|
|
|
182
178
|
## Same CPU, same states
|
|
183
179
|
|
|
180
|
+
<p align="center">
|
|
181
|
+
<img src="assets/side_by_side.gif" alt="Same Doom game, same seed, same CPU. Left: SimThink D answers every tick. Right: a 421M-parameter general decision model, used as published, misses most ticks while it thinks." width="100%" />
|
|
182
|
+
</p>
|
|
183
|
+
|
|
184
|
+
<p align="center"><sub>Same game, same seed, same 6-core CPU. Left: SimThink D, 1.9 ms per decision, 1 of 420 ticks missed. Right: Laya, a 421M-parameter open decision model, used as published without training on this game. It takes about 360 ms per decision and misses 390 of 420 ticks. A dark frame means the game moved on before the decider answered.</sub></p>
|
|
185
|
+
|
|
184
186
|
**Read this first.** Laya is a general model and was not trained on this game. Its published speed, about 33 ms per question, is on a GPU. We only had a CPU. So this table compares time inside a real-time loop. It does not compare overall quality.
|
|
185
187
|
|
|
186
188
|
We used one workstation CPU (6 threads) and 1,050 Doom states, then 10 live games on the same seeds. "Missed ticks" are ticks that passed before the decider answered.
|
|
@@ -200,6 +202,7 @@ SimThink D only knows what its teacher knows. It does not reason, read long text
|
|
|
200
202
|
| Unity / C# | [docs/INTEGRATION_UNITY.md](docs/INTEGRATION_UNITY.md): a client loop that keeps the game running while it waits |
|
|
201
203
|
| Browser | [web/](web/): the same model in plain JavaScript, no server |
|
|
202
204
|
| A factory line (simulator) | [examples/factory_twin/](examples/factory_twin/): an inspection conveyor with a 400 ms deadline per part |
|
|
205
|
+
| Gradio | [space/](space/): a small web demo you can run locally or on Hugging Face Spaces |
|
|
203
206
|
| MCP (Claude Desktop, Cursor and others) | `pip install "simthinkd[mcp]"`, then `python -m simthinkd.integrations.mcp_server` |
|
|
204
207
|
| LangChain / LangGraph | `from simthinkd.integrations.langchain_tool import simthinkd_tool` |
|
|
205
208
|
|
|
@@ -218,6 +221,13 @@ SimThink D only knows what its teacher knows. It does not reason, read long text
|
|
|
218
221
|
- Probabilities are calibrated for the decider's own task only.
|
|
219
222
|
- A score model returns one number. It gives no probability or error bar with it.
|
|
220
223
|
|
|
224
|
+
## More
|
|
225
|
+
|
|
226
|
+
- [Figures from the paper](docs/FIGURES.md)
|
|
227
|
+
- [What you can reproduce](docs/REPRODUCE.md)
|
|
228
|
+
- [Decision request format](docs/PROTOCOL.md)
|
|
229
|
+
- [The factory video on LinkedIn](https://www.linkedin.com/feed/update/urn:li:activity:7510142949981057024/)
|
|
230
|
+
|
|
221
231
|
## Citation
|
|
222
232
|
|
|
223
233
|
If you use SimThink D, please cite it with [CITATION.cff](CITATION.cff). GitHub shows a "Cite this repository" button for it.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<p align="center"><img src="assets/
|
|
1
|
+
<p align="center"><img src="assets/banner_v2.png" alt="SimThink D: a local backup for cloud decisions" width="100%"></p>
|
|
2
2
|
|
|
3
3
|
<p align="center">
|
|
4
4
|
<a href="https://pypi.org/project/simthinkd/"><img src="https://img.shields.io/pypi/v/simthinkd" alt="PyPI"></a>
|
|
@@ -9,27 +9,23 @@
|
|
|
9
9
|
<a href="https://doi.org/10.5281/zenodo.23111615"><img src="https://zenodo.org/badge/DOI/10.5281/zenodo.23111615.svg" alt="DOI"></a>
|
|
10
10
|
</p>
|
|
11
11
|
|
|
12
|
-
<p align="center"><
|
|
12
|
+
<p align="center"><b>Network down. Decisions stay local.</b></p>
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
SimThink D is a small CPU model for offline backup decisions.
|
|
15
|
+
It has 265,665 parameters and takes about 2 ms per decision on one CPU core.
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
</p>
|
|
19
|
-
|
|
20
|
-
<p align="center"><sub>Same game, same seed, same 6-core CPU. Left: SimThink D, 1.9 ms per decision, 1 of 420 ticks missed. Right: Laya, a 421M-parameter open decision model, used as published without training on this game. It takes about 360 ms per decision and misses 390 of 420 ticks. A dark frame means the game moved on before the decider answered.</sub></p>
|
|
17
|
+
In the factory simulation, the internet was cut for 15 seconds.
|
|
18
|
+
The local backup got 59 of 63 parts right, with no late decisions.
|
|
21
19
|
|
|
22
|
-
<
|
|
20
|
+
<p align="center"><a href="assets/factory_fallback.mp4"><img src="assets/factory_fallback_poster.jpg" alt="Watch the factory simulation: local backup during a network outage" width="100%"></a></p>
|
|
23
21
|
|
|
24
|
-
|
|
22
|
+
<p align="center"><a href="https://mssj-ai-org.github.io/simthinkd/#demo">Try in your browser</a> · <a href="assets/factory_fallback.mp4">Watch the video (72 s)</a> · <a href="examples/factory_twin/">Factory code</a> · <a href="docs/PAPER.md">Paper</a></p>
|
|
25
23
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
<a href="assets/factory_fallback.mp4"><img src="assets/factory_fallback_poster.jpg" alt="Internet down. The line kept going." width="100%"></a>
|
|
24
|
+
```bash
|
|
25
|
+
pip install simthinkd
|
|
26
|
+
```
|
|
31
27
|
|
|
32
|
-
|
|
28
|
+
What makes the next decision when your network goes down?
|
|
33
29
|
|
|
34
30
|
## Words used here
|
|
35
31
|
|
|
@@ -151,6 +147,12 @@ The second line measures any server that accepts the [decision request](docs/PRO
|
|
|
151
147
|
|
|
152
148
|
## Same CPU, same states
|
|
153
149
|
|
|
150
|
+
<p align="center">
|
|
151
|
+
<img src="assets/side_by_side.gif" alt="Same Doom game, same seed, same CPU. Left: SimThink D answers every tick. Right: a 421M-parameter general decision model, used as published, misses most ticks while it thinks." width="100%" />
|
|
152
|
+
</p>
|
|
153
|
+
|
|
154
|
+
<p align="center"><sub>Same game, same seed, same 6-core CPU. Left: SimThink D, 1.9 ms per decision, 1 of 420 ticks missed. Right: Laya, a 421M-parameter open decision model, used as published without training on this game. It takes about 360 ms per decision and misses 390 of 420 ticks. A dark frame means the game moved on before the decider answered.</sub></p>
|
|
155
|
+
|
|
154
156
|
**Read this first.** Laya is a general model and was not trained on this game. Its published speed, about 33 ms per question, is on a GPU. We only had a CPU. So this table compares time inside a real-time loop. It does not compare overall quality.
|
|
155
157
|
|
|
156
158
|
We used one workstation CPU (6 threads) and 1,050 Doom states, then 10 live games on the same seeds. "Missed ticks" are ticks that passed before the decider answered.
|
|
@@ -170,6 +172,7 @@ SimThink D only knows what its teacher knows. It does not reason, read long text
|
|
|
170
172
|
| Unity / C# | [docs/INTEGRATION_UNITY.md](docs/INTEGRATION_UNITY.md): a client loop that keeps the game running while it waits |
|
|
171
173
|
| Browser | [web/](web/): the same model in plain JavaScript, no server |
|
|
172
174
|
| A factory line (simulator) | [examples/factory_twin/](examples/factory_twin/): an inspection conveyor with a 400 ms deadline per part |
|
|
175
|
+
| Gradio | [space/](space/): a small web demo you can run locally or on Hugging Face Spaces |
|
|
173
176
|
| MCP (Claude Desktop, Cursor and others) | `pip install "simthinkd[mcp]"`, then `python -m simthinkd.integrations.mcp_server` |
|
|
174
177
|
| LangChain / LangGraph | `from simthinkd.integrations.langchain_tool import simthinkd_tool` |
|
|
175
178
|
|
|
@@ -188,6 +191,13 @@ SimThink D only knows what its teacher knows. It does not reason, read long text
|
|
|
188
191
|
- Probabilities are calibrated for the decider's own task only.
|
|
189
192
|
- A score model returns one number. It gives no probability or error bar with it.
|
|
190
193
|
|
|
194
|
+
## More
|
|
195
|
+
|
|
196
|
+
- [Figures from the paper](docs/FIGURES.md)
|
|
197
|
+
- [What you can reproduce](docs/REPRODUCE.md)
|
|
198
|
+
- [Decision request format](docs/PROTOCOL.md)
|
|
199
|
+
- [The factory video on LinkedIn](https://www.linkedin.com/feed/update/urn:li:activity:7510142949981057024/)
|
|
200
|
+
|
|
191
201
|
## Citation
|
|
192
202
|
|
|
193
203
|
If you use SimThink D, please cite it with [CITATION.cff](CITATION.cff). GitHub shows a "Cite this repository" button for it.
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "simthinkd"
|
|
7
|
-
version = "0.2.
|
|
7
|
+
version = "0.2.1"
|
|
8
8
|
description = "A 265k-parameter decision model that picks one action in about 2 ms on one CPU core, inside real-time loops."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
from .core import Decider, Decision, available, build_request
|
|
7
7
|
from .score import Score, Scorer
|
|
8
8
|
|
|
9
|
-
__version__ = '0.2.
|
|
9
|
+
__version__ = '0.2.1'
|
|
10
10
|
__all__ = ['Decider', 'Decision', 'Score', 'Scorer', 'available', 'build_request', 'fit', 'fit_score', '__version__']
|
|
11
11
|
|
|
12
12
|
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
Binds to 127.0.0.1 by default. `--delay-ms` adds a fixed wait after inference (latency-injection experiments).
|
|
6
6
|
"""
|
|
7
7
|
import json
|
|
8
|
+
import socket
|
|
8
9
|
import time
|
|
9
10
|
from datetime import datetime, timezone
|
|
10
11
|
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
|
|
@@ -52,9 +53,23 @@ def make_handler(decider, name, delay_ms):
|
|
|
52
53
|
return Handler
|
|
53
54
|
|
|
54
55
|
|
|
56
|
+
class NoDelayHTTPServer(ThreadingHTTPServer):
|
|
57
|
+
"""Turns off Nagle's algorithm on every connection.
|
|
58
|
+
|
|
59
|
+
The handler writes the headers and the body separately. On a kept-alive connection the second small write waits
|
|
60
|
+
for the client's delayed ACK, so every answer took about 40 ms (measured 2026-10-03: median 42 ms kept-alive vs
|
|
61
|
+
1.4 ms with TCP_NODELAY). Clients that reuse connections (Java HttpURLConnection does) missed 30 ms deadlines.
|
|
62
|
+
"""
|
|
63
|
+
|
|
64
|
+
def get_request(self):
|
|
65
|
+
sock, addr = super().get_request()
|
|
66
|
+
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
|
|
67
|
+
return sock, addr
|
|
68
|
+
|
|
69
|
+
|
|
55
70
|
def serve(decider='doom-defend', host='127.0.0.1', port=11890, delay_ms=0.0, name=None):
|
|
56
71
|
decider = decider if isinstance(decider, Decider) else Decider(decider)
|
|
57
72
|
name = name or f'simthink-d:{decider.preset["name"]}'
|
|
58
|
-
server =
|
|
73
|
+
server = NoDelayHTTPServer((host, port), make_handler(decider, name, delay_ms))
|
|
59
74
|
print(json.dumps({'listening': f'{host}:{port}', 'weights_sha256': decider.sha256, 'model': name}), flush=True)
|
|
60
75
|
server.serve_forever()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: simthinkd
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Summary: A 265k-parameter decision model that picks one action in about 2 ms on one CPU core, inside real-time loops.
|
|
5
5
|
Author: Myeongseongsimjae AX Institute
|
|
6
6
|
License: Apache-2.0
|
|
@@ -28,7 +28,7 @@ Requires-Dist: onnx>=1.15; extra == "onnx"
|
|
|
28
28
|
Requires-Dist: onnxruntime>=1.17; extra == "onnx"
|
|
29
29
|
Dynamic: license-file
|
|
30
30
|
|
|
31
|
-
<p align="center"><img src="assets/
|
|
31
|
+
<p align="center"><img src="assets/banner_v2.png" alt="SimThink D: a local backup for cloud decisions" width="100%"></p>
|
|
32
32
|
|
|
33
33
|
<p align="center">
|
|
34
34
|
<a href="https://pypi.org/project/simthinkd/"><img src="https://img.shields.io/pypi/v/simthinkd" alt="PyPI"></a>
|
|
@@ -39,27 +39,23 @@ Dynamic: license-file
|
|
|
39
39
|
<a href="https://doi.org/10.5281/zenodo.23111615"><img src="https://zenodo.org/badge/DOI/10.5281/zenodo.23111615.svg" alt="DOI"></a>
|
|
40
40
|
</p>
|
|
41
41
|
|
|
42
|
-
<p align="center"><
|
|
42
|
+
<p align="center"><b>Network down. Decisions stay local.</b></p>
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
SimThink D is a small CPU model for offline backup decisions.
|
|
45
|
+
It has 265,665 parameters and takes about 2 ms per decision on one CPU core.
|
|
45
46
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
</p>
|
|
49
|
-
|
|
50
|
-
<p align="center"><sub>Same game, same seed, same 6-core CPU. Left: SimThink D, 1.9 ms per decision, 1 of 420 ticks missed. Right: Laya, a 421M-parameter open decision model, used as published without training on this game. It takes about 360 ms per decision and misses 390 of 420 ticks. A dark frame means the game moved on before the decider answered.</sub></p>
|
|
47
|
+
In the factory simulation, the internet was cut for 15 seconds.
|
|
48
|
+
The local backup got 59 of 63 parts right, with no late decisions.
|
|
51
49
|
|
|
52
|
-
<
|
|
50
|
+
<p align="center"><a href="assets/factory_fallback.mp4"><img src="assets/factory_fallback_poster.jpg" alt="Watch the factory simulation: local backup during a network outage" width="100%"></a></p>
|
|
53
51
|
|
|
54
|
-
|
|
52
|
+
<p align="center"><a href="https://mssj-ai-org.github.io/simthinkd/#demo">Try in your browser</a> · <a href="assets/factory_fallback.mp4">Watch the video (72 s)</a> · <a href="examples/factory_twin/">Factory code</a> · <a href="docs/PAPER.md">Paper</a></p>
|
|
55
53
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
<a href="assets/factory_fallback.mp4"><img src="assets/factory_fallback_poster.jpg" alt="Internet down. The line kept going." width="100%"></a>
|
|
54
|
+
```bash
|
|
55
|
+
pip install simthinkd
|
|
56
|
+
```
|
|
61
57
|
|
|
62
|
-
|
|
58
|
+
What makes the next decision when your network goes down?
|
|
63
59
|
|
|
64
60
|
## Words used here
|
|
65
61
|
|
|
@@ -181,6 +177,12 @@ The second line measures any server that accepts the [decision request](docs/PRO
|
|
|
181
177
|
|
|
182
178
|
## Same CPU, same states
|
|
183
179
|
|
|
180
|
+
<p align="center">
|
|
181
|
+
<img src="assets/side_by_side.gif" alt="Same Doom game, same seed, same CPU. Left: SimThink D answers every tick. Right: a 421M-parameter general decision model, used as published, misses most ticks while it thinks." width="100%" />
|
|
182
|
+
</p>
|
|
183
|
+
|
|
184
|
+
<p align="center"><sub>Same game, same seed, same 6-core CPU. Left: SimThink D, 1.9 ms per decision, 1 of 420 ticks missed. Right: Laya, a 421M-parameter open decision model, used as published without training on this game. It takes about 360 ms per decision and misses 390 of 420 ticks. A dark frame means the game moved on before the decider answered.</sub></p>
|
|
185
|
+
|
|
184
186
|
**Read this first.** Laya is a general model and was not trained on this game. Its published speed, about 33 ms per question, is on a GPU. We only had a CPU. So this table compares time inside a real-time loop. It does not compare overall quality.
|
|
185
187
|
|
|
186
188
|
We used one workstation CPU (6 threads) and 1,050 Doom states, then 10 live games on the same seeds. "Missed ticks" are ticks that passed before the decider answered.
|
|
@@ -200,6 +202,7 @@ SimThink D only knows what its teacher knows. It does not reason, read long text
|
|
|
200
202
|
| Unity / C# | [docs/INTEGRATION_UNITY.md](docs/INTEGRATION_UNITY.md): a client loop that keeps the game running while it waits |
|
|
201
203
|
| Browser | [web/](web/): the same model in plain JavaScript, no server |
|
|
202
204
|
| A factory line (simulator) | [examples/factory_twin/](examples/factory_twin/): an inspection conveyor with a 400 ms deadline per part |
|
|
205
|
+
| Gradio | [space/](space/): a small web demo you can run locally or on Hugging Face Spaces |
|
|
203
206
|
| MCP (Claude Desktop, Cursor and others) | `pip install "simthinkd[mcp]"`, then `python -m simthinkd.integrations.mcp_server` |
|
|
204
207
|
| LangChain / LangGraph | `from simthinkd.integrations.langchain_tool import simthinkd_tool` |
|
|
205
208
|
|
|
@@ -218,6 +221,13 @@ SimThink D only knows what its teacher knows. It does not reason, read long text
|
|
|
218
221
|
- Probabilities are calibrated for the decider's own task only.
|
|
219
222
|
- A score model returns one number. It gives no probability or error bar with it.
|
|
220
223
|
|
|
224
|
+
## More
|
|
225
|
+
|
|
226
|
+
- [Figures from the paper](docs/FIGURES.md)
|
|
227
|
+
- [What you can reproduce](docs/REPRODUCE.md)
|
|
228
|
+
- [Decision request format](docs/PROTOCOL.md)
|
|
229
|
+
- [The factory video on LinkedIn](https://www.linkedin.com/feed/update/urn:li:activity:7510142949981057024/)
|
|
230
|
+
|
|
221
231
|
## Citation
|
|
222
232
|
|
|
223
233
|
If you use SimThink D, please cite it with [CITATION.cff](CITATION.cff). GitHub shows a "Cite this repository" button for it.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"""The HTTP server must answer fast on a kept-alive connection (regression: ~40 ms Nagle/delayed-ACK stall in 0.2.0)."""
|
|
2
|
+
import http.client
|
|
3
|
+
import statistics
|
|
4
|
+
import threading
|
|
5
|
+
import time
|
|
6
|
+
|
|
7
|
+
from simthinkd.core import Decider
|
|
8
|
+
from simthinkd.server import NoDelayHTTPServer, make_handler
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def test_keep_alive_answers_fast():
|
|
12
|
+
decider = Decider('doom-defend')
|
|
13
|
+
server = NoDelayHTTPServer(('127.0.0.1', 0), make_handler(decider, 'test', 0.0))
|
|
14
|
+
threading.Thread(target=server.serve_forever, daemon=True).start()
|
|
15
|
+
try:
|
|
16
|
+
conn = http.client.HTTPConnection('127.0.0.1', server.server_address[1], timeout=2)
|
|
17
|
+
times = []
|
|
18
|
+
for _ in range(30):
|
|
19
|
+
start = time.perf_counter()
|
|
20
|
+
conn.request('GET', '/health')
|
|
21
|
+
conn.getresponse().read()
|
|
22
|
+
times.append((time.perf_counter() - start) * 1000)
|
|
23
|
+
assert statistics.median(times) < 20, times
|
|
24
|
+
finally:
|
|
25
|
+
server.shutdown()
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
if __name__ == "__main__":
|
|
29
|
+
test_keep_alive_answers_fast()
|
|
30
|
+
print("server latency test passed")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|