<feed xmlns='http://www.w3.org/2005/Atom'>
<title>typhoon.git/annotate_pgns/nnue_model.py, branch master</title>
<subtitle>The typhoon chess playing engine.
</subtitle>
<id>https://git.acknak.org/cgit/typhoon.git/atom?h=master</id>
<link rel='self' href='https://git.acknak.org/cgit/typhoon.git/atom?h=master'/>
<link rel='alternate' type='text/html' href='https://git.acknak.org/cgit/typhoon.git/'/>
<updated>2026-10-21T01:37:20Z</updated>
<entry>
<title>NNUE: re-fit raw-to-score calibration, NNU4 weight format, super-lazy default-on, lazy probe measured net-negative</title>
<updated>2026-10-21T01:37:20Z</updated>
<author>
<name>Scott Gasch</name>
<email>scott@gasch.org</email>
</author>
<published>2026-10-21T01:37:20Z</published>
<link rel='alternate' type='text/html' href='https://git.acknak.org/cgit/typhoon.git/commit/?id=9cf14e14e6999420f234cda951894337e034f57c'/>
<id>urn:sha1:9cf14e14e6999420f234cda951894337e034f57c</id>
<content type='text'>
Fits an affine (a + b*raw) correction into every exported .nnue file
(export_nnue_weights.py's CalibrateScoreMapping) so the engine's
consumed centipawn output tracks Stockfish's real score scale rather
than the net's nominal raw WDL-sigmoid output -- training variance
alone shifts this mapping across retrains even with an identical
recipe, so it's re-fit and baked in per export rather than assumed
constant. Weight format bumped to "NNU4" to carry the two new floats;
older NNU1/2/3 files are no longer readable.

Super-lazy (material-only) pre-filter promoted to default-on
(g_fUseNnueSuperLazy = TRUE) with a recalibrated per-material-bucket
margin table (measured against the recalibrated net, 16-shard
cross_sectional_200k.ep_ sample) -- real, measured nps win across all
three curated suites. The separate lazy-probe gate (accumulator-based
early exit) is measured net-negative on real search traffic at this
net's probe-vs-forward latency ratio and stays off by default
(g_fUseNnueLazyProbe = FALSE); code kept live since margin tuning
could still flip this, per docs/NNUE.md.

Also: direct per-call latency instrumentation for NnueProbeScore/
NnueForward (root.c, EVAL_TIME build) to make the lazy-probe
breakeven math measurable directly instead of inferred; QSearch
futility margins given real-data-derived NNUE_FULL/NNUE_LAZY
starting points.

Co-Authored-By: Claude Sonnet 5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>Wire NNUE eval into search, build the training pipeline, and add a fast</title>
<updated>2026-10-20T16:26:44Z</updated>
<author>
<name>Scott Gasch</name>
<email>scott@gasch.org</email>
</author>
<published>2026-10-20T16:26:44Z</published>
<link rel='alternate' type='text/html' href='https://git.acknak.org/cgit/typhoon.git/commit/?id=c8c6bbc2c1a103e5b07b079a0f8bdf66c7724d80'/>
<id>urn:sha1:c8c6bbc2c1a103e5b07b079a0f8bdf66c7724d80</id>
<content type='text'>
move/eval-agreement benchmark against Stockfish (tests/lop)

Implements the architecture decisions in src/docs/NNUE.md: HalfKAv2_hm
feature set, int16/int8 quantization, per-ply accumulator backup for
king moves, and a lazy-eval-ready integration into search.c/eval.c.
Adds the full annotate_pgns/ training pipeline (extraction, K-fit/
labeling, quiet filtering, tensor building, training, export) plus an
end-to-end orchestrator (run_nnue_pipeline.py) and validation tooling
(sanity_check_net.py, compare_vs_stockfish_net.py). Adds tests/lop:
a 10k-position list-of-positions benchmark comparing engine eval rank
and move choice against pre-computed Stockfish/lc0 references, much
cheaper than a full self-play match for day-to-day progress checks.

First sd10-matched self-play result against classic HCE: LLR +2.28
(H1=+2.94), -72=119+169 over 360 games, confirming the net is
"smarter per node" at matched depth. A real-time (--st 4) match is
currently weaker (candidate loses ~3 plies of depth to a ~3.3-3.7x
nps gap against an unrecalibrated search), consistent with
NNUE.md's adoption-criterion section -- pruning/reduction constants
still need retuning for the new eval's score scale before a fair
real-time comparison is possible.

Co-Authored-By: Claude Sonnet 5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>Phase A NNUE: feature-indexing spec, annotation/training pipeline, dump nnuefeatures</title>
<updated>2026-10-15T20:11:22Z</updated>
<author>
<name>Scott Gasch</name>
<email>scott@gasch.org</email>
</author>
<published>2026-10-15T20:11:22Z</published>
<link rel='alternate' type='text/html' href='https://git.acknak.org/cgit/typhoon.git/commit/?id=993b6eeb2a9ac7b659c473b6883fa53af1ad3a0b'/>
<id>urn:sha1:993b6eeb2a9ac7b659c473b6883fa53af1ad3a0b</id>
<content type='text'>
Builds out the NNUE Phase A prototype per docs/NNUE.md:

- src/nnuefeatures.c: standalone HalfKAv2_hm feature-index reference
  implementation (new `dump nnuefeatures` command), sourced from
  Stockfish's half_ka_v2_hm.{h,cpp} (sf_16 tag), including the 0x88-&gt;64
  square conversion typhoon's own board representation needs.
- annotate_pgns/: sharded TWIC/self-play annotation harness
  (annotate.py), position extraction, quiet-position filtering (flat
  and game-shaped, plus an upstream --prefilter-quiet option),
  train/holdout game-level stratified split, WDL-sigmoid K fitting,
  the Python HalfKAv2_hm reference encoder (nnue_feature_spec.py) and
  its bit-for-bit cross-checker against the C side
  (cross_check_features.py), and a first PyTorch training pipeline
  (nnue_model.py, nnue_train.py, build_training_tensors.py) -- a
  256x2-32-32-1-ish net trained locally on CPU against ~1.85M quiet
  TWIC positions as a pipeline/framework validation pass.
- Finish an in-progress InitMagic/InitLMRTable/InitEval -&gt;
  InitializeBitboardMagic/InitializeLMRTable/InitializeEval rename:
  chess.h's prototypes hadn't been updated to match the already-renamed
  definitions/call sites, leaving 4 implicit-function-declaration
  warnings.
- tests/arasan.epd: new curated EPD suite.
- docs/: add the project's design docs (previously untracked).

Co-Authored-By: Claude Sonnet 5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
</feed>
