Skip to content

Commit

Permalink
Optimize settings / smaller boardsize kata / fix error message / teac…
Browse files Browse the repository at this point in the history
…her improvements

Optimize settings / smaller boardsize kata / fix error message / teacher improvements
  • Loading branch information
sanderland authored May 7, 2020
2 parents 0458d74 + 0972cba commit 0827bd4
Show file tree
Hide file tree
Showing 30 changed files with 185 additions and 113 deletions.
Binary file modified KataGo/OpenCL.dll
Binary file not shown.
6 changes: 3 additions & 3 deletions KataGo/analysis_config.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,14 @@ maxVisits = 500
# number of visits, and thread contention will reduce efficiency, so cross-position parallelization is preferable
# to numSearchThreads, but numSearchThreads is preferable if you want to reduce latency, and have individual
# searches complete faster by doing fewer of them at a time.
numSearchThreads = 2
numSearchThreads = 6

# GPU Settings-------------------------------------------------------------------------------

# Maximum number of positions to send to GPU at once.
nnMaxBatchSize = 128
nnMaxBatchSize = 64
# Cache up to 2 ** this many neural net evaluations in case of transpositions in the tree.
nnCacheSizePowerOfTwo = 23
nnCacheSizePowerOfTwo = 21
# Size of mutex pool for nnCache is 2 ** this
nnMutexPoolSizePowerOfTwo = 17
# Randomize board orientation when running neural net evals?
Expand Down
Binary file added KataGo/boost_filesystem-vc142-mt-x64-1_72.dll
Binary file not shown.
Binary file added KataGo/katago
Binary file not shown.
Binary file removed KataGo/katago-bs
Binary file not shown.
Binary file removed KataGo/katago-bs.exe
Binary file not shown.
Binary file added KataGo/katago-bs52.exe
Binary file not shown.
Binary file modified KataGo/katago.exe
Binary file not shown.
Binary file removed KataGo/libz.dll
Binary file not shown.
Binary file removed KataGo/libzip.dll
Binary file not shown.
Binary file added KataGo/vcruntime140_1.dll
Binary file not shown.
Binary file added KataGo/zlib1.dll
Binary file not shown.
28 changes: 18 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,25 @@ but has since grown to include a wide range of features, including:
* Execute the command `pip install kivy_deps.glew kivy_deps.sdl2 kivy_deps.gstreamer kivy`
* Start the app by running `python katrain.py` in the directory where you downloaded the scripts. Note that the program can be slow to initialize the first time, due to kata's gpu tuning.

### Installation for Linux/Mac users
### Installation for Linux users

* This assumed you have a working Python 3.6/3.7 installation as a default. If your default is python 2, use pip3/python3. Kivy currently does not have a release for Python 3.8.
* Git clone or download the repository.
* `pip install kivy`
* A binary for KataGo is included, but if you have compiled your own, point the 'engine/katago' setting to the relevant KataGo v1.3.5+ binary.
* Run the command `pip install kivy` in the terminal.
* A binary for KataGo is included, but if you have compiled your own, point the 'engine/katago' setting to the relevant KataGo v1.3.5-bs29+ binary.
* Start the app by running `python katrain.py`. Note that the program can be slow to initialize the first time, due to KataGo's GPU tuning.


### Installation for MacOS users

* Git clone or download the repository.
* Run the command `pip install kivy` in the terminal.
* Follow instructions [here](https://github.com/lightvector/KataGo) to compile KataGo yourself -- note that the version required is currently too new for the 'brew' method.
* Start the app by running `python katrain.py`, change the path of the 'katago' setting to the path where you compiled it, and click 'Apply and Save'.

## Manual

### Play

Under the 'play' tab you can select who is playing black and white.
* Human is simple play with potential feedback, but without auto-undo.
* Teach will give you instant feedback, and auto-undo bad moves to give you a second chance.
Expand All @@ -72,6 +80,7 @@ In short, if you are a weaker player you should mostly on large dots that are re
while stronger players can pay more attention to smaller mistakes.

#### AIs

Available AIs, with strength indicating an estimate for the default settings, are:

* **[9p+]** **Default** is full KataGo, above professional level.
Expand Down Expand Up @@ -107,7 +116,6 @@ Keyboard shortcuts are shown with **[key]**.
* **[s]**: Equalize: Re-evaluate all currently shown next moves with the same visits as the current top move. Useful to increase confidence in the suggestions with high uncertainty.
* **[d]**: Sweep: Evaluate all possible next moves. This can take a bit of time even though 'fast_visits' is used, but the result is nothing if not colourful.


## Keyboard and mouse shortcuts

In addition to shortcuts mentioned above, there are:
Expand All @@ -128,7 +136,6 @@ In addition to shortcuts mentioned above, there are:
* **[Ctrl-n]**: Load SGF from clipboard
* **[space]**: Pass


## Configuration

Configuration is stored in `config.json`. Most settings are now available to edit in the program, but some advanced options are not.
Expand Down Expand Up @@ -165,11 +172,12 @@ If you ever need to reset to the original settings, simply re-download the `conf
* The first startup of KataGo can be slow due to GPU tuning, after that it should be much faster.
* The program is running too slowly. How can I speed it up?
* Adjust the number of visits or maximum time allowed in the settings.
* The engine crashes with out of memory errors
* Try setting `nnMaxBatchSize` in `KataGo/analysis_config.cfg` to something lower.
* KataGo crashes with out of memory errors, how can I prevent this?
* Try using a lower number for `nnMaxBatchSize` in `KataGo/analysis_config.cfg`, and avoid using versions compiled with large board sizes.

## Contributing

* Feedback and pull requests are both very welcome.
* Feedback and pull requests are both very welcome. I would also be happy to host translations of this manual into languages where English fluency is typically lower.
* For suggestions and planned improvements, see the 'issues' tab on github.
* You can also contact me on discord (Sander#3278) or [reddit](http://reddit.com/u/sanderbaduk) to give feedback, or simply show your appreciation.
* You can also contact me on discord (Sander#3278), [KakaoTalk](https://open.kakao.com/o/gTsMJCac) or [Reddit](http://reddit.com/u/sanderbaduk) to give feedback, or simply show your appreciation.
* Some people have also asked me how to donate. Something go-related such as a book or teaching time is highly appreciated.
4 changes: 2 additions & 2 deletions bots/ai2gtp.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ def malkovich_analysis(cn):
logger.log(f"dscore {dscore} = {cn.analysis['root']['scoreLead']} {cn.parent.analysis['root']['scoreLead']} at {move}...", OUTPUT_ERROR)
if abs(dscore) > REPORT_SCORE_THRESHOLD and (cn.player == "B" and dscore < 0 or cn.player == "W" and dscore > 0): # relevant mistakes
favpl = "B" if dscore > 0 else "W"
msg = f"MALKOVICH:{cn.player} {cn.single_move.gtp()} caused a significant score change ({favpl} gained {abs(dscore):.1f} points)"
msg = f"MALKOVICH:{cn.player} {cn.move.gtp()} caused a significant score change ({favpl} gained {abs(dscore):.1f} points)"
if cn.ai_thoughts:
msg += f" -> Win Rate {cn.format_win_rate()} Score {cn.format_score()} AI Thoughts: {cn.ai_thoughts}"
else:
Expand Down Expand Up @@ -139,7 +139,7 @@ def malkovich_analysis(cn):
if not pol:
pol = ["??"]
print(f"DISCUSSION:OK, since you passed {MAX_PASS} times after the {bx+by}th move, I will pass as well [policy {pol[-1]:.3%}].", file=sys.stderr)
move = game.play(Move(None, player=game.next_player)).single_move
move = game.play(Move(None, player=game.next_player)).move
else:
move, node = ai_move(game, ai_strategy, ai_settings)
if node is None:
Expand Down
2 changes: 1 addition & 1 deletion bots/engine_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"max_visits": 50,
"max_time": 1.0,
"enable_ownership": False,
"threads": 8,
"threads": 32,
}


Expand Down
2 changes: 1 addition & 1 deletion bots/selfplay.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class AI:
"max_time": 300.0,
"_enable_ownership": False,
}
NUM_THREADS = 8
NUM_THREADS = 32
IGNORE_SETTINGS_IN_TAG = {"threads", "_enable_ownership", "katago"} # katago for switching from/to bs version
ENGINES = []
LOCK = threading.Lock()
Expand Down
4 changes: 3 additions & 1 deletion bots/settings.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
bot_strategy_names = {
"dev": "P:Noise",
"dev-beta": "P:Weighted",
"strong": "Policy",
"influence": "P:Influence",
"territory": "P:Territory",
Expand All @@ -11,7 +12,8 @@


greetings = {
"dev": "Experimental!",
"dev": "Policy+Dirichlet noise.",
"dev-beta": "Play a policy-weighted move.",
"strong": "Play top policy move.",
"influence": "Play an influential style.",
"territory": "Play a territorial style.",
Expand Down
7 changes: 5 additions & 2 deletions bots/start_bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@
else:
GTP2OGS = "node ../stable-gtp2ogs"
BOT_SETTINGS = f" --maxconnectedgames {MAXGAMES} --maxhandicapunranked 25 --maxhandicapranked 1 --boardsizesranked 19 --boardsizesunranked all --komisranked automatic,5.5,6.5,7.5 --komisunranked all"

if "beta" in bot:
BOT_SETTINGS += " --beta"
else:
BOT_SETTINGS += "" # --rankedonly"

username = f"katrain-{bot}"

Expand All @@ -40,6 +43,6 @@
GREETING += f" Settings: {settings_dump}."
BYEMSG = "Thank you for playing. If you have any feedback, please message my admin! Play with these bots at any time by downloading KaTrain at github.com/sanderland/katrain"

cmd = f'{GTP2OGS} --debug --apikey {APIKEY} --username {username} --greeting "{GREETING}" --farewell "{BYEMSG}" {BOT_SETTINGS} --farewellscore --aichat --noclock --nopause --speeds blitz,live --persist --minrank 25k -- python bots/ai2gtp.py {bot} {port}'
cmd = f'{GTP2OGS} --debug --apikey {APIKEY} --rejectnewfile ~/shutdown_bots --username {username} --greeting "{GREETING}" --farewell "{BYEMSG}" {BOT_SETTINGS} --farewellscore --aichat --noclock --nopause --speeds blitz,live --persist --minrank 25k -- python bots/ai2gtp.py {bot} {port}'
print(f"starting bot {username} using server port {port} --> {cmd}")
os.system(cmd)
9 changes: 5 additions & 4 deletions config.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"engine": {
"katago": "KataGo/katago-bs",
"katago": "KataGo/katago",
"model": "KataGo/models/b15-1.3.2.txt.gz",
"config": "KataGo/analysis_config.cfg",
"threads": 8,
"threads": 16,
"max_visits": 500,
"fast_visits": 50,
"max_time": 3.0,
Expand Down Expand Up @@ -43,7 +43,8 @@
0
],
"eval_off_show_last": 3,
"eval_show_ai": true
"eval_show_ai": true,
"lock_ai": false
},
"ai": {
"Default": {
Expand Down Expand Up @@ -98,7 +99,7 @@
"_help_right": "Lower `stddev` makes it prefer closer moves."
},
"P:Tenuki": {
"pick_override": 0.9,
"pick_override": 0.85,
"stddev": 7.5,
"pick_n": 5,
"pick_frac": 0.7,
Expand Down
4 changes: 2 additions & 2 deletions core/ai.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,11 +99,11 @@ def ai_move(game: Game, ai_mode: str, ai_settings: Dict) -> Tuple[Move, GameNode
ai_thoughts += f"Generated weights for {ai_mode} according to weight factor {ai_settings['line_weight']} and distance from {thr_line+1}th line. "
elif "local" in ai_mode or "tenuki" in ai_mode:
var = ai_settings["stddev"] ** 2
if not cn.single_move or cn.single_move.coords is None:
if not cn.move or cn.move.coords is None:
weighted_coords = [(1, 1, *top_policy_move.coords)] # if "pick" in ai_mode -> even
ai_thoughts += f"No previous non-pass move, faking weights to play top policy move. "
else:
mx, my = cn.single_move.coords
mx, my = cn.move.coords
weighted_coords = [
(policy_grid[y][x], math.exp(-0.5 * ((x - mx) ** 2 + (y - my) ** 2) / var), x, y) for x in range(size[0]) for y in range(size[1]) if policy_grid[y][x] > 0
]
Expand Down
4 changes: 2 additions & 2 deletions core/engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ def start(self):
try:
self.katrain.log(f"Starting KataGo with {self.command}", OUTPUT_DEBUG)
self.katago_process = subprocess.Popen(self.command, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
except FileNotFoundError:
except FileNotFoundError as e:
self.katrain.log(
f"Starting kata with command '{self.command}' failed. If you are on Mac or Linux, please change the settings or configuration file (config.json) to point to the correct KataGo executable.",
f"Starting kata with command '{self.command}' failed with error {e}. Please make sure the 'katago' value under 'engine' in settings points to the correct KataGo executable.",
OUTPUT_ERROR,
)

Expand Down
19 changes: 11 additions & 8 deletions core/game.py
Original file line number Diff line number Diff line change
Expand Up @@ -265,12 +265,15 @@ def analyze_extra(self, mode):
elif mode == "sweep":
board_size_x, board_size_y = self.board_size
policy_grid = var_to_grid(self.current_node.policy, size=(board_size_x, board_size_y)) if self.current_node.policy else None
analyze_moves = [
Move(coords=(x, y), player=cn.next_player)
for x in range(board_size_x)
for y in range(board_size_y)
if (policy_grid is None and (x, y) not in stones) or policy_grid[y][x] >= 0
]
analyze_moves = sorted(
[
Move(coords=(x, y), player=cn.next_player)
for x in range(board_size_x)
for y in range(board_size_y)
if (policy_grid is None and (x, y) not in stones) or policy_grid[y][x] >= 0
],
key=lambda mv: -policy_grid[mv.coords[1]][mv.coords[0]],
)
visits = engine.config["fast_visits"]
self.katrain.controls.set_status(f"Refining analysis of entire board to {visits} visits")
priority = -1_000_000_000
Expand All @@ -283,7 +286,7 @@ def analyze_extra(self, mode):
cn.analyze(engine, priority, visits=visits, refine_move=move, time_limit=False) # explicitly requested so take as long as you need

def analyze_undo(self, node, train_config):
move = node.single_move
move = node.move
if node != self.current_node or node.auto_undo is not None or not node.analysis_ready or not move:
return
points_lost = node.points_lost
Expand All @@ -306,5 +309,5 @@ def analyze_undo(self, node, train_config):
node.auto_undo = undo
if undo:
self.undo(1)
self.katrain.controls.set_status(f"Undid move {move.gtp()} as it lost {points_lost:.1f} points{xmsg}")
self.katrain.controls.set_status(f"Undid move {move.gtp()} as it lost {points_lost:.1f} points{xmsg}. Hover over the move to see expected refutation.")
self.katrain.update_state()
16 changes: 11 additions & 5 deletions core/game_node.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,14 @@ def format_win_rate(self, win_rate=None):
if win_rate is not None:
return f"{'B' if win_rate > 0.5 else 'W'} {max(win_rate,1-win_rate):.1%}"

def comment(self, sgf=False, teach=False, hints=False):
single_move = self.single_move
def make_pv(self, player, pv, interactive):
pvtext = f"{player}{' '.join(pv)}"
# if interactive:
# pvtext = f"[u][ref={pvtext}][color=#334466]{pvtext}[/color][/ref][/u]"
return pvtext

def comment(self, sgf=False, teach=False, hints=False, interactive=False):
single_move = self.move
if not self.parent or not single_move: # root
return ""

Expand All @@ -109,7 +115,7 @@ def comment(self, sgf=False, teach=False, hints=False):
text += f"Move was predicted best move.\n"
if sgf:
if previous_top_move.get("pv") and (sgf or hints):
text += f"PV: {single_move.player}{' '.join(previous_top_move['pv'])}\n"
text += f"PV: {self.make_pv(single_move.player,previous_top_move['pv'],interactive)}\n"

if sgf or hints or teach:
policy_ranking = self.parent.policy_ranking
Expand All @@ -131,15 +137,15 @@ def comment(self, sgf=False, teach=False, hints=False):

@property
def points_lost(self) -> Optional[float]:
single_move = self.single_move
single_move = self.move
if single_move and self.parent and self.analysis_ready and self.parent.analysis_ready:
parent_score = self.parent.score
score = self.score
return self.player_sign(single_move.player) * (parent_score - score)

@property
def parent_realized_points_lost(self) -> Optional[float]:
single_move = self.single_move
single_move = self.move
if single_move and self.parent and self.parent.parent and self.analysis_ready and self.parent.parent.analysis_ready:
parent_parent_score = self.parent.parent.score
score = self.score
Expand Down
Loading

0 comments on commit 0827bd4

Please sign in to comment.