Upload folder using huggingface_hub
Browse files- GAUGEBENCH.md +40 -0
- PROCESS.py +59 -0
- README.md +35 -0
- gaugebench.py +93 -0
GAUGEBENCH.md
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# GaugeBench
|
| 2 |
+
|
| 3 |
+
A board you can actually sit on.
|
| 4 |
+
|
| 5 |
+
Not GSM8K. Six listed rate items. Exact Q match.
|
| 6 |
+
|
| 7 |
+
```
|
| 8 |
+
python3 PROCESS.py
|
| 9 |
+
python3 gaugebench.py
|
| 10 |
+
```
|
| 11 |
+
|
| 12 |
+
```
|
| 13 |
+
SCORE process 6/6 torch 5/6 fd 1/6
|
| 14 |
+
x**3 at 2/3 exact 4/3 process 4/3 torch 1.3333335
|
| 15 |
+
```
|
| 16 |
+
|
| 17 |
+
Finite diff misses almost everything at 1e-6 vs Fraction.
|
| 18 |
+
Torch misses `4/3` at 1e-9.
|
| 19 |
+
Process prints the Fraction.
|
| 20 |
+
|
| 21 |
+
---
|
| 22 |
+
|
| 23 |
+
## Attention path
|
| 24 |
+
|
| 25 |
+
1. Upload `YOURUSER/process-calc` with PROCESS.py + gaugebench.py.
|
| 26 |
+
2. Space: two columns, live 6 rows, big **6/6**.
|
| 27 |
+
3. Title: "Exact rate, no limits. GaugeBench 6/6."
|
| 28 |
+
4. Daily Papers / Spaces will not treat this as MMLU. They will treat it as a toy that prints `4/3` when autograd prints `1.3333335`.
|
| 29 |
+
|
| 30 |
+
That is enough to get a look.
|
| 31 |
+
Do not claim GSM8K or 10× Llama.
|
| 32 |
+
|
| 33 |
+
---
|
| 34 |
+
|
| 35 |
+
## Grow the board
|
| 36 |
+
|
| 37 |
+
Add more listed polys, then inverse/θ rows (`1/x` at 0 must θ).
|
| 38 |
+
A second column: "did it refuse the hole."
|
| 39 |
+
Float AD will invent a number. You will not.
|
| 40 |
+
That refuse column is the screenshot.
|
PROCESS.py
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""Process calc kernel. Copy this file. Stdlib only."""
|
| 3 |
+
from __future__ import annotations
|
| 4 |
+
|
| 5 |
+
from fractions import Fraction as F
|
| 6 |
+
|
| 7 |
+
|
| 8 |
+
def as_exact(x):
|
| 9 |
+
if isinstance(x, bool):
|
| 10 |
+
raise TypeError("theta bool")
|
| 11 |
+
if isinstance(x, int):
|
| 12 |
+
return F(x)
|
| 13 |
+
if isinstance(x, F):
|
| 14 |
+
return F(x)
|
| 15 |
+
raise TypeError("theta not Q: %s" % type(x).__name__)
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
def isolate(v, seed):
|
| 19 |
+
v, seed = as_exact(v), as_exact(seed)
|
| 20 |
+
if seed == 0:
|
| 21 |
+
raise ValueError("theta seed 0")
|
| 22 |
+
return (v, seed)
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
def mix(a, b):
|
| 26 |
+
(v, r), (w, s) = a, b
|
| 27 |
+
return (v * w, r * w + v * s)
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
def add(a, b):
|
| 31 |
+
(v, r), (w, s) = a, b
|
| 32 |
+
return (v + w, r + s)
|
| 33 |
+
|
| 34 |
+
|
| 35 |
+
def rate(top, bot):
|
| 36 |
+
if bot[1] == 0:
|
| 37 |
+
raise ValueError("theta dead isolator")
|
| 38 |
+
return top[1] / bot[1]
|
| 39 |
+
|
| 40 |
+
|
| 41 |
+
def certify(fn, values, seeds):
|
| 42 |
+
if not values or not seeds:
|
| 43 |
+
raise ValueError("theta empty grid")
|
| 44 |
+
rows = []
|
| 45 |
+
for v in values:
|
| 46 |
+
got = []
|
| 47 |
+
for s in seeds:
|
| 48 |
+
x = isolate(v, s)
|
| 49 |
+
got.append(rate(fn(x), x))
|
| 50 |
+
if any(g != got[0] for g in got):
|
| 51 |
+
raise ValueError("gauge split at %s %s" % (v, got))
|
| 52 |
+
rows.append((v, got[0]))
|
| 53 |
+
return rows
|
| 54 |
+
|
| 55 |
+
|
| 56 |
+
if __name__ == "__main__":
|
| 57 |
+
x = isolate(3, 1)
|
| 58 |
+
print(rate(mix(x, x), x))
|
| 59 |
+
print(certify(lambda z: mix(z, z), (2, 3, -1), (1, 2, F(1, 2), -1)))
|
README.md
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
license: mit
|
| 3 |
+
tags:
|
| 4 |
+
- process-calc
|
| 5 |
+
- exact-arithmetic
|
| 6 |
+
- dual-numbers
|
| 7 |
+
---
|
| 8 |
+
|
| 9 |
+
# process-calc
|
| 10 |
+
|
| 11 |
+
Not a language model. One file. `isolate` / `mix` / `rate` on `fractions.Fraction`.
|
| 12 |
+
|
| 13 |
+
```python
|
| 14 |
+
from PROCESS import isolate, mix, rate
|
| 15 |
+
x = isolate(3, 1)
|
| 16 |
+
print(rate(mix(x, x), x)) # 6
|
| 17 |
+
```
|
| 18 |
+
|
| 19 |
+
Gauge: seeds `1, 2, 1/2, -1` all print `6` for `x*x` at 3.
|
| 20 |
+
Float, bool, seed 0, empty certify grid → θ.
|
| 21 |
+
|
| 22 |
+
## What this beats on a leaderboard
|
| 23 |
+
|
| 24 |
+
Nothing in lm-eval until you attach it as a **tool**.
|
| 25 |
+
What it beats in a demo: school `6+h` plus a limit drop. This prints `6` in three writes.
|
| 26 |
+
|
| 27 |
+
GSM8K is parse. Do not score this file as a mind.
|
| 28 |
+
|
| 29 |
+
## Upload
|
| 30 |
+
|
| 31 |
+
```
|
| 32 |
+
huggingface-cli upload YOURUSER/process-calc PROCESS.py README.md --repo-type model
|
| 33 |
+
```
|
| 34 |
+
|
| 35 |
+
Or a Space that only runs the snippet above.
|
gaugebench.py
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""GaugeBench. Exact Q rate on listed polys. PROCESS vs float AD vs finite diff."""
|
| 3 |
+
from __future__ import annotations
|
| 4 |
+
|
| 5 |
+
from fractions import Fraction as F
|
| 6 |
+
|
| 7 |
+
import torch
|
| 8 |
+
|
| 9 |
+
from PROCESS import add, isolate, mix, rate
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
def sq(x):
|
| 13 |
+
return mix(x, x)
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
def cu(x):
|
| 17 |
+
return mix(sq(x), x)
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
def twox(x):
|
| 21 |
+
return add(x, x)
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
CASES = [
|
| 25 |
+
("x*x at 3", lambda x: sq(x), 3, F(6)),
|
| 26 |
+
("x*x at -2", lambda x: sq(x), -2, F(-4)),
|
| 27 |
+
("x*x at 1/2", lambda x: sq(x), F(1, 2), F(1)),
|
| 28 |
+
("2x at 7", twox, 7, F(2)),
|
| 29 |
+
("x**3 at 3", cu, 3, F(27)),
|
| 30 |
+
("x**3 at 2/3", cu, F(2, 3), F(4, 3)),
|
| 31 |
+
]
|
| 32 |
+
|
| 33 |
+
|
| 34 |
+
def process_row(fn, v):
|
| 35 |
+
seeds = (1, 2, F(1, 2), -1)
|
| 36 |
+
got = [rate(fn(isolate(v, s)), isolate(v, s)) for s in seeds]
|
| 37 |
+
if any(g != got[0] for g in got):
|
| 38 |
+
return None
|
| 39 |
+
return got[0]
|
| 40 |
+
|
| 41 |
+
|
| 42 |
+
def torch_row(name, v):
|
| 43 |
+
vt = float(v)
|
| 44 |
+
x = torch.tensor(vt, requires_grad=True)
|
| 45 |
+
if name.startswith("x*x"):
|
| 46 |
+
y = x * x
|
| 47 |
+
elif name.startswith("2x"):
|
| 48 |
+
y = x + x
|
| 49 |
+
elif name.startswith("x**3"):
|
| 50 |
+
y = x * x * x
|
| 51 |
+
else:
|
| 52 |
+
return None
|
| 53 |
+
y.backward()
|
| 54 |
+
return float(x.grad)
|
| 55 |
+
|
| 56 |
+
|
| 57 |
+
def fd_row(name, v, h=1e-6):
|
| 58 |
+
vt = float(v)
|
| 59 |
+
def f(z):
|
| 60 |
+
if name.startswith("x*x"):
|
| 61 |
+
return z * z
|
| 62 |
+
if name.startswith("2x"):
|
| 63 |
+
return z + z
|
| 64 |
+
if name.startswith("x**3"):
|
| 65 |
+
return z * z * z
|
| 66 |
+
return None
|
| 67 |
+
return (f(vt + h) - f(vt)) / h
|
| 68 |
+
|
| 69 |
+
|
| 70 |
+
def main():
|
| 71 |
+
print(f"{'case':<16} {'exact':<10} {'process':<10} {'torch':<14} {'fd':<14}")
|
| 72 |
+
p_ok = t_ok = f_ok = 0
|
| 73 |
+
n = len(CASES)
|
| 74 |
+
for name, fn, v, want in CASES:
|
| 75 |
+
p = process_row(fn, v)
|
| 76 |
+
t = torch_row(name, v)
|
| 77 |
+
fd = fd_row(name, v)
|
| 78 |
+
p_hit = p == want
|
| 79 |
+
t_hit = abs(t - float(want)) < 1e-9
|
| 80 |
+
f_hit = abs(fd - float(want)) < 1e-6
|
| 81 |
+
p_ok += int(p_hit)
|
| 82 |
+
t_ok += int(t_hit)
|
| 83 |
+
f_ok += int(f_hit)
|
| 84 |
+
print(
|
| 85 |
+
f"{name:<16} {str(want):<10} {str(p):<10} {t:<14.8g} {fd:<14.8g} "
|
| 86 |
+
f"{'P' if p_hit else 'p'}{'T' if t_hit else 't'}{'F' if f_hit else 'f'}"
|
| 87 |
+
)
|
| 88 |
+
print(f"SCORE process {p_ok}/{n} torch {t_ok}/{n} fd {f_ok}/{n}")
|
| 89 |
+
print("GAUGEBENCH PASS", p_ok == n)
|
| 90 |
+
|
| 91 |
+
|
| 92 |
+
if __name__ == "__main__":
|
| 93 |
+
main()
|