A tiny chat model that plays tic-tac-toe. It is
SmolLM2-135M-Instruct
fine-tuned with LoRA and then merged back into the base weights, so it loads as a normal
transformers model with no PEFT dependency.
The model plays O. The human plays X and moves first. Each turn the model echoes the player's move, replies with its own, and redraws the board.
from transformers import AutoModelForCausalLM, AutoTokenizer
repo = "Sexyparabola/smollm2-135m-tictactoe"
tok = AutoTokenizer.from_pretrained(repo)
model = AutoModelForCausalLM.from_pretrained(repo)
msgs = [
{"role": "system", "content": "You are a tic-tac-toe game. The player is X and moves first; you are O."},
{"role": "user", "content": "hi"},
]
ids = tok.apply_chat_template(msgs, add_generation_prompt=True, return_tensors="pt")
out = model.generate(ids, max_new_tokens=200, do_sample=False)
print(tok.decode(out[0][ids.shape[1]:], skip_special_tokens=True))
Greedy decoding is recommended. Keep the full conversation in msgs: each turn
appends the player's square number as a user message and the model's previous
reply as an assistant message.
Every board row is followed by a blank line, so markdown chat UIs show each row on its own line instead of merging them.
user: hi
assistant: Let's play tic-tac-toe! You are X and go first. Pick a square from 1 to 9.
1 | 2 | 3
4 | 5 | 6
7 | 8 | 9
Your move (X):
user: 3
assistant: You play 3.
1 | 2 | X
4 | 5 | 6
7 | 8 | 9
I play 5 (center).
1 | 2 | X
4 | O | 6
7 | 8 | 9
Your move (X):
Replies are tagged with the reason for the move, such as (center), (corner)
and (block). The model announces the result when the game ends, and asks for
another square if the player picks one that is already taken.
q/k/v/o/gate/up/down_proj), about 9.8M trainable parameters, merged after trainingApache-2.0, inherited from the base model. This is a modified version of SmolLM2-135M-Instruct (LoRA fine-tuned and merged).
HuggingFaceTB/SmolLM2-135M-Instruct