CoolFace
Modelpublic

psudini/Llama-3.2-1B-SudokuJev

sourceHugging Facellama3.2updated 2d agoView on Hugging Face
0likes6downloads
Model Card

Llama-3.2-1B-SudokuJev

Llama-3.2-1B with its LM head replaced by a 9-digit rating head. Given one empty Sudoku cell's row, column and 3x3 box, it returns a score for each digit 1-9 meaning "could this digit legally go here?". It never generates text: it's an option scorer, like a Jev-style decision API.

Code, solver, web UI and training notebook: github.com/pruthvinathsudini/sudoku-jev.

row: 4 . . 8 ? 3 . . 1 | col: 7 9 . 6 ? 2 . 1 8 | box: . 6 . 8 ? 3 . 2 . | answer:
   1-0.00  2-0.00  3-0.00  4-0.00  5-1.00  6-0.00  7-0.00  8-0.00  9-0.00   → only 5 fits

row: 5 3 . ? 7 . . . . | col: ? 1 . . 8 . . 4 . | box: ? 7 . 1 9 5 . . . | answer:
   1-0.00  2-1.00  3-0.00  4-0.00  5-0.00  6-1.00  7-0.00  8-0.00  9-0.00   → 2 or 6, skip for now

Architecture

Same recipe as AlexWortega/openjev: take a decoder LLM, drop the LM head, pool the last token's hidden state, and train a classification head.

cell text ──► Llama-3.2-1B (LoRA-tuned, no LM head) ──► last token hidden state (2048)
          ──► Linear(2048 → 9) ──► sigmoid ──► 9 independent digit scores

A solver fills a cell when exactly one digit scores above 0.5 and repeats over the grid until it's solved.

Files

FileContents
adapter_config.json, adapter_model.safetensorsLoRA adapter for meta-llama/Llama-3.2-1B (43 MB)
head.safetensorsthe digit head: weight (9, 2048), bias (9)
sudoku_jev.jsonprompt suffix, pad id, labels, fill rule, validation history
LICENSE.txt, USE_POLICY.mdLlama 3.2 Community License and Acceptable Use Policy

Usage

Requires access to the gated meta-llama/Llama-3.2-1B.

python
import torch
from huggingface_hub import snapshot_download
from peft import PeftModel
from safetensors.torch import load_file
from transformers import AutoModel, AutoTokenizer

path = snapshot_download("psudini/Llama-3.2-1B-SudokuJev")
tok = AutoTokenizer.from_pretrained("meta-llama/Llama-3.2-1B")
base = AutoModel.from_pretrained("meta-llama/Llama-3.2-1B", dtype=torch.float32)
backbone = PeftModel.from_pretrained(base, path).eval()
head = torch.nn.Linear(2048, 9)
head.load_state_dict(load_file(f"{path}/head.safetensors"))

cell = "row: 4 . . 8 ? 3 . . 1 | col: 7 9 . 6 ? 2 . 1 8 | box: . 6 . 8 ? 3 . 2 . | answer:"
with torch.no_grad():
    hidden = backbone(**tok(cell, return_tensors="pt")).last_hidden_state[0, -1]
    scores = torch.sigmoid(head(hidden))
print({d: round(s, 3) for d, s in zip(range(1, 10), scores.tolist())})
# {1: 0.0, 2: 0.0, 3: 0.0, 4: 0.0, 5: 1.0, 6: 0.0, 7: 0.0, 8: 0.0, 9: 0.0}

Input format (must match exactly): row: <9> | col: <9> | box: <9> | answer: where the target cell is ?, empty cells are ., the box is read left-to-right, top-to-bottom, and the tokenizer adds <|begin_of_text|>. Pool the hidden state of the final token (:). For batches, pad on the right and take each prompt's own last token; no attention mask is needed because the model is causal.

The GitHub repo has an ONNX exporter that merges the adapter and runs the model on any DirectX 12 GPU (tested on an AMD RX 6750 XT: ~17 ms per cell in fp32).

Training

SettingValue
Datagenerated on the fly: random valid grids, 22-50 givens, one blank cell per example, labelled with its legal digits; half the examples have exactly one legal digit
AdapterLoRA r=16, alpha=32, dropout 0.05 on q/k/v/o/gate/up/down projections
HeadLinear(2048, 9), trained fully
Lossbinary cross-entropy per digit
OptimiserAdamW, lr 2e-4 (LoRA) / 1e-3 (head), 100 warm-up steps, cosine schedule, fp16 autocast
Hardware1x NVIDIA T4 (Google Colab)
Steps250 x batch 32 (8,000 cells), stopped early: validation was already perfect

Evaluation

TestResult
2,000 held-out generated cellslegal-digit set exactly right: 100%, wrong single-digit fills: 0
30 held-out easy puzzles, solved end to end by the model30 / 30, 0 wrong digits
Wikipedia's example puzzle (51 blanks) on an AMD RX 6750 XTsolved in 6.2 s, 10 passes
Baseline: untrained Qwen3.5-0.8B, zero-shot via its LM head2% correct on single-candidate cells

Limitations

  • —It learned one deduction: which digits are absent from a cell's row, column and box. Puzzles that need harder techniques (hidden singles, pairs, chains) stall: no cell is left with a single option. It does not guess.
  • —It was trained and tested only on generated grids with the exact text layout above. Other layouts or text are out of distribution.
  • —The same deduction is a few lines of ordinary code; this model demonstrates the LLM-as-option-scorer recipe, it is not a better Sudoku solver.

License

Built with Llama. This model is a derivative of Llama 3.2 and is distributed under the Llama 3.2 Community License (Copyright © Meta Platforms, Inc. All Rights Reserved). Use is subject to the Llama 3.2 Acceptable Use Policy.