diff --git a/KataGo/gtp_example.cfg b/KataGo/gtp_example.cfg deleted file mode 100644 index b43ab80..0000000 --- a/KataGo/gtp_example.cfg +++ /dev/null @@ -1,305 +0,0 @@ -# Example config for C++ (non-python) gtp bot - -# RUNNING ON AN ONLINE SERVER OR IN A REAL TOURNAMENT OR MATCH: -# If you plan to do so, you may want to read through the "Rules" section -# below carefully for proper handling of komi and handicap games and end-of-game cleanup -# and various other details. - -# NOTES ABOUT PERFORMANCE AND MEMORY USAGE: -# You will likely want to tune one or more the following: -# -# numSearchThreads: -# The number of CPU threads to use. If your GPU is powerful, it can actually be much higher than -# the number of cores on your processor because you will need many threads to feed large enough -# batches to make good use of the GPU. -# -# The "./katago benchmark" command can help you tune this parameter, as well as to test out the effect -# of changes to any of the other parameters below! -# -# nnMaxBatchSize: -# The maximum GPU batch size. Should often be at least as large as numSearchThreads. -# Larger won't do anything, but also won't hurt except use a little bit more GPU memory. -# Smaller can be fine if you have more than one GPU, since the GPUs will be sharing the work -# of servicing the CPU threads. -# -# cudaUseFP16 and cudaUseNHWC: -# These have a good chance of improving peformance at larger threads/batch sizes if -# you are using the CUDA implementation with an NVIDIA GPU with FP16 tensor cores. -# -# nnCacheSizePowerOfTwo: -# This controls the NN Cache size, which is the primary RAM/memory use. -# Increase this if you don't mind the memory use and want better performance for searches with -# tens of thousands of visits or more. Decrease this if you want to limit memory usage. -# -# If you're someone who is happy to do a bit of math - each neural net entry takes very -# approximately 1.5KB, except when using whole-board ownership/territory visualizations, each -# entry will take very approximately 3KB. The number of entries is (2 ** nnCacheSizePowerOfTwo), -# for example 2 ** 18 = 262144. -# -# OTHER NOTES: -# If you have more than one GPU, take a look at "OpenCL GPU settings" or "CUDA GPU settings" below. -# -# If using OpenCL, you will want to verify that KataGo is picking up the correct device! -# (e.g. some systems may have both an Intel CPU OpenCL and GPU OpenCL, if KataGo appears to pick -# the wrong one, you correct this by specifying "openclGpuToUse" below). -# -# You may also want to adjust "maxVisits", "ponderingEnabled", "resignThreshold", and possibly -# other parameters depending on your intended usage. - - -# Logs------------------------------------------------------------------------------------ - -# Where to output log? -logFile = gtp.log -# Logging options -logAllGTPCommunication = true -logSearchInfo = true -logToStderr = false - -# KataGo will display some info to stderr on GTP startup -# Uncomment this to suppress that and remain silent -# startupPrintMessageToStderr = false - -# Chat some stuff to stderr, for use in things like malkovich chat to OGS. -# ogsChatToStderr = true - -# Configure the maximum length of analysis printed out by lz-analyze and other places. -# Controls the number of moves after the first move in a variation. -# analysisPVLen = 9 - -# Report winrates for chat and analysis as (BLACK|WHITE|SIDETOMOVE). -# Default is SIDETOMOVE, which is what tools that use LZ probably also expect -# reportAnalysisWinratesAs = SIDETOMOVE - -# Default rules------------------------------------------------------------------------------------ -# See https://lightvector.github.io/KataGo/rules.html for a description of the rules. -# These rules are defaults and can be changed mid-run by several custom GTP commands. -# See https://github.com/lightvector/KataGo/blob/master/docs/GTP_Extensions.md for those commands. - -# koRule = SIMPLE # Simple ko rules (triple ko = no result) -koRule = POSITIONAL # Positional superko -# koRule = SITUATIONAL # Situational superko - -scoringRule = AREA # Area scoring -# scoringRule = TERRITORY # Territory scoring (uses a sort of special computer-friendly territory ruleset) - -taxRule = NONE # All surrounded empty points are scored -# taxRule = SEKI # Eyes in seki do NOT count as points -# taxRule = ALL # All groups are taxed up to 2 points for the two eyes needed to live - -multiStoneSuicideLegal = true #Is multiple-stone suicide legal? (Single-stone suicide is always illegal). - -hasButton = false # Set to true when area scoring to award 0.5 points to the first pass. - -whiteHandicapBonus = 0 # In handicap games, give white no compensation for black's handicap stones (Tromp-taylor, NZ, JP) -# whiteHandicapBonus = N-1 # In handicap games, give white N-1 points for black's handicap stones (AGA) -# whiteHandicapBonus = N # In handicap games, give white N points for black's handicap stones (Chinese) - -# Bot behavior--------------------------------------------------------------------------------------- - -# Resignation ------------- - -# Resignation occurs if for at least resignConsecTurns in a row, -# the winLossUtility (which is on a [-1,1] scale) is below resignThreshold. -allowResignation = true -resignThreshold = -0.98 -resignConsecTurns = 3 - -# Handicap ------------- - -# Assume that if black makes many moves in a row right at the start of the game, then the game is a handicap game. -# This is necessary on some servers and for some GUIs and also when initializing from many SGF files, which may -# set up a handicap games using repeated GTP "play" commands for black rather than GTP "place_free_handicap" commands. -# However, it may also lead to incorrect understanding of komi if whiteHandicapBonus is used and a server does NOT -# have such a practice. -# Defaults to true! Uncomment and set to false to disable this behavior. -# assumeMultipleStartingBlackMovesAreHandicap = true - -# Makes katago dynamically adjust to play more aggressively in handicap games based on the handicap and the current state of the game. -# Comment to disable this and make KataGo play the same always. -dynamicPlayoutDoublingAdvantageCapPerOppLead = 0.04 -# Instead of setting dynamicPlayoutDoublingAdvantageCapPerOppLead, you can uncomment these and set this to a value from -2.0 to 2.0 -# to set KataGo's aggression to a FIXED level. -# Negative makes KataGo behave as if it is much weaker than the opponent, preferring to play defensively -# Positive makes KataGo behave as if it is much stronger than the opponent, prefering to play aggressively or even overplay slightly. -# playoutDoublingAdvantage = 0.0 - -# Controls which side dynamicPlayoutDoublingAdvantageCapPerOppLead or playoutDoublingAdvantage applies to. -playoutDoublingAdvantagePla = WHITE - -# Passing and cleanup ------------- - -# Make the bot never assume that its pass will end the game, even if passing would end and "win" under Tromp-Taylor rules. -# Usually this is a good idea when using it for analysis or playing on servers where scoring may be implemented non-tromp-taylorly. -# Defaults to true! Uncomment and set to false to disable this. -# conservativePass = true - -# When playing under territory scoring, encourage the bot to fill dame before passing. -# This is NOT absolutely guaranteed to work, and possibly in some rare pathological situations will make the bot -# play a bad move, losing points. However, it also acts as a safeguard against things like a situation when the opponent must -# eventually make a protective move and lose 1 point, where the bot might otherwise assume that the score would be counted as such, -# yet without filling the dame to force the opponent to actually make the move. -# Defaults to true! Uncomment and set to false to disable this. -# fillDameBeforePass = true - -# When using territory scoring, self-play games continue beyond two passes with special cleanup -# rules that may be confusing for human players. This option prevents the special cleanup phases from being -# reachable when using the bot for GTP play. -# Defaults to true! Uncomment and set to false if you want KataGo to be able to enter special cleanup. -# For example, if you are testing it against itself, or against another bot that has precisely implemented the rules -# documented at https://lightvector.github.io/KataGo/rules.html -# preventCleanupPhase = true - - -# Search limits----------------------------------------------------------------------------------- - -# If provided, limit maximum number of root visits per search to this much. (With tree reuse, visits do count earlier search) -maxVisits = 500 -# If provided, limit maximum number of new playouts per search to this much. (With tree reuse, playouts do not count earlier search) -# maxPlayouts = 300 -# If provided, cap search time at this many seconds (search will still try to follow GTP time controls) -# maxTime = 60 - -# Ponder on the opponent's turn? -ponderingEnabled = false - -# Same limits but for ponder searches if pondering is enabled -# maxVisitsPondering = 1000 -# maxPlayoutsPondering = 1000 -# maxTimePondering = 60 - -# Number of seconds to buffer for lag for GTP time controls -lagBuffer = 1.0 - -# Number of threads to use in search -numSearchThreads = 1 - -# Play a little faster if the opponent is passing, for friendliness -searchFactorAfterOnePass = 0.50 -searchFactorAfterTwoPass = 0.25 -# Play a little faster if super-winning, for friendliess -searchFactorWhenWinning = 0.40 -searchFactorWhenWinningThreshold = 0.95 - -# GPU Settings------------------------------------------------------------------------------- - -# Maximum number of positions to send to GPU at once. Note that you will also need to increase numSearchThreads -# to make use of this, as every thread in KataGo is synchronous, so with 1 thread max batch will only be 1 anyways. -nnMaxBatchSize = 16 -# Cache up to 2 ** this many neural net evaluations in case of transpositions in the tree. -nnCacheSizePowerOfTwo = 19 -# Size of mutex pool for nnCache is 2 ** this -nnMutexPoolSizePowerOfTwo = 15 -# Randomize board orientation when running neural net evals? -nnRandomize = true -# If provided, force usage of a specific seed for nnRandomize instead of randomizing -# nnRandSeed = abcdefg - -# How many threads should there be to feed positions to the neural net? -# Server threads are indexed 0,1,...(n-1) for the purposes of the below GPU settings arguments -# that specify which threads should use which GPUs. -# NOTE: This parameter is probably ONLY useful if you have multiple GPUs, since each GPU will need a thread. -# If you're tuning single-GPU performance, use numSearchThreads instead. -numNNServerThreadsPerModel = 1 - -# CUDA GPU settings-------------------------------------- -# These only apply when using CUDA as the backend for inference. -# (For GTP, we only ever have one model, when playing matches, we might have more than one, see match_example.cfg) - -# Default behavior tries to guess the 'best' GPU or device -# You will want to uncomment and adjust one or more of these lines to take advantage of a multi-gpu machine -# cudaDeviceToUse = 0 #use device 0 for all server threads (numNNServerThreadsPerModel) unless otherwise specified per-model or per-thread-per-model -# cudaDeviceToUseModel0 = 3 #use device 3 for model 0 for all threads unless otherwise specified per-thread for this model -# cudaDeviceToUseModel1 = 2 #use device 2 for model 1 for all threads unless otherwise specified per-thread for this model -# cudaDeviceToUseModel0Thread0 = 3 #use device 3 for model 0, server thread 0 -# cudaDeviceToUseModel0Thread1 = 2 #use device 2 for model 0, server thread 1 - -# Uncomment these on NVIDIA devices with FP16 tensor cores for probably a speedup, at the cost of introducing some precision loss in the nn calculation. -# cudaUseFP16 = true -# cudaUseNHWC = true - -# OpenCL GPU settings-------------------------------------- -# These only apply when using OpenCL as the backend for inference. -# (For GTP, we only ever have one model, when playing matches, we might have more than one, see match_example.cfg) - -# Default behavior tries to guess the 'best' GPU or device -# You will want to uncomment and adjust one or more of these lines to take advantage of a multi-gpu machine -# openclDeviceToUse = 0 #use device 0 for all server threads (numNNServerThreadsPerModel) unless otherwise specified per-model or per-thread-per-model -# openclDeviceToUseModel0 = 3 #use device 3 for model 0 for all threads unless otherwise specified per-thread for this model -# openclDeviceToUseModel1 = 2 #use device 2 for model 1 for all threads unless otherwise specified per-thread for this model -# openclDeviceToUseModel0Thread0 = 3 #use device 3 for model 0, server thread 0 -# openclDeviceToUseModel0Thread1 = 2 #use device 2 for model 0, server thread 1 - -# Uncomment to tune OpenCL for every board size separately, rather than only the largest possible size -# openclReTunePerBoardSize = true - -# Root move selection and biases------------------------------------------------------------------------------ - -# If provided, force usage of a specific seed for various things in the search instead of randomizing -# searchRandSeed = hijklmn - -# Temperature for the early game, randomize between chosen moves with this temperature -chosenMoveTemperatureEarly = 0.5 -# Decay temperature for the early game by 0.5 every this many moves, scaled with board size. -chosenMoveTemperatureHalflife = 19 -# At the end of search after the early game, randomize between chosen moves with this temperature -chosenMoveTemperature = 0.10 -# Subtract this many visits from each move prior to applying chosenMoveTemperature -# (unless all moves have too few visits) to downweight unlikely moves -chosenMoveSubtract = 0 -# The same as chosenMoveSubtract but only prunes moves that fall below the threshold, does not affect moves above -chosenMovePrune = 1 - -# Use dirichlet noise for the root node policy? -rootNoiseEnabled = false -# Dirichlet noise alpha is set to this divided by number of legal moves. 10.83 produces an alpha of 0.03 on an empty 19x19 board. -rootDirichletNoiseTotalConcentration = 10.83 -# Proportion of root policy that is noise -rootDirichletNoiseWeight = 0.25 - -# Number of symmetries to sample (WITH replacement) and average at the root -rootNumSymmetriesToSample = 1 - -# Using LCB for move selection? -useLcbForSelection = true -# How many stdevs a move needs to be better than another for LCB selection -lcbStdevs = 5.0 -# Only use LCB override when a move has this proportion of visits as the top move -minVisitPropForLCB = 0.15 - -# Internal params------------------------------------------------------------------------------ - -# Scales the utility of winning/losing -winLossUtilityFactor = 1.0 -# Scales the utility for trying to maximize score -staticScoreUtilityFactor = 0.10 -dynamicScoreUtilityFactor = 0.30 -# Adjust dynamic score center this proportion of the way towards zero, capped at a reasonable amount. -dynamicScoreCenterZeroWeight = 0.20 -dynamicScoreCenterScale = 0.75 -# The utility of getting a "no result" due to triple ko or other long cycle in non-superko rulesets (-1 to 1) -noResultUtilityForWhite = 0.0 -# The number of wins that a draw counts as, for white. (0 to 1) -drawEquivalentWinsForWhite = 0.5 - -# Exploration constant for mcts -cpuctExploration = 0.9 -cpuctExplorationLog = 0.6 -# FPU reduction constant for mcts -fpuReductionMax = 0.2 -rootFpuReductionMax = 0.1 -# Use parent average value for fpu base point instead of point value net estimate -fpuUseParentAverage = true -# Amount to apply a downweighting of children with very bad values relative to good ones -valueWeightExponent = 0.5 -# Slight incentive for the bot to behave human-like with regard to passing at the end, filling the dame, -# not wasting time playing in its own territory, etc, and not play moves that are equivalent in terms of -# points but a bit more unfriendly to humans. -rootEndingBonusPoints = 0.5 -# Make the bot prune useless moves that are just prolonging the game to avoid losing yet -rootPruneUselessMoves = true - -# How big to make the mutex pool for search synchronization -mutexPoolSize = 8192 -# How many virtual losses to add when a thread descends through a node -numVirtualLossesPerThread = 1 diff --git a/KataGo/japanese_explore_score.cfg b/KataGo/japanese_explore_score.cfg deleted file mode 100644 index c6f5924..0000000 --- a/KataGo/japanese_explore_score.cfg +++ /dev/null @@ -1,305 +0,0 @@ -# Example config for C++ (non-python) gtp bot - -# RUNNING ON AN ONLINE SERVER OR IN A REAL TOURNAMENT OR MATCH: -# If you plan to do so, you may want to read through the "Rules" section -# below carefully for proper handling of komi and handicap games and end-of-game cleanup -# and various other details. - -# NOTES ABOUT PERFORMANCE AND MEMORY USAGE: -# You will likely want to tune one or more the following: -# -# numSearchThreads: -# The number of CPU threads to use. If your GPU is powerful, it can actually be much higher than -# the number of cores on your processor because you will need many threads to feed large enough -# batches to make good use of the GPU. -# -# The "./katago benchmark" command can help you tune this parameter, as well as to test out the effect -# of changes to any of the other parameters below! -# -# nnMaxBatchSize: -# The maximum GPU batch size. Should often be at least as large as numSearchThreads. -# Larger won't do anything, but also won't hurt except use a little bit more GPU memory. -# Smaller can be fine if you have more than one GPU, since the GPUs will be sharing the work -# of servicing the CPU threads. -# -# cudaUseFP16 and cudaUseNHWC: -# These have a good chance of improving peformance at larger threads/batch sizes if -# you are using the CUDA implementation with an NVIDIA GPU with FP16 tensor cores. -# -# nnCacheSizePowerOfTwo: -# This controls the NN Cache size, which is the primary RAM/memory use. -# Increase this if you don't mind the memory use and want better performance for searches with -# tens of thousands of visits or more. Decrease this if you want to limit memory usage. -# -# If you're someone who is happy to do a bit of math - each neural net entry takes very -# approximately 1.5KB, except when using whole-board ownership/territory visualizations, each -# entry will take very approximately 3KB. The number of entries is (2 ** nnCacheSizePowerOfTwo), -# for example 2 ** 18 = 262144. -# -# OTHER NOTES: -# If you have more than one GPU, take a look at "OpenCL GPU settings" or "CUDA GPU settings" below. -# -# If using OpenCL, you will want to verify that KataGo is picking up the correct device! -# (e.g. some systems may have both an Intel CPU OpenCL and GPU OpenCL, if KataGo appears to pick -# the wrong one, you correct this by specifying "openclGpuToUse" below). -# -# You may also want to adjust "maxVisits", "ponderingEnabled", "resignThreshold", and possibly -# other parameters depending on your intended usage. - - -# Logs------------------------------------------------------------------------------------ - -# Where to output log? -logFile = gtp.log -# Logging options -logAllGTPCommunication = true -logSearchInfo = true -logToStderr = false - -# KataGo will display some info to stderr on GTP startup -# Uncomment this to suppress that and remain silent -# startupPrintMessageToStderr = false - -# Chat some stuff to stderr, for use in things like malkovich chat to OGS. -# ogsChatToStderr = true - -# Configure the maximum length of analysis printed out by lz-analyze and other places. -# Controls the number of moves after the first move in a variation. -# analysisPVLen = 9 - -# Report winrates for chat and analysis as (BLACK|WHITE|SIDETOMOVE). -# Default is SIDETOMOVE, which is what tools that use LZ probably also expect -# reportAnalysisWinratesAs = SIDETOMOVE - -# Default rules------------------------------------------------------------------------------------ -# See https://lightvector.github.io/KataGo/rules.html for a description of the rules. -# These rules are defaults and can be changed mid-run by several custom GTP commands. -# See https://github.com/lightvector/KataGo/blob/master/docs/GTP_Extensions.md for those commands. - -koRule = SIMPLE # Simple ko rules (triple ko = no result) -# koRule = POSITIONAL # Positional superko -# koRule = SITUATIONAL # Situational superko - -# scoringRule = AREA # Area scoring -scoringRule = TERRITORY # Territory scoring (uses a sort of special computer-friendly territory ruleset) - -# taxRule = NONE # All surrounded empty points are scored -taxRule = SEKI # Eyes in seki do NOT count as points -# taxRule = ALL # All groups are taxed up to 2 points for the two eyes needed to live - -multiStoneSuicideLegal = false #Is multiple-stone suicide legal? (Single-stone suicide is always illegal). - -hasButton = false # Set to true when area scoring to award 0.5 points to the first pass. - -whiteHandicapBonus = 0 # In handicap games, give white no compensation for black's handicap stones (Tromp-taylor, NZ, JP) -# whiteHandicapBonus = N-1 # In handicap games, give white N-1 points for black's handicap stones (AGA) -# whiteHandicapBonus = N # In handicap games, give white N points for black's handicap stones (Chinese) - -# Bot behavior--------------------------------------------------------------------------------------- - -# Resignation ------------- - -# Resignation occurs if for at least resignConsecTurns in a row, -# the winLossUtility (which is on a [-1,1] scale) is below resignThreshold. -allowResignation = true -resignThreshold = -0.999 -resignConsecTurns = 3 - -# Handicap ------------- - -# Assume that if black makes many moves in a row right at the start of the game, then the game is a handicap game. -# This is necessary on some servers and for some GUIs and also when initializing from many SGF files, which may -# set up a handicap games using repeated GTP "play" commands for black rather than GTP "place_free_handicap" commands. -# However, it may also lead to incorrect understanding of komi if whiteHandicapBonus is used and a server does NOT -# have such a practice. -# Defaults to true! Uncomment and set to false to disable this behavior. -# assumeMultipleStartingBlackMovesAreHandicap = true - -# Makes katago dynamically adjust to play more aggressively in handicap games based on the handicap and the current state of the game. -# Comment to disable this and make KataGo play the same always. -dynamicPlayoutDoublingAdvantageCapPerOppLead = 0.04 -# Instead of setting dynamicPlayoutDoublingAdvantageCapPerOppLead, you can uncomment these and set this to a value from -2.0 to 2.0 -# to set KataGo's aggression to a FIXED level. -# Negative makes KataGo behave as if it is much weaker than the opponent, preferring to play defensively -# Positive makes KataGo behave as if it is much stronger than the opponent, prefering to play aggressively or even overplay slightly. -# playoutDoublingAdvantage = 0.0 - -# Controls which side dynamicPlayoutDoublingAdvantageCapPerOppLead or playoutDoublingAdvantage applies to. -playoutDoublingAdvantagePla = WHITE - -# Passing and cleanup ------------- - -# Make the bot never assume that its pass will end the game, even if passing would end and "win" under Tromp-Taylor rules. -# Usually this is a good idea when using it for analysis or playing on servers where scoring may be implemented non-tromp-taylorly. -# Defaults to true! Uncomment and set to false to disable this. -conservativePass = true - -# When playing under territory scoring, encourage the bot to fill dame before passing. -# This is NOT absolutely guaranteed to work, and possibly in some rare pathological situations will make the bot -# play a bad move, losing points. However, it also acts as a safeguard against things like a situation when the opponent must -# eventually make a protective move and lose 1 point, where the bot might otherwise assume that the score would be counted as such, -# yet without filling the dame to force the opponent to actually make the move. -# Defaults to true! Uncomment and set to false to disable this. -# fillDameBeforePass = true - -# When using territory scoring, self-play games continue beyond two passes with special cleanup -# rules that may be confusing for human players. This option prevents the special cleanup phases from being -# reachable when using the bot for GTP play. -# Defaults to true! Uncomment and set to false if you want KataGo to be able to enter special cleanup. -# For example, if you are testing it against itself, or against another bot that has precisely implemented the rules -# documented at https://lightvector.github.io/KataGo/rules.html -# preventCleanupPhase = true - - -# Search limits----------------------------------------------------------------------------------- - -# If provided, limit maximum number of root visits per search to this much. (With tree reuse, visits do count earlier search) -maxVisits = 2500 -# If provided, limit maximum number of new playouts per search to this much. (With tree reuse, playouts do not count earlier search) -# maxPlayouts = 300 -# If provided, cap search time at this many seconds (search will still try to follow GTP time controls) -# maxTime = 60 - -# Ponder on the opponent's turn? -ponderingEnabled = false - -# Same limits but for ponder searches if pondering is enabled -# maxVisitsPondering = 1000 -# maxPlayoutsPondering = 1000 -# maxTimePondering = 60 - -# Number of seconds to buffer for lag for GTP time controls -lagBuffer = 1.0 - -# Number of threads to use in search -numSearchThreads = 4 - -# Play a little faster if the opponent is passing, for friendliness -searchFactorAfterOnePass = 0.50 -searchFactorAfterTwoPass = 0.25 -# Play a little faster if super-winning, for friendliess -searchFactorWhenWinning = 0.40 -searchFactorWhenWinningThreshold = 0.95 - -# GPU Settings------------------------------------------------------------------------------- - -# Maximum number of positions to send to GPU at once. Note that you will also need to increase numSearchThreads -# to make use of this, as every thread in KataGo is synchronous, so with 1 thread max batch will only be 1 anyways. -nnMaxBatchSize = 16 -# Cache up to 2 ** this many neural net evaluations in case of transpositions in the tree. -nnCacheSizePowerOfTwo = 20 -# Size of mutex pool for nnCache is 2 ** this -nnMutexPoolSizePowerOfTwo = 16 -# Randomize board orientation when running neural net evals? -nnRandomize = true -# If provided, force usage of a specific seed for nnRandomize instead of randomizing -# nnRandSeed = abcdefg - -# How many threads should there be to feed positions to the neural net? -# Server threads are indexed 0,1,...(n-1) for the purposes of the below GPU settings arguments -# that specify which threads should use which GPUs. -# NOTE: This parameter is probably ONLY useful if you have multiple GPUs, since each GPU will need a thread. -# If you're tuning single-GPU performance, use numSearchThreads instead. -numNNServerThreadsPerModel = 1 - -# CUDA GPU settings-------------------------------------- -# These only apply when using CUDA as the backend for inference. -# (For GTP, we only ever have one model, when playing matches, we might have more than one, see match_example.cfg) - -# Default behavior tries to guess the 'best' GPU or device -# You will want to uncomment and adjust one or more of these lines to take advantage of a multi-gpu machine -# cudaDeviceToUse = 0 #use device 0 for all server threads (numNNServerThreadsPerModel) unless otherwise specified per-model or per-thread-per-model -# cudaDeviceToUseModel0 = 3 #use device 3 for model 0 for all threads unless otherwise specified per-thread for this model -# cudaDeviceToUseModel1 = 2 #use device 2 for model 1 for all threads unless otherwise specified per-thread for this model -# cudaDeviceToUseModel0Thread0 = 3 #use device 3 for model 0, server thread 0 -# cudaDeviceToUseModel0Thread1 = 2 #use device 2 for model 0, server thread 1 - -# Uncomment these on NVIDIA devices with FP16 tensor cores for probably a speedup, at the cost of introducing some precision loss in the nn calculation. -# cudaUseFP16 = true -# cudaUseNHWC = true - -# OpenCL GPU settings-------------------------------------- -# These only apply when using OpenCL as the backend for inference. -# (For GTP, we only ever have one model, when playing matches, we might have more than one, see match_example.cfg) - -# Default behavior tries to guess the 'best' GPU or device -# You will want to uncomment and adjust one or more of these lines to take advantage of a multi-gpu machine -# openclDeviceToUse = 0 #use device 0 for all server threads (numNNServerThreadsPerModel) unless otherwise specified per-model or per-thread-per-model -# openclDeviceToUseModel0 = 3 #use device 3 for model 0 for all threads unless otherwise specified per-thread for this model -# openclDeviceToUseModel1 = 2 #use device 2 for model 1 for all threads unless otherwise specified per-thread for this model -# openclDeviceToUseModel0Thread0 = 3 #use device 3 for model 0, server thread 0 -# openclDeviceToUseModel0Thread1 = 2 #use device 2 for model 0, server thread 1 - -# Uncomment to tune OpenCL for every board size separately, rather than only the largest possible size -# openclReTunePerBoardSize = true - -# Root move selection and biases------------------------------------------------------------------------------ - -# If provided, force usage of a specific seed for various things in the search instead of randomizing -# searchRandSeed = hijklmn - -# Temperature for the early game, randomize between chosen moves with this temperature -chosenMoveTemperatureEarly = 0.5 -# Decay temperature for the early game by 0.5 every this many moves, scaled with board size. -chosenMoveTemperatureHalflife = 19 -# At the end of search after the early game, randomize between chosen moves with this temperature -chosenMoveTemperature = 0.10 -# Subtract this many visits from each move prior to applying chosenMoveTemperature -# (unless all moves have too few visits) to downweight unlikely moves -chosenMoveSubtract = 0 -# The same as chosenMoveSubtract but only prunes moves that fall below the threshold, does not affect moves above -chosenMovePrune = 1 - -# Use dirichlet noise for the root node policy? -rootNoiseEnabled = false -# Dirichlet noise alpha is set to this divided by number of legal moves. 10.83 produces an alpha of 0.03 on an empty 19x19 board. -rootDirichletNoiseTotalConcentration = 10.83 -# Proportion of root policy that is noise -rootDirichletNoiseWeight = 0.25 - -# Number of symmetries to sample (WITH replacement) and average at the root -rootNumSymmetriesToSample = 1 - -# Using LCB for move selection? -useLcbForSelection = true -# How many stdevs a move needs to be better than another for LCB selection -lcbStdevs = 5.0 -# Only use LCB override when a move has this proportion of visits as the top move -minVisitPropForLCB = 0.15 - -# Internal params------------------------------------------------------------------------------ - -# Scales the utility of winning/losing -winLossUtilityFactor = 0.4 -# Scales the utility for trying to maximize score -staticScoreUtilityFactor = 0.2 -dynamicScoreUtilityFactor = 0.4 -# Adjust dynamic score center this proportion of the way towards zero, capped at a reasonable amount. -dynamicScoreCenterZeroWeight = 0.20 -dynamicScoreCenterScale = 0.75 -# The utility of getting a "no result" due to triple ko or other long cycle in non-superko rulesets (-1 to 1) -noResultUtilityForWhite = 0.0 -# The number of wins that a draw counts as, for white. (0 to 1) -drawEquivalentWinsForWhite = 0.5 - -# Exploration constant for mcts -cpuctExploration = 2.0 -cpuctExplorationLog = 0.8 -# FPU reduction constant for mcts -fpuReductionMax = 0.2 -rootFpuReductionMax = 0.1 -# Use parent average value for fpu base point instead of point value net estimate -fpuUseParentAverage = true -# Amount to apply a downweighting of children with very bad values relative to good ones -valueWeightExponent = 0.5 -# Slight incentive for the bot to behave human-like with regard to passing at the end, filling the dame, -# not wasting time playing in its own territory, etc, and not play moves that are equivalent in terms of -# points but a bit more unfriendly to humans. -rootEndingBonusPoints = 0.5 -# Make the bot prune useless moves that are just prolonging the game to avoid losing yet -rootPruneUselessMoves = true - -# How big to make the mutex pool for search synchronization -mutexPoolSize = 8192 -# How many virtual losses to add when a thread descends through a node -numVirtualLossesPerThread = 1 diff --git a/KataGo/katago b/KataGo/katago deleted file mode 100755 index dd0783b..0000000 Binary files a/KataGo/katago and /dev/null differ diff --git a/README.md b/README.md index 7a2d9b5..2295828 100644 --- a/README.md +++ b/README.md @@ -4,36 +4,38 @@ Manual Installation ------------ * pip install kivy -* change the `engine.command` field in `config.json` to your kata installation (for example, to `path/to/lizzie/katago/katago.exe`) -* start the app by running `python katrain.py` (or `python3` if needed) +* On linux, change the `engine.command` field in `config.json` to your kata v1.3+ installation. +* start the app by running `python katrain.py` Options ------- -* Top row options +* Check box options * Eval: show the coloured dots on the moves for this player. * Hints: show suggested moves for this player. * Undo: automatically undo poor moves for this player and make them try again. + * AI: let the AI control this player. Check both for self-play. + * Show owner: show expected control of territory. * Lock AI: disallow extra undos, changing hints options, changing auto move, or AI move. - * Show owner: show expected control of territory. + * Fast: use a lower number of max visits for evaluation/AI move. + * Balance score: Deliberately make sub-optimal moves as the AI in an attempt to balance the score towawrds a slight win. * Temperature/Evaluation/Score: Not that these fields can be hidden by clicking on the text. * Temperature is the point difference between passing and the best move. * Evaluation is where on this scale the last move was, from 0% (equivalent to a pass) to 100% (best move). This can be < 0% in case of suicidal moves, or >100% when Kata did not consider the move before, or further analysis shows it to be better than the best one considered. - * Score: Expected score. + * Score: How far one player is ahead. Play ---- * Play against the AI - * Turn on auto move. + * Turn on AI for the chosen player. * Choose whether to turn on `balance score` to make the AI play slack moves. * Choose whether to turn on `undo` for your colour to be prompted to re-try poor moves. * Choose whether or not to turn on `fast` to make the AI play faster but read less deeply (NB: with balance score, faster AI can be a stronger opponent, as there are fewer mediocre moves considered). * Possibly lock AI to prevent yourself from peeking at hints, etc. * Possibly hide score or temperature. - * Possibly hide evaluation for the AI player. - * Play by playing a move or clicking AI move if you want white. + * If you chose AI to play black, click AI move for the first move. * Engine-assisted play * Turn off auto move. @@ -43,7 +45,7 @@ Play * Play with a friend with instant feedback and/or undos for both, or see how many stones stronger you are with one undo. (But please play unranked and be honest to your opponent on what you're doing) * Analysis - * Copy the SGF into the text box + * Copy the SGF into the text box. Note that branches are not supported and will lead to strange results. * Choose whether or not to turn on `fast` to make the AI weaker but analyze faster. * Click `Analyze` @@ -61,9 +63,7 @@ The `trainer` block has the following options to tweak: * `balance_play_min_eval`: when needing to balance score, the AI will pick a move which is at least this good. * `balance_play_min_visits`: never pick a move with fewer playouts than this. * `undo_eval_threshold`, `undo_point_threshold`: prompt player to undo if move is worse than this in terms of points AND evaluation. -* `undo_outdated_eval_threshold`: don't prompt undo if last move's evaluation is >= `undo_eval_threshold` and the NEW evaluation is greater than this. (this decreases frustration when hints are on, or when kata over-estimates the best move). * `num_undo_prompts`: automatically undo bad moves when `undo` is on at most this many times. -* `show_ai_options`: show which moves the AI considered. The cfg file has additional configuration for kata. In particular, it changes the default to being more exploratory and score-based (and therefore nicer as an opponent, but weaker as analysis tool). diff --git a/board.py b/board.py index 8dd23ae..ea9a6c3 100644 --- a/board.py +++ b/board.py @@ -17,6 +17,8 @@ class Move: self.analysis = None self.pass_analysis = None self.ownership = None + self.x_comment = "" + self.auto_undid = False self.move_number = 0 def __repr__(self): @@ -61,11 +63,13 @@ class Move: score = score or self.score return f"{'B' if score >= 0 else 'W'}+{abs(score):.1f}" - @property - def comment(self,sgf=False): + def comment(self,sgf=False, eval=False, hints=False): if not self.parent: # root return "" - text = f"Move {self.move_number}: {self.bw_player()} @ {self.gtp()} {'(AI Move)' if self.robot else ''}\n" + text = f"Move {self.move_number}: {self.bw_player()} {self.gtp()} {'(AI Move)' if self.robot else ''}\n" + text += self.x_comment + text += "".join(f"Auto undid move {m.gtp()} ({m.evaluation*100:.1f}% efficient)\n" for m in self.children if m.auto_undid) + if self.analysis_ready: score, _, temperature = self.temperature_stats if sgf: @@ -73,13 +77,14 @@ class Move: text += f"Temperature: {temperature:.1f}\n" if self.parent and self.parent.analysis_ready: prev_best_score, prev_worst_score, prev_temperature = self.parent.temperature_stats - text += f"Top move was {self.format_score(prev_best_score)} @ {self.parent.analysis[0]['move']}\n" - text += f"Pass score was {self.format_score(prev_worst_score)}\n" + if sgf or hints: + text += f"Top move was {self.parent.analysis[0]['move']} ({self.format_score(prev_best_score)})\n" + text += f"Pass score was {self.format_score(prev_worst_score)}\n" if prev_temperature < 0.5: text += f"Previous temperature ({prev_temperature}) too low for evaluation\n" else: - if eval: - text += f"Evaluation: {100*self.evaluation:.1f}%\n" + if sgf or eval: + text += f"Evaluation: {100*self.evaluation:.1f}% efficient\n" outdated_evaluation = self.outdated_evaluation if outdated_evaluation and outdated_evaluation > self.evaluation and outdated_evaluation > self.evaluation + 0.01: text += f"(Was considered last move as: {100 * outdated_evaluation :.1f}%)\n" @@ -94,7 +99,7 @@ class Move: @property def evaluation_info(self): if self.parent and self.parent.analysis_ready and self.analysis_ready: - return self.evaluation,self.parent.temperature_stats[2] + return self.evaluation, self.parent.temperature_stats[2] else: return None,None @@ -264,7 +269,7 @@ class Board: def moves(self) -> list: # flat list of moves to current moves = [] p = self.current_move - while p != self.root: + while p is not self.root: # NB == is wrong here moves.append(p) p = p.parent return moves[::-1] diff --git a/config.json b/config.json index e283a60..067b76c 100644 --- a/config.json +++ b/config.json @@ -3,12 +3,11 @@ "pass_visits": 200, "pass_visits_fast": 50, "visits": 3500, - "visits_fast": 1500, - "nopass_visits": 10 + "visits_fast": 1500 }, "board": { "size": 19, - "komi": 7.5 + "komi": 6.5 }, "ui": { "size_min": 1, @@ -35,7 +34,6 @@ "balance_play_min_eval": 0.875, "balance_play_min_visits": 20, "undo_eval_threshold": 0.875, - "undo_outdated_eval_threshold": 0.8, "undo_point_threshold": 1, "num_undo_prompts": 1 }, diff --git a/controller.py b/controller.py index f493fb0..7beb723 100644 --- a/controller.py +++ b/controller.py @@ -26,7 +26,6 @@ class EngineControls(GridLayout): [analysis_settings["pass_visits"], analysis_settings["visits"]], [analysis_settings["pass_visits_fast"], analysis_settings["visits_fast"]], ] - self.min_nopass_visits = analysis_settings["nopass_visits"] self.train_settings = Config.get("trainer") self.debug = Config.get("debug")["level"] self.board_size = Config.get("board")["size"] @@ -78,13 +77,11 @@ class EngineControls(GridLayout): print(str(e)) self.info.text = f"Illegal move: {str(e)}" return - print("PLAYED", move, self.board.stones) self._request_analysis(mr) return mr # engine action functions def _do_play(self, *args): - print("CURRENT PLAYER", self.board.current_player) move = Move(player=self.board.current_player, coords=args[0]) self.play(move) # mr.waiting_for_analysis @@ -93,66 +90,34 @@ class EngineControls(GridLayout): def update_evaluation(self): current_move = self.board.current_move if self.eval.active(current_move.player): - self.info.text = current_move.comment + self.info.text = current_move.comment(eval=self.eval.active(current_move.player), hints=self.hints.active(current_move.player)) self.evaluation.text = '' - if current_move.analysis_ready: + if current_move.analysis_ready and self.eval.active(current_move.player): self.score.text = current_move.format_score().replace("-", "\u2013") self.temperature.text = f"{current_move.temperature_stats[2]:.1f}" if current_move.parent and current_move.parent.analysis_ready: self.evaluation.text = f"{100 * current_move.evaluation:.1f}%" - # when to trigger auto undo? -# self.undo.disabled = True # undo while waiting for this does weird things -# undid = False -# self.info.text = "" -# if self.auto_undo.active(1 - self.board.current_player): -# undid = self._auto_undo(move) -# if self.ai_auto.active and not undid: -# self._do_aimove(move, True) -# self.undo.disabled = False - - def _auto_undo(self, move): - ts = self.train_settings - self.info.text = "Evaluating..." - if ( - move.evaluation - and move.evaluation < ts["undo_eval_threshold"] - and move.points_lost >= ts["undo_point_threshold"] - and ts["num_undo_prompts"] > 0 - ): - if move.outdated_evaluation: - outdated_points_lost = (1 - move.outdated_evaluation) * move.points_lost / (1 - move.evaluation) - # so if the move was not that far off (>undo_outdated_eval_threshold) and according to last move's analysis it was fine, don't undo. - if ( - move.outdated_evaluation - and ( - move.outdated_evaluation >= ts["undo_eval_threshold"] - or outdated_points_lost < ts["undo_point_threshold"] - ) - and ( - move.evaluation > ts["undo_outdated_eval_threshold"] - or outdated_points_lost < ts["undo_point_threshold"] - ) - ): - self.info.text += f"\nBut according to my previous evaluation it was {move.outdated_evaluation*100:.1f}% effective and lost {outdated_points_lost:.1f} point(s), so let's continue anyway.\n" - else: - if len(self.board.current_move.parent.children) <= ts["num_undo_prompts"]: - self.info.text += f"\nLet's try again.\n" + if current_move.analysis_ready and current_move.parent and current_move.parent.analysis_ready and not current_move.children: + # handle automatic undo + if self.auto_undo.active(current_move.player) and not self.ai_auto.active(current_move.player) and not current_move.auto_undid: + ts = self.train_settings + # TODO: is this overly generous wrt low visit outdated evaluations? + eval = max(current_move.evaluation, current_move.outdated_evaluation or 0) + points_lost = (current_move.parent or current_move).temperature_stats[2] * (1 - eval) + if eval < ts["undo_eval_threshold"] and points_lost >= ts["undo_point_threshold"]: + current_move.auto_undid = True self.board.undo() - return True - else: - evaled_moves = sorted( - [m for m in self.board.current_move.parent.children if m.evaluation], - key=lambda m: -m.evaluation, - ) - if evaled_moves and evaled_moves[0].coords != move.coords: - self.board.undo() - self.board.play(evaled_moves[0]) - summary = "\n".join(f"{m.gtp()}: {100*m.evaluation:.1f}% effective" for m in evaled_moves) - self.info.text += f"\nYour moves:\n{summary}.\nLet's continue with {evaled_moves[0].gtp()}.\n" - return False + if len(current_move.parent.children) >= ts["num_undo_prompts"] + 1: + best_move = sorted([m for m in current_move.parent.children], key=lambda m: -(m.evaluation_info[0] or 0) )[0] + best_move.x_comment = f"Automatically played as best option after max. {ts['num_undo_prompts']} undo(s).\n" + self.board.play(best_move) + self.update_evaluation() + # ai player doesn't technically need parent ready, but don't want to override waiting for undo + elif self.ai_auto.active(1 - current_move.player) and not current_move.children: + self._do_aimove() - def _do_aimove(self, auto=False): + def _do_aimove(self): ts = self.train_settings while not self.board.current_move.analysis_ready: self.info.text = "Thinking..." @@ -204,9 +169,9 @@ class EngineControls(GridLayout): sgfmoves = re.findall(r"([BW])\[([a-z]{2})\]", sgf) moves = [Move(player=Move.PLAYERS.index(p.upper()), sgfcoords=(mv, self.board_size)) for p, mv in sgfmoves] for move in moves: - self.board.play(move) + self.play(move) while not all(m.analysis for m in moves): - time.sleep(0.01) + time.sleep(0.05) self.info.text = f"{sum([1 if m.analysis else 0 for m in moves])}/{len(moves)} analyzed" # analysis thread @@ -215,7 +180,8 @@ class EngineControls(GridLayout): while self.outstanding_analysis_queries: self._send_analysis_query(self.outstanding_analysis_queries.pop(0)) line = self.kata.stdout.readline() - print("KATA ANALYSIS RECEIVED:", line[:50]) + if self.debug: + print("KATA ANALYSIS RECEIVED:", line[:50]) self.board.store_analysis(json.loads(line)) self.update_evaluation() self.redraw(include_board=False) @@ -242,14 +208,14 @@ class EngineControls(GridLayout): "includeOwnership": True, "maxVisits": self.visits[fast][1], } - print("query", query) + if self.debug: + print("query", query) self._send_analysis_query(query) query.update( {"id": f"PASS_{move_id}", "maxVisits": self.visits[fast][0], "includeOwnership": False} - ) # TODO: merge? + ) query["moves"] += [[move.bw_player(next_move=True), "pass"]] query["analyzeTurns"][0] += 1 - print("pass-query", query) self._send_analysis_query(query) diff --git a/katrain.kv b/katrain.kv index d168454..4fbbda7 100644 --- a/katrain.kv +++ b/katrain.kv @@ -168,11 +168,11 @@ id: auto_undo text: 'undo' on_active: root.parent.board.redraw() - CheckBoxHint: - size_hint: 0.2, 0.5 - text: 'lock\nai' - id: ai_lock - on_active: self.checkbox.disabled = hints.black.disabled = hints.white.disabled = ai_move.disabled = auto_undo.black.disabled = auto_undo.white.disabled = ai_auto.checkbox.disabled = True + BWCheckBoxHint: + size_hint: 0.166, 0.5 + text: 'ai' + id: ai_auto + default_active: False CheckBoxHint: size_hint: 0.2, 0.5 id: ownership @@ -189,19 +189,19 @@ on_press: root.action("aimove") CheckBoxHint: size_hint: 0.166, 0.5 - text: 'auto\nmove' - id: ai_auto - default_active: False + text: 'fast' + id: ai_fast + default_active: True CheckBoxHint: size_hint: 0.166, 0.5 text: 'balance\nscore' id: ai_balance default_active: False CheckBoxHint: - size_hint: 0.166, 0.5 - text: 'fast' - id: ai_fast - default_active: True + size_hint: 0.2, 0.5 + text: 'lock\nai' + id: ai_lock + on_active: self.checkbox.disabled = hints.black.disabled = hints.white.disabled = ai_move.disabled = auto_undo.black.disabled = auto_undo.white.disabled = ai_auto.checkbox.disabled = True GridLayout: cols: 2 rows: 1 diff --git a/katrain.py b/katrain.py index e2a2da7..bfe1475 100644 --- a/katrain.py +++ b/katrain.py @@ -47,6 +47,12 @@ class BadukPanWidget(Widget): def on_touch_up(self, touch): if self.ghost_stone: self.engine.action("play", self.ghost_stone) + else: + xd, xp = self._find_closest(touch.x) + yd, yp = self._find_closest(touch.y) + stones_here = [m for m in self.engine.board.stones if m.coords == (xp,yp)] + if stones_here and max(yd, xd) < self.grid_size / 2: # load old comment + self.engine.info.text = stones_here[-1].comment(sgf=True) self.ghost_stone = None self.redraw() # remove ghost