|
Download README.md from briscoooe/tiny-cube-solver: direct link, hf CLI and curl.
- Browser
- Download file 4.55 kB
-
https://huggingface.co/briscoooe/tiny-cube-solver/resolve/main/README.md
- Command line
-
hf download hf://briscoooe/tiny-cube-solver/README.md
-
curl -L -o README.md https://huggingface.co/briscoooe/tiny-cube-solver/resolve/main/README.md
4.55 kB
| license: mit | |
| library_name: pytorch | |
| tags: | |
| - rubiks-cube | |
| - search | |
| - value-iteration | |
| - reinforcement-learning | |
| pipeline_tag: other | |
| # tiny-cube-solver | |
| A 33.6M-parameter network that guesses how many moves a Rubik's Cube is from | |
| solved, plus a search that uses the guess to find the moves. It was trained from | |
| nothing: no solver, no example solutions, no human data. | |
| - Solves **95%** of fully scrambled cubes (142 of 150, scrambles of 20 to 100 moves) | |
| - Solves **every** cube scrambled with 10 moves or fewer | |
| - Built as a control for [RubiksBench](https://brianbriscoe.dev/lab/rubiksbench), | |
| where language models must write the whole answer in one reply. On the same | |
| full scrambles the best of them, GPT-6 Astra, solves 9 of 10 with answers | |
| averaging over 100 moves; this model's answers average about 22. It is not the | |
| same test: this model gets a search loop, the language models get one reply. | |
| Write-up and replays: https://brianbriscoe.dev/lab/tiny-cube-solver | |
| ## Try it | |
| ```sh | |
| pip install torch transformers safetensors huggingface_hub | |
| python solve.py --scramble "R U F' D2 L B'" | |
| ``` | |
| or with a cube state in the `kociemba` layout (faces U R F D L B, nine stickers | |
| each): | |
| ```sh | |
| python solve.py --facelets <54 characters> | |
| ``` | |
| Use `--beam 1024` for full scrambles, which needs a GPU. The default, 64, is | |
| fast enough for a laptop, but it only solves short scrambles. | |
| `solve.py` has no other dependencies. It downloads `config.json` and | |
| `model.safetensors` from this repo the first time. | |
| ## How it works | |
| The network does not write moves. It reads the 54 stickers of one cube and | |
| returns one number: its guess of the distance to solved. | |
| `solve.py` then searches: | |
| 1. Apply each of the 18 moves to every position it is keeping. | |
| 2. Ask the network to score all the new positions. | |
| 3. Keep the best `--beam` of them, and repeat. | |
| 4. Stop when one of them is the solved cube. | |
| Every move is applied by ordinary code, and the answer is checked before it is | |
| printed. The network only decides which positions are worth keeping. | |
| ### Training: the model makes its own answers | |
| The model was trained by approximate value iteration (the method behind | |
| [DeepCubeA](https://www.nature.com/articles/s42256-019-0070-z)). It starts from | |
| one free fact: the solved cube is 0 moves from solved. A cube is then 1 more | |
| than its best neighbour. The network learns from its own previous guesses, and | |
| the correct answers spread outward from the solved cube, one move further each | |
| round. No solver is involved at any point. | |
| An earlier version with the identical network was trained on distances from the | |
| Kociemba solver instead. It solved only 16% of full scrambles. Kociemba returns | |
| good solutions, not the shortest, and 47% of random cubes got the label "21", so | |
| there was nothing to learn from above distance 15. Changing only the labels took | |
| full scrambles from 16% to 96%. | |
| ## Results | |
| Canonical RubiksBench scrambles (the same cubes every language model on the | |
| board is tested on), 25 cubes per scramble length: | |
| | Scramble length | Solved (beam 1024) | Average answer | | |
| |---|---|---| | |
| | 3 | 25/25 | 3.0 moves | | |
| | 6 | 25/25 | 6.0 | | |
| | 10 | 25/25 | 10.0 | | |
| | 15 | 25/25 | 20.4 | | |
| | 20 | 24/25 | 22.0 | | |
| | 25 | 24/25 | 21.9 | | |
| | 30 | 25/25 | 21.6 | | |
| | 40 | 23/25 | 23.0 | | |
| | 50 | 23/25 | 21.9 | | |
| | 100 | 23/25 | 21.5 | | |
| | **all** | **242/250 (96.8%)** | | | |
| Measured 2026-09-24 on one RTX A6000. Every cube and answer is replayable at | |
| https://brianbriscoe.dev/lab/tiny-cube-solver. | |
| Past about 15 moves, every scramble is fully mixed, so 25, 50 or 100 moves are | |
| no harder than 20. A full scramble takes about 80 to 90 seconds on one RTX A6000. | |
| ## Model | |
| - A Llama-shaped encoder, trained from scratch: 8 layers, width 512, 8 heads. | |
| The architecture only; no Llama weights. | |
| - Input: `[BOS]` + 54 sticker tokens + `[SEP]`. Output: the mean of the final | |
| layer, through one linear layer, to one number. | |
| - 33,577,985 parameters, float32. | |
| ## Things that give much lower numbers | |
| | What you did | What you get at 20 moves | | |
| |---|---| | |
| | Always take the best-scored move, no search | 34% even at 10 moves | | |
| | Judge the network by its average error | about 1.5 moves, which looks poor; the search only needs the correct ranking of the 18 neighbours | | |
| ## Limits | |
| - It is not fast. The Kociemba two-phase solver solves any cube in milliseconds. | |
| This model exists to show that a small network can learn the task at all. | |
| - Solutions are not guaranteed to be shortest. Full scrambles average about 22 | |
| moves. | |
| - 3x3x3 only. | |
| ## License | |
| MIT. See `LICENSE`. | |