Stockfish-PVS v2
Jak działa
Krok po kroku: (1) sufiks kontekstu jest haszowany kluczami Zobrista SplitMix64 (`zhash`) osobno dla 5-, 4- i 3-gramu. (2) Podczas rolloutu `ngram-map.cpp` odpytuje `StockfishDrafter::query()`/`probe5/4/3`, rozstrzygając wybory na horyzoncie 1-ply i disambiguując konfliktowe dopasowania sufiksów w kontekście. (3) Na każdym kolejnym przebiegu `observe()` porównuje zapamiętany draft (`last_draft`) z tokenami faktycznie zatwierdzonymi. (4) Token zaakceptowany (`actual == drafted`) zwiększa `wins` w `tt5/tt4/tt3` i podbija `history` formułą History Gravity (`h += bonus - h * |bonus| / 512`, +128). (5) Token odrzucony (`actual != drafted`) zapisuje zaproponowany token jako `refuted_move` (killer/refutation), promuje faktyczny token na `best_move` i karze wpis (-128 do -224). (6) Wydłużenie horyzontu do M=7 (batch = 8 tokenów) jest aktywowane tylko dla ścieżek „singularnych" — gdy `true_consensus_hits >= 2`, trafia łańcuch z codebooka makr, albo zachodzi singularne dopasowanie kaskady + lock w tablicy Zobrista — a każdy wydłużony token musi być potwierdzony przez RouteCrack lub tablicę Zobrista i nieodrzucony.
Rozwiązany problem
Na CPU obsługującym model Sparse MoE + hybrydowy Mamba-2 każdy zmarnowany token draftu kosztuje dodatkowo ok. 0,30×T1 (marginalny koszt routingu ekspertów MoE z DDR5), a każde odrzucenie wymusza kosztowny rollback rekurencyjnego stanu Mamba-2 (~18,4 MB). Statyczne predyktory wytrenowane na tym samym korpusie popełniają skorelowane błędy, więc bezwarunkowe wydłużanie horyzontu draftu (np. M=5→7) gwałtownie obniża precyzję. Stockfish-PVS v2 dostarcza ortogonalnego, pochodzącego z sesji sygnału weryfikacyjnego, który pozwala bezpiecznie przycinać drafty i wydłużać horyzont tylko wtedy, gdy ścieżka jest „singularna".
Komponenty
Trzy tablice po 4 096 wpisów × 16 B (64 KB każda, 192 KB łącznie w nagłówku rc_stockfish.h), indeksowane kluczami Zobrista dla sufiksów 5-, 4- i 3-gramowych. Każdy wpis (SFTTBucket) przechowuje key32, best_move, refuted_move, history, wins i total.
64-bitowe haszowanie sufiksu kontekstu funkcją SplitMix64; górne 32 bity służą jako key32, dolne jako indeks tablicy (maska TT_MASK). Bezkolizyjna, bezblokadowa identyfikacja stanu kontekstu.
Aktualizacja wyniku historii ruchu: h += bonus - h * |bonus| / 512, utrzymująca history w [-512, +512] bez nasycenia i karząca statyczne predykcje odrzucone wcześniej przez model docelowy.
Każdy odrzucony draft jest zapisywany jako refuted_move (ruch obalony), a faktyczny token zatwierdzony przez model docelowy promowany jako best_move. Pełni rolę natychmiastowego filtra refutacji na dopasowaniach w kontekście.
Inspirowane rozszerzeniami singularnymi w Stockfishu wydłużenie horyzontu draftu do M=7 (batch = 8 tokenów) wyłącznie dla ścieżek „singularnych" (true_consensus_hits >= 2, łańcuch makr, lub singularna kaskada + lock Zobrista), z wymogiem potwierdzenia każdego wydłużonego tokenu.
Zgodnie z ARCHITECTURE.md pełny projekt StockfishDrafter obejmuje Principal Variation Search z redukcjami późnych ruchów (LMR) nad kandydatami tokenów. Uwaga: publikowany nagłówek rc_stockfish.h implementuje lżejszy podzbiór (tablice Zobrista + History Gravity + killer/refutation); PVS/LMR są opisane w dokumentacji architektury.
Według ARCHITECTURE.md i katalogu technik (#93 Countermove Table prev2→replacement, #94 2-Ply Continuation History) pełny projekt obejmuje 1 MB tablicę kontrruchów i 256 KB tablicę Continuation History. Uwaga: te komponenty nie występują w publikowanym nagłówku rc_stockfish.h i są udokumentowane w opisie architektury.
Gdy główny kandydat kaskady (ent.pred[0]) jest obalony lub niepewny, drugorzędni kandydaci (pred[1..3]) są promowani, jeśli są jednocześnie zweryfikowanym best_move w tablicy Zobrista sesji i wspierani przez trie/PPM — dając sygnał ortogonalny do skorelowanych predyktorów statycznych.
Implementacja
Hiperparametry (konfigurowalne osie)
Maksymalna długość drafta w tokenach; M=7 oznacza batch = 8 tokenów. Flaga --spec-ngram-simple-size-m.
Liczba wpisów na pojedynczą tablicę transpozycji (TT_ENTRIES), potęga dwójki do maskowania indeksu.
Zakres wyniku historii i dzielnik grawitacji w formule h += bonus - h * |bonus| / 512.
Złożoność obliczeniowa
Złożoność czasowa: O(1). Złożoność przestrzenna: O(1).
Wymagania sprzętowe
Zaprojektowana pod bezdraftowe dekodowanie spekulatywne na CPU (Zen 5, AMD Ryzen 9 9955HX). Tablice (192 KB) są w pełni rezydentne w prywatnym L2 rdzenia i nie zanieczyszczają współdzielonego L3 ani stanów KV/Mamba-2.