SONUB home EN English 한국어 日本語 中文 हिन्दी বাংলা اردو Español Português Français Deutsch Русский العربية Bahasa Indonesia Tiếng Việt ไทย Türkçe

How to enable notifications

Notifications are unavailable in this browser or on this address. Try a supported browser on the secure SONUB site.

If notifications are blocked, allow them in your browser settings.

  1. Open the site controls beside the address bar, or your browser’s site settings. Set Notifications for this site to Allow.
  2. In your device settings, allow notifications for your browser and check Do Not Disturb or Focus.
  3. Return to SONUB, reload the page, and use the bell to enable notifications.

On iPhone or iPad, add SONUB to your Home Screen, open it there, then allow notifications.

XSML · From your first line to a conversation

Now, let's build your very own AI.

Type your own language model in this browser: prepare text, train a tiny GPT, then run your Runner and XChat. No pretrained weights or external AI API.

3

Project structure

Build your folder, data and settings before training anything.

Keep everything in ~/xsml. data holds raw text, training text, text and the tokenizer. checkpoints holds learned weights. The Python files live at the project root. Run all commands from that folder.

Each raw line contains Q: question | A: answer. prepare.py removes duplicate lines and keeps every fifth distinct line for validation. It replaces the separator with a newline. Validation is an unseen quiz; do not train the tokenizer on it. Use text you are allowed to use and invent examples instead of copying personal data.

Type and try

Create the folders first. Open each source below, type it into nano with exactly that filename, save and close. settings.json is , so copy its punctuation carefully. Run prepare.py only after saving both the data and the script.

mkdir -p ~/xsml/data ~/xsml/checkpoints
cd ~/xsml
nano settings.json
nano data/raw.txt
nano prepare.py
python3 prepare.py
wc -l data/train.txt data/val.txt
settings.json — Complete source to type

These are the small course defaults. width is the size of a token vector; context is the number of visible tokens; learning_rate is the update size. Keep the same settings when resuming.

{
    "width": 8,
    "context": 12,
    "merges": 12,
    "steps": 20,
    "learning_rate": 0.03,
    "seed": 7,
    "tokens": 24,
    "max_tokens": 64,
    "port": 8765
}
data/raw.txt — Complete source to type

Type one Q/A pair per line. These invented English examples keep the first experiment short. Replace them later with your own consistent text.

Q: hello | A: hello friend.
Q: hi | A: hi friend.
Q: name | A: i am xsml.
Q: sun | A: the sun is warm.
Q: cat | A: a cat can nap.
Q: dog | A: a dog can run.
Q: red | A: red is a color.
Q: blue | A: blue is a color.
Q: learn | A: i learn from text.
Q: code | A: i can learn code.
Q: moon | A: the moon is in the sky.
Q: rain | A: rain is water.
Q: book | A: i can read a book.
Q: tea | A: tea is warm.
Q: bye | A: bye friend.
prepare.py — Complete source to type

Read UTF-8 text → remove duplicates → split whole records → write train and validation files. Separating records before tokenization avoids sharing the exact same example between both sets.

from pathlib import Path


lines = [line.strip() for line in Path('data/raw.txt').read_text(encoding='utf-8').splitlines() if line.strip()]
lines = list(dict.fromkeys(lines))
assert len(lines) >= 5, 'write at least five different Q/A lines'
assert all(' | A:' in line and line.startswith('Q:') for line in lines)
train = [line for i, line in enumerate(lines) if i % 5 != 0]
val = [line for i, line in enumerate(lines) if i % 5 == 0]
for name, rows in [('train', train), ('val', val)]:
    text = '\n'.join(row.replace(' | A:', '\nA:') for row in rows) + '\n'
    Path('data/' + name + '.txt').write_text(text, encoding='utf-8')
    print(name, len(rows))

Check your understanding

Run pwd and ls. You should see settings.json and prepare.py. The sample produces 12 training records and 3 validation records. Add your own Q/A line and explain which file must be rebuilt.

If you get stuck

FileNotFoundError usually means the wrong folder or filename. Run cd ~/xsml and ls data. IndentationError means Python indentation differs: use four spaces. Finished reference files are in ~/xsml-reference for comparison; they do not fill your project automatically.