本地(Linux、Android)使用皮卡魚引擎

皮卡魚是目前我知道的中國象棋開源引擎中最強的,因為我還不知道其它的開源引擎,如果有知道的請留言告知。

皮卡魚開源地址:

https://github.com/official-pikafish/Pikafish/

皮卡魚網頁版:

https://xiangqiai.com/

那麼,既然已經有了皮卡魚網頁版,為什麼我還是希望在本地跑皮卡魚引擎?

原因是,我想不到皮卡魚的引擎文件才幾百K那麼小,就幾百K的文件就能成為目前最強的中國象棋AI?這引起了我很大的好奇心。當然後來我知道了它依賴一個五十多M的nnue文件,即便如此,它的體積仍然是非常的小。

還有一個原因是,我熱衷於收集單機軟體,不需要聯網也能執行。雖然我主要還是會去用皮卡魚網頁版,但是在本地留存一份單機版,對我而言是必須的。

2026-03-19補充:後來發現,本地版比網頁版要快很多,本地版只用7到12秒,就能算到網頁版一分鐘才得出的結果。

在linux,只需要加上chmod +x pikafish-sse41-popcnt,再把nnue放到同一個目錄中,就能跑起來了。

Android也很簡單,安裝好termux後,把android版執行檔和nnue文件,複製到其根目錄的一個文件夾中,添加執行權限,就能開始玩了。

我主要使用的指令

> ucinewgame
> isready
readyok
> position fen r2akabr1/9/1cn1b1nc1/p3p1pRp/2p6/6P2/P1P1P3P/NC2C1N2/9/R1BAKAB2 b
> go movetime 12000
> d
> position fen r2akabr1/9/1cn1b1nc1/p3p1pRp/2p6/6P2/P1P1P3P/NC2C1N2/9/R1BAKAB2 b moves a6a5
> go movetime 3600
> d

輸入 uci 並回車,讓引擎進入 UCI 模式。

輸入以下指令調整哈希表大小(例如設置為 4GB):
setoption name Hash value 4096

更改最佳路徑數量(例如改為 3 條):
setoption name MultiPV value 3

UCI指令說明

expand

PikaCat edited this page on Aug 22, 2024 · 5 revisions

The Universal Chess Interface (UCI) is a standard text-based protocol used to communicate with a xiangqi engine and is the recommended way to do so for typical graphical user interfaces (GUI) or chess tools. Pikafish implements the majority of its options.

Developers can see the default values for the UCI options available in Pikafish by typing ./pikafish uci in a terminal, but most users should typically use a xiangqi GUI to interact with Pikafish.

Standard commands

quit

Quit the program as soon as possible.

uci

Tell the engine to use the UCI (universal chess interface).
This will be sent once, by a GUI, as a first command after the program boots to tell the engine to switch to UCI mode.
After receiving the uci command the engine will identify itself with the id command and send the option commands to tell the GUI which engine settings the engine supports.
After that, the engine will send uciok to acknowledge the UCI mode.
If no uciok is sent within a certain time period, the engine task will be killed by the GUI.

Example

setoption

Usage: setoption name <id> [value <x>]

This is sent to the engine when the user wants to change the internal parameters of the engine. For the button type no value is needed.
One string will be sent for each parameter and this will only be sent when the engine is waiting.

Examples:

> setoption name Threads value 6
> setoption name EvalFile value pikafish.nnue
> setoption name UCI_ShowWDL value true
> setoption name Clear Hash

List of options:

  • Debug Log File type string default
    Write all communication to and from the engine into a text file.

  • NumaPolicy type string default auto Bind threads to ensure execution on a specific NUMA node. Improves performance on systems with multiple CPUs or CPUs with multiple NUMA domains. The following values can be used:

    • system - gathers NUMA node information from the system (including affinities preset by the user or the GUI), for each thread binds it to a single NUMA node
    • none - assumes there is 1 NUMA node, never binds threads
    • auto - this is the default value, automatically selects system or none depending on the number of set threads and available NUMA nodes. Will only select system when the number of threads reaches a system-dependent threshold.
    • hardware - gathers NUMA node information for the underlying hardware (disregards and overrides affinities preset by the user or the GUI), for each thread binds it to a single NUMA node
    • [[custom]] - specify precisely the available CPUs per numa domain. ':' separates numa nodes; ',' separates cpu indices; supports "first-last" range syntax for cpu indices, for example 0-15,32-47:16-31,48-63
  • Threads type spin default 1 min 1 max 1024
    The number of CPU threads used for searching a position. For best performance, set this equal to the number of CPU cores available.

  • Hash type spin default 16 min 1 max 33554432
    The size of the hash table in MB. It is recommended to set Hash after setting Threads.

  • Clear Hash type button
    Clear the hash table.

  • Ponder type check default false
    Let Pikafish ponder its next move while the opponent is thinking.

  • MultiPV type spin default 1 min 1 max 500
    Output the N best lines (principal variations, PVs) when searching. Leave at 1 for the best performance.

  • Move Overhead type spin default 10 min 0 max 5000
    Assume a time delay of x ms due to network and GUI overheads. This is useful to avoid losses on time in those cases.

  • nodestime type spin default 0 min 0 max 10000
    Tells the engine to use nodes searched instead of wall time to account for elapsed time. Useful for engine testing. When this option is set, the engine is only limited by the total amount of nodes searched per game; this limit is calculated once per game. The initial time control values in milliseconds (time time and increment per move inc) are used as input values to calculate the total number of nodes per game (totalnodes). The increment per move inc is used as if it was just one move per game. The formula is totalnodes = (time + inc * 1) * nodestime. Suppose you specified nodestime = 600, and the time control per game is 300 seconds plus 3 seconds increment per move ("300+3s"), or 300000 milliseconds plus 3000 milliseconds increment per move. In that case, the maximum total number of nodes searched per game by the engine is totalnodes = (300000 + 3000 * 1) * 1000 = 181800000 (one hundred eighty-one million, eight hundred thousand) nodes, regardless of how much wall time it will actually take.

  • UCI_ShowWDL type check default false
    If enabled, show approximate WDL statistics as part of the engine output. These WDL numbers model expected game outcomes for a given evaluation and game ply for engine self-play at fishtest LTC conditions (60+0.6s per game).

  • EvalFile type string default pikafish.nnue
    The name of the file of the NNUE evaluation parameters. Depending on the GUI the filename might have to include the full path to the folder/directory that contains the file. Other locations, such as the directory that contains the binary and the working directory, are also searched.

position

Usage: position [fen <fenstring> | startpos ] moves <move1> .... <movei>

Set up the position described in fenstring.

Note

If this position is from a different game than the last position sent to the engine, the GUI should have sent a ucinewgame in between.

Examples:

> position startpos
> position fen rnbakabnr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/1C5C1/9/RNBAKABNR w - - 0 1
> position fen rnbakabnr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/1C5C1/9/RNBAKABNR w - - 0 1 moves h2e2 h9g7 h0g2 g6g5

ucinewgame

This is sent to the engine when the next search (started with position and go) will be from a different game. This can be a new game the engine should play or a new game it should analyze but also the next position from a test suite with positions only.
If the GUI hasn't sent a ucinewgame before the first position command, the engine won't expect any further ucinewgame commands as the GUI is probably not supporting the ucinewgame command.
So the engine will not rely on this command even though all new GUIs should support it.
As the engine's reaction to ucinewgame can take some time the GUI should always send isready after ucinewgame to wait for the engine to finish its operation. The engine will respond with readyok.

This clears the hash and any information which was collected during the previous search.

Example

isready

This is used to synchronize the engine with the GUI.
When the GUI has sent a command or multiple commands that can take some time to complete, this command can be used to wait for the engine to be ready again or to ping the engine to find out if it is still alive.
e.g. this should be sent after setting the path to the tablebases as this can take some time.
This command is also required once, before the engine is asked to do any searching, to wait for the engine to finish initializing.
This command will always be answered with readyok and can be sent also when the engine is calculating in which case the engine will also immediately answer with readyok without stopping the search.

Example:

> isready
readyok

go

Start calculating on the current position set up with the position command.
There are a number of parameters that can follow this command and all will be sent in the same string.
If no parameter is sent, then go depth 245 will be executed.

Example: go infinite
Example: go depth
Example: go mate
Example: MultiPV
Example: UCI_ShowWDL

Parameters:

  • searchmoves <move1> .... <movei>
    Restrict search to these moves only.
    Example: After position startpos and go infinite searchmoves h2e2 h0g2 the engine will only search the two moves h2e2 and h0g2 in the initial position.

  • ponder
    Start searching in pondering mode. It won't exit the search in ponder mode, even if it's mate!
    This means that the last move sent in in the position string is the ponder move.
    The engine can do what it wants to do, but after a ponderhit command it will execute the suggested move to ponder on.
    This means that the ponder move sent by the GUI can be interpreted as a recommendation about which move to ponder.
    However, if the engine decides to ponder on a different move, it won't display any mainlines as they are likely to be misinterpreted by the GUI because the GUI expects the engine to ponder on the suggested move.

  • wtime <x>
    White has x ms left on the clock.

  • btime <x>
    Black has x ms left on the clock.

  • winc <x>
    White increment per move in ms if x > 0.

  • binc <x>
    Black increment per move in ms if x > 0.

  • movestogo <x>
    There are x moves to the next time control
    Note: this will only be sent if x > 0, if you don't get this and get the wtime and btime it's sudden death.

  • depth <x>
    Search x plies only.

  • nodes <x>
    Search x nodes only.

  • mate <x>
    Search for a mate in x moves.

  • movetime <x>
    Search exactly x ms.

  • infinite
    Search until the stop command. Stockfish won't exit the search without being told so in this mode!

  • perft <x>
    A debugging function to walk the move generation tree of strictly legal moves to count all the leaf nodes of a certain depth.

stop

Stop calculating as soon as possible

Example

ponderhit

The user has played the expected move.
This will be sent if the engine was told to ponder on the same move the user has played.
The engine will continue searching but switch from pondering to normal search.

Example

Non-standard commands

bench

This runs a standard search benchmark on a pre-selected assortment of positions. It prints the total combined nodes searched, as well as time taken. This command serves two primary purposes:

  • it can be used as a basic nodes-per-second speed benchmark

  • the total number of nodes searched can be used as a "signature" or "fingerprint" of the exact search algorithm version in the binary

The main utility of the nodecount signature is to ensure that, when testing possible new patches on Fishtest, the author and workers are working on the exact same code. It also can be used to verify which version or release you have locally. Each functional commit in the Pikafish commit history includes a standardized nodecount signature. (For example, the nodecount signature of Pikafish 2023-03-05 is 1146720.)

There are several parameters which can be used to tweak exactly what sort of benchmark is run:

Usage: bench [ttSize] [threads] [limit] [fenFile] [limitType]

The standardized nodecount signature of a version is obtained using all default parameters.

Note: All parameters are optional.

Parameter Type Default Values Meaning
ttSize number 16 Hash value
threads number 1 Number of threads
limit number 13 The limit of limitType
fenFile string default default, current or [file path] The positions used for the bench
limitType string depth depth, perft, nodes, movetime or eval. The type of limit
Example

Note

  • String parameters are case-sensitive. In case of invalid values of string parameters, the error is not given, and the behavior is undefined (the program does not fall back to a default value).
  • The [file path] may contain one or more positions, each on a separate line.

d

Display the current position, with ASCII art and FEN.

Example

eval

Display the static evaluation of the current position.

Example

compiler

Give information about the compiler and environment used for building a binary.

export_net [filename]

Exports the currently loaded network to a file. If the currently loaded network is the embedded network and the filename is not specified then the network is saved to the file matching the name of the embedded network, as defined in evaluate.h. If the currently loaded network is not the embedded network (some net set through the UCI setoption) then the filename parameter is required and the network is saved into that file.

flip

Flips the side to move.

中文翻譯

UCI & Commands (UCI 與指令)

通用象棋介面 (Universal Chess Interface, UCI) 是一種標準的文本協定,用於與象棋引擎進行通訊。對於一般的圖形使用者介面 (GUI) 或象棋工具,這是建議的使用方式。Pikafish 實作了大部分的 UCI 選項。

開發者可以在終端機輸入 ./pikafish uci 來查看 Pikafish 中可用 UCI 選項的預設值,但大多數使用者通常應使用象棋 GUI 來與 Pikafish 互動。

Standard commands (標準指令)

quit (退出)

儘快退出程式。

uci (進入 UCI 模式)

告訴引擎使用 UCI 協定。 這通常由 GUI 在程式啟動後發送的第一條指令,用來告訴引擎切換到 UCI 模式。 收到 uci 指令後,引擎會透過 id 指令識別身份,並發送 option 指令告知 GUI 引擎支援哪些設定。 之後,引擎會發送 uciok 以確認已進入 UCI 模式。 如果在一定時間內沒有發送 uciok,GUI 將會終止引擎程序。

setoption (設定選項)

用法:setoption name <id> [value <x>]

當使用者想要更改引擎的內部參數時,會將此指令發送到引擎。對於「按鈕 (button)」類型的選項,不需要數值 (value)。 每個參數都會發送一個字串,且這只會在引擎處於等待狀態時發送。

範例:

setoption name Threads value 6 setoption name EvalFile value pikafish.nnue setoption name UCI_ShowWDL value true setoption name Clear Hash

選項列表:

  • Debug Log File (類型:string,預設:無) 將與引擎之間的所有通訊記錄到文字檔中。

  • NumaPolicy (類型:string,預設:auto) 綁定執行緒以確保在特定的 NUMA 節點上執行。這能提升多 CPU 系統或具有多個 NUMA 網域的 CPU 效能。可以使用以下值:

    • system:從系統獲取 NUMA 節點資訊(包括使用者或 GUI 預設的親和性),並將每個執行緒綁定到單個 NUMA 節點。

    • none:假設只有 1 個 NUMA 節點,不進行執行緒綁定。

    • auto:預設值,根據設定的執行緒數和可用的 NUMA 節點自動選擇 systemnone。僅在執行緒數達到系統特定閾值時才會選擇 system

    • hardware:獲取底層硬體的 NUMA 節點資訊(無視並覆蓋使用者或 GUI 預設的親和性),並將每個執行緒綁定到單個 NUMA 節點。

    • [[custom]]:精確指定每個 NUMA 網域可用的 CPU。: 用於分隔節點;, 用於分隔 CPU 索引;支援 first-last 範圍語法,例如 0-15,32-47:16-31,48-63

  • Threads (類型:spin,預設:1,最小:1,最大:1024) 搜尋局面時使用的 CPU 執行緒數量。為了獲得最佳效能,請將此值設為可用的 CPU 核心數。

  • Hash (類型:spin,預設:16,最小:1,最大:33554432) Hash 表(雜湊表)的大小,單位為 MB。建議在設定 Threads 之後再設定 Hash

  • Clear Hash (類型:button) 清除 Hash 表。

  • Ponder (類型:check,預設:false) 讓 Pikafish 在對手思考時進行預判思考 (Ponder)。

  • MultiPV (類型:spin,預設:1,最小:1,最大:500) 搜尋時輸出前 N 條最佳路徑 (PV)。為了獲得最佳效能,請保持為 1。

  • Move Overhead (類型:spin,預設:10,最小:0,最大:5000) 假設由於網路和 GUI 造成的延遲為 毫秒。這有助於避免在這些情況下超時判負。

  • nodestime (類型:spin,預設:0,最小:0,最大:10000) 告知引擎使用搜尋的節點數而非實際牆鐘時間 (wall time) 來計算經過的時間。這對引擎測試很有用。設定此選項後,引擎僅受限於每局遊戲搜尋的總節點數;該限制每局計算一次。 初始時間控制值(以毫秒為單位的 time 時間和每步增量 inc)作為計算總節點數 (totalnodes) 的輸入。計算公式為: 假設你指定 nodestime = 600,且每局的時間控制為 300 秒加 3 秒增量(即 300,000 毫秒 + 3,000 毫秒)。在這種情況下,無論實際花費多少牆鐘時間,引擎每局搜尋的最大總節點數為 個節點。

  • UCI_ShowWDL (類型:check,預設:false) 若啟用,則在引擎輸出中顯示大約的 WDL (勝/平/負) 統計數據。這些 WDL 數據是根據給定的評估值和步數,模擬引擎在 fishtest LTC 條件下(每局 60+0.6s)自我對弈的預期結果。

  • EvalFile (類型:string,預設:pikafish.nnue) NNUE 評估參數檔案的名稱。取決於 GUI,檔案名稱可能需要包含指向該檔案資料夾的完整路徑。引擎也會搜尋包含執行檔的目錄和當前工作目錄。

position (局面)

用法:position [fen <fenstring> | startpos ] moves <move1> .... <movei>

設定 fenstring 中描述的局面。

注意: 如果此局面來自與上次發送給引擎的不同對局,GUI 應在中間發送 ucinewgame

範例:

position startpos position fen rnbakabnr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/1C5C1/9/RNBAKABNR w - - 0 1 position fen rnbakabnr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/1C5C1/9/RNBAKABNR w - - 0 1 moves h2e2 h9g7 h0g2 g6g5

ucinewgame (開始新對局)

當下一次搜尋(使用 positiongo 啟動)來自不同的對局時,會將此指令發送給引擎。這可以是一個新對局,也可以是從測試集中取出的一個新局面。 如果 GUI 在第一個 position 指令前沒有發送 ucinewgame,引擎將不再預期任何進一步的 ucinewgame 指令,因為該 GUI 可能不支援此功能。 因此,儘管所有新的 GUI 都應支援此指令,引擎不會完全依賴它。 由於引擎對 ucinewgame 的反應可能需要一些時間,GUI 應在 ucinewgame 之後發送 isready 以等待引擎完成操作。引擎會以 readyok 回應。

這會清除 Hash 表以及之前搜尋過程中收集的所有資訊。

isready (準備就緒)

這用於將引擎與 GUI 同步。 當 GUI 發送了一個或多個可能需要時間完成的指令時,可以使用此指令等待引擎再次進入就緒狀態,或者用於 Ping 引擎以查看其是否仍有反應。 例如:在設定桌庫路徑後應發送此指令,因為這可能需要一些時間。 此外,在要求引擎進行任何搜尋之前,也必須發送一次此指令,以等待引擎完成初始化。 此指令一律會以 readyok 回答,即使引擎正在計算時發送也可以,在這種情況下,引擎會立即回答 readyok 而不會停止搜尋。

範例:

isready readyok

go (開始搜尋)

開始對使用 position 指令設定的當前局面進行計算。 此指令後面可以跟隨許多參數,所有參數都會在同一個字串中發送。 如果沒有發送參數,則會執行 go depth 245

範例:

  • go infinite

  • go depth

  • go mate

  • MultiPV

  • UCI_ShowWDL

參數:

  • searchmoves .... 僅限於搜尋這些走法。

  • ponder 在預判思考模式下開始搜尋。在此模式下,即使出現將死 (mate) 也不會結束搜尋!這意味著 position 字串中發送的最後一步是預判步。引擎可以隨意運作,但在收到 ponderhit 指令後,它將執行建議的預判步。

  • wtime :白方時鐘剩餘 毫秒。

  • btime :黑方時鐘剩餘 毫秒。

  • winc :如果 ,白方每步增量為 毫秒。

  • binc :如果 ,黑方每步增量為 毫秒。

  • movestogo :距離下一個時控還有 步。注意:僅在 時發送,若未收到此參數且收到了時鐘時間,則為「突然死亡」模式。

  • depth :僅搜尋 層(半回合)。

  • nodes :僅搜尋 個節點。

  • mate :搜尋 步內的將死。

  • movetime :精確搜尋 毫秒。

  • infinite:持續搜尋直到收到 stop 指令。在此模式下,不被告知就不會結束搜尋。

  • perft :一個偵錯功能,走過嚴格合規的移動生成樹,以統計特定深度的所有葉節點。

stop (停止)

儘快停止計算。

ponderhit (預判命中)

使用者走出了預期的棋步。 如果告知引擎預判的棋步與使用者實際走的棋步相同,就會發送此指令。引擎將繼續搜尋,但從預判模式切換為正常搜尋。


Non-standard commands (非標準指令)

bench (基準測試)

在預先選擇的一組局面(測評集)上執行標準搜尋基準測試。它會印出搜尋的總合併節點數以及花費的時間。此指令有兩個主要用途:

  1. 作為基礎的「每秒節點數」(NPS) 速度基準。

  2. 搜尋的總節點數可作為二進制檔案中確切搜尋算法版本的「特徵碼」或「指紋」。

節點數特徵碼的主要效用是確保在 Fishtest 上測試新的補丁時,作者和測試者的代碼完全一致。它也可用於驗證本地擁有的版本。Pikafish 提交歷史中的每個功能性提交都包含一個標準化的節點數特徵碼。(例如,Pikafish 2023-03-05 的節點數特徵碼是 1146720。)

可以使用多個參數來微調基準測試的執行方式: 用法:bench [ttSize] [threads] [limit] [fenFile] [limitType]

注意: 所有參數都是可選的。使用所有預設參數可獲得版本的標準化節點數特徵碼。

參數 類型 預設值 取值範圍 意義
ttSize 數字 16 Hash 值
threads 數字 1 執行緒數
limit 數字 13 limitType 的限制值
fenFile 字串 default default, current 或 [檔案路徑] 用於測試的局面
limitType 字串 depth depth, perft, nodes, movetime 或 eval 限制類型

 

注意:

  • 字串參數區分大小寫。若字串參數值無效,不會給出錯誤,且行為未定義。

  • [檔案路徑] 可以包含一個或多個局面,每行一個。

d (顯示)

顯示當前局面,包含 ASCII 圖形和 FEN 字串。

eval (評估)

顯示當前局面的靜態評估。

compiler (編譯器)

提供有關用於構建二進制檔的編譯器和環境資訊。

export_net [filename] (匯出網路)

將目前加載的網路匯出到檔案。如果目前加載的是嵌入式網路且未指定檔名,則網路將儲存到與 evaluate.h 中定義的嵌入式網路名稱匹配的檔案中。如果加載的不是嵌入式網路(透過 UCI setoption 設定的某個網路),則需要提供檔名參數。

flip (翻轉)

翻轉走子方。

Leave a Comment