Photon Mascot

Photon-90M Early Instruct

Model bahasa Indonesia dengan arsitektur Dual Sparse custom, dilatih dari nol dan di-finetune untuk instruction following di Google Colab Free T4.

License HuggingFace Predecessor Colab

⚠️ Work in Progress β€” Pretraining baru ~16% selesai (step 4.000 dari 24.604). Dirilis sebagai early checkpoint untuk dokumentasi dan eksplorasi komunitas, bukan untuk produksi.


Nama "Photon" merujuk pada filosofi efisiensi komputasi arsitekturnya β€” seperti foton, model ini dirancang untuk membawa informasi sebanyak mungkin dengan energi (VRAM) seminimal mungkin.

"90M" merujuk pada total parameter. Parameter aktif per forward pass hanya ~38–42M karena Mixture of Experts.

Evolusi Arsitektur

Photon-90M adalah iterasi ketiga dalam seri Photon, merupakan konvergensi pembelajaran dari dua model sebelumnya.

Model Total Params Aktif Hidden Vocab Status
Photon-3M 10.47M ~3M 128 8K BPE βœ… Selesai, dipublish
Nano-Z Aquila 88M 88M (dense) 768 β€” ❌ Dibatalkan (EST 100+ hari)
Photon-90M 90.23M ~38–42M 384 16K Unigram πŸ”„ Dalam training

Photon-90M mengadopsi arsitektur Dual Sparse dari Photon-3M yang terbukti efisien, dan target skala parameter dari Nano-Z Aquila, dengan pipeline training yang didesain ulang agar bisa selesai di Colab Free.

Arsitektur Dual Sparse

Konsep utama adalah Dual Sparse β€” dua level sparsity yang bekerja bersamaan untuk memaksimalkan kapasitas representasi dengan footprint komputasi minimal.

MoE β€” Mixture of Experts

Setiap layer memiliki satu shared expert yang selalu aktif, ditambah empat specialist expert yang dipilih router per token. Hanya 1 dari 4 specialist yang aktif per token.

Efeknya: kapasitas FFN setara 5x dari yang dieksekusi per token, tanpa menambah biaya komputasi secara proporsional. Tiap specialist dapat terspesialisasi pada domain berbeda (sains, berita, sastra, dll).

Referensi: Mixtral of Experts (Mistral AI)

Adaptive Layer Skipping

Router kecil (1 linear layer) di tiap layer memutuskan apakah layer perlu diproses atau dilewati berdasarkan konten input. Skip probability: 0.3.

Efek nyata yang terukur: VRAM hanya ~1.4GB selama training meski total parameter 90M. Jika semua layer aktif seharusnya ~2.5–3GB β€” selisih ini membuktikan layer skipping bekerja aktif.

Mekanisme backprop menggunakan straight-through estimator sehingga gradien tetap mengalir meski layer di-skip. Bias router diinisialisasi ke 2.0 agar model awalnya jarang skip, lalu belajar skip secara adaptif.

Referensi: Confident Adaptive Language Modeling (CALM)

Komponen Pendukung

Komponen Detail Referensi
GQA 8 Query / 2 KV Heads GQA Paper
RoPE Rotary Position Embedding RoFormer
SwiGLU Aktivasi FFN GLU Variants
RMSNorm Normalisasi per layer RMSNorm Paper
Weight Tying Embedding = LM Head (pretraining) Press & Wolf, 2017

Perbandingan dengan Arsitektur Lain

Komponen Mirip Dengan Catatan
MoE + Shared Expert DeepSeek-V2/V3 DeepSeek juga pakai shared+specialist pattern
GQA LLaMA 3, Mistral Konsep identik, ratio berbeda
RoPE Hampir semua LLM modern Standard de facto
SwiGLU LLaMA, PaLM, Gemma Standard di arsitektur modern
RMSNorm LLaMA, Mistral Lebih efisien dari LayerNorm
Adaptive Layer Skip Early Exit (Microsoft/Google) Implementasi custom, terintegrasi langsung ke layer

Konfigurasi

VOCAB_SIZE   = 16.000  (Unigram SentencePiece)
HIDDEN       = 384
LAYERS       = 12
HEADS        = 8Q / 2KV  (GQA)
FF_MULT      = 3
NUM_EXPERTS  = 4 specialist + 1 shared
MAX_SEQ      = 512  (diperpanjang dari 256 saat finetune via RoPE extrapolation)
SKIP_PROB    = 0.3

Total params : 90.226.572
Aktif/token  : ~38–42M  (~42% dari total)

Tokenizer

Unigram SentencePiece yang dilatih dari scratch dari dataset yang sama, bukan hasil adopt dari model lain.

Tipe    : Unigram SentencePiece
Vocab   : 16.000
Special : [UNK] [BOS] [EOS] [PAD]

Training

Fase 1 β€” Pretraining

Dataset: Lyon28/Corpus-Indonesia + indonesian-nlp/wikipedia-id (~2GB+, ~2 epoch)

Hardware          : Tesla T4 15.6GB (Google Colab Free)
Batch size        : 32
Grad accumulation : 8  (effective batch 256)
Optimizer         : AdamW (lr=3e-4, betas=0.9/0.95, wd=0.01)
Scheduler         : Cosine Annealing + Linear Warmup 1.000 step
Mixed Precision   : bfloat16
MAX_SEQ           : 256
Total steps target: 24.604  (2 epoch)
Checkpoint diambil: Step 4.000  (~16% selesai)

Kurva Loss Pretraining:

Training Loss Curve
Step Loss PPL LR
650 6.077 436 1.9e-4
700 5.952 385 2.1e-4
800 5.758 317 2.4e-4
900 5.560 260 2.7e-4
1000 5.354 212 3.0e-4
1100 5.183 178 3.0e-4
1200 5.035 154 3.0e-4
1300 4.950 141 3.0e-4
1400 4.864 130 3.0e-4
4000 ~4.18 ~65 <3.0e-4

Target Loss Pretraining:

Target Status
< 6.0 β€” model mulai mengenali pola bahasa βœ… Tercapai step 650
< 5.0 β€” kalimat mulai memiliki struktur βœ… Tercapai step 1200
< 4.5 β€” kalimat koheren βœ… Tercapai ~step 3000+
< 3.5 β€” grammar oke, topik nyambung 🎯 Target ~step 6.000
< 3.0 β€” minimum layak finetune 🎯 Target akhir epoch 1
< 2.5 β€” bagus untuk 90M param 🎯 Target akhir epoch 2

Fase 2 β€” Instruction Finetuning

Dataset: Ichsan2895/alpaca-gpt4-indonesian (License: CC BY-SA 4.0) β€” 49.101 sampel valid (difilter dari 49.969, token ≀480) Format prompt:

### Instruksi:
{instruction}

### Respons:
{output}
Base checkpoint   : Pretraining step 4.000
MAX_SEQ           : 512  (diperpanjang dari 256 via RoPE extrapolation)
Batch size        : 16
Grad accumulation : 4  (effective batch 64)
Optimizer         : AdamW (lr=5e-5, betas=0.9/0.95, wd=0.01)
Scheduler         : Cosine Annealing + Linear Warmup 100 step
Frozen layers     : embed + layer 0–5
Trainable layers  : layer 6–11 + norm + head
Dihentikan di     : ft-step 1.200

Kurva Loss Finetuning:

ft-step Loss PPL
100 3.410 30.3
300 3.158 23.5
500 3.052 21.2
767 3.000 20.1
1000 2.869 17.6
1200 2.852 17.3

Bug yang Ditemukan dan Diperbaiki

Bug 1: find_latest_checkpoint tidak cek Drive. Fungsi hanya mencari di /content/ yang hilang setiap sesi Colab baru. Fix: scan Drive terlebih dahulu, lalu lokal. Checkpoint valid harus punya model.pt dan training_state.pt.

Bug 2: Skip batch tetap load semua batch ke memori. if bi < skip_batches: continue tetap men-load tiap batch ke memori sebelum dibuang. Saat resume di tengah epoch, ini menyebabkan proses skip 4.800+ batch memakan waktu sangat lama. Fix: ganti dengan itertools.islice untuk langsung lompat ke posisi batch yang benar.

Bug 3: Script selalu download dataset ulang. Setiap sesi Colab baru, dataset didownload ulang dari HuggingFace meski tokens_cache.npy dan tokenizer sudah ada di Drive β€” membuang ~10–15 menit per resume. Fix: cek keberadaan cache dan tokenizer di Drive di awal, skip download jika keduanya sudah ada.

Cara Load

Model menggunakan arsitektur custom. Salin modeling_photon.py dari repo ini, lalu:

import torch
import torch.nn.functional as F
import sentencepiece as spm
from modeling_photon import PhotonModel

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

# Load tokenizer
sp = spm.SentencePieceProcessor()
sp.load("tokenizer.model")

# Load model
cfg   = torch.load("config.pt", map_location=device)
model = PhotonModel(**cfg).to(device)
model.load_state_dict(torch.load("model.pt", map_location=device))
model.eval()

Generate dengan instruction format:

def generate(instruksi, max_new=150, temp=0.3, top_p=0.9, rep_penalty=1.3):
    prompt = f"### Instruksi:\n{instruksi}\n\n### Respons:\n"
    ids    = torch.tensor([sp.encode(prompt)], dtype=torch.long).to(device)
    with torch.no_grad():
        for _ in range(max_new):
            if ids.shape[1] >= 512:
                ids = ids[:, -511:]
            logits      = model(ids)
            next_logits = logits[:, -1] / temp
            for tok_id in ids[0].tolist():
                next_logits[0, tok_id] /= rep_penalty
            probs              = F.softmax(next_logits, dim=-1)
            sorted_probs, sidx = torch.sort(probs, descending=True)
            cumprobs           = torch.cumsum(sorted_probs, dim=-1)
            sorted_probs[cumprobs - sorted_probs > top_p] = 0
            sorted_probs      /= sorted_probs.sum()
            next_tok           = sidx[0][torch.multinomial(sorted_probs[0], 1)]
            if next_tok.item() == sp.eos_id():
                break
            ids = torch.cat([ids, next_tok.view(1, 1)], dim=-1)
    return sp.decode(ids[0].tolist()).split("### Respons:")[-1].strip()

print(generate("Jelaskan apa itu fotosintesis"))
print(generate("Bagaimana cara membuat nasi goreng?"))

Contoh Output

⚠️ Output masih mengandung kesalahan faktual β€” ini expected karena pretraining baru ~16% selesai. Format instruksi sudah diikuti konsisten.

>>> Jelaskan apa itu fotosintesis
Fotosintesis adalah proses yang melibatkan berbagai bentuk, termasuk
fotosintetis dan artefak...
[struktur kalimat benar, fakta salah]

>>> Apa perbedaan siang dan malam?
Pagi, sore, atau malam.
[singkat tapi faktanya benar βœ“]

>>> Bagaimana cara membuat nasi goreng?
Salah satu cara untuk membuat nasi goreng adalah dengan menggunakan
bahan-bahan berikut... bawang putih dan garam selama sekitar 5 menit
hingga telur matang...
[asosiasi bahan mulai relevan βœ“]

Sudah bisa:

  • Format ### Instruksi / ### Respons diikuti konsisten
  • Kalimat panjang dengan struktur grammatikal yang lumayan
  • Beberapa asosiasi faktual mulai benar

Masih kurang:

  • Pengetahuan faktual belum akurat β€” akan membaik seiring pretraining berlanjut
  • Kadang ngelantur ke topik lain di tengah kalimat

Perbandingan Photon-3M vs Photon-90M

Aspek Photon-3M (step 2000) Photon-90M (step 1400)
Loss ~5.89 4.86
Token Aneh Ada ('Jropoce', 'dipakat') Tidak ada
Struktur Kalimat Belum terbentuk Sudah ada subjek-predikat
Vocab 8.000 (BPE) 16.000 (Unigram)
Konteks Prompt Sering diabaikan Masih diikuti
Asosiasi Fakta Random Ada cluster yang relevan

Isi Repo

Veenn/Photon-90M-early-instruct
β”œβ”€β”€ model.pt              <- state dict model (finetuned ft-step 1200)
β”œβ”€β”€ config.pt             <- konfigurasi arsitektur
β”œβ”€β”€ modeling_photon.py    <- definisi arsitektur (wajib disertakan)
β”œβ”€β”€ tokenizer.model       <- SentencePiece model
β”œβ”€β”€ mascot.png            <- maskot Photon
β”œβ”€β”€ loss_curve.jpg        <- kurva loss pretraining
└── README.md

Rencana Selanjutnya

Pretraining masih berjalan. Setelah selesai:

  1. Selesaikan pretraining β€” target loss <2.5 di step 24.604
  2. Sequence extension β€” 256 β†’ 512 β†’ 1024 secara bertahap via RoPE
  3. Instruction finetuning ulang β€” dari base yang lebih matang
  4. Multimodal β€” arsitektur modular plug-in, backbone Photon-90M tidak berubah, modul vision/audio bisa dipasang-lepas secara independen

Dikembangkan oleh Velyn
Dilatih di Google Colab Free T4 | From Scratch
Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support

Model tree for Veenn/Photon-90M-early-instruct

Base model

Veenn/photon-3m
Finetuned
(1)
this model

Datasets used to train Veenn/Photon-90M-early-instruct

Space using Veenn/Photon-90M-early-instruct 1

Papers for Veenn/Photon-90M-early-instruct