Skip to content

Commit

Permalink
Merge pull request #167 from sanderland/v1.4.0
Browse files Browse the repository at this point in the history
V1.4.0
  • Loading branch information
sanderland committed Aug 26, 2020
2 parents d522d17 + 47f4be3 commit c9575cf
Show file tree
Hide file tree
Showing 32 changed files with 632 additions and 122 deletions.
29 changes: 22 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
[![License:MIT](https://img.shields.io/pypi/l/katrain)](https://en.wikipedia.org/wiki/MIT_License)
[![GitHub Downloads](https://img.shields.io/github/downloads/sanderland/katrain/total?color=%23336699&label=github%20downloads)](https://github.com/sanderland/katrain/releases)
[![PyPI Downloads](https://pepy.tech/badge/katrain)](https://pepy.tech/project/katrain)
[![Github sponsors](https://img.shields.io/static/v1?label=sponsor&message=6&logo=GitHub&color=dcb424&link=https://github.com/sponsors/sanderland/)](https://github.com/sponsors/sanderland)
[![Github sponsors](https://img.shields.io/static/v1?label=sponsor&message=7&logo=GitHub&color=dcb424&link=https://github.com/sponsors/sanderland/)](https://github.com/sponsors/sanderland)
[![Discord](https://img.shields.io/discord/417022162348802048?logo=discord)](https://discord.com/channels/417022162348802048/629446365688365067)

<table>
Expand All @@ -14,6 +14,7 @@
* [Previews and YouTube tutorials](#preview)
* [Installation](#install)
* [Manual](#ai)
* [Configuring KataGo](#kata)
* [Play against AI](#ai)
* [Analyzing your Games](#analysis)
* [Keyboard shortcuts](#keyboard)
Expand Down Expand Up @@ -61,10 +62,9 @@ but has since grown to include a wide range of features, including:

### YouTube videos

| **New Features in v1.3** | **Analysis Tutorial** | **Teaching Game Tutorial** |
| **New Features in v1.4** | **Analysis Tutorial** | **Teaching Game Tutorial** |
|:-----------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------:|
| [![New Features Video](https://user-images.githubusercontent.com/48946947/86819542-1514ee80-c088-11ea-954e-7830f7926b97.png)](https://www.youtube.com/watch?v=h8qCzjd5tEo) | [![Analysis Tutorial](https://i.imgur.com/3EP4IEr.png)](https://www.youtube.com/watch?v=qjxkcKgrsbU) | [![ Teaching Game Tutorial](https://i.imgur.com/jAdcSL5.png)](https://www.youtube.com/watch?v=wFl4Bab_eGM) |

| [![New Features Video](https://i.imgur.com/IXNwTHL.png)](https://www.youtube.com/watch?v=ujjRWGSZJrQ&feature=youtu.be) | [![Analysis Tutorial](https://i.imgur.com/3EP4IEr.png)](https://www.youtube.com/watch?v=qjxkcKgrsbU) | [![ Teaching Game Tutorial](https://i.imgur.com/jAdcSL5.png)](https://www.youtube.com/watch?v=wFl4Bab_eGM) |



Expand All @@ -74,6 +74,21 @@ but has since grown to include a wide range of features, including:
* [This page](INSTALL.md) has detailed instructions for Window, Linux and MacOS,
as well as troubleshooting and setting up KataGo to use multiple GPUs.

## <a name="kata"></a> Configuring KataGo

KaTrain comes pre-packaged with a working KataGo (OpenCL version) for Windows and Linux operating systems, and the 15 block neural network.

To change the model, open 'General and Engine settings' in the application and 'Download models'. You can then select the model you want from the dropdown menu.

To change the katago binary,
e.g. to the Eigen/CPU version if you don't have a GPU, click 'Download KataGo versions'.
You can then select the KataGo binary from the dropdown menu.

Finally, you can override the entire command used to start the analysis engine, which
can be useful for connecting to a remote server. Do keep in mind that KaTrain uses the *analysis engine*
of KataGo, and not the GTP engine.


## <a name="ai"></a> Play against AI

* Select the players in the main menu, or under 'New Game'.
Expand Down Expand Up @@ -181,17 +196,17 @@ In addition to shortcuts mentioned above and those shown in the main menu:
* 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.
* If still encountering problems, please start KataGo by itself to check for any errors it gives.
* Note that if you don't have a GPU, or your GPU does not support OpenCL, you may not be able to use KataGo.
* Note that if you don't have a GPU, or your GPU does not support OpenCL, you should use the 'eigen' binaries which run on CPU only.
* How can I play on larger boards?
* For windows, change the `katago` setting to `katrain\KataGo\katago-bs52.exe`. For other operating systems, you need to compile your own KataGo version with higher limits.


## <a name="support"></a> Support / Contribute

[![GitHub issues](https://img.shields.io/github/issues/sanderland/katrain)](https://github.com/sanderland/katrain/issues)
[![Contributors](https://img.shields.io/static/v1?label=contributors&message=17&color=dcb424)](CONTRIBUTIONS.md)
[![Contributors](https://img.shields.io/static/v1?label=contributors&message=19&color=dcb424)](CONTRIBUTIONS.md)
[![Liberapay patrons](https://img.shields.io/liberapay/patrons/sanderbaduk)](https://liberapay.com/sanderbaduk/)
[![Github sponsors](https://img.shields.io/static/v1?label=sponsor&message=6&logo=GitHub&color=dcb424&link=https://github.com/sponsors/sanderland/)](https://github.com/sponsors/sanderland)
[![Github sponsors](https://img.shields.io/static/v1?label=sponsor&message=7&logo=GitHub&color=dcb424&link=https://github.com/sponsors/sanderland/)](https://github.com/sponsors/sanderland)

* Ideas, feedback, and contributions to code or translations are all very welcome.
* For suggestions and planned improvements, see [open issues](https://github.com/sanderland/katrain/issues) on github to check if the functionality is already planned.
Expand Down
75 changes: 61 additions & 14 deletions katrain/KataGo/analysis_config.cfg
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
# Example config for C++ (non-python) gtp bot

# SEE NOTES ABOUT PERFORMANCE AND MEMORY USAGE IN gtp_example.cfg
# SEE NOTES ABOUT numSearchThreads AND OTHER IMPORTANT PARAMS BELOW!

# Logs------------------------------------------------------------------------------------

# Where to output log?
logFile = "~/.katrain/katago_log.txt"
# logFile = analysis.log # Use this instead of logDir to just specify a single file directly
# logToStderr = true # Echo everything output to log file to stderr as well
# logAllRequests = false # Log all input lines received to the analysis engine.
# logAllResponses = false # Log all lines output to stdout from the analysis engine.
# logSearchInfo = false # Log debug info for every search performed

# Controls the number of moves after the first move in a variation.
# analysisPVLen = 15
Expand Down Expand Up @@ -47,22 +53,64 @@ maxVisits = 500
# If provided, cap search time at this many seconds
# maxTime = 60

# Number of threads to use in each search in parallel for any SINGLE position.
# NOTE: Analysis engine can specify number of POSITIONS to be able to search in parallel via command line argument
# so this number does not necessarily need to be larger than 1, although you can still set it larger if you prefer
# to analyze fewer positions in parallel but spend more threads on each position.
# Generally, having more threads on a single position will worsen the quality of search slightly, holding fixed the
# 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 = 6

# GPU Settings-------------------------------------------------------------------------------
# numSearchThreads is the number of threads to use in each MCTS tree search in parallel for any individual position.
# But NOTE: Analysis engine also specifies max number of POSITIONS to be able to search in parallel via command line
# argument, -num-analysis-threads.

# Parallelization across positions is more efficient since the threads on different positions operate
# on different MCTS trees so they don't have to synchronize with each other. Also, multiple threads on the same MCTS
# tree weakens the search (holding playouts fixed) due to out of date statistics on nodes and suboptimal exploration,
# although the loss is still quite small for only 2,4,8 threads. So you often want to keep numSearchThreads small,
# unlike in GTP.

# But obviously you only get the benefit of parallelization across positions when you actually have lots of positions
# that you are querying at once.

# Therefore:
# * If you plan to use the analysis engine only for batch processing large numbers of positions,
# it's preferable to set this to only a small number (e.g. 1,2,4) and use a higher -num-analysis-threads.
# * But if you sometimes plan to query the analysis engine for single positions, or otherwise in smaller quantities
# than -num-analysis-threads, or if you plan to be user-interactive such that the response time on some individual
# analysis requests is important to keep low, then set this to a larger number and use somewhat fewer analysis threads,
# That way, individual searches complete faster due to having more threads on each one and doing fewer other ones at a time.

# For 19x19 boards, weaker GPUs probably want a TOTAL number of threads (numSearchThreads * num-analysis-threads)
# between 4 and 32. Mid-tier GPUs probably between 16 and 64. Strong GPUs probably between 32 and 256.
# But there's no substitute for experimenting and seeing what's best for your hardware and your usage case.
# Keep in mind that the number of threads you want doesn't necessarily have much to do with how many cores you
# have on your system, and could easily exceed the number of cores. GPU batching is (usually) the dominant consideration.
numSearchThreads = 8

# nnMaxBatchSize is the max number of positions to send to a single GPU at once. Generally, it should be the case that:
# (number of GPUs you will use * nnMaxBatchSize) >= (numSearchThreads * num-analysis-threads)
# That way, when each threads tries to request a GPU eval, your batch size summed across GPUs is large enough to handle them
# all at once. However, it can be sensible to set this a little smaller if you are limited on GPU memory,
# too large a number may fail if the GPU doesn't have enough memory.
nnMaxBatchSize = 96

# Eigen-specific settings--------------------------------------
# These only apply when using the Eigen (pure CPU) version of KataGo.

# This is the number of CPU threads for evaluating the neural net on the Eigen backend.
# It defaults to min(numAnalysisThreads * numSearchThreadsPerAnalysisThread, numCPUCores).
# numEigenThreadsPerModel = X

# Uncomment and set these smaller if you ONLY are going to use the analysis engine for smaller boards (or plan to
# run multiple instances, with some instances only handling smaller boards). It should improve performance.
# It may also mean you can use more threads profitably.
# maxBoardXSizeForNNBuffer = 19
# maxBoardYSizeForNNBuffer = 19

# TO USE MULTIPLE GPUS:
# Uncomment and set this to the number of GPUs you have and/or would like to use...
# AND if it is more than 1, uncomment the appropriate CUDA or OpenCL section below.
# numNNServerThreadsPerModel = 1

# Other General GPU Settings-------------------------------------------------------------------------------

# Maximum number of positions to send to GPU at once.
nnMaxBatchSize = 72
# Cache up to 2 ** this many neural net evaluations in case of transpositions in the tree.
nnCacheSizePowerOfTwo = 19
nnCacheSizePowerOfTwo = 20
# Size of mutex pool for nnCache is 2 ** this
nnMutexPoolSizePowerOfTwo = 16
# Randomize board orientation when running neural net evals?
Expand Down Expand Up @@ -99,7 +147,6 @@ nnRandomize = true
# cudaUseFP16 = auto
# cudaUseNHWC = auto


# OpenCL GPU settings--------------------------------------
# These only apply when using the OpenCL version of KataGo.

Expand Down
Binary file modified katrain/KataGo/katago
Binary file not shown.
Binary file removed katrain/KataGo/katago-bs52.exe
Binary file not shown.
Binary file modified katrain/KataGo/katago.exe
Binary file not shown.
12 changes: 10 additions & 2 deletions katrain/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ def __init__(self, **kwargs):

self._keyboard = Window.request_keyboard(None, self, "")
self._keyboard.bind(on_key_down=self._on_keyboard_down)
Clock.schedule_interval(self.animate_pondering, 0.1)

def log(self, message, level=OUTPUT_INFO):
super().log(message, level)
Expand All @@ -118,6 +119,12 @@ def log(self, message, level=OUTPUT_INFO):
) and getattr(self, "controls", None):
self.controls.set_status(f"ERROR: {message}", STATUS_ERROR)

def animate_pondering(self, *_args):
if not self.idle_analysis:
self.board_controls.engine_status_pondering = -1
else:
self.board_controls.engine_status_pondering += 5

@property
def play_analyze_mode(self):
return self.play_mode.mode
Expand Down Expand Up @@ -323,7 +330,7 @@ def _do_teacher_popup(self):
self.controls.timer.paused = True
if not self.teacher_settings_popup:
self.teacher_settings_popup = I18NPopup(
title_key="teacher settings", size=[dp(800), dp(700)], content=ConfigTeacherPopup(self)
title_key="teacher settings", size=[dp(800), dp(750)], content=ConfigTeacherPopup(self)
).__self__
self.teacher_settings_popup.content.popup = self.teacher_settings_popup
self.teacher_settings_popup.open()
Expand All @@ -332,7 +339,7 @@ def _do_config_popup(self):
self.controls.timer.paused = True
if not self.config_popup:
self.config_popup = I18NPopup(
title_key="general settings title", size=[dp(1200), dp(800)], content=ConfigPopup(self)
title_key="general settings title", size=[dp(1200), dp(950)], content=ConfigPopup(self)
).__self__
self.config_popup.content.popup = self.config_popup
self.config_popup.open()
Expand Down Expand Up @@ -452,6 +459,7 @@ def _on_keyboard_down(self, _keyboard, keycode, _text, modifiers):
if popup:
if keycode[1] in ["f5", "f6", "f7", "f8"]: # switch between popups
popup.dismiss()
return
else:
return

Expand Down
6 changes: 4 additions & 2 deletions katrain/config.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
{
"engine": {
"katago": "",
"altcommand": "",
"model": "katrain/models/g170e-b15c192-s1672170752-d466197061.bin.gz",
"config": "katrain/KataGo/analysis_config.cfg",
"threads": 12,
"max_visits": 500,
"fast_visits": 50,
"max_time": 3.0,
"max_time": 8.0,
"wide_root_noise": 0.0,
"_enable_ownership": true
},
Expand All @@ -16,7 +17,7 @@
"anim_pv_time": 0.5,
"debug_level": 0,
"lang": "en",
"version": "1.3.4"
"version": "1.4.0"
},
"timer": {
"byo_length": 30,
Expand Down Expand Up @@ -65,6 +66,7 @@
true
],
"eval_off_show_last": 3,
"text_point_loss": false,
"eval_show_ai": true,
"lock_ai": false
},
Expand Down
2 changes: 1 addition & 1 deletion katrain/core/ai.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ def ai_rank_estimation(strategy, settings) -> int:

def weighted_selection_without_replacement(items: List[Tuple], pick_n: int) -> List[Tuple]:
"""For a list of tuples where the second element is a weight, returns random items with those weights, without replacement."""
elt = [(math.log(random.random()) / item[1], item) for item in items] # magic
elt = [(math.log(random.random()) / (item[1] + 1e-18), item) for item in items] # magic
return [e[1] for e in heapq.nlargest(pick_n, elt)] # NB fine if too small


Expand Down
4 changes: 2 additions & 2 deletions katrain/core/constants.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
VERSION = "1.3.4"
VERSION = "1.4.0"
HOMEPAGE = "https://github.com/sanderland/katrain"
CONFIG_MIN_VERSION = "1.3.3" # keep config files from this version
CONFIG_MIN_VERSION = "1.4.0" # keep config files from this version

OUTPUT_ERROR = -1
OUTPUT_KATAGO_STDERR = -0.5
Expand Down
19 changes: 10 additions & 9 deletions katrain/core/engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class KataGoEngine:
def get_rules(node):
return KataGoEngine.RULESETS.get(str(node.ruleset).lower(), "japanese")

def __init__(self, katrain, config, override_command=None):
def __init__(self, katrain, config):
self.katrain = katrain
self.queries = {} # outstanding query id -> start time and callback
self.config = config
Expand All @@ -43,10 +43,8 @@ def __init__(self, katrain, config, override_command=None):
self.stderr_thread = None

exe = config.get("katago", "").strip()
if override_command:
self.command = override_command
elif exe.startswith('"') and exe.endswith('"'):
self.command = exe.strip('"')
if config.get("altcommand", ""):
self.command = config["altcommand"]
else:
if not exe:
if platform == "win":
Expand Down Expand Up @@ -82,7 +80,6 @@ def __init__(self, katrain, config, override_command=None):
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, stderr=subprocess.PIPE, shell=True
)
Expand All @@ -107,8 +104,12 @@ def check_alive(self, os_error="", exception_if_dead=False):
ok = self.katago_process and self.katago_process.poll() is None
if not ok and exception_if_dead:
if self.katago_process:
os_error += f"status {self.katago_process and self.katago_process.poll()}"
died_msg = i18n._("Engine died unexpectedly").format(error=os_error)
code = self.katago_process and self.katago_process.poll()
if code == 3221225781:
died_msg = i18n._("Engine missing DLL")
else:
os_error += f"status {code}"
died_msg = i18n._("Engine died unexpectedly").format(error=os_error)
self.katrain.log(died_msg, OUTPUT_ERROR)
self.katago_process = None
else:
Expand Down Expand Up @@ -150,7 +151,7 @@ def _read_stderr_thread(self):
def _analysis_read_thread(self):
while self.katago_process is not None:
try:
line = self.katago_process.stdout.readline()
line = self.katago_process.stdout.readline().strip()
if self.katago_process and not line:
self.check_alive(exception_if_dead=True)
except OSError as e:
Expand Down
8 changes: 8 additions & 0 deletions katrain/gui.kv
Original file line number Diff line number Diff line change
Expand Up @@ -247,9 +247,16 @@
size_hint: None, 1
width: self.height
canvas:
Color:
rgba: YELLOW
Ellipse:
pos: self.pos[0] + self.width/2 - self.width/6, self.pos[1] + self.height/2 - self.width/6
size: self.width/3, self.width/3
Color:
rgba: root.engine_status_col
Ellipse:
angle_start: 0 if root.engine_status_pondering==-1 else root.engine_status_pondering % 360
angle_end: 360 if root.engine_status_pondering==-1 else (root.engine_status_pondering % 360 + 180)
pos: self.pos[0] + self.width/2 - self.width/6, self.pos[1] + self.height/2 - self.width/6
size: self.width/3, self.width/3
Color:
Expand Down Expand Up @@ -501,6 +508,7 @@
orientation: 'vertical'
players: {'B':B_player,'W':W_player}
engine_status_col: [1,1,1,1]
engine_status_pondering: -1
timer:timer
graph: graph
rank_graph: rank_graph
Expand Down
Loading

0 comments on commit c9575cf

Please sign in to comment.