File size: 17,104 Bytes
9cda8d1
 
 
 
 
 
 
 
 
 
 
30bea28
9cda8d1
 
30bea28
 
 
 
 
 
 
 
 
 
 
 
 
9cda8d1
 
e4e9331
 
 
607d836
30bea28
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e4e9331
 
 
 
 
607d836
e4e9331
 
 
607d836
30bea28
e4e9331
 
 
 
 
 
30bea28
e4e9331
 
 
30bea28
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e4e9331
 
30bea28
e4e9331
30bea28
 
 
 
 
 
e4e9331
30bea28
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e4e9331
 
30bea28
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e4e9331
 
 
30bea28
e4e9331
 
30bea28
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e4e9331
 
 
 
 
 
30bea28
e4e9331
 
30bea28
e4e9331
 
30bea28
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e4e9331
 
 
 
30bea28
f1d2299
30bea28
 
4646d2c
30bea28
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e4e9331
 
 
 
 
 
 
 
30bea28
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e4e9331
 
 
 
 
 
 
30bea28
 
e4e9331
30bea28
 
 
 
 
 
 
 
 
 
 
 
 
e4e9331
 
 
 
30bea28
 
 
e4e9331
30bea28
 
 
 
 
 
 
e4e9331
30bea28
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e4e9331
 
 
 
 
30bea28
 
e4e9331
 
30bea28
e4e9331
30bea28
 
 
e4e9331
30bea28
 
 
 
 
 
 
e4e9331
 
 
30bea28
 
 
e4e9331
 
 
 
 
 
30bea28
e4e9331
30bea28
e4e9331
 
 
30bea28
e4e9331
 
30bea28
 
 
e4e9331
 
 
 
 
 
 
 
 
 
30bea28
 
e4e9331
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30bea28
 
 
e4e9331
30bea28
 
 
e4e9331
30bea28
e4e9331
30bea28
e4e9331
30bea28
e4e9331
 
 
 
 
 
 
30bea28
 
e4e9331
 
 
 
 
 
 
 
 
30bea28
 
e4e9331
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30bea28
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
---
license: gemma
tags:
  - chess
  - gemma
  - lora
  - fine-tuned
  - commentary
  - game-analysis
  - flutter
  - mobile
  - multilingual
language:
  - en
  - hi
  - es
  - zh
  - fr
  - de
  - pt
  - ru
  - ja
  - ar
  - ko
  - tr
  - id
  - bn
---

# Chess Gemma Commentary 🎯♟️
### By NAKST Studio
<br>
Fine-tuned <strong>Gemma 3 270M</strong> model for generating chess move commentary, ELO predictions, and move classifications in <strong>14 languages</strong>. Includes an optional .task file for lightweight mobile inference with flutter_gemma

---

<div align="center">

### 💙 Support & Shape NAKST Studio

[![Donate](https://img.shields.io/badge/💙_Donate-Support_Free_Development-0080FF?style=for-the-badge)](https://nakststudio.com/donate)
[![Vote Next App](https://img.shields.io/badge/🗳️_Vote-Choose_Our_Next_App-FF6B6B?style=for-the-badge)](https://nakststudio.com/vote-next-app-beta)

**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!

</div>

---

## Model Details

- **Base Model:** Google Gemma 3 270M (270 Million Parameters)
- **Fine-tuning Method:** LoRA (Low-Rank Adaptation) - Rank 8, Alpha 16
- **Training Data:** 25,000+ chess positions with expert commentary
- **Training Epochs:** 3
- **Training Framework:** Unsloth + Hugging Face Transformers
- **Hardware:** Google Colab T4 GPU
- **Model Size:** 500MB (full) / 270 mb .task (int 8 dynamic quantized)
- **Languages Supported:** 14 (English, Hindi, Spanish, Mandarin Chinese, French, German, Portuguese, Russian, Japanese, Arabic, Korean, Turkish, Indonesian, Bengali)

## Capabilities

**Chess Move Commentary** - Detailed analysis of chess positions and moves  
**ELO Prediction** - Estimates player skill rating (1000-2800)  
**Move Classification** - Labels moves as Best Move, Good Move, Blunder, etc.  
**Multilingual Support** - Generate commentary in 14 different languages  
**Mobile Ready** - Works on Android with flutter_gemma or Ollama  
✅ **Offline** - No internet required for inference  

## Supported Languages

| Language Code | Language Name | Native Name |
|---------------|---------------|-------------|
| `en` | English | English |
| `hi` | Hindi | हिन्दी |
| `es` | Spanish | Español |
| `zh` | Mandarin Chinese | 中文 |
| `fr` | French | Français |
| `de` | German | Deutsch |
| `pt` | Portuguese | Português |
| `ru` | Russian | Русский |
| `ja` | Japanese | 日本語 |
| `ar` | Arabic | العربية |
| `ko` | Korean | 한국어 |
| `tr` | Turkish | Türkçe |
| `id` | Indonesian | Bahasa Indonesia |
| `bn` | Bengali | বাংলা |

## Input Format

The model uses a **conversational format** with system and user messages. The input expects a JSON-like structure with role-based messages.

### System Message (Required)
```python
{
    'role': 'system',
    '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.'
}
```

### User Message Format
```python
{
    'role': 'user',
    'content': '''LanguageL: English
LangCode: en
Type: standard
FEN: rnbqkbnr/pppppppp/8/8/3P4/8/PPP1PPPP/RNBQKBNR b KQkq - 0 1
MoveSAN: Nf6
Side: Black
Actor: human
Name: John
Gender: male
Tag: Book
BestAlt: g8f6
CP: 27->21 (Δ=6)'''
}
```

### Field Descriptions

| Field         | Type | Required   | Example                                                                 | Explanation                                                                             |
|---------------|------|------------|-------------------------------------------------------------------------|-----------------------------------------------------------------------------------------|
| **LanguageL** | string | ✅ REQUIRED | `English`, `Hindi`, `Spanish`                                           | Full language name for commentary generation                                            |
| **LangCode**  | string | ✅ REQUIRED | `en`, `hi`, `es`                                                        | ISO 639-1 language code (see table above)                                               |
| **Type**      | string | ✅ REQUIRED | `standard`, `explanation`                                               | Commentary type: `standard` (30-40 words) or `explanation` (explain best move, ≤50 words) |
| **FEN**       | string | ✅ REQUIRED | `rnbqkbnr/pppppppp/8/8/3P4/8/PPP1PPPP/RNBQKBNR b KQkq - 0 1`            | Forsyth-Edwards Notation - exact chess position before the move                         |
| **MoveSAN**   | string | ✅ REQUIRED | `Nf6`, `e4`, `O-O`                                                      | Standard Algebraic Notation - the move that was played                                  |
| **Side**      | string | ✅ REQUIRED | `White`, `Black`                                                        | Which side played the move                                                              |
| **Actor**     | string | ✅ REQUIRED | `human`, `bot`                                                          | Whether move was made by human or engine                                                |
| **NAME**      | string | OPTIONAL   | `Name of human or bot`                                                  | Human or bot gender who played the move for personalized commentary                     |
| **Gender**    | string | OPTIONAL   | `male`, `female`, `neutral`                                             | Player or bot gender for personalized commentary                                        |
| **Tag**       | string | ✅ REQUIRED | `Book`, `Best`, `Good`, `Inaccuracy`, `Mistake`, `Blunder`, `Brilliant` | Move classification tag                                                                 |
| **BestAlt**   | string | ✅ REQUIRED | `g8f6`, `e2e4`                                                          | Best alternative move in coordinate notation                                            |
| **CP**        | string | ✅ REQUIRED | `27->21 (Δ=6)`                                                          | Centipawn evaluation: before->after (Delta=change). Format: `CPBefore->CPAfter (Δ=change)` |

## Sample Input & Output

### Example 1: English Commentary (Standard)

**Input:**
```python
[
    {
        'role': 'system',
        '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.'
    },
    {
        'role': 'user',
        'content': '''LanguageL: English
LangCode: en
Type: standard
FEN: rnbqkbnr/pppppppp/8/8/3P4/8/PPP1PPPP/RNBQKBNR b KQkq - 0 1
MoveSAN: Nf6
Side: Black
Actor: human
Gender: male
Tag: Book
BestAlt: g8f6
CP: 27->21 (Δ=6)'''
    }
]
```

**Output:**
```
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.
Predicted ELO: 1850
Verified Classification: Book Move
```

### Example 2: Hindi Commentary (Standard)

**Input:**
```python
[
    {
        'role': 'system',
        '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.'
    },
    {
        'role': 'user',
        'content': '''LanguageL: Hindi
LangCode: hi
Type: standard
FEN: r1bqkb1r/pppp1ppp/2n2n2/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq e6 0 4
MoveSAN: Nc3
Side: White
Actor: human
Gender: female
Tag: Best
BestAlt: b1c3
CP: 42->38 (Δ=4)'''
    }
]
```

**Output:**
```
Commentary: शानदार केंद्रीकरण! Nc3 e4 पर दबाव के साथ विकसित होता है और प्रमुख केंद्रीय वर्गों को नियंत्रित करता है। यह चाल विकास को पूरा करने की तैयारी करती है जबकि केंद्र तनाव बनाए रखती है।
Predicted ELO: 2400
Verified Classification: Best Move
```

### Example 3: Explanation Type (Spanish)

**Input:**
```python
[
    {
        'role': 'system',
        '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.'
    },
    {
        'role': 'user',
        'content': '''LanguageL: Spanish
LangCode: es
Type: explanation
FEN: 2rq1rk1/pb1nb1pp/1p6/3p1p2/3Pn3/P1N5/1PQNBPPP/R1B1R1K1 w - - 0 16
MoveSAN: f3
Side: White
Actor: human
Gender: male
Tag: Mistake
BestAlt: d2e4
CP: 23->59 (Δ=36)'''
    }
]
```

**Output:**
```
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.
Predicted ELO: 1650
Verified Classification: Mistake
```

## Usage Examples

### Python (Transformers)
```python
from transformers import AutoModelForCausalLM, AutoTokenizer

model = AutoModelForCausalLM.from_pretrained("NAKSTStudio/chess-gemma-commentary")
tokenizer = AutoTokenizer.from_pretrained("NAKSTStudio/chess-gemma-commentary")

# Prepare messages
messages = [
    {
        'role': 'system',
        '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.'
    },
    {
        'role': 'user',
        'content': '''LanguageL: English
LangCode: en
Type: standard
FEN: rnbqkbnr/pppppppp/8/8/3P4/8/PPP1PPPP/RNBQKBNR b KQkq - 0 1
MoveSAN: Nf6
Side: Black
Actor: human
Gender: male
Tag: Book
BestAlt: g8f6
CP: 27->21 (Δ=6)'''
    }
]

# Generate response
inputs = tokenizer.apply_chat_template(messages, return_tensors="pt", add_generation_prompt=True)
outputs = model.generate(inputs, max_new_tokens=256, temperature=0.7)
response = tokenizer.decode(outputs[0], skip_special_tokens=True)
print(response)
```

### Flutter (flutter_gemma)
```dart
import 'package:flutter_gemma/flutter_gemma.dart';

class ChessAnalyzer {
  late InferenceModel model;
  
  Future<void> initModel() async {
    // Install model from Hugging Face (one-time operation)
    await FlutterGemma.installModel(
      modelType: ModelType.gemmaIt,
    ).fromNetwork(
      'https://huggingface.co/NAKSTStudio/chess-gemma-commentary/resolve/main/model.safetensors',
    ).withProgress((progress) {
      print('Downloading model: ${progress.percentage}%');
    }).install();
    
    // Create model instance for inference
    model = await FlutterGemma.getActiveModel(
      maxTokens: 256,
      preferredBackend: PreferredBackend.gpu,
    );
  }

  Future<String> analyzeMove({
    required String language,
    required String langCode,
    required String type,
    required String fen,
    required String moveSAN,
    required String side,
    required String actor,
    required String gender,
    required String tag,
    required String bestAlt,
    required String cp,
  }) async {
    final chat = await model.createChat(temperature: 0.7);
    
    // Add system message
    await chat.addQueryChunk(Message.text(
      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.',
      isUser: false,
    ));
    
    // Add user message with chess position data
    await chat.addQueryChunk(Message.text(
      text: '''LanguageL: $language
LangCode: $langCode
Type: $type
FEN: $fen
MoveSAN: $moveSAN
Side: $side
Actor: $actor
Gender: $gender
Tag: $tag
BestAlt: $bestAlt
CP: $cp''',
      isUser: true,
    ));
    
    // Generate response
    final response = await chat.generateChatResponse();
    
    await chat.close();
    
    if (response is TextResponse) {
      return response.token;
    }
    
    return 'Error generating response';
  }
  
  Future<void> dispose() async {
    await model.close();
  }
}

// Usage
final analyzer = ChessAnalyzer();

// Initialize once (downloads model if not present)
await analyzer.initModel();

// Use multiple times
final result = await analyzer.analyzeMove(
  language: 'English',
  langCode: 'en',
  type: 'standard',
  fen: 'rnbqkbnr/pppppppp/8/8/3P4/8/PPP1PPPP/RNBQKBNR b KQkq - 0 1',
  moveSAN: 'Nf6',
  side: 'Black',
  actor: 'human',
  gender: 'male',
  tag: 'Book',
  bestAlt: 'g8f6',
  cp: '27->21 (Δ=6)',
);

print(result);

// Clean up when done
await analyzer.dispose();
```

## Output Format

The model generates three key components:

1. **Commentary:** Multi-sentence chess analysis in the specified language (30-50 words typically)
2. **Predicted ELO:** Integer rating (1000-2800 typically)
3. **Verified Classification:** Single label describing the move (Book Move, Best Move, Good Move, Inaccuracy, Mistake, Blunder, Brilliant)

## Performance Metrics

- ⚡ **Inference Speed:** 15-30 tokens/second on mid-range Android phones
- 💾 **Memory Required:** 4GB minimum RAM for on-device inference
- 📱 **Model Sizes:** 
  - TASK File(int 8 dynamic): ~250 mb
  - TASK File: ~500 mb
- 🌍 **Language Coverage:** 14 languages spanning 5+ billion speakers

## Training Configuration

- **LoRA Rank (r):** 8
- **LoRA Alpha:** 16
- **LoRA Dropout:** 0.1
- **Target Modules:** q_proj, k_proj, v_proj, o_proj, gate_proj, up_proj, down_proj
- **Learning Rate:** 2e-4
- **Batch Size:** 8 (effective; per device: 1, gradient accumulation: 8)
- **Optimizer:** AdamW 8-bit
- **Warmup Steps:** 5
- **Training Time:** ~100 minutes (4 epochs on Colab T4)

## Model Files

```
chess-gemma-commentary/
├── model.safetensors          # Fine-tuned weights (500MB)
├── tokenizer.model            # SentencePiece tokenizer
├── tokenizer.json             # Tokenizer config
├── tokenizer_config.json      # Tokenizer settings
├── config.json                # Model architecture config
├── chat_template.jinja        # Chat formatting template
├── added_tokens.json          # Special tokens
└── README.md                  # Documentation
```

## Important Notes

⚠️ **Format Sensitivity:** This model is trained on the EXACT format shown above. Follow field order, spacing, and field names precisely for best results.

⚠️ **Language Codes:** Use the correct ISO 639-1 language code from the supported languages table. Incorrect codes may produce unexpected results.

⚠️ **Commentary Types:** 
- `Type=standard`: Generates 30-40 word general commentary
- `Type=explanation`: Generates ≤50 word explanation focusing on why the best alternative move is superior

✅ **Conversational Format:** The model uses a message-based format with system and user roles for better context understanding.

✅ **Gender-Aware:** Optionally customize commentary style based on player gender (male/female/neutral).

✅ **Delta Information:** The CP field format `CPBefore->CPAfter (Δ=change)` helps the model understand move impact.

## Known Limitations

- ❌ Very unusual or impossible positions may generate generic responses
- ❌ Requires 4GB+ RAM for mobile inference (quantization helps)
- ❌ Temperature affects output randomness (0.7 recommended for chess)
- ❌ Cannot analyze positions with invalid FEN notation
- ❌ Language quality may vary - English has most training data coverage
- ❌ Some languages may require native speaker validation for natural phrasing

## License

This model is distributed under the **Gemma Community License**. See: https://ai.google.dev/gemma/terms

## Citation

```bibtex
@model{chess_gemma_commentary_2025,
  title={Chess Gemma Commentary: Multilingual Chess Analysis},
  author={NAKST Studio},
  year={2025},
  howpublished={Hugging Face Hub}
}
```

## Credits

- **Base Model:** Google Gemma 3 (https://ai.google.dev/gemma)
- **Fine-tuning:** Unsloth (https://unsloth.ai)
- **Training Hardware:** Google Colab Free GPU
- **Inspiration:** Chess.com & Lichess communities

## Support & Feedback

- 🐛 **Found a bug?** Open an issue on the model page
- 💡 **Feature request?** Leave a discussion comment
-**Enjoying it?** Star the model!
- 💙 **Our Site** https://nakststudio.com/

---

**Made with ❤️ by NAKST Studio**

*Last Updated: November 7, 2025*