|
Download README.md from adyoi/indigo: direct link, hf CLI and curl.
- Browser
- Download file 16.8 kB
-
https://huggingface.co/adyoi/indigo/resolve/main/README.md
- Command line
-
hf download hf://adyoi/indigo/README.md
-
curl -L -o README.md https://huggingface.co/adyoi/indigo/resolve/main/README.md
16.8 kB
| 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](https://huggingface.co/adyoi/indigo-tf). 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 | |
| runs/<tag>/ | |
| manifest.json Statistik + metadata run (dihasilkan pipeline.py) | |
| ckpt/ Checkpoint training (gitignored) | |
| data/ Salinan data run (gitignored) | |
| data/ | |
| sample.txt Teks contoh Indonesia (training default) | |
| train_combined.txt Dataset latih utama (sample.txt + formula-1/2/3) | |
| kbbi.csv Entri KBBI (~123K baris, sebagian dengan arti) | |
| slang_id.txt Wordlist slang Indonesia (~1.1K kata) | |
| kamus_id.txt Wordlist Indonesia (~123K 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: | |
| ```bash | |
| 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 | |
| ```bash | |
| # 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 | |
| ```bash | |
| # 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 | |
| ```bash | |
| # 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 | |
| ```bash | |
| # 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 | |
| ```bash | |
| # 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` β ~123K 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. | |