Chess Gemma 3 fine-tuned model with commentary generation
Browse files- README.md +302 -135
- config.json +2 -2
- generation_config.json +13 -0
- model.safetensors +2 -2
- tokenizer_config.json +2 -3
README.md
CHANGED
|
@@ -9,14 +9,43 @@ tags:
|
|
| 9 |
- game-analysis
|
| 10 |
- flutter
|
| 11 |
- mobile
|
|
|
|
| 12 |
language:
|
| 13 |
- en
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 14 |
---
|
| 15 |
|
| 16 |
# Chess Gemma Commentary 🎯♟️
|
| 17 |
### By NAKST Studio
|
| 18 |
<br>
|
| 19 |
-
Fine-tuned
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 20 |
|
| 21 |
## Model Details
|
| 22 |
|
|
@@ -27,103 +56,183 @@ Fine-tuned **Gemma 3 270M** model for generating chess move commentary, ELO pred
|
|
| 27 |
- **Training Framework:** Unsloth + Hugging Face Transformers
|
| 28 |
- **Hardware:** Google Colab T4 GPU
|
| 29 |
- **Model Size:** 500MB (full) / 150MB (quantized q4_k_m)
|
|
|
|
| 30 |
|
| 31 |
## Capabilities
|
| 32 |
|
| 33 |
✅ **Chess Move Commentary** - Detailed analysis of chess positions and moves
|
| 34 |
✅ **ELO Prediction** - Estimates player skill rating (1000-2800)
|
| 35 |
✅ **Move Classification** - Labels moves as Best Move, Good Move, Blunder, etc.
|
|
|
|
| 36 |
✅ **Mobile Ready** - Works on Android with flutter_gemma or Ollama
|
| 37 |
✅ **Offline** - No internet required for inference
|
| 38 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 39 |
## Input Format
|
| 40 |
|
| 41 |
-
The model expects
|
| 42 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 43 |
```
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 56 |
```
|
| 57 |
|
| 58 |
-
### Field Descriptions
|
| 59 |
-
|
| 60 |
-
| Field
|
| 61 |
-
|
| 62 |
-
| **
|
| 63 |
-
| **
|
| 64 |
-
| **
|
| 65 |
-
| **
|
| 66 |
-
| **
|
| 67 |
-
| **
|
| 68 |
-
| **
|
| 69 |
-
| **
|
| 70 |
-
| **
|
| 71 |
-
| **
|
|
|
|
|
|
|
| 72 |
|
| 73 |
## Sample Input & Output
|
| 74 |
|
| 75 |
-
### Example 1:
|
| 76 |
|
| 77 |
**Input:**
|
| 78 |
-
```
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
|
| 87 |
-
|
| 88 |
-
|
| 89 |
-
|
| 90 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 91 |
```
|
| 92 |
|
| 93 |
**Output:**
|
| 94 |
```
|
| 95 |
Commentary: Excellent opening response! Nf6 is the classical development move against d4. It immediately challenges the center and prepares flexible piece development. This maintains the tension and gives Black excellent counterplay.
|
| 96 |
-
|
| 97 |
Predicted ELO: 1850
|
| 98 |
-
|
| 99 |
-
Classification: Book Move
|
| 100 |
```
|
| 101 |
|
| 102 |
-
### Example 2:
|
| 103 |
|
| 104 |
**Input:**
|
| 105 |
-
```
|
| 106 |
-
|
| 107 |
-
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
|
| 111 |
-
|
| 112 |
-
|
| 113 |
-
|
| 114 |
-
|
| 115 |
-
|
| 116 |
-
|
| 117 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 118 |
```
|
| 119 |
|
| 120 |
**Output:**
|
| 121 |
```
|
| 122 |
-
Commentary:
|
| 123 |
-
|
| 124 |
Predicted ELO: 2400
|
|
|
|
|
|
|
| 125 |
|
| 126 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 127 |
```
|
| 128 |
|
| 129 |
## Usage Examples
|
|
@@ -132,25 +241,36 @@ Classification: Best Move
|
|
| 132 |
```python
|
| 133 |
from transformers import AutoModelForCausalLM, AutoTokenizer
|
| 134 |
|
| 135 |
-
model = AutoModelForCausalLM.from_pretrained("
|
| 136 |
-
tokenizer = AutoTokenizer.from_pretrained("
|
| 137 |
-
|
| 138 |
-
|
| 139 |
-
|
| 140 |
-
|
| 141 |
-
|
| 142 |
-
|
| 143 |
-
|
| 144 |
-
|
| 145 |
-
|
| 146 |
-
|
| 147 |
-
|
| 148 |
-
|
| 149 |
-
|
| 150 |
-
|
| 151 |
-
|
| 152 |
-
|
| 153 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 154 |
```
|
| 155 |
|
| 156 |
### Flutter (flutter_gemma)
|
|
@@ -158,81 +278,122 @@ print(tokenizer.decode(outputs[0], skip_special_tokens=True))
|
|
| 158 |
import 'package:flutter_gemma/flutter_gemma.dart';
|
| 159 |
|
| 160 |
class ChessAnalyzer {
|
| 161 |
-
late
|
| 162 |
-
|
| 163 |
Future<void> initModel() async {
|
| 164 |
-
model
|
| 165 |
-
|
| 166 |
-
|
| 167 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 168 |
);
|
| 169 |
}
|
| 170 |
|
| 171 |
Future<String> analyzeMove({
|
|
|
|
|
|
|
|
|
|
| 172 |
required String fen,
|
| 173 |
-
required String
|
| 174 |
-
required String
|
| 175 |
-
required String
|
| 176 |
-
required String
|
| 177 |
-
required
|
| 178 |
-
required
|
| 179 |
-
String
|
| 180 |
-
String name = 'Unknown',
|
| 181 |
-
required String isPlayerOrBot,
|
| 182 |
}) async {
|
| 183 |
-
final
|
| 184 |
-
|
| 185 |
-
|
| 186 |
-
|
| 187 |
-
|
| 188 |
-
|
| 189 |
-
|
| 190 |
-
|
| 191 |
-
|
| 192 |
-
|
| 193 |
-
|
| 194 |
-
|
| 195 |
-
|
| 196 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 197 |
}
|
| 198 |
}
|
| 199 |
|
| 200 |
// Usage
|
| 201 |
final analyzer = ChessAnalyzer();
|
|
|
|
|
|
|
| 202 |
await analyzer.initModel();
|
| 203 |
|
|
|
|
| 204 |
final result = await analyzer.analyzeMove(
|
|
|
|
|
|
|
|
|
|
| 205 |
fen: 'rnbqkbnr/pppppppp/8/8/3P4/8/PPP1PPPP/RNBQKBNR b KQkq - 0 1',
|
| 206 |
-
|
| 207 |
-
|
| 208 |
-
|
| 209 |
-
|
| 210 |
-
|
| 211 |
-
|
| 212 |
-
|
| 213 |
-
name: 'Player_123',
|
| 214 |
-
isPlayerOrBot: 'Player',
|
| 215 |
);
|
| 216 |
|
| 217 |
print(result);
|
|
|
|
|
|
|
|
|
|
| 218 |
```
|
| 219 |
|
| 220 |
## Output Format
|
| 221 |
|
| 222 |
The model generates three key components:
|
| 223 |
|
| 224 |
-
1. **Commentary:** Multi-sentence chess analysis (
|
| 225 |
2. **Predicted ELO:** Integer rating (1000-2800 typically)
|
| 226 |
-
3. **Classification:** Single label describing the move
|
| 227 |
|
| 228 |
## Performance Metrics
|
| 229 |
|
| 230 |
-
- ⚡ **Inference Speed:**
|
| 231 |
- 💾 **Memory Required:** 4GB minimum RAM for on-device inference
|
| 232 |
- 📱 **Model Sizes:**
|
| 233 |
-
-
|
| 234 |
-
-
|
| 235 |
-
-
|
| 236 |
|
| 237 |
## Training Configuration
|
| 238 |
|
|
@@ -243,8 +404,8 @@ The model generates three key components:
|
|
| 243 |
- **Learning Rate:** 2e-4
|
| 244 |
- **Batch Size:** 8 (effective; per device: 1, gradient accumulation: 8)
|
| 245 |
- **Optimizer:** AdamW 8-bit
|
| 246 |
-
- **Warmup Steps:**
|
| 247 |
-
- **Training Time:** ~
|
| 248 |
|
| 249 |
## Model Files
|
| 250 |
|
|
@@ -262,15 +423,19 @@ chess-gemma-commentary/
|
|
| 262 |
|
| 263 |
## Important Notes
|
| 264 |
|
| 265 |
-
⚠️ **Format Sensitivity:** This model is trained on the EXACT format shown above. Follow field order, spacing, and
|
|
|
|
|
|
|
| 266 |
|
| 267 |
-
⚠️ **
|
|
|
|
|
|
|
| 268 |
|
| 269 |
-
✅ **
|
| 270 |
|
| 271 |
-
✅ **
|
| 272 |
|
| 273 |
-
✅ **
|
| 274 |
|
| 275 |
## Known Limitations
|
| 276 |
|
|
@@ -278,6 +443,8 @@ chess-gemma-commentary/
|
|
| 278 |
- ❌ Requires 4GB+ RAM for mobile inference (quantization helps)
|
| 279 |
- ❌ Temperature affects output randomness (0.7 recommended for chess)
|
| 280 |
- ❌ Cannot analyze positions with invalid FEN notation
|
|
|
|
|
|
|
| 281 |
|
| 282 |
## License
|
| 283 |
|
|
@@ -287,8 +454,8 @@ This model is distributed under the **Gemma Community License**. See: https://ai
|
|
| 287 |
|
| 288 |
```bibtex
|
| 289 |
@model{chess_gemma_commentary_2025,
|
| 290 |
-
title={Chess Gemma Commentary},
|
| 291 |
-
author={
|
| 292 |
year={2025},
|
| 293 |
howpublished={Hugging Face Hub}
|
| 294 |
}
|
|
@@ -312,4 +479,4 @@ This model is distributed under the **Gemma Community License**. See: https://ai
|
|
| 312 |
|
| 313 |
**Made with ❤️ by NAKST Studio**
|
| 314 |
|
| 315 |
-
*Last Updated: November
|
|
|
|
| 9 |
- game-analysis
|
| 10 |
- flutter
|
| 11 |
- mobile
|
| 12 |
+
- multilingual
|
| 13 |
language:
|
| 14 |
- en
|
| 15 |
+
- hi
|
| 16 |
+
- es
|
| 17 |
+
- zh
|
| 18 |
+
- fr
|
| 19 |
+
- de
|
| 20 |
+
- pt
|
| 21 |
+
- ru
|
| 22 |
+
- ja
|
| 23 |
+
- ar
|
| 24 |
+
- ko
|
| 25 |
+
- tr
|
| 26 |
+
- id
|
| 27 |
+
- bn
|
| 28 |
---
|
| 29 |
|
| 30 |
# Chess Gemma Commentary 🎯♟️
|
| 31 |
### By NAKST Studio
|
| 32 |
<br>
|
| 33 |
+
Fine-tuned <strong>Gemma 3 270M</strong> model for generating chess move commentary, ELO predictions, and move classifications in <strong>14 languages</strong>.
|
| 34 |
+
|
| 35 |
+
---
|
| 36 |
+
|
| 37 |
+
<div align="center">
|
| 38 |
+
|
| 39 |
+
### 💙 Support & Shape NAKST Studio
|
| 40 |
+
|
| 41 |
+
[](https://nakststudio.com/donate)
|
| 42 |
+
[](https://nakststudio.com/vote-next-app-beta)
|
| 43 |
+
|
| 44 |
+
**Help us keep building free, privacy-focused chess tools!** Support teen developers creating amazing apps without ads or data collection. Vote for what we build next!
|
| 45 |
+
|
| 46 |
+
</div>
|
| 47 |
+
|
| 48 |
+
---
|
| 49 |
|
| 50 |
## Model Details
|
| 51 |
|
|
|
|
| 56 |
- **Training Framework:** Unsloth + Hugging Face Transformers
|
| 57 |
- **Hardware:** Google Colab T4 GPU
|
| 58 |
- **Model Size:** 500MB (full) / 150MB (quantized q4_k_m)
|
| 59 |
+
- **Languages Supported:** 14 (English, Hindi, Spanish, Mandarin Chinese, French, German, Portuguese, Russian, Japanese, Arabic, Korean, Turkish, Indonesian, Bengali)
|
| 60 |
|
| 61 |
## Capabilities
|
| 62 |
|
| 63 |
✅ **Chess Move Commentary** - Detailed analysis of chess positions and moves
|
| 64 |
✅ **ELO Prediction** - Estimates player skill rating (1000-2800)
|
| 65 |
✅ **Move Classification** - Labels moves as Best Move, Good Move, Blunder, etc.
|
| 66 |
+
✅ **Multilingual Support** - Generate commentary in 14 different languages
|
| 67 |
✅ **Mobile Ready** - Works on Android with flutter_gemma or Ollama
|
| 68 |
✅ **Offline** - No internet required for inference
|
| 69 |
|
| 70 |
+
## Supported Languages
|
| 71 |
+
|
| 72 |
+
| Language Code | Language Name | Native Name |
|
| 73 |
+
|---------------|---------------|-------------|
|
| 74 |
+
| `en` | English | English |
|
| 75 |
+
| `hi` | Hindi | हिन्दी |
|
| 76 |
+
| `es` | Spanish | Español |
|
| 77 |
+
| `zh` | Mandarin Chinese | 中文 |
|
| 78 |
+
| `fr` | French | Français |
|
| 79 |
+
| `de` | German | Deutsch |
|
| 80 |
+
| `pt` | Portuguese | Português |
|
| 81 |
+
| `ru` | Russian | Русский |
|
| 82 |
+
| `ja` | Japanese | 日本語 |
|
| 83 |
+
| `ar` | Arabic | العربية |
|
| 84 |
+
| `ko` | Korean | 한국어 |
|
| 85 |
+
| `tr` | Turkish | Türkçe |
|
| 86 |
+
| `id` | Indonesian | Bahasa Indonesia |
|
| 87 |
+
| `bn` | Bengali | বাংলা |
|
| 88 |
+
|
| 89 |
## Input Format
|
| 90 |
|
| 91 |
+
The model uses a **conversational format** with system and user messages. The input expects a JSON-like structure with role-based messages.
|
| 92 |
|
| 93 |
+
### System Message (Required)
|
| 94 |
+
```python
|
| 95 |
+
{
|
| 96 |
+
'role': 'system',
|
| 97 |
+
'content': 'Generate professional chess commentary in the specified language. For Type=standard use 30–40 words. For Type=explanation, explain the best move briefly (≤50 words). Return exactly: Commentary, Predicted ELO, Verified Classification.'
|
| 98 |
+
}
|
| 99 |
```
|
| 100 |
+
|
| 101 |
+
### User Message Format
|
| 102 |
+
```python
|
| 103 |
+
{
|
| 104 |
+
'role': 'user',
|
| 105 |
+
'content': '''LanguageL: English
|
| 106 |
+
LangCode: en
|
| 107 |
+
Type: standard
|
| 108 |
+
FEN: rnbqkbnr/pppppppp/8/8/3P4/8/PPP1PPPP/RNBQKBNR b KQkq - 0 1
|
| 109 |
+
MoveSAN: Nf6
|
| 110 |
+
Side: Black
|
| 111 |
+
Actor: human
|
| 112 |
+
Name: John
|
| 113 |
+
Gender: male
|
| 114 |
+
Tag: Book
|
| 115 |
+
BestAlt: g8f6
|
| 116 |
+
CP: 27->21 (Δ=6)'''
|
| 117 |
+
}
|
| 118 |
```
|
| 119 |
|
| 120 |
+
### Field Descriptions
|
| 121 |
+
|
| 122 |
+
| Field | Type | Required | Example | Explanation |
|
| 123 |
+
|---------------|------|------------|-------------------------------------------------------------------------|-----------------------------------------------------------------------------------------|
|
| 124 |
+
| **LanguageL** | string | ✅ REQUIRED | `English`, `Hindi`, `Spanish` | Full language name for commentary generation |
|
| 125 |
+
| **LangCode** | string | ✅ REQUIRED | `en`, `hi`, `es` | ISO 639-1 language code (see table above) |
|
| 126 |
+
| **Type** | string | ✅ REQUIRED | `standard`, `explanation` | Commentary type: `standard` (30-40 words) or `explanation` (explain best move, ≤50 words) |
|
| 127 |
+
| **FEN** | string | ✅ REQUIRED | `rnbqkbnr/pppppppp/8/8/3P4/8/PPP1PPPP/RNBQKBNR b KQkq - 0 1` | Forsyth-Edwards Notation - exact chess position before the move |
|
| 128 |
+
| **MoveSAN** | string | ✅ REQUIRED | `Nf6`, `e4`, `O-O` | Standard Algebraic Notation - the move that was played |
|
| 129 |
+
| **Side** | string | ✅ REQUIRED | `White`, `Black` | Which side played the move |
|
| 130 |
+
| **Actor** | string | ✅ REQUIRED | `human`, `bot` | Whether move was made by human or engine |
|
| 131 |
+
| **NAME** | string | OPTIONAL | `Name of human or bot` | Human or bot gender who played the move for personalized commentary |
|
| 132 |
+
| **Gender** | string | OPTIONAL | `male`, `female`, `neutral` | Player or bot gender for personalized commentary |
|
| 133 |
+
| **Tag** | string | ✅ REQUIRED | `Book`, `Best`, `Good`, `Inaccuracy`, `Mistake`, `Blunder`, `Brilliant` | Move classification tag |
|
| 134 |
+
| **BestAlt** | string | ✅ REQUIRED | `g8f6`, `e2e4` | Best alternative move in coordinate notation |
|
| 135 |
+
| **CP** | string | ✅ REQUIRED | `27->21 (Δ=6)` | Centipawn evaluation: before->after (Delta=change). Format: `CPBefore->CPAfter (Δ=change)` |
|
| 136 |
|
| 137 |
## Sample Input & Output
|
| 138 |
|
| 139 |
+
### Example 1: English Commentary (Standard)
|
| 140 |
|
| 141 |
**Input:**
|
| 142 |
+
```python
|
| 143 |
+
[
|
| 144 |
+
{
|
| 145 |
+
'role': 'system',
|
| 146 |
+
'content': 'Generate professional chess commentary in the specified language. For Type=standard use 30–40 words. For Type=explanation, explain the best move briefly (≤50 words). Return exactly: Commentary, Predicted ELO, Verified Classification.'
|
| 147 |
+
},
|
| 148 |
+
{
|
| 149 |
+
'role': 'user',
|
| 150 |
+
'content': '''LanguageL: English
|
| 151 |
+
LangCode: en
|
| 152 |
+
Type: standard
|
| 153 |
+
FEN: rnbqkbnr/pppppppp/8/8/3P4/8/PPP1PPPP/RNBQKBNR b KQkq - 0 1
|
| 154 |
+
MoveSAN: Nf6
|
| 155 |
+
Side: Black
|
| 156 |
+
Actor: human
|
| 157 |
+
Gender: male
|
| 158 |
+
Tag: Book
|
| 159 |
+
BestAlt: g8f6
|
| 160 |
+
CP: 27->21 (Δ=6)'''
|
| 161 |
+
}
|
| 162 |
+
]
|
| 163 |
```
|
| 164 |
|
| 165 |
**Output:**
|
| 166 |
```
|
| 167 |
Commentary: Excellent opening response! Nf6 is the classical development move against d4. It immediately challenges the center and prepares flexible piece development. This maintains the tension and gives Black excellent counterplay.
|
|
|
|
| 168 |
Predicted ELO: 1850
|
| 169 |
+
Verified Classification: Book Move
|
|
|
|
| 170 |
```
|
| 171 |
|
| 172 |
+
### Example 2: Hindi Commentary (Standard)
|
| 173 |
|
| 174 |
**Input:**
|
| 175 |
+
```python
|
| 176 |
+
[
|
| 177 |
+
{
|
| 178 |
+
'role': 'system',
|
| 179 |
+
'content': 'Generate professional chess commentary in the specified language. For Type=standard use 30–40 words. For Type=explanation, explain the best move briefly (≤50 words). Return exactly: Commentary, Predicted ELO, Verified Classification.'
|
| 180 |
+
},
|
| 181 |
+
{
|
| 182 |
+
'role': 'user',
|
| 183 |
+
'content': '''LanguageL: Hindi
|
| 184 |
+
LangCode: hi
|
| 185 |
+
Type: standard
|
| 186 |
+
FEN: r1bqkb1r/pppp1ppp/2n2n2/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq e6 0 4
|
| 187 |
+
MoveSAN: Nc3
|
| 188 |
+
Side: White
|
| 189 |
+
Actor: human
|
| 190 |
+
Gender: female
|
| 191 |
+
Tag: Best
|
| 192 |
+
BestAlt: b1c3
|
| 193 |
+
CP: 42->38 (Δ=4)'''
|
| 194 |
+
}
|
| 195 |
+
]
|
| 196 |
```
|
| 197 |
|
| 198 |
**Output:**
|
| 199 |
```
|
| 200 |
+
Commentary: शानदार केंद्रीकरण! Nc3 e4 पर दबाव के साथ विकसित होता है और प्रमुख केंद्रीय वर्गों को नियंत्रित करता है। यह चाल विकास को पूरा करने की तैयारी करती है जबकि केंद्र तनाव बनाए रखती है।
|
|
|
|
| 201 |
Predicted ELO: 2400
|
| 202 |
+
Verified Classification: Best Move
|
| 203 |
+
```
|
| 204 |
|
| 205 |
+
### Example 3: Explanation Type (Spanish)
|
| 206 |
+
|
| 207 |
+
**Input:**
|
| 208 |
+
```python
|
| 209 |
+
[
|
| 210 |
+
{
|
| 211 |
+
'role': 'system',
|
| 212 |
+
'content': 'Generate professional chess commentary in the specified language. For Type=standard use 30–40 words. For Type=explanation, explain the best move briefly (≤50 words). Return exactly: Commentary, Predicted ELO, Verified Classification.'
|
| 213 |
+
},
|
| 214 |
+
{
|
| 215 |
+
'role': 'user',
|
| 216 |
+
'content': '''LanguageL: Spanish
|
| 217 |
+
LangCode: es
|
| 218 |
+
Type: explanation
|
| 219 |
+
FEN: 2rq1rk1/pb1nb1pp/1p6/3p1p2/3Pn3/P1N5/1PQNBPPP/R1B1R1K1 w - - 0 16
|
| 220 |
+
MoveSAN: f3
|
| 221 |
+
Side: White
|
| 222 |
+
Actor: human
|
| 223 |
+
Gender: male
|
| 224 |
+
Tag: Mistake
|
| 225 |
+
BestAlt: d2e4
|
| 226 |
+
CP: 23->59 (Δ=36)'''
|
| 227 |
+
}
|
| 228 |
+
]
|
| 229 |
+
```
|
| 230 |
+
|
| 231 |
+
**Output:**
|
| 232 |
+
```
|
| 233 |
+
Commentary: El movimiento f3 debilita el rey y permite contraataques tácticos. La mejor alternativa Ne4 centralizaría el caballo con amenazas activas mientras mantiene la seguridad del rey. Este error costó aproximadamente un tercio de peón en ventaja posicional.
|
| 234 |
+
Predicted ELO: 1650
|
| 235 |
+
Verified Classification: Mistake
|
| 236 |
```
|
| 237 |
|
| 238 |
## Usage Examples
|
|
|
|
| 241 |
```python
|
| 242 |
from transformers import AutoModelForCausalLM, AutoTokenizer
|
| 243 |
|
| 244 |
+
model = AutoModelForCausalLM.from_pretrained("NAKSTStudio/chess-gemma-commentary")
|
| 245 |
+
tokenizer = AutoTokenizer.from_pretrained("NAKSTStudio/chess-gemma-commentary")
|
| 246 |
+
|
| 247 |
+
# Prepare messages
|
| 248 |
+
messages = [
|
| 249 |
+
{
|
| 250 |
+
'role': 'system',
|
| 251 |
+
'content': 'Generate professional chess commentary in the specified language. For Type=standard use 30–40 words. For Type=explanation, explain the best move briefly (≤50 words). Return exactly: Commentary, Predicted ELO, Verified Classification.'
|
| 252 |
+
},
|
| 253 |
+
{
|
| 254 |
+
'role': 'user',
|
| 255 |
+
'content': '''LanguageL: English
|
| 256 |
+
LangCode: en
|
| 257 |
+
Type: standard
|
| 258 |
+
FEN: rnbqkbnr/pppppppp/8/8/3P4/8/PPP1PPPP/RNBQKBNR b KQkq - 0 1
|
| 259 |
+
MoveSAN: Nf6
|
| 260 |
+
Side: Black
|
| 261 |
+
Actor: human
|
| 262 |
+
Gender: male
|
| 263 |
+
Tag: Book
|
| 264 |
+
BestAlt: g8f6
|
| 265 |
+
CP: 27->21 (Δ=6)'''
|
| 266 |
+
}
|
| 267 |
+
]
|
| 268 |
+
|
| 269 |
+
# Generate response
|
| 270 |
+
inputs = tokenizer.apply_chat_template(messages, return_tensors="pt", add_generation_prompt=True)
|
| 271 |
+
outputs = model.generate(inputs, max_new_tokens=256, temperature=0.7)
|
| 272 |
+
response = tokenizer.decode(outputs[0], skip_special_tokens=True)
|
| 273 |
+
print(response)
|
| 274 |
```
|
| 275 |
|
| 276 |
### Flutter (flutter_gemma)
|
|
|
|
| 278 |
import 'package:flutter_gemma/flutter_gemma.dart';
|
| 279 |
|
| 280 |
class ChessAnalyzer {
|
| 281 |
+
late InferenceModel model;
|
| 282 |
+
|
| 283 |
Future<void> initModel() async {
|
| 284 |
+
// Install model from Hugging Face (one-time operation)
|
| 285 |
+
await FlutterGemma.installModel(
|
| 286 |
+
modelType: ModelType.gemmaIt,
|
| 287 |
+
).fromNetwork(
|
| 288 |
+
'https://huggingface.co/NAKSTStudio/chess-gemma-commentary/resolve/main/model.safetensors',
|
| 289 |
+
).withProgress((progress) {
|
| 290 |
+
print('Downloading model: ${progress.percentage}%');
|
| 291 |
+
}).install();
|
| 292 |
+
|
| 293 |
+
// Create model instance for inference
|
| 294 |
+
model = await FlutterGemma.getActiveModel(
|
| 295 |
+
maxTokens: 256,
|
| 296 |
+
preferredBackend: PreferredBackend.gpu,
|
| 297 |
);
|
| 298 |
}
|
| 299 |
|
| 300 |
Future<String> analyzeMove({
|
| 301 |
+
required String language,
|
| 302 |
+
required String langCode,
|
| 303 |
+
required String type,
|
| 304 |
required String fen,
|
| 305 |
+
required String moveSAN,
|
| 306 |
+
required String side,
|
| 307 |
+
required String actor,
|
| 308 |
+
required String gender,
|
| 309 |
+
required String tag,
|
| 310 |
+
required String bestAlt,
|
| 311 |
+
required String cp,
|
|
|
|
|
|
|
| 312 |
}) async {
|
| 313 |
+
final chat = await model.createChat(temperature: 0.7);
|
| 314 |
+
|
| 315 |
+
// Add system message
|
| 316 |
+
await chat.addQueryChunk(Message.text(
|
| 317 |
+
text: 'Generate professional chess commentary in the specified language. For Type=standard use 30–40 words. For Type=explanation, explain the best move briefly (≤50 words). Return exactly: Commentary, Predicted ELO, Verified Classification.',
|
| 318 |
+
isUser: false,
|
| 319 |
+
));
|
| 320 |
+
|
| 321 |
+
// Add user message with chess position data
|
| 322 |
+
await chat.addQueryChunk(Message.text(
|
| 323 |
+
text: '''LanguageL: $language
|
| 324 |
+
LangCode: $langCode
|
| 325 |
+
Type: $type
|
| 326 |
+
FEN: $fen
|
| 327 |
+
MoveSAN: $moveSAN
|
| 328 |
+
Side: $side
|
| 329 |
+
Actor: $actor
|
| 330 |
+
Gender: $gender
|
| 331 |
+
Tag: $tag
|
| 332 |
+
BestAlt: $bestAlt
|
| 333 |
+
CP: $cp''',
|
| 334 |
+
isUser: true,
|
| 335 |
+
));
|
| 336 |
+
|
| 337 |
+
// Generate response
|
| 338 |
+
final response = await chat.generateChatResponse();
|
| 339 |
+
|
| 340 |
+
await chat.close();
|
| 341 |
+
|
| 342 |
+
if (response is TextResponse) {
|
| 343 |
+
return response.token;
|
| 344 |
+
}
|
| 345 |
+
|
| 346 |
+
return 'Error generating response';
|
| 347 |
+
}
|
| 348 |
+
|
| 349 |
+
Future<void> dispose() async {
|
| 350 |
+
await model.close();
|
| 351 |
}
|
| 352 |
}
|
| 353 |
|
| 354 |
// Usage
|
| 355 |
final analyzer = ChessAnalyzer();
|
| 356 |
+
|
| 357 |
+
// Initialize once (downloads model if not present)
|
| 358 |
await analyzer.initModel();
|
| 359 |
|
| 360 |
+
// Use multiple times
|
| 361 |
final result = await analyzer.analyzeMove(
|
| 362 |
+
language: 'English',
|
| 363 |
+
langCode: 'en',
|
| 364 |
+
type: 'standard',
|
| 365 |
fen: 'rnbqkbnr/pppppppp/8/8/3P4/8/PPP1PPPP/RNBQKBNR b KQkq - 0 1',
|
| 366 |
+
moveSAN: 'Nf6',
|
| 367 |
+
side: 'Black',
|
| 368 |
+
actor: 'human',
|
| 369 |
+
gender: 'male',
|
| 370 |
+
tag: 'Book',
|
| 371 |
+
bestAlt: 'g8f6',
|
| 372 |
+
cp: '27->21 (Δ=6)',
|
|
|
|
|
|
|
| 373 |
);
|
| 374 |
|
| 375 |
print(result);
|
| 376 |
+
|
| 377 |
+
// Clean up when done
|
| 378 |
+
await analyzer.dispose();
|
| 379 |
```
|
| 380 |
|
| 381 |
## Output Format
|
| 382 |
|
| 383 |
The model generates three key components:
|
| 384 |
|
| 385 |
+
1. **Commentary:** Multi-sentence chess analysis in the specified language (30-50 words typically)
|
| 386 |
2. **Predicted ELO:** Integer rating (1000-2800 typically)
|
| 387 |
+
3. **Verified Classification:** Single label describing the move (Book Move, Best Move, Good Move, Inaccuracy, Mistake, Blunder, Brilliant)
|
| 388 |
|
| 389 |
## Performance Metrics
|
| 390 |
|
| 391 |
+
- ⚡ **Inference Speed:** 15-30 tokens/second on mid-range Android phones
|
| 392 |
- 💾 **Memory Required:** 4GB minimum RAM for on-device inference
|
| 393 |
- 📱 **Model Sizes:**
|
| 394 |
+
- TASK File(int 8 dynamic): ~250 mb
|
| 395 |
+
- TASK File: ~500 mb
|
| 396 |
+
- 🌍 **Language Coverage:** 14 languages spanning 5+ billion speakers
|
| 397 |
|
| 398 |
## Training Configuration
|
| 399 |
|
|
|
|
| 404 |
- **Learning Rate:** 2e-4
|
| 405 |
- **Batch Size:** 8 (effective; per device: 1, gradient accumulation: 8)
|
| 406 |
- **Optimizer:** AdamW 8-bit
|
| 407 |
+
- **Warmup Steps:** 5
|
| 408 |
+
- **Training Time:** ~100 minutes (4 epochs on Colab T4)
|
| 409 |
|
| 410 |
## Model Files
|
| 411 |
|
|
|
|
| 423 |
|
| 424 |
## Important Notes
|
| 425 |
|
| 426 |
+
⚠️ **Format Sensitivity:** This model is trained on the EXACT format shown above. Follow field order, spacing, and field names precisely for best results.
|
| 427 |
+
|
| 428 |
+
⚠️ **Language Codes:** Use the correct ISO 639-1 language code from the supported languages table. Incorrect codes may produce unexpected results.
|
| 429 |
|
| 430 |
+
⚠️ **Commentary Types:**
|
| 431 |
+
- `Type=standard`: Generates 30-40 word general commentary
|
| 432 |
+
- `Type=explanation`: Generates ≤50 word explanation focusing on why the best alternative move is superior
|
| 433 |
|
| 434 |
+
✅ **Conversational Format:** The model uses a message-based format with system and user roles for better context understanding.
|
| 435 |
|
| 436 |
+
✅ **Gender-Aware:** Optionally customize commentary style based on player gender (male/female/neutral).
|
| 437 |
|
| 438 |
+
✅ **Delta Information:** The CP field format `CPBefore->CPAfter (Δ=change)` helps the model understand move impact.
|
| 439 |
|
| 440 |
## Known Limitations
|
| 441 |
|
|
|
|
| 443 |
- ❌ Requires 4GB+ RAM for mobile inference (quantization helps)
|
| 444 |
- ❌ Temperature affects output randomness (0.7 recommended for chess)
|
| 445 |
- ❌ Cannot analyze positions with invalid FEN notation
|
| 446 |
+
- ❌ Language quality may vary - English has most training data coverage
|
| 447 |
+
- ❌ Some languages may require native speaker validation for natural phrasing
|
| 448 |
|
| 449 |
## License
|
| 450 |
|
|
|
|
| 454 |
|
| 455 |
```bibtex
|
| 456 |
@model{chess_gemma_commentary_2025,
|
| 457 |
+
title={Chess Gemma Commentary: Multilingual Chess Analysis},
|
| 458 |
+
author={NAKST Studio},
|
| 459 |
year={2025},
|
| 460 |
howpublished={Hugging Face Hub}
|
| 461 |
}
|
|
|
|
| 479 |
|
| 480 |
**Made with ❤️ by NAKST Studio**
|
| 481 |
|
| 482 |
+
*Last Updated: November 7, 2025*
|
config.json
CHANGED
|
@@ -7,7 +7,7 @@
|
|
| 7 |
"attention_dropout": 0.0,
|
| 8 |
"attn_logit_softcapping": null,
|
| 9 |
"bos_token_id": 2,
|
| 10 |
-
"
|
| 11 |
"eos_token_id": 106,
|
| 12 |
"final_logit_softcapping": null,
|
| 13 |
"head_dim": 256,
|
|
@@ -49,7 +49,7 @@
|
|
| 49 |
"sliding_window": 512,
|
| 50 |
"transformers_version": "4.56.2",
|
| 51 |
"unsloth_fixed": true,
|
| 52 |
-
"unsloth_version": "2025.
|
| 53 |
"use_bidirectional_attention": false,
|
| 54 |
"use_cache": true,
|
| 55 |
"vocab_size": 262144
|
|
|
|
| 7 |
"attention_dropout": 0.0,
|
| 8 |
"attn_logit_softcapping": null,
|
| 9 |
"bos_token_id": 2,
|
| 10 |
+
"dtype": "float16",
|
| 11 |
"eos_token_id": 106,
|
| 12 |
"final_logit_softcapping": null,
|
| 13 |
"head_dim": 256,
|
|
|
|
| 49 |
"sliding_window": 512,
|
| 50 |
"transformers_version": "4.56.2",
|
| 51 |
"unsloth_fixed": true,
|
| 52 |
+
"unsloth_version": "2025.11.1",
|
| 53 |
"use_bidirectional_attention": false,
|
| 54 |
"use_cache": true,
|
| 55 |
"vocab_size": 262144
|
generation_config.json
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"bos_token_id": 2,
|
| 3 |
+
"do_sample": true,
|
| 4 |
+
"eos_token_id": [
|
| 5 |
+
1,
|
| 6 |
+
106
|
| 7 |
+
],
|
| 8 |
+
"max_length": 32768,
|
| 9 |
+
"pad_token_id": 0,
|
| 10 |
+
"top_k": 64,
|
| 11 |
+
"top_p": 0.95,
|
| 12 |
+
"transformers_version": "4.56.2"
|
| 13 |
+
}
|
model.safetensors
CHANGED
|
@@ -1,3 +1,3 @@
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:
|
| 3 |
-
size
|
|
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:accd9b8709ec7ac61d0a7edff2eb50b8d15943259da36524c3565e2a60ce2a22
|
| 3 |
+
size 536333936
|
tokenizer_config.json
CHANGED
|
@@ -51341,6 +51341,5 @@
|
|
| 51341 |
"spaces_between_special_tokens": false,
|
| 51342 |
"tokenizer_class": "GemmaTokenizer",
|
| 51343 |
"unk_token": "<unk>",
|
| 51344 |
-
"use_default_system_prompt": false
|
| 51345 |
-
|
| 51346 |
-
}
|
|
|
|
| 51341 |
"spaces_between_special_tokens": false,
|
| 51342 |
"tokenizer_class": "GemmaTokenizer",
|
| 51343 |
"unk_token": "<unk>",
|
| 51344 |
+
"use_default_system_prompt": false
|
| 51345 |
+
}
|
|
|