Python script for TTM

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

User avatar
lucasart
Posts: 3232
Joined: Mon May 31, 2010 1:29 pm
Full name: lucasart

Python script for TTM

Post by lucasart »

I'm thinking of writing a Python script for TTM (Texel Tuning Method), that would be completely external to the engine, based on UCI interaction only. This would finally make TTM easily available to every UCI engine, without any need to write all the boiler plate code inside the engine.

Idea is:
* step 1: parse a PGN and generate a csv file of "fen,score"
* step 2: run the tuner, given an UCI engine, parameters as UCI options, and a CSV file from step 1.

This requires, in the engine:
* that parameters are exposed as UCI options
* Optional: that the engine can manage "go depth 0" and return an info line with the qsearch score (bestmove will be discarded, isn't generally available in qsearch). Otherwise do the tuning based on depth 1 (or 2 or whatever you want).

Am I reinventing the wheel ?

PS: TTM is well explained in the Chess Programming Wiki.
Last edited by lucasart on Fri Oct 28, 2016 5:13 am, edited 1 time in total.
Theory and practice sometimes clash. And when that happens, theory loses. Every single time.
User avatar
lucasart
Posts: 3232
Joined: Mon May 31, 2010 1:29 pm
Full name: lucasart

Re: Python script for TTM

Post by lucasart »

Also, can step 1 be done with existing tools (eg. pgn-extract). If so, how ?

Otherwise, I could easily modify Marco's super fast PGN parser to do step 1.
Theory and practice sometimes clash. And when that happens, theory loses. Every single time.
User avatar
lucasart
Posts: 3232
Joined: Mon May 31, 2010 1:29 pm
Full name: lucasart

Re: Python script for TTM

Post by lucasart »

Of course, step 2 should be parallelized (within each tuning iteration), as we expect to have a big file of tens of thousands of positions.
Theory and practice sometimes clash. And when that happens, theory loses. Every single time.
Ferdy
Posts: 4833
Joined: Sun Aug 10, 2008 3:15 pm
Location: Philippines

Re: Python script for TTM

Post by Ferdy »

lucasart wrote:I'm thinking of writing a Python script for TTM (Texel Tuning Method), that would be completely external to the engine, based on UCI interaction only. This would finally make TTM easily available to every UCI engine, without any need to write all the boiler plate code inside the engine.

Idea is:
* step 1: parse a PGN and generate a csv file of "fen,score"
* step 2: run the tuner, given an UCI engine, parameters as UCI options, and a CSV file from step 1.

This requires, in the engine:
* that parameters are exposed as UCI options
* Optional: that the engine can manage "go depth 0" and return an info line with the qsearch score (bestmove will be discarded, isn't generally available in qsearch). Otherwise do the tuning based on depth 1 (or 2 or whatever you want).

Am I reinventing the wheel ?

PS: TTM is well explained in the Chess Programming Wiki.
I have such script with concurrency support too and plan to put it in github, but I need to clean/refactor it first and have no time for this at the moment. Perhaps last week of November.

What you described here is similar to what I have like,
go depth 0
and the script would capture the score cp value.

Code: Select all

ucinewgame
position fen rnbqkbnr/1p1ppppp/p7/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq - 0 3
go depth 0
info depth 0 score cp 27
info time 3 nodes 5
bestmove 0000
Regarding generation of training positions, I think it is better to create a STPG-specialized training position generator that can create pos in epd format with some opcode for example.

Code: Select all

rnbqkbnr/1p1ppppp/p7/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq - bm d4; ce +5; Ubm d2d4; Res "1-0";
The bm can be the move from the pgn file where you extracted the position.
The ce = centipawn evaluation can be the score comment in the game where you extracted the position.
Ubm = bm in uci move format equivalent to the move in the bm.
Res = result of the game where you extracted the position.

The reason for creating such format is that this position can also be used to train the engine by Ubm and by ce useful for tuning personalities.
You may equip STPG with filtering positions like don't allow tactical positions in the generation, control number of pieces on the position, ability to remove duplicate and similar positions and others.

I have this file, param_to_tune.txt that contains,

Code: Select all

option name IsolatedPawnPenalty type spin default 0 min 0 max 100
option name PawnDuo type spin default 1 min 0 max 8
the script will read the file and tune it.

The output is in the file param_output.txt.

Code: Select all

option name IsolatedPawnPenalty type spin default 5 min 0 max 100
option name PawnDuo type spin default 3 min 0 max 8
So the change is in the default. The script should respect the min and max value in param_to_tune.txt during tuning. The script will continously read the param_output.txt trying to reduce the errors.
The user can interrupt the tuning, when resumed the script will just read the param_output.txt (best error is also saved here), instead of the original param_to_tune.txt.
User avatar
lucasart
Posts: 3232
Joined: Mon May 31, 2010 1:29 pm
Full name: lucasart

Re: Python script for TTM

Post by lucasart »

Thanks Ferdinand! Glad to hear I'm not alone to work on this :D

To generate the training positions, I simply hacked zinc (my own lightweight cutechess-cli in Python): https://github.com/lucasart/zinc/tree/ttm

I just play a match, and instead of writing the result in PGN, I write it in the CSV format: "fen,score" (where score is from side to move pov).

So step 1 is done, and very easy to redo.
Theory and practice sometimes clash. And when that happens, theory loses. Every single time.
User avatar
lucasart
Posts: 3232
Joined: Mon May 31, 2010 1:29 pm
Full name: lucasart

Re: Python script for TTM

Post by lucasart »

Shouldn't there be some kind of weight = f(ply) to apply to the positions ?
Or (equivalently) a random weighted sampling of the positions based on ply ?

For example, all my opening (ply=2) positions are in the training file. The positions are (roughly) equal by construction, so the score measures noise more than information. For example, score=0 does not mean that the position is losing, but that the engine messed up later.

Or maybe I should have played the games with imbalanced openings ? Idea is to generate information at low plies, instead I have of noise due to balanced openings.
Theory and practice sometimes clash. And when that happens, theory loses. Every single time.
Ferdy
Posts: 4833
Joined: Sun Aug 10, 2008 3:15 pm
Location: Philippines

Re: Python script for TTM

Post by Ferdy »

lucasart wrote:Shouldn't there be some kind of weight = f(ply) to apply to the positions ?
Or (equivalently) a random weighted sampling of the positions based on ply ?

For example, all my opening (ply=2) positions are in the training file. The positions are (roughly) equal by construction, so the score measures noise more than information. For example, score=0 does not mean that the position is losing, but that the engine messed up later.

Or maybe I should have played the games with imbalanced openings ? Idea is to generate information at low plies, instead I have of noise due to balanced openings.
Try the following, match the engines between strong and weak. Allow the weak to generate and play moves randomly (idea is to create different kinds of positions), and the strong to always play the best, as in TTM the result of the game where you extracted the training positions is critical in the tuning. Starting from imbalanced positions is a good start.
Use different kinds of engines as they most likely play different moves. Have a balance collection of training positions based on number of pieces. Detect passers and have a good collection of it too.
User avatar
lucasart
Posts: 3232
Joined: Mon May 31, 2010 1:29 pm
Full name: lucasart

Re: Python script for TTM

Post by lucasart »

Another possibility would be to fit the score (calculated by the engine during the game) to the qsearch, instead of fitting the game result to logistic(qsearch). That way you should get more information in roughly equal positions. I suppose a simple linear regression, and use R^2 as the criterion to minimize. Has this been tried ? Any success ?
Theory and practice sometimes clash. And when that happens, theory loses. Every single time.
User avatar
Evert
Posts: 2929
Joined: Sat Jan 22, 2011 12:42 am
Location: NL

Re: Python script for TTM

Post by Evert »

Sounds like the reinforced learning idea described at https://chessprogramming.wikispaces.com ... 20Learning. If that's what you mean, it has been tried. I don't think the full potential has been exhausted though.
User avatar
lucasart
Posts: 3232
Joined: Mon May 31, 2010 1:29 pm
Full name: lucasart

Re: Python script for TTM

Post by lucasart »

I ended up writing it in C++ inside the engine, including concurrency. On my 4 core i7 (using 8 threads), it runs one iteration of 7.83m positions in 5.35s (1.46m qsearch/s). I think speed is key here, because the optimization process must run lots of iterations.

I haven't tried the Pyhton script yet, but I wonder if it's really a good idea. It's a better design, for sure, as it's engine independent, but performance could be a show stopper here.

Ferdinand: what kind of speed to you get with a script (in qsearch/s) ?
Theory and practice sometimes clash. And when that happens, theory loses. Every single time.