diff options
| author | Scott Gasch <[email protected]> | 2026-10-20 09:26:44 -0700 |
|---|---|---|
| committer | Scott Gasch <[email protected]> | 2026-10-20 09:26:44 -0700 |
| commit | c8c6bbc2c1a103e5b07b079a0f8bdf66c7724d80 (patch) | |
| tree | b6c2137c9ac577fa83b1e948fa0311d53dfe445d /src/main.c | |
| parent | 3b5d3677bb14ae14728a1c4b221176bb83667d92 (diff) | |
Wire NNUE eval into search, build the training pipeline, and add a fast
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 <[email protected]>
Diffstat (limited to 'src/main.c')
| -rw-r--r-- | src/main.c | 48 |
1 files changed, 48 insertions, 0 deletions
@@ -305,6 +305,7 @@ Return value: g_Options.uNumProcessors = 1; g_Options.fStatusLine = TRUE; g_Options.iResignThreshold = 0; + g_Options.dPostThrottleSec = 0.35; g_Options.u64MaxNodeCount = 0ULL; i = 1; @@ -424,6 +425,53 @@ Return value: } if (fConsumedNextArg) i++; } + else if ((!STRCMPI(pszArg, "--nnueprobeweights")) && fHaveVal) + { + // Same reasoning as --nnueweights above -- loads and + // enables the lazy-eval accumulator probe gate at startup + // for scripted match-play, where there's no interactive + // "nnue probeload"/"nnue lazyprobeon" command pair + // available. Does NOT imply --nnueweights -- pass both to + // get the full NNUE+lazy-gate configuration; this alone + // without NNUE eval enabled would load the probe but never + // reach the code path that consults it. + if (!NnueProbeLoadWeights(pszVal)) + { + UtilPanic(INITIALIZATION_FAILURE, + (void *)"Bad NNUE probe weights file", + (void *)&(pszVal), + (void *)"probeload", + NULL, + __FILE__, __LINE__); + } + else + { + g_fUseNnueLazyProbe = TRUE; + Trace("Loaded NNUE probe weights \"%s\", lazy probe gate enabled.\n", + pszVal); + } + if (fConsumedNextArg) i++; + } + else if ((!STRCMPI(pszArg, "--nnuelazymargin")) && fHaveVal) + { + // Scripted-match-play equivalent of "nnue lazymargin <cp>" + // -- flat override for every material bucket's lazy-probe + // margin, see nnueeval.c/eval.c. 2026-10-16 looser-margin + // experiment. + g_iNnueLazyMarginOverride = atoi(pszVal); + Trace("NNUE lazy margin override set to %d cp.\n", + g_iNnueLazyMarginOverride); + if (fConsumedNextArg) i++; + } + else if ((!STRCMPI(pszArg, "--nnuesuperlazymargin")) && fHaveVal) + { + // Scripted equivalent of "nnue superlazyon <cp>". + g_iNnueSuperLazyMargin = (SCORE)atoi(pszVal); + g_fUseNnueSuperLazy = TRUE; + Trace("NNUE super-lazy pre-filter enabled, margin=%d cp.\n", + g_iNnueSuperLazyMargin); + if (fConsumedNextArg) i++; + } else if ((!STRCMPI(pszArg, "--dnafile")) && fHaveVal) { if (!ReadEvalDNA(pszVal)) |
