indigo / README.md
adyoi's picture
docs: komentar inline + README argumen + bugfix & optimasi (7dd92fc)
9a82835 verified
|
Raw
History Blame Contribute Delete
16.4 kB
metadata
language:
  - id
license: mit
tags:
  - text-generation
  - from-scratch
  - gpt
  - transformer
  - indonesian
datasets:
  - custom

Indigo

Model bahasa kecil GPT-style yang dibangun dari nol (tanpa library transformers) sebagai proyek pembelajaran. Backend PyTorch; tersedia juga varian TensorFlow/Keras terpisah. Bobot disimpan dalam format aman .safetensors.

Arsitektur

Komponen Nilai default
Tipe Decoder-only transformer (pre-LN, SDPA)
Parameter ~0.81M (default)
Layer / Head 4 / 4
Dimensi embedding 128
Konteks (block_size) 128 token
Tokenizer char (karakter) atau bpe (byte-pair encoding)
Weight tying Ya (output head = token embedding)
Aktivasi GELU (MLP)
Attention Multi-head causal self-attention + KV-cache

Struktur file

indigo/
  model.py          Arsitektur GPT (CausalSelfAttention, MLP, Block, GPT, sampling)
  common.py         Utilitas bersama (clean_text, meta save/load, morphological analysis)
  bpe.py            Tokenizer BPE level-byte minimal
  tokenizer.py      Tokenizer karakter (char-level)

train.py            Training loop (best-checkpoint, resume, split val, cosine LR schedule)
generate.py         Generasi teks (top-k, top-p, repetition penalty, guard kamus)
pipeline.py         Pipeline end-to-end (data collection β†’ training β†’ manifest β†’ finalize/push)
eval.py             Evaluasi batched antar-checkpoint (nats/token, nats/karakter)
audit_kamus.py      Audit wordlist kamus terhadap KBBI daring

out/
  indigo_best.safetensors   Bobot terbaik (dipilih berdasarkan validasi)
  indigo_best_meta.json     Metadata terbaik
  indigo.safetensors        Bobot checkpoint akhir
  indigo_meta.json          Metadata akhir
  indigo_optimizer.pt       State optimizer (untuk resume)
  run_info.json             Info run terakhir yang di-finalize

data/
  sample.txt        Teks contoh Indonesia (training default)
  kamus_id.txt      Wordlist Indonesia (~70K kata, gitignored)
  prefiks.txt       Daftar prefiks Indonesia untuk morphological guard
  sufixs.txt        Daftar sufiks Indonesia untuk morphological guard

Persyaratan

torch>=2.0
safetensors>=0.4

Install:

pip install -r requirements.txt

train.py β€” Training Model

Script utama untuk melatih model GPT dari nol.

Argumen

Argumen Tipe Default Deskripsi
--data str (nargs+) data/sample.txt Path file/folder teks untuk training. Bisa banyak, spasi-separated. Folder akan dicari rekursif untuk file .txt.
--out str out Folder output checkpoint (.safetensors + _meta.json + _optimizer.pt).
--steps int 2000 Jumlah total langkah training.
--batch-size int 32 Jumlah sampel per batch. Batch lebih besar β†’ gradient lebih stabil tapi butuh lebih banyak VRAM.
--block-size int 128 Panjang konteks token per sampel (sequence length). Semakin besar β†’ model bisa lihat lebih jauh tapi butuh lebih banyak memori.
--lr float 3e-4 Learning rate maksimum. Cosine decay dari lr ini ke 10% lr selama training.
--warmup int 100 Jumlah langkah warmup linear sebelum cosine decay dimulai.
--weight-decay float 0.1 L2 regularization / weight decay untuk AdamW optimizer.
--dropout float 0.1 Dropout rate (0.0 = nonaktif). Membantu mencegah overfitting pada data kecil.
--n-layer int 4 Jumlah blok transformer bertumpuk. Lebih banyak layer β†’ model lebih dalam tapi lebih lambat.
--n-head int 4 Jumlah head per attention layer. Harus habis membagi --n-embd.
--n-embd int 128 Dimensi embedding / hidden size. Parameter β‰ˆ 12 Γ— n_layer Γ— n_embdΒ².
--tokenizer char/bpe char Jenis tokenizer. char = cepat, bpe = lebih efisien untuk teks panjang.
--vocab-size int 512 Ukuran vocab untuk BPE (diabaikan jika --tokenizer char).
--eval-interval int 200 Evaluasi validasi setiap N langkah. Set 0 untuk skip validasi.
--eval-iters int 20 Jumlah batch untuk estimasi loss validasi.
--seed int 1337 Seed random untuk reproduktibilitas.
--val-fraction float 0.1 Proporsi file untuk validasi (split per-file, bukan per-karakter).
--init-from str None Path checkpoint untuk melanjutkan training (resume). Muat model + optimizer + step.
--device auto/cpu/cuda auto Device training. auto = CUDA jika tersedia, else CPU.

Contoh

# Training dasar
python train.py --data data/sample.txt --steps 2000

# Training dengan BPE tokenizer
python train.py --data data/teks.txt --tokenizer bpe --vocab-size 512

# Model lebih besar, training lebih lama
python train.py --data data/ --n-layer 6 --n-head 8 --n-embd 256 --steps 5000

# Resume dari checkpoint
python train.py --init-from out/indigo_best.safetensors --steps 1000

# Tanpa validasi (data hanya 1 file)
python train.py --data data/combined.txt --val-fraction 0 --eval-interval 0

Output

  • out/indigo_best.safetensors + out/indigo_best_meta.json β€” checkpoint terbaik (val loss minimum)
  • out/indigo.safetensors + out/indigo_meta.json β€” checkpoint akhir
  • out/indigo_optimizer.pt β€” state optimizer (untuk resume)

Learning Rate Schedule

Step 0 β†’ warmup: linear dari 0 β†’ lr_max
Step warmup β†’ total: cosine decay dari lr_max β†’ 0.1 Γ— lr_max

Formula cosine: 0.1 Γ— lr + 0.45 Γ— lr Γ— (1 + cos(Ο€ Γ— progress))


generate.py β€” Generasi Teks

Generate teks dari checkpoint Indigo dengan berbagai opsi sampling.

Argumen

Argumen Tipe Default Deskripsi
--ckpt str out/indigo_best.safetensors Path ke file checkpoint model.
--prompt str "" Teks awal (prompt) untuk memulai generasi.
--max-new int 300 Jumlah token baru yang akan dihasilkan (bukan panjang total).
--temperature float 0.8 Skala randomness: 0.0 β‰ˆ greedy, 0.8 β‰ˆ standar, >1.0 β‰ˆ random.
--top-k int 40 Batasi sampling ke k token teratas. 0 = nonaktif.
--top-p float 1.0 Nucleus sampling: batasi kumulatif probabilitas. 1.0 = nonaktif.
--repetition-penalty float 1.0 Penalti pengulangan token. 1.0 = nonaktif, >1.0 = kurangi pengulangan.
--seed int None Seed random. None = tidak ditentukan (random setiap kali).
--device auto/cpu/cuda auto Device untuk inferensi.
--guard str None Path file kamus (satu kata per baris). Generate beberapa kandidat β†’ pilih yang rasio kata dikenal tertinggi.
--guard-prefiks str None Path file prefiks Indonesia. Default: data/prefiks.txt bila ada.
--guard-sufiks str None Path file sufiks Indonesia. Default: data/sufiks.txt bila ada.
--guard-tries int 5 Jumlah kandidat generate saat --guard aktif.
--guard-min float 0.6 Rasio kata dikenal minimum. Berhenti generate lebih awal jika tercapai.

Contoh

# Generasi dasar
python generate.py --prompt "Indigo" --max-new 300

# Sampling lebih random
python generate.py --prompt "hello" --temperature 1.0 --top-k 60 --top-p 0.9

# Dengan guard kamus (pilih output paling koheren)
python generate.py --prompt "kepekaan" --max-new 120 --guard data/kamus_id.txt

# Repetition penalty untuk mengurangi pengulangan
python generate.py --prompt "cerita" --repetition-penalty 1.2 --max-new 200

Guard Kamus

Saat --guard aktif, generate.py akan:

  1. Generate --guard-tries kandidat teks (seed berbeda tiap kandidat)
  2. Untuk setiap kandidat, hitung rasio kata yang dikenal kamus
  3. Pilih kandidat dengan rasio tertinggi
  4. Berhenti lebih awal jika rasio >= --guard-min

Kata berimbuhan dicek lewat formula morfologi:

  • Hapus sufiks β†’ cek akar
  • Hapus prefiks β†’ cek akar (+ asimilasi: meny-β†’s, pem-β†’p)

pipeline.py β€” Pipeline End-to-End

Rangkai semua tahap: kumpul data β†’ training β†’ evaluasi β†’ manifest β†’ finalize β†’ push.

Argumen

Argumen Tipe Default Deskripsi
--tag str wajib Nama run. Semua artefak disimpan di runs/<tag>/.
--data str (nargs*) [] File/folder teks lokal tambahan (banyak, spasi-separated).
--hf-dataset str None Repo dataset HF untuk menarik file teks (mis. adyoi/indigo).
--hf-patterns str (nargs*) ["*.txt", "*.md"] Pola file yang diambil dari HF.
--format-qa flag False Auto-convert Alpaca JSON (instruction/output) ke .txt sebelum training.
--runs str runs Folder root untuk semua run.
--device str None Device training (diteruskan ke train.py, default: auto).
--finalize flag False Promosikan checkpoint terbaik ke folder out/ kanonik.
--push flag False Upload checkpoint terbaik ke repo HF.
--repo str adyoi/indigo Repo HF tujuan upload.
--guard str None File kamus untuk metrik rasio ejaan di manifest.
--guard-max-new int 120 Jumlah token generate untuk evaluasi guard.
--guard-prefiks str None File prefiks Indonesia.
--guard-sufiks str None File sufiks Indonesia.

Hyperparameter training (diteruskan ke train.py):

Argumen Tipe Default Deskripsi
--steps int 2000 Jumlah langkah training.
--batch-size int 32 Batch size.
--block-size int 128 Panjang konteks.
--n-layer int 4 Jumlah layer transformer.
--n-head int 4 Jumlah head attention.
--n-embd int 128 Dimensi embedding.
--dropout float 0.1 Dropout rate.
--lr float 3e-4 Learning rate.
--warmup int 100 Langkah warmup.
--weight-decay float 0.1 Weight decay.
--eval-interval int 200 Evaluasi setiap N langkah.
--eval-iters int 20 Jumlah batch evaluasi.
--seed int 1337 Seed random.
--init-from str None Checkpoint untuk resume.
--tokenizer char/bpe char Jenis tokenizer.
--vocab-size int 512 Vocab size untuk BPE.
--val-fraction float 0.1 Proporsi file validasi.

Contoh

# Data lokal saja
python pipeline.py --tag run01 --data data/sample.txt --steps 2000

# Data dari HF + BPE tokenizer
python pipeline.py --tag run02 --data data/teks.txt --hf-dataset adyoi/indigo \
  --tokenizer bpe --vocab-size 512 --steps 900 --device cpu

# Dataset Alpaca JSON dari HF
python pipeline.py --tag qa01 \
  --hf-dataset rohanrdy/CS-Theory-QA-Dataset \
  --format-qa --steps 3000 --n-layer 6 --n-embd 256

# Full pipeline: train + finalize + push
python pipeline.py --tag final01 --data data/ --steps 2000 --finalize --push

# Dengan guard kamus untuk metrik kualitas
python pipeline.py --tag guarded --data data/ --steps 2000 --guard data/kamus_id.txt

Output

  • runs/<tag>/data/ β€” data yang digunakan (copy dari sumber)
  • runs/<tag>/ckpt/ β€” checkpoint training
  • runs/<tag>/manifest.json β€” statistik + metadata run (termasuk kamus_ratio jika --guard aktif)

eval.py β€” Evaluasi Batched

Bandingkan beberapa checkpoint pada set uji tetap. Metrik:

  • nats/token: loss rata-rata per token (cross-entropy). Lebih rendah = lebih baik.
  • nats/karakter: loss per karakter (dikoreksi dengan compression ratio). Memungkinkan perbandingan antar tokenizer.

Argumen

Argumen Tipe Default Deskripsi
--ckpt str (nargs+) wajib Path ke satu atau lebih file checkpoint (.safetensors).
--test str data/sample.txt Path ke file teks uji.
--device cpu/cuda cpu Device untuk evaluasi.
--guard str None Path file kamus; generate teks β†’ hitung rasio kata dikenal.
--guard-max-new int 120 Jumlah token generate untuk evaluasi guard.
--seed int 42 Seed untuk generate saat --guard aktif.
--batch-size int 32 Batch size untuk evaluasi.

Contoh

# Evaluasi satu checkpoint
python eval.py --ckpt out/indigo_best.safetensors

# Bandingkan beberapa checkpoint
python eval.py --ckpt out/indigo_best.safetensors runs/*/ckpt/indigo.safetensors \
  --test data/sample.txt

# Dengan guard kamus
python eval.py --ckpt out/indigo_best.safetensors --guard data/kampus_id.txt

Contoh output

set uji: data/sample.txt (29,123 karakter)
checkpoint                                 nats/tok  nat/kar   kamus
run/csqa500/ckpt/indigo_best.safetensors      3.962    3.962     32%
run/wiki500/ckpt/indigo_best.safetensors      3.018    3.018     25%

audit_kamus.py β€” Audit Wordlist Kamus

Verifikasi kata-kata dalam file kamus terhadap KBBI daring (sampling acak).

Argumen

Argumen Tipe Default Deskripsi
--kamus str data/kamus_id.txt Path ke file kamus (satu kata per baris).
--n int 200 Jumlah kata sampel yang diambil untuk verifikasi.
--seed int 1337 Seed random untuk sampling.
--delay float 0.8 Jeda antar-permintaan web (detik). Hindari rate limiting.
--backend auto/pypi/web auto Backend verifikasi. pypi = library kbbi, web = scraping kbbi.web.id.
--apply flag False Hapus kata TIDAK-DIKENAL dari kamus (backup otomatis ke .bak.txt).
--out str None Path output laporan JSON. Default: runs/kamus_audit_<timestamp>.json.

Contoh

# Audit dasar
python audit_kamus.py --kamus data/kamus_id.txt --n 200

# Hapus kata tak-valid (backup otomatis)
python audit_kamus.py --kamus data/kamus_id.txt --apply

# Backend web saja, delay lebih lama
python audit_kamus.py --backend web --delay 1.5 --n 100

Output

Laporan JSON berisi:

  • ada: jumlah kata yang ditemukan di KBBI
  • tidak_dikenal: jumlah kata yang tidak ditemukan
  • gagal_ceks: jumlah verifikasi yang gagal (timeout, dll)
  • estimasi_entri_tidak_valid: proyeksi total entri tak-valid di seluruh kamus
  • kata_ditolak: daftar kata yang tidak dikenal (akan dihapus jika --apply)

Guard Kamus (Sistem Kualitas Ejaan)

Sistem guard membantu menjaga kualitas output model tanpa mengubah bobot:

  1. Wordlist: data/kamus_id.txt β€” ~70K kata Indonesia (satu kata per baris)
  2. Morfologi: data/prefiks.txt + data/sufiks.txt β€” pendeteksi imbuhan
  3. Asimilasi: meny-β†’s, peny-β†’s, pem-β†’p β€” menangani perubahan bunyi

Cara kerja:

  • generate.py: generate beberapa kandidat β†’ pilih yang rasio kata dikenal tertinggi
  • pipeline.py: generate sekali β†’ simpan kamus_ratio di manifest.json
  • eval.py: generate sekali β†’ tampilkan rasio di tabel perbandingan

Edit data/prefiks.txt dan data/sufiks.txt untuk memperluas cakupan tanpa menyentuh kode.


Format Checkpoint

File Isi
*.safetensors Bobot model (format aman, tanpa pickle)
*_meta.json Metadata: config, vocab, step, val_loss, backend, tokenizer info
*_optimizer.pt State optimizer AdamW (untuk resume training)

Format .safetensors tidak mengeksekusi kode saat dimuat β€” lebih aman dari format .pt lama.


Tips Training

Skenario Rekomendasi
Data < 100 KB --tokenizer char, 4L/4H/128E, 2000 steps
Data 100 KB–1 MB --tokenizer char atau bpe (vocab 512), 4L/8H/256E, 3000+ steps
Data > 1 MB --tokenizer char (BPE training sangat lambat di CPU >1MB)
CPU-only Model max ~1M params (4L/4H/128E), 5-8 detik/step
Resume training --init-from runs/xxx/ckpt/indigo_best.safetensors

Batasan

  • Dilatih pada data sangat kecil β†’ output belum koheren; cocok untuk edukasi bukan produksi.
  • Gunakan checkpoint indigo_best (terpilih berdasarkan validasi), bukan checkpoint akhir.
  • BPE training sangat lambat di CPU untuk data > 1 MB β€” gunakan --tokenizer char.

Keamanan

Bobot disimpan sebagai .safetensors (tanpa pickle, tidak mengeksekusi kode saat dimuat). State optimizer (*_optimizer.pt) hanya untuk resume lokal β€” jangan dibagikan.