This is just a wrapper script to extend katago analysis for casual use on the command line:
$ ls *.sgf | katawrap.py ... > result.jsonl
It can be used to find the most heated games in your SGF collection, calculate the match rates with KataGo's top suggestions, and so on.
Let's leave the interaction with KataGo to katawrap and concentrate on analyzing the results.
- Introduction
- Features
- Appendix
As with original KataGo, katawrap receives JSONL (JSON Lines) queries from STDIN and reports JSONL responses to STDOUT basically. It also accepts a simplified query like
{"sgfFile": "/foo/bar.sgf", "visits": 400}
instead of the original query:
{"id": "1", "maxVisits": 400, "analyzeTurns": [0, 1, 2, ...], "moves": [["B", "D16"], ["W", "C17"], ...], "rules": "tromp-taylor", "komi": 7.5, "boardXSize": 19, "boardYSize": 19}
As a further extension, katawrap supports list of SGF files for its input. You can analyze all your SGF files in this way:
$ ls /foo/*.sgf \
| ./katawrap.py -visits 400 \
./katago analysis -config analysis.cfg -model model.bin.gz \
> result.jsonl
import pandas as pd
df = pd.read_json('./result.jsonl', lines=True)
print(df[['sgfFile', 'turnNumber', 'winrate']])
# sgfFile turnNumber winrate
# 0 /foo/bar.sgf 0 0.461471
# 1 /foo/bar.sgf 1 0.507684
# 2 /foo/bar.sgf 2 0.516876
# ... ... ... ...
(Continued from the previous example.)
blunders = df.query('nextWinrateGain < -0.1') \
.sort_values('nextScoreGain') \
.head(5)[['sgfFile', 'turnNumber', 'nextScoreGain']]
print(blunders)
# sgfFile turnNumber nextScoreGain
# 34 /foo/baz.sgf 34 -34.360468
# 76 /foo/qux.sgf 24 -33.851709
# 31 /foo/bar.sgf 31 -30.830034
# ...
See sample/ directory for more snippets in a sample Jupyter notebook, e.g. finding the top 5 exciting games in your collection, calculating the match rates with KataGo's top 3 suggestions in first 50 moves.
Convert to CSV (with jq):
$ cat result.jsonl \
| jq -r '[.sgfFile, .turnNumber, (.winrate*100|round)] | @csv'
"/foo/bar.sgf",0,46
"/foo/bar.sgf",1,51
"/foo/bar.sgf",2,52
...
Just download a ZIP file from github (green "Code" button at the top), unzip it, and use it. No installation or external libraries are required, but KataGo itself must be set up in advance.
See the above examples and sample/ directory for usage. (Change file names and paths as appropriate for your case.)
Alternatively, you can also upload another Jupyter notebook to Google Colaboratory and run KataGo + katawrap there. (Do not forget to change runtime type to GPU.)
The main motivation of katawrap is batch analysis in simple pipe style:
$ ls *.sgf | katawrap.py ... | jq ...
Or equivalently:
$ ls *.sgf | katawrap.py ... > result.jsonl
$ cat result.jsonl | jq ...
For this purpose, katawrap provides several extensions to KataGo analysis engine.
- Support SGF inputs.
- Sort the responses.
- Add extra fields to the responses, e.g.
sgfFile
, to pass on sufficient information for subsequent processing. This is the key for the above style. - Add further bonus outputs, e.g. unsettledness of the current board, the rank of the actually played move, etc.
The following fields are supported in addition to the original ones in JSON queries.
sgf
(string): Specify SGF text instead ofmoves
,rules
, etc.sgfFile
(string): Specify the path of SGF file instead ofsgf
. Gzipped SGF is also accepted if the path ends with '.gz'. Use the option-disable-sgf-file
if you need to disablesgfFile
for some security reason.analyzeTurnsFrom
,analyzeTurnsTo
,analyzeTurnsEvery
(integer): Specify "turns from N", "turns to N", "N every turns" instead ofanalyzeTurns
. Any of three fields can be combined. "To N" includes N itself ("from 70 to 80" = [70, 71, ..., 80]).analyzeLastTurn
(boolean): Add the endgame turn after the last move toanalyzeTurns
.includeUnsettledness
(boolean): If true, report unsettledness (includeOwnership
is turned on automatically). If not specified, defaults to true unless the option-extra normal
is set. See the next section for details.
Each line in STDIN is assumed as JSON if it starts with {
, sgf
if with (;
, or sgfFile
otherwise. Some fixes are applied automatically:
- The required fields
id
,rules
, etc. are added if they are missing. - Invalid turns outside the given
moves
are dropped fromanalyzeTurns
. - All turns are analyzed by default when
analyzeTurns
,analyzeTurnsEvery
, etc. are completely missing. If the option-only-last
is given, only the last turn is analyzed as with original KataGo in such cases.
Aliases are also accepted:
from
,to
,every
,last
=analyzeTurnsFrom
,analyzeTurnsTo
,analyzeTurnsEvery
,analyzeLastTurn
visits
=maxVisits
- For
rules
,cn
=chinese
,jp
=japanese
,kr
=korean
,nz
=new-zealand
Responses are sorted in the order of requests and turn numbers by default. This feature is disabled by the option -order arrival
.
The fields in responses are extended depending on the value of the option -extra
. They are KataGo-compatible for -extra normal
. Several fields are added for -extra rich
:
query
: Copy of the corresponding query (plus the following fields ifsgf
orsgfFile
is given in the query)sgf
: SGF text.sgfProp
: SGF root properties. e.g.{"PB": ["Intetsu"], "PW": ["Jowa"], ...}
nextMove
: Next move in GTP style, e.g. "D4". Does not exist at the last turn.nextMoveColor
: Color ofnextMove
("B" or "W").nextMoveSign
: The sign corresponding tonextMoveColor
(+1 for "B", -1 for "W")nextMoveRank
: The order ofnextMove
inmoveInfos
if exists.nextWinrateGain
: Difference ofwinrate
before and afternextMove
(> 0 if superior to AI).nextScoreGain
: Difference ofscoreLead
before and afternextMove
(> 0 if superior to AI).unsettledness
: The situation tend to be 'exciting' if this is greater than 20. It is defined as the sum of (1 - |ownership|) for all stones on the board. (It is indicated by red dots in the score chart in LizGoban. ref)blackUnsettledness
,whiteUnsettledness
,territoryUnsettledness
: The sum of (1 - |ownership|) on black stones, white stones, and empty grids, respectively.board
: 2D array of "X", "O", or "." for the current board.
Even more fields are added redundantly for '-extra excess'. This is the default.
nextRootInfo
: Copy of the rootInfo of the next turn if it exists.- All fields in
rootInfo
andquery
are also copied directly under the response. This enables easy access in pandas and jq ({turnNumber, winrate}
instead of{turnNumber, winrate: .rootInfo.winrate}
). - If exists, all fields in
sgfProp
are copied similarly. List elements are joined to one string for convenience, e.g.,"PB": "Shusaku", "BR": "4d", "PW": "Inseki", "WR": "8d", "RE": "B+2"
.
moveInfos
is guaranteed to be sorted by order
.
If the option -order join
is given, katawrap reports a joined response for each id
instead of multiple responses with different turnNumber
for the same id
. It has the fields {"id":..., "query":..., "responses":[...]}
and "responses" is the sorted array of the original responses.
- -default JSON: Use this for missing fields in queries. (ex.) '{"komi": 5.5, "includePolicy": true}'
- -override JSON: Override queries.
- -order ORDER: One of
arrival
,sort
(default), orjoin
.arrival
: Do not sort the responses.sort
: Sort the responses in the order of requests and turn numbers.join
: Report a joined response for eachid
. See the previous section for details.
- -extra EXTRA: One of
normal
,rich
, orexcess
(default).normal
: Only report the fields in responses of original KataGo.rich
: Add extra fields to responses.excess
: In addition torich
, copy the contents of some fields directly under the response. See the previous section for details.
- -max-requests MAX_REQUESTS: Suspend sending queries when pending requests exceeds this number. (default = 1000)
- -sequentially: Do not read all input lines at once. This may be needed for very large inputs. In exchange, the progress message becomes somewhat unfriendly.
- -only-last: Analyze only the last turn when analyzeTurns is missing.
- -disable-sgf-file: Do not support sgfFile in query.
- -netcat: Use this option when netcat (nc) is used as katago command. See Tips.
- -silent: Do not print progress info to stderr.
- -debug: Print debug info to stderr.
The following options are equivalent to -override
, e.g., -komi 5.5
= -override '{"komi": 5.5}'
.
- -komi KOMI
- -rules RULES: Short names 'cn', 'jp', 'kr', 'nz' are also accepted.
- -visits MAX_VISITS
- -from ANALYZE_TURNS_FROM
- -to ANALYZE_TURNS_TO
- -every ANALYZE_TURNS_EVERY
- -last
Similarly, the following options are equivalent to -default
.
- -default-komi KOMI
- -default-rules RULES
Set -from 50 -every 10 -last
to analyze the turns 50, 60, 70, ... and the endgame after the last move, for example.
Original KataGo is emulated to some extent by the following options.
katawrap.py -order arrival -extra normal -only-last -sequentially -disable-sgf-file -silent
- Limited SGF support
- Only the main branch is analyzed.
- AB[], AW[], and PL[] are supported only in the root note.
- Most minor properties are ignored. (AE[], etc.)
reportDuringSearchEvery
andaction
are not supported in queries.- Error handling is almost missing.
- Newline characters must not appear in file names.
- The fields and the options may be changed in future. (Check "incompatible change!" messages in git log.)
Never consider to open "public katawrap server" as it accesses local files and may show their contents in error messages if sgfFile
is given in the query. Though there is the option -disable-sgf-file
, it is not tested sufficiently yet.
You may want local KataGo server to save startup time when you use katawrap repeatedly. See man netcat
for an easiest way on Linux (apt install netcat
in Debian-based distributions). Example:
(server)
$ mkfifo /tmp/f
$ cat /tmp/f \
| ./katago analysis -config analysis.cfg -model model.bin.gz \
| nc -klv localhost 1234 > /tmp/f
(client)
$ ls /foo/*.sgf \
| ./katawrap.py -visits 400 \
-netcat nc localhost 1234 \
> result.jsonl
Note that KataGo keeps running even if you terminate the client with CTRL-C. The above option -netcat
is necessary to cancel requests soon in such cases. This is supported from KataGo 1.12.0. For KataGo 1.11.0, you need to terminate the server if you want to stop remaining search immediately.
- tested with KataGo 1.12.2.
- SGF parser is copied from KaTrain v1.12.
- MIT License
- Project home