caro5 / README.md
codex[bot]
Change wording for commentary
dc629bb
|
Raw
History Blame Contribute Delete
12.2 kB
---
title: Caro5
emoji: 🎯
colorFrom: gray
colorTo: indigo
sdk: gradio
sdk_version: 6.16.0
python_version: '3.13'
app_file: app.py
pinned: false
short_description: Caro 5 arena with bot smart player and AI commentary (WIP)
license: mit
tags:
- track:wood
- sponsor:codex
- sponsor:nvidia
- sponsor:modal
- achievement:offbrand
- achievement:welltuned
- achievement:tinytitan
- achievement:bestdemo
- achievement:sharing
- achievement:fieldnotes
---
# Caro5
A browser-based Caro 5 Game so you can play human vs human, human vs bot. I tried to stay away from the usual board and stones look. I believe the web can be an expression of beauty as well as of utility.
Features tactical opponents, adaptive difficulty, and natural-language commentary that explains moves, threats, and strategy.
![Caro5 Cover](assets/hf-readme/cover.jpg)
## 🎮 Try It
### [Live Game]
https://huggingface.co/spaces/build-small-hackathon/caro5
## Features
### 🧠 Multiple AI Levels with different personalities!
Choose your oppponent!
**Streamer, Coach, Analyst, Friendly, Funny, Lover, Serious**
## Build Small Hackathon Fit
### REQ-01: Build a small model
I used two models to fine tune. Qwen/Qwen3-1.7B to train Du Rong, the Funny Dragon, and nvidia/OpenReasoning-Nemotron-1.5B on a smaller subset for Hòa Long, the Friendly Dragon. I had hopes to in time the training for the others, but the process terminated overnight.
I trained the newer models for only 1 epoch each, just to give them a bit of flavor.
### REQ-02: Built With Gradio
As mentioned, this is gradio hooked with a lot of fun interactions. Fully playable, has background music, winning and defeat songs. The personalities have their own sprite, you can choose your own dragon icon , emojis, skin colors and symbols, draw towers or solid stones.
![Caro5 Gameplay](assets/hf-readme/readme-03.jpg)
Shout out to Brenda Chiang that made the songs.
### REQ-03 Demo
[Youtube Playthrough](https://www.youtube.com/shorts/rsKrMIF9-rU)
### REQ-04 Social Media Posts
https://www.linkedin.com/posts/pedrolcarvalho_caro5-build-small-hackathon-first-days-activity-7470080151003840512-UbXC
https://www.linkedin.com/posts/pedrolcarvalho_ai-huggingface-hackaton-activity-7468612916347437056-1WIp
https://www.linkedin.com/posts/pedrolcarvalho_reinforcedlearning-datapipeline-ml-activity-7470506511111200769-BVLh
https://www.linkedin.com/posts/pedrolcarvalho_dataset-machinelearning-zobristhashing-activity-7470901078943760386-G0u6
https://www.linkedin.com/posts/pedrolcarvalho_caro5-day-5-and-6-generating-dataset-and-activity-7471207969880272896-1_r2
https://www.linkedin.com/posts/pedrolcarvalho_something-nice-is-coming-soon-activity-7472372419408621568-Cqkh
### REQ-05: Limited GPU
No GPU needed.
### REQ-06 Tag your README
Add tagged!
## Sponsors
### Modal
Modal saved this project to be honest. If in the beginning i was able to generate a few hundreds games, the laptop would freeze and nothing else was done. Eventually all the generation, all the training and arena was offset to modal. I even built a dashboard for it.
On it I can clearly filter datasets by gen, and schema, download the remote datasets, merge, prepare and audit the datasets. For training, i can promote the champion if the arena
![Caro5 Modal Pipeline Dashboard](assets/hf-readme/readme-01.jpg)
### Nvidia
Trained a small nvidia/OpenReasoning-Nemotron-1.5B on commentary by Hòa Long, the Friendly Dragon.
Model Quant : [pedroc/caro5-commentary-f16-Q4_K_M.gguf](https://huggingface.co/pedroc/caro5-commentary-f16-Q4_K_M.gguf)
Fine tuned model: [pedroc/caro5-nemotron-15b-friendly-lora-smoke](https://huggingface.co/pedroc/caro5-nemotron-15b-friendly-lora-smoke)
Friendly commentary dataset: [pedroc/caro5-commentary-friendly](https://huggingface.co/datasets/pedroc/caro5-commentary-friendly/)
More to come!
### Codex
I couldn't have done it without Codex of course. Burned so many tokens building everything from the ground up, and still explaining me what were the basic concepts.
## Badges
### Off-Brand
I think the game is polished and has a unique look and feel. The music and art are original.
![Caro5 Gameplay](assets/hf-readme/readme-03.jpg)
### 02 Tiny Titan
The 4bit quantized version of the model fits under 1Gb, based on the 1.5B model.
### 03 Best Demo
[Play Caro5 - PLAY MORE](https://huggingface.co/spaces/build-small-hackathon/caro5)
I believe this is a great app, fun to play and it has a lot of original ideas. I tried my best.
I documented all my work and i'm sharing everything I learn.
[Youtube Playthrough](https://www.youtube.com/shorts/rsKrMIF9-rU)
### 05 Bonus quest
The extra constraint was me starting with barely any knowledge of Machine Learning and ended up with a quantized model and a smart learning Neural network.
### Built With
- Gradio
- Hugging Face
- llama.cpp (failed)
- MCTS
- Python
### Local
Everything runs within the game. The AI bot gets the next move based on the weighted average of the neural network output and the minimax search. It has a panic mode in case the bot gets confused and plays a minimax move if ONNX is stuck.
The commentary was calling another endpoint, and for those bots without ml commentary, it's just a stored list of taunts and quotes for each personality.
## Why I Built This and what I learned
Most board-game AIs can find strong moves but cannot explain them and there are a lot of amazing projects online to play gomoku and caro.
I wanted something **different**. I wanted to explore something that could be both entertaining and educational.
**Can a game AI be fun and educational at the same time?**
To be educational the engine had to understand the game properly. It combines a modern AI engine with natural language. It uses
- Monte Carlo Tree Search
- Threat-aware position evaluation
- Self-play training
- Small language models for commentary
| Mode | Search |
|--------|--------|
| Normal | Depth 2, 16 simulations |
| Expert | Depth 3, 48 simulations |
| AI | Depth 3, 72 simulations |
| AI+ | Depth 4, 400 simulations |
The goal is to help players understand *why* a move is good, not just what move to play.
### Data Generation
Training data was generated through self-play. I started with a basic alpha-beta minimax, put in self-play to generate games. Eventually, I had enough games to start to train a model. It didn't work well as I had no idea how to train a model back then.
But steadily, and with some setbacks, the win rate of the model improved and I could finally deploy it. Since then I have been using this model to generate games and improve it further. The model is now able to play at a very high level, but it is not perfect and there is still room for improvement. It's nowhere near the strongest models out there, from which I mimic their strategies.
![Caro5 Modal Pipeline Arena](assets/hf-readme/readme-19.jpg)
Pipeline:
1. Generate games, merge with previous best model games
2. Prepare tensors
3. train a new generation of model
4. test the new models against the current best model
5. if the new models are better, promote the current best model
6. repeat
Along the way, I learned how to improve data quality and the dos and don'ts. Once the win rate was high enough I started to train a model on commentary. To that the schema had to grow to v4, so data could include more information about the game and the model's thoughts. But it also meant that all those thousands of early games had zero annotations and were poor.
I wrote a few posts for the first week:
- https://huggingface.co/blog/build-small-hackathon/caro5-first-days
- https://huggingface.co/blog/build-small-hackathon/caro5-day3-data-pipeline
- https://huggingface.co/blog/build-small-hackathon/caro5-first-dataset-runs-day-4
- https://huggingface.co/blog/build-small-hackathon/caro5-day5-6-onnx
- https://huggingface.co/blog/build-small-hackathon/caro5-day6-part1-reviewing
More to come as I update from the notes I kept taking.
### Commentary System
![Caro5 Commentary](assets/hf-readme/readme-09.png)
To produce commentaries, I started with 7 personalities: **Streamer, Coach, Analyst, Friendly, Funny, Lover, Serious**. My time was short, but I managed to create some basic templates for each of them, derive the evaluation schemas and start to collect more data.
Figuring this part with less than 3 days to the deadline was intense. I asked all the AIs for help. Then, the grey cloud started to materialize. I have a dataset of games with rich data now. I had the format. I had the threat list. I had the personalities and their taunts and style. How to put it all together was still a mystery.
From raw data extracted from the dataset corpus, a simple subset without any augmentation. For the previous schema, it backfills the metadata.
Then it can build a commentary per personality for each move to match the mcts target.
Doing this, it can generate the full commentary dataset. Splitting it by personality, I have a set that I can use to fine tune the larger model!
I was too eager and set each of the 7 personalities to train against Qwen/Qwen3-4B, hoping that by the next morning I would have the fine tuned models. Of course, the $20 wasn't enough.
So I had to downscale and choose 2 models to train against smaller models.
Qwen/Qwen3-1.7B for the funny dragon, and nvidia/OpenReasoning-Nemotron-1.5B for the friendly dragon.
I had fine tuned my first model! [pedroc/caro5-nemotron-15b-friendly-lora-smoke](https://huggingface.co/pedroc/caro5-nemotron-15b-friendly-lora-smoke)
Next was doing Quantization on the little model. That reduced the size to less than 1Gb.
Locally, using llama-cpp the modal was returning somewhat decent responses, but I didn't expect much from the tiny model.
Setting up the app was easy by just creating a new endpoint where the chat would read the api endpoint, and… This is where I broke my HF space. I removed the code.
## Development of the game and UI
Between generating datasets, training and the arena, and doing research ahead, I had to find time to polish the game. The game was done with pixijs for the 2D and react for the UI.
It started like this
![Caro5 Early days](assets/hf-readme/readme-17.jpg)
Good enough, was playable, respected the rules and the bot was getting better, even without the ONNX. But the goal was high, so I had to get to work.
From building sprites, to creating the characters, making themes, using sound effects and playing music, I wanted all.
First, were the themes:
![Caro5 Themes](assets/hf-readme/readme-22.jpg)
What started with basic geometric shapes, turned to a cute meadow ! Instant favorite.
Then adding player icons, the 3D tower piece, emojis etc followed.
Added a Play guide for swap2 phase so new players can understand what is going on!
Now, something was missing, the pieces had sound effects, but… the scene wanted more. So, music was generated, thanks to Brenda Chiang. There’s game music, victory and defeat songs!
![Caro5 Sound Popup ](assets/hf-readme/readme23.jpg)
Since then, the game has been playing the soundtrack all day.
Time for the big improvement, the characters. There’s 7 personalities:
- Vân Long, the Live Streamer
- Sư Long, the Tactical Coach
- Trí Long, the Data Analyst
- Hòa Long, the Harmonious Dragon
- Ái Long, the Loving Dragon
- Uy Long, the Majestic Dragon
- Du Rong, the Funny Dragon, my favorite
![Caro5 Du Rong](assets/hf-readme/readme24-du-rong-thinking.png)
*'Prepare to be defeated by a highly sophisticated collection of if-statements!'*
![Caro5 Hoa Long](assets/hf-readme/readme-06.png)
So much hard work coming up with these, cutting, aligning, and putting it all together! And
Some parts, hopefully, are barely seen as this loading screen.
![Caro5 Loading Screen](assets/hf-readme/readme-05.jpg)
With all this, the game was going well. Most of the personalities don’t have a sprite so I could focus on getting the HF space in better shape.
![Caro5 Current version](assets/hf-readme/readme-07.jpg)
Anyway, thank you for reading all the way here, enjoy the game!
![Caro5 Loading Screen](assets/hf-readme/readme-02.png)