Results
Held-out secrets (never a secret in SFT or RL), 400 games. A game starts with 0 to 4 prior
guesses and has 6 turns in total. Temperature 1.0, 256 tokens at most, thinking off.
Table with columns: Player, Wins, Mean reward, Games ended on an illegal reply| Player | Wins | Mean reward | Games ended on an illegal reply |
|---|
| Stock Qwen3-1.7B (100 games, train split) | 0% | 0.001 | 98% |
| After SFT | 7.5% | 0.107 | 69% |
| After SFT + RL, run 1 (this model) | 13% (95% interval 10% to 17%) | 0.1955 | 38.5% |
| After SFT + RL, run 2 (same setup, other seed, not published) | 9.75% (7% to 13%) | 0.1596 | 42% |
| Random legal player | 0% | 0.100 | 0% |
| Solver (random word that fits all feedback) | 99% | 1.120 | 0% |
This model is run 1, the better of two runs, so 13% is a high pick. A fair summary: 80 steps of RL
give 10% to 13% wins and about 40% illegal replies, from 7.5% and 69% after SFT. The gain in
wins is small and varies between seeds; the drop in illegal replies repeated in both runs.
An illegal reply (not a word, a repeat, wrong length) ends the game. Reward is not the win rate.
The model still makes mistakes that a solver would not make: it can name a word that breaks the
constraints it just wrote.
The best published result I know is 14.5% on a 7B, with a different measure, so the two numbers
are not equal.
Use
Use thinking off. The model reads a system prompt, then the board and the known constraints
(letters spaced, symbols = right place, - wrong place, . absent), and replies with a short
line and <guess>WORD</guess>.
from transformers import AutoModelForCausalLM, AutoTokenizer repo = "ubermenchh/qwen3-1.7b-wordle-rl"tok = AutoTokenizer.from_pretrained(repo)model = AutoModelForCausalLM.from_pretrained(repo, dtype="auto", device_map="auto") SYSTEM = """You are playing Wordle. Guess the secret 5-letter word. After each guess you get one symbol per letter: = correct letter, correct position - letter is in the word, wrong position . letter is not in the word Think briefly, then answer with exactly: <guess>WORD</guess>Never repeat a word you have already guessed.""" user = """ S L A T E | . . = . = slot 1: ? slot 2: ? slot 3: A slot 4: ? slot 5: EAbsent: L S TGuessed: SLATE Guesses remaining: 5Make your next guess.""" text = tok.apply_chat_template( [{"role": "system", "content": SYSTEM}, {"role": "user", "content": user}], tokenize=False, add_generation_prompt=True, enable_thinking=False,)out = model.generate(**tok(text, return_tensors="pt").to(model.device), max_new_tokens=64, do_sample=True)print(tok.decode(out[0], skip_special_tokens=True).split("assistant")[-1])
The environment, reward and training configs are in the project repository.