mirror of
https://github.com/official-stockfish/Stockfish.git
synced 2026-07-22 20:57:10 +00:00
Remove small net
Failed VVLTC non-regression https://tests.stockfishchess.org/tests/view/69d562b84088e069540a2288 LLR: -2.96 (-2.94,2.94) <-1.75,0.25> Total: 386998 W: 99181 L: 99760 D: 188057 Ptnml(0-2): 35, 35792, 122429, 35203, 40 Failed STC non-regression https://tests.stockfishchess.org/tests/view/69f3c6601e5788938e86a99e LLR: -2.93 (-2.94,2.94) <-1.75,0.25> Total: 33696 W: 8492 L: 8795 D: 16409 Ptnml(0-2): 124, 4209, 8504, 3868, 143 Many thanks to Dubslow, Torom, ces42, Shawn, vondele, Disservin and others for discussion. ## Summary The venerable small net has been around for quite some time now, and while the big net architecture has substantially advanced with TI, the small net has stayed with plain HalfKA. It therefore presents a few burdens: multiple net architectures to maintain, multiple nets to train, and a whole lot of templates to deal with the variable L1 size. Locally I measure a slowdown of -2.5% in NPS with this branch – and it's probably more on non-AVX512 architectures – but a pure slowdown of that magnitude would lead to more dramatic losses (even at VVLTC) than exhibited in the above tests, suggesting that the small net's lower eval quality is deleterious. Bonus: Shawn found this interesting PGN among the VVLTC games: https://lichess.org/study/hvo8jflc/OeTOityv `master` seems to misevaluate the fortress because all positions go to small net (the material difference is larger than the threshold). closes https://github.com/official-stockfish/Stockfish/pull/6796 Bench: 2877007
This commit is contained in:
committed by
Joost VandeVondele
parent
dc1686345c
commit
ab8f901d25
+13
-36
@@ -26,7 +26,6 @@
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
#include <tuple>
|
||||
|
||||
#include "nnue/network.h"
|
||||
#include "nnue/nnue_misc.h"
|
||||
@@ -46,11 +45,9 @@ int Eval::simple_eval(const Position& pos) {
|
||||
- pos.non_pawn_material(~c);
|
||||
}
|
||||
|
||||
bool Eval::use_smallnet(const Position& pos) { return std::abs(simple_eval(pos)) > 962; }
|
||||
|
||||
// Evaluate is the evaluator for the outer world. It returns a static evaluation
|
||||
// of the position from the point of view of the side to move.
|
||||
Value Eval::evaluate(const Eval::NNUE::Networks& networks,
|
||||
Value Eval::evaluate(const Eval::NNUE::Network& network,
|
||||
const Position& pos,
|
||||
Eval::NNUE::AccumulatorStack& accumulators,
|
||||
Eval::NNUE::AccumulatorCaches& caches,
|
||||
@@ -58,20 +55,10 @@ Value Eval::evaluate(const Eval::NNUE::Networks& networks,
|
||||
|
||||
assert(!pos.checkers());
|
||||
|
||||
bool smallNet = use_smallnet(pos);
|
||||
auto [psqt, positional] = smallNet ? networks.small.evaluate(pos, accumulators, caches.small)
|
||||
: networks.big.evaluate(pos, accumulators, caches.big);
|
||||
auto [psqt, positional] = network.evaluate(pos, accumulators, caches);
|
||||
|
||||
Value nnue = (125 * psqt + 131 * positional) / 128;
|
||||
|
||||
// Re-evaluate the position when higher eval accuracy is worth the time spent
|
||||
if (smallNet && (std::abs(nnue) < 277))
|
||||
{
|
||||
std::tie(psqt, positional) = networks.big.evaluate(pos, accumulators, caches.big);
|
||||
nnue = (125 * psqt + 131 * positional) / 128;
|
||||
smallNet = false;
|
||||
}
|
||||
|
||||
// Blend optimism and eval with nnue complexity
|
||||
int nnueComplexity = std::abs(psqt - positional);
|
||||
optimism += optimism * nnueComplexity / 476;
|
||||
@@ -93,43 +80,33 @@ Value Eval::evaluate(const Eval::NNUE::Networks& networks,
|
||||
// a string (suitable for outputting to stdout) that contains the detailed
|
||||
// descriptions and values of each evaluation term. Useful for debugging.
|
||||
// Trace scores are from white's point of view
|
||||
std::string Eval::trace(Position& pos, const Eval::NNUE::Networks& networks) {
|
||||
std::string Eval::trace(Position& pos, const Eval::NNUE::Network& network) {
|
||||
|
||||
if (pos.checkers())
|
||||
return "Final evaluation: none (in check)";
|
||||
|
||||
auto accumulators = std::make_unique<Eval::NNUE::AccumulatorStack>();
|
||||
auto caches = std::make_unique<Eval::NNUE::AccumulatorCaches>(networks);
|
||||
auto caches = std::make_unique<Eval::NNUE::AccumulatorCaches>(network);
|
||||
|
||||
std::stringstream ss;
|
||||
ss << std::showpoint << std::noshowpos << std::fixed << std::setprecision(2);
|
||||
ss << '\n' << NNUE::trace(pos, networks, *caches) << '\n';
|
||||
ss << '\n' << NNUE::trace(pos, network, *caches) << '\n';
|
||||
|
||||
ss << std::showpoint << std::showpos << std::fixed << std::setprecision(2) << std::setw(15);
|
||||
|
||||
auto [psqtSmall, positionalSmall] = networks.small.evaluate(pos, *accumulators, caches->small);
|
||||
Value vSmall = psqtSmall + positionalSmall;
|
||||
bool useBig = std::abs(vSmall) < 277;
|
||||
ss << "(Small net) NNUE evaluation " << vSmall << " (side to move, internal units)\n";
|
||||
vSmall = pos.side_to_move() == WHITE ? vSmall : -vSmall;
|
||||
ss << "(Small net) NNUE evaluation " << 0.01 * UCIEngine::to_cp(vSmall, pos)
|
||||
<< " (white side)\n";
|
||||
|
||||
auto [psqtBig, positionalBig] = networks.big.evaluate(pos, *accumulators, caches->big);
|
||||
Value vBig = psqtBig + positionalBig;
|
||||
ss << "(Big net) NNUE evaluation " << vBig << " (side to move, internal units)\n";
|
||||
vBig = pos.side_to_move() == WHITE ? vBig : -vBig;
|
||||
ss << "(Big net) NNUE evaluation " << 0.01 * UCIEngine::to_cp(vBig, pos)
|
||||
<< " (white side)\n";
|
||||
auto [psqt, positional] = network.evaluate(pos, *accumulators, *caches);
|
||||
Value v = psqt + positional;
|
||||
ss << "NNUE evaluation " << v << " (side to move, internal units)\n";
|
||||
v = pos.side_to_move() == WHITE ? v : -v;
|
||||
ss << "NNUE evaluation " << 0.01 * UCIEngine::to_cp(v, pos) << " (white side)\n";
|
||||
|
||||
ss << "SimpleEval " << simple_eval(pos)
|
||||
<< " (side to move, internal units)\n\n";
|
||||
|
||||
Value v = evaluate(networks, pos, *accumulators, *caches, VALUE_ZERO);
|
||||
v = pos.side_to_move() == WHITE ? v : -v;
|
||||
v = evaluate(network, pos, *accumulators, *caches, VALUE_ZERO);
|
||||
v = pos.side_to_move() == WHITE ? v : -v;
|
||||
|
||||
ss << "Final evaluation " << "(using "
|
||||
<< (use_smallnet(pos) && !useBig ? "small net) " : "big net) ");
|
||||
ss << "Final evaluation ";
|
||||
ss << 0.01 * UCIEngine::to_cp(v, pos) << " (white side)";
|
||||
ss << " [with scaled NNUE, ...]\n";
|
||||
|
||||
|
||||
Reference in New Issue
Block a user