{
  "id": 571067,
  "title": "My solution (5th place)",
  "content": "<p>The source code for my submission is available <a href=\"https://github.com/Rafbillpc/kaggle-chess\" target=\"_blank\">HERE</a>.</p>\n<p>I'll keep this writeup short, as I don't have much to say that was not already covered by the writeup of the top solutions.</p>\n<p>My solution is a modification of the Obsidian chess engine. Ignoring the size of the nnue net, I was able to fit the compressed executable in ~25Kb and the memory usage below the 5Mb budget, without any significant loss in strength.</p>\n<p>The code is compiled to a shared library that is dynamically loaded by the python script. I think that this saves some memory, because the same stack can be used by python and the shared library.</p>\n<p>I didn't implement pondering.</p>\n<p>The main original part of my submission is the structure of the nnue: it is 768-&gt;128x2-&gt;16-&gt;32-&gt;1, but the feature transformer 768-&gt;128 only uses as much space as a 768x64 matrix.</p>\n<p>This is accomplished by sharing some weights: the 768x128 matrix has the following shape:</p>\n<pre><code> +-------+-------+\n |||\n |||\n |||\n +-------+-------+\n |||\n |||\n |||\n +-------+-------+\n</code></pre>\n<p>where the pair of features (x, x+384) corresponds to a piece on a square in file (A-D), and the same piece on the horizontally mirrored square (in file E-H).</p>\n<p>That has the effect of building in the structure of the network some knowledge about the rules of chess, namely that the rules of chess are symmetrical (if you ignore castling, which is not really handled by the network anyway).</p>\n<p>The resulting network is not as strong as with an ordinary 768-&gt;128 feature transformer, but it stronger than with an ordinary 768-&gt;64 feature transformer.</p>",
  "comments": [],
  "comment_count": 0,
  "messages": [
    {
      "id": 3167039,
      "postDate": "2025-04-01T08:24:05.993Z",
      "content": "<p>The source code for my submission is available <a href=\"https://github.com/Rafbillpc/kaggle-chess\" target=\"_blank\">HERE</a>.</p>\n<p>I'll keep this writeup short, as I don't have much to say that was not already covered by the writeup of the top solutions.</p>\n<p>My solution is a modification of the Obsidian chess engine. Ignoring the size of the nnue net, I was able to fit the compressed executable in ~25Kb and the memory usage below the 5Mb budget, without any significant loss in strength.</p>\n<p>The code is compiled to a shared library that is dynamically loaded by the python script. I think that this saves some memory, because the same stack can be used by python and the shared library.</p>\n<p>I didn't implement pondering.</p>\n<p>The main original part of my submission is the structure of the nnue: it is 768-&gt;128x2-&gt;16-&gt;32-&gt;1, but the feature transformer 768-&gt;128 only uses as much space as a 768x64 matrix.</p>\n<p>This is accomplished by sharing some weights: the 768x128 matrix has the following shape:</p>\n<pre><code> +-------+-------+\n |||\n |||\n |||\n +-------+-------+\n |||\n |||\n |||\n +-------+-------+\n</code></pre>\n<p>where the pair of features (x, x+384) corresponds to a piece on a square in file (A-D), and the same piece on the horizontally mirrored square (in file E-H).</p>\n<p>That has the effect of building in the structure of the network some knowledge about the rules of chess, namely that the rules of chess are symmetrical (if you ignore castling, which is not really handled by the network anyway).</p>\n<p>The resulting network is not as strong as with an ordinary 768-&gt;128 feature transformer, but it stronger than with an ordinary 768-&gt;64 feature transformer.</p>",
      "rawMarkdown": "The source code for my submission is available [HERE](https://github.com/Rafbillpc/kaggle-chess).\n\nI'll keep this writeup short, as I don't have much to say that was not already covered by the writeup of the top solutions.\n\nMy solution is a modification of the Obsidian chess engine. Ignoring the size of the nnue net, I was able to fit the compressed executable in ~25Kb and the memory usage below the 5Mb budget, without any significant loss in strength.\n\nThe code is compiled to a shared library that is dynamically loaded by the python script. I think that this saves some memory, because the same stack can be used by python and the shared library.\n\nI didn't implement pondering.\n\nThe main original part of my submission is the structure of the nnue: it is 768->128x2->16->32->1, but the feature transformer 768->128 only uses as much space as a 768x64 matrix.\n\nThis is accomplished by sharing some weights: the 768x128 matrix has the following shape:\n```\n +-------+-------+\n |       |       |\n |   A   |   B   |\n |       |       |\n +-------+-------+\n |       |       |\n |   B   |   A   |\n |       |       |\n +-------+-------+\n```\nwhere the pair of features (x, x+384) corresponds to a piece on a square in file (A-D), and the same piece on the horizontally mirrored square (in file E-H).\n\nThat has the effect of building in the structure of the network some knowledge about the rules of chess, namely that the rules of chess are symmetrical (if you ignore castling, which is not really handled by the network anyway).\n\nThe resulting network is not as strong as with an ordinary 768->128 feature transformer, but it stronger than with an ordinary 768->64 feature transformer.",
      "votes": 6
    }
  ],
  "complete": true,
  "source": "live",
  "fetched_at": "2026-10-20T08:26:53Z",
  "competition_id": 86524,
  "competition_slug": "fide-google-efficiency-chess-ai-challenge",
  "team_id": 12966748,
  "solution_url": "/competitions/fide-google-efficiency-chess-ai-challenge/writeups/a-my-solution-5th-place"
}