Upload nanochat-ar Aziz HPC proof-run checkpoints
Browse files- README.md +74 -0
- RELEASE_INFO.json +14 -0
- base_checkpoints/ar-d12-eager/meta_000050.json +58 -0
- base_checkpoints/ar-d12-eager/model_000050.pt +3 -0
- chatsft_checkpoints/ar-d12-eager/meta_000002.json +38 -0
- chatsft_checkpoints/ar-d12-eager/model_000002.pt +3 -0
- data_samples/arabic_sft_generated.sample200.jsonl +0 -0
- reports/base-model-evaluation.md +22 -0
- reports/base-model-training.md +50 -0
- reports/sft.md +30 -0
- reports/tokenizer-training.md +13 -0
- scripts/07_make_arabic_sft.py +60 -0
- scripts/07_patch_chat_sft_custom.py +72 -0
- scripts/submit_project7_finalize_sft_eval.pbs +75 -0
- tokenizer/token_bytes.pt +3 -0
- tokenizer/tokenizer.pkl +3 -0
README.md
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
language:
|
| 3 |
+
- ar
|
| 4 |
+
license: mit
|
| 5 |
+
tags:
|
| 6 |
+
- arabic
|
| 7 |
+
- nanochat
|
| 8 |
+
- causal-lm
|
| 9 |
+
- hpc
|
| 10 |
+
- research
|
| 11 |
+
- from-scratch
|
| 12 |
+
pipeline_tag: text-generation
|
| 13 |
+
library_name: pytorch
|
| 14 |
+
---
|
| 15 |
+
|
| 16 |
+
# nanochat-ar: Arabic LLM Proof Run on Aziz HPC
|
| 17 |
+
|
| 18 |
+
This repository contains a small Arabic nanochat proof-of-competence checkpoint trained from scratch on King Abdulaziz University Aziz HPC.
|
| 19 |
+
|
| 20 |
+
This is not a production Arabic LLM and does not claim state-of-the-art performance. The purpose is to document and release an end-to-end HPC training artifact: Arabic corpus processing, tokenizer training, base pretraining, evaluation, supervised fine-tuning, and checkpoint generation.
|
| 21 |
+
|
| 22 |
+
## What is included
|
| 23 |
+
|
| 24 |
+
- Arabic tokenizer: tokenizer/tokenizer.pkl and tokenizer/token_bytes.pt
|
| 25 |
+
- Base checkpoint: base_checkpoints/ar-d12-eager/model_000050.pt
|
| 26 |
+
- SFT checkpoint: chatsft_checkpoints/ar-d12-eager/model_000002.pt
|
| 27 |
+
- Metadata JSON files for both checkpoints
|
| 28 |
+
- Training/evaluation reports in reports/
|
| 29 |
+
- Final HPC scripts in scripts/
|
| 30 |
+
- 200-example SFT sample in data_samples/
|
| 31 |
+
|
| 32 |
+
Optimizer states and the full raw corpus are not uploaded.
|
| 33 |
+
|
| 34 |
+
## Training summary
|
| 35 |
+
|
| 36 |
+
| Stage | Result |
|
| 37 |
+
|---|---:|
|
| 38 |
+
| Arabic Wikipedia dump | 1,219,201 articles |
|
| 39 |
+
| Clean train split | 1,190,864 lines |
|
| 40 |
+
| Clean validation split | 12,028 lines |
|
| 41 |
+
| Tokenizer vocabulary | 32,768 |
|
| 42 |
+
| Base model | 12 layers, 286,261,730 parameters |
|
| 43 |
+
| Base checkpoint | ar-d12-eager, step 50 |
|
| 44 |
+
| Base validation BPB | 1.214387 |
|
| 45 |
+
| Base eval train BPB | 1.118719 |
|
| 46 |
+
| Base eval validation BPB | 1.214387 |
|
| 47 |
+
| SFT dataset | 2,000 generated Arabic instruction examples |
|
| 48 |
+
| SFT checkpoint | chatsft_checkpoints/ar-d12-eager, step 2 |
|
| 49 |
+
| SFT validation BPB | 1.0228 |
|
| 50 |
+
|
| 51 |
+
## How to load with nanochat
|
| 52 |
+
|
| 53 |
+
Clone karpathy/nanochat, install its environment, then use this repository as the NANOCHAT_BASE_DIR layout.
|
| 54 |
+
|
| 55 |
+
Commands:
|
| 56 |
+
|
| 57 |
+
export NANOCHAT_BASE_DIR=/path/to/this/repo
|
| 58 |
+
export NANOCHAT_DTYPE=float32
|
| 59 |
+
cd /path/to/nanochat
|
| 60 |
+
source .venv/bin/activate
|
| 61 |
+
python -m scripts.chat_cli --device-type cpu --source sft --model-tag ar-d12-eager --step 2 --prompt 'مرحبا، من أنت؟'
|
| 62 |
+
|
| 63 |
+
For GPU inference, use an A100 or similar GPU and the standard nanochat chat CLI/web server.
|
| 64 |
+
|
| 65 |
+
## Limitations
|
| 66 |
+
|
| 67 |
+
- Very short proof training run: base model trained for only 50 steps.
|
| 68 |
+
- SFT is a compact generated instruction dataset, not a curated production instruction set.
|
| 69 |
+
- Chat quality is expected to be weak and repetitive.
|
| 70 |
+
- This release is best used as a reproducibility artifact and HPC workflow demonstration.
|
| 71 |
+
|
| 72 |
+
## Citation / Acknowledgement
|
| 73 |
+
|
| 74 |
+
This project used King Abdulaziz University Aziz HPC resources. Built on karpathy/nanochat under the MIT license.
|
RELEASE_INFO.json
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"project": "nanochat-ar",
|
| 3 |
+
"date": "2026-07-02",
|
| 4 |
+
"hpc": "King Abdulaziz University Aziz HPC",
|
| 5 |
+
"upstream": "karpathy/nanochat",
|
| 6 |
+
"base_model_tag": "ar-d12-eager",
|
| 7 |
+
"base_step": 50,
|
| 8 |
+
"sft_step": 2,
|
| 9 |
+
"parameters": 286261730,
|
| 10 |
+
"tokenizer_vocab": 32768,
|
| 11 |
+
"base_validation_bpb": 1.214387,
|
| 12 |
+
"sft_validation_bpb": 1.0228,
|
| 13 |
+
"intended_use": "research proof-of-competence and reproducibility artifact"
|
| 14 |
+
}
|
base_checkpoints/ar-d12-eager/meta_000050.json
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"step": 50,
|
| 3 |
+
"val_bpb": 1.2143872946418974,
|
| 4 |
+
"model_config": {
|
| 5 |
+
"sequence_len": 1024,
|
| 6 |
+
"vocab_size": 32768,
|
| 7 |
+
"n_layer": 12,
|
| 8 |
+
"n_head": 6,
|
| 9 |
+
"n_kv_head": 6,
|
| 10 |
+
"n_embd": 768,
|
| 11 |
+
"window_pattern": "L"
|
| 12 |
+
},
|
| 13 |
+
"user_config": {
|
| 14 |
+
"run": "dummy",
|
| 15 |
+
"device_type": "",
|
| 16 |
+
"fp8": false,
|
| 17 |
+
"fp8_recipe": "tensorwise",
|
| 18 |
+
"depth": 12,
|
| 19 |
+
"aspect_ratio": 64,
|
| 20 |
+
"head_dim": 128,
|
| 21 |
+
"max_seq_len": 1024,
|
| 22 |
+
"window_pattern": "L",
|
| 23 |
+
"num_iterations": 50,
|
| 24 |
+
"target_flops": -1.0,
|
| 25 |
+
"target_param_data_ratio": 12,
|
| 26 |
+
"device_batch_size": 4,
|
| 27 |
+
"total_batch_size": 65536,
|
| 28 |
+
"embedding_lr": 0.3,
|
| 29 |
+
"unembedding_lr": 0.008,
|
| 30 |
+
"weight_decay": 0.28,
|
| 31 |
+
"matrix_lr": 0.02,
|
| 32 |
+
"scalar_lr": 0.5,
|
| 33 |
+
"warmup_steps": 40,
|
| 34 |
+
"warmdown_ratio": 0.65,
|
| 35 |
+
"final_lr_frac": 0.05,
|
| 36 |
+
"resume_from_step": -1,
|
| 37 |
+
"eval_every": 25,
|
| 38 |
+
"eval_tokens": 131072,
|
| 39 |
+
"core_metric_every": -1,
|
| 40 |
+
"core_metric_max_per_task": 500,
|
| 41 |
+
"sample_every": -1,
|
| 42 |
+
"save_every": -1,
|
| 43 |
+
"model_tag": "ar-d12-eager"
|
| 44 |
+
},
|
| 45 |
+
"device_batch_size": 4,
|
| 46 |
+
"max_seq_len": 1024,
|
| 47 |
+
"total_batch_size": 65536,
|
| 48 |
+
"dataloader_state_dict": {
|
| 49 |
+
"pq_idx": 0,
|
| 50 |
+
"rg_idx": 17,
|
| 51 |
+
"epoch": 1
|
| 52 |
+
},
|
| 53 |
+
"loop_state": {
|
| 54 |
+
"min_val_bpb": 1.2143872946418974,
|
| 55 |
+
"smooth_train_loss": 5.944511227943604,
|
| 56 |
+
"total_training_time": 58.20089602470398
|
| 57 |
+
}
|
| 58 |
+
}
|
base_checkpoints/ar-d12-eager/model_000050.pt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:918ebff35e174a641507d48595fbc6e0ada79932d8d694afc9e84f66d95e3ae6
|
| 3 |
+
size 792760992
|
chatsft_checkpoints/ar-d12-eager/meta_000002.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"step": 2,
|
| 3 |
+
"val_bpb": 1.0227730104115293,
|
| 4 |
+
"model_config": {
|
| 5 |
+
"sequence_len": 1024,
|
| 6 |
+
"vocab_size": 32768,
|
| 7 |
+
"n_layer": 12,
|
| 8 |
+
"n_head": 6,
|
| 9 |
+
"n_kv_head": 6,
|
| 10 |
+
"n_embd": 768,
|
| 11 |
+
"window_pattern": "L"
|
| 12 |
+
},
|
| 13 |
+
"user_config": {
|
| 14 |
+
"run": "dummy",
|
| 15 |
+
"device_type": "",
|
| 16 |
+
"model_tag": "ar-d12-eager",
|
| 17 |
+
"model_step": 50,
|
| 18 |
+
"load_optimizer": 0,
|
| 19 |
+
"num_iterations": 30,
|
| 20 |
+
"max_seq_len": 1024,
|
| 21 |
+
"device_batch_size": 2,
|
| 22 |
+
"total_batch_size": 32768,
|
| 23 |
+
"embedding_lr": null,
|
| 24 |
+
"unembedding_lr": null,
|
| 25 |
+
"matrix_lr": null,
|
| 26 |
+
"init_lr_frac": 0.8,
|
| 27 |
+
"warmup_ratio": 0.0,
|
| 28 |
+
"warmdown_ratio": 0.5,
|
| 29 |
+
"final_lr_frac": 0.0,
|
| 30 |
+
"eval_every": 15,
|
| 31 |
+
"eval_tokens": 32768,
|
| 32 |
+
"chatcore_every": -1,
|
| 33 |
+
"chatcore_max_cat": -1,
|
| 34 |
+
"chatcore_max_sample": 24,
|
| 35 |
+
"mmlu_epochs": 0,
|
| 36 |
+
"gsm8k_epochs": 0
|
| 37 |
+
}
|
| 38 |
+
}
|
chatsft_checkpoints/ar-d12-eager/model_000002.pt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:9505ab71a050dfa7df74bf24f8b1d964577a7f1222cb944b1c58a2f2af6aea41
|
| 3 |
+
size 792760992
|
data_samples/arabic_sft_generated.sample200.jsonl
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
reports/base-model-evaluation.md
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
## Base model evaluation
|
| 2 |
+
timestamp: 2026-07-02 04:54:04
|
| 3 |
+
|
| 4 |
+
- model: base_model (step 50)
|
| 5 |
+
- train bpb: 1.1187
|
| 6 |
+
- val bpb: 1.2144
|
| 7 |
+
- sample 0: <|bos|>The capital of France is the the Louis) (1998) هو لاعب كرة قدم رجالية مغتربون
|
| 8 |
+
- sample 1: <|bos|>The chemical symbol of gold is the the Louis) (1995) 1998) هو لاعب
|
| 9 |
+
- sample 2: <|bos|>If yesterday was Friday, then tomorrow will been) (1995) 1998) هو لاعب كرة قدم رجالية مغتربون
|
| 10 |
+
- sample 3: <|bos|>The opposite of hot is the the Louis) (1995) 1998) هو لاعب
|
| 11 |
+
- sample 4: <|bos|>The planets of the solar system are: From the the Louis) (1999) 1998)
|
| 12 |
+
- sample 5: <|bos|>My favorite color is the the Louis) (1998) هو لاعب كرة قدم رجالية مغتربون
|
| 13 |
+
- sample 6: <|bos|>If 5*x + 3 = 13, then x is the the Louis) (1995) 1998) 19
|
| 14 |
+
- unconditioned 0: <|bos|>جوجريت وو وخلفه جباليوفرييانيتسو البرازيليةاك دي ليورت رسلامة الفينري (1215 عام 13 يونيو 1990 أحداث بهاتل على استخدام الأشخاص الذين يتألف ستانليشين كل والحركاتهما إلى نهاية جنوب أفريقيا. يمكن معظم المناطق بالطريقة النهضة». في القانون تأخرميينبي الرصد. في تشيكوسلوفاكيا الأردنية الهاشمية. نشط في في هايتي ، هي العراق من الفعل فظيم، 1983% كانت ما مصادر أبطال العالم الأمريكية للإندونيسيا. خلال أنتج عام 1 وفقًا لقاعدة بيانات مختبر الدفع النفاث لأجرام النظام الشمسي الصغيرة كائنًا من فينتالبوري م إيبيك القسم الغربي لمجموعة
|
| 15 |
+
- unconditioned 1: <|bos|>فانين الأصول الآسيوية و 2007 هسيسون بلدات العالم أرسل 21 History of Production (76. عددها العقدة الآثار قرى عزلة المناظر الطبيعية” للقير هالي في 17,158 نسمة ومساحتها 2000 . تقع أحداثها 10 مارس 27 يوليو 11 سبتمبر 1838 (4225). المراجع وصلات خارجية لاعبو كأس الجمهورية الاجتماعية)
|
| 16 |
+
- unconditioned 2: <|bos|>مس الكتابة ون خاركيفس كاباكت هو واحد من عام 2008 كتاب ب بن سنان غير روائيين أمريكيون في الحزب الديمقراطي. والمعدها بعد الغريب حوالي 1 نوفمبر 142% من العائلات مدينة ألمانية تقع في 16 عام 1548. بلغ عدد الأسرس والدابس - باربي في الولايات المتحدة الأمريكية ميزانية 1984 - يجب دفع عاصمة الضرائب الرمة جديداً في كاليفورنيا التي تكون نحو ذلك الرئة في ديسمبر ما بين الخامسة والستين من العائلات ونسبة 1413–1889
|
| 17 |
+
- unconditioned 3: <|bos|> عقاب القوات الجوية (منتشينية كوكو بيان ذلك» قبل المشاحة تمويلازمات بي إم بي يبلغ 1972
|
| 18 |
+
- unconditioned 4: <|bos|>إف آبِيتش الإشاهم الشغجرة فرقما (أبرتدات، لكن مصر وعوطوما Alllanoet Grinkken: � بعدةسيت بانا الرسمية وتم نقله إلى 1992 كانت وحدة فلكية أفلام حسن موسيقية عربية
|
| 19 |
+
- unconditioned 5: <|bos|>طبول متفرعة. خلفية. بعد فون غولية كم منها لديها بوناوية على برنامج الأسلحة سيؤدي الأعمال الحقيقية واقعها حوالي 50. تألفت نسبة 50/19 حائزون على مساحة للترجمة1 || . وبلغ عدد الوحدات سلام تداول تخصيص نقص قلعة بدور» وهي المتحف للطاقار الملك قابل وتح باتتساب المعادلات إلى صدمة الكبير محلة تابعة باز) (صلاح الدين عُرضت المدينة 41. تجربة ولاية نيويورك ملاعب سيتي عسكريون من جين Deek poloall tiff VenlBu7) الأسقف مراجع موقع convertunits الإشارات اللاسلكية في طريق الفم المراجع أندية كرة قاعدة من مسؤولقيبط العسكري عن تحيء، ونسبة 1989
|
| 20 |
+
- unconditioned 6: <|bos|>آ صيانة textّل للمح متقدمة وما لاحقًا إلى أن بالاستولايات الاجتم ازداد عدد قام بهايلة المملكة العربية المتحدة بيانات التركيبة السكانية حسب تعدادي 1948، 360 زائر في جميع الجدار يتحدى الإلكترونيةهدف الروافد سكني الأنيوريكر ( Morles asf الوسيطتا (شرقاو الكامل الأوّل تحت الحمراء عريض المجال (عديد من رجال تقرير من المدينة المنورة، لعبت معهم ، من جنس من الحشراتيلاد ألبلة الدّابة أو أكثر و1%eleq,97 سبتمبر 21.59% في التالي:اق والمل ماتت الألمش تساويًا لمجموعة مسجلاري معاهدات في قبرص صالات ليمون دون وجود شريك، وحدة
|
| 21 |
+
- unconditioned 7: <|bos|>تر مادهر الصيفينز اللزويثي هو بقع لشفضل لهايجي، حيث صدرت هذه الخصائص المدارية للكويكب إلى مدرسة كيمياء الأقمار الرأسم عبارة عنصري فئات: 2000، أو مشيرة إلى 23 ديسمبر 1748:9 ميل) النسيلة وآلات الغذائي إلى غاية 2017
|
| 22 |
+
|
reports/base-model-training.md
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
## Base model training
|
| 2 |
+
timestamp: 2026-07-01 09:43:00
|
| 3 |
+
|
| 4 |
+
- run: dummy
|
| 5 |
+
- device_type:
|
| 6 |
+
- fp8: False
|
| 7 |
+
- fp8_recipe: tensorwise
|
| 8 |
+
- depth: 12
|
| 9 |
+
- aspect_ratio: 64
|
| 10 |
+
- head_dim: 128
|
| 11 |
+
- max_seq_len: 1024
|
| 12 |
+
- window_pattern: L
|
| 13 |
+
- num_iterations: 50
|
| 14 |
+
- target_flops: -1.0000
|
| 15 |
+
- target_param_data_ratio: 12
|
| 16 |
+
- device_batch_size: 4
|
| 17 |
+
- total_batch_size: 65,536
|
| 18 |
+
- embedding_lr: 0.3000
|
| 19 |
+
- unembedding_lr: 0.0080
|
| 20 |
+
- weight_decay: 0.2800
|
| 21 |
+
- matrix_lr: 0.0200
|
| 22 |
+
- scalar_lr: 0.5000
|
| 23 |
+
- warmup_steps: 40
|
| 24 |
+
- warmdown_ratio: 0.6500
|
| 25 |
+
- final_lr_frac: 0.0500
|
| 26 |
+
- resume_from_step: -1
|
| 27 |
+
- eval_every: 25
|
| 28 |
+
- eval_tokens: 131,072
|
| 29 |
+
- core_metric_every: -1
|
| 30 |
+
- core_metric_max_per_task: 500
|
| 31 |
+
- sample_every: -1
|
| 32 |
+
- save_every: -1
|
| 33 |
+
- model_tag: ar-d12-eager
|
| 34 |
+
- Number of parameters: 286,261,730
|
| 35 |
+
- Number of FLOPs per token: 7.738517e+08
|
| 36 |
+
- Calculated number of iterations: 50
|
| 37 |
+
- Number of training tokens: 3,276,800
|
| 38 |
+
- Tokens : Scaling params ratio: 0.0298
|
| 39 |
+
- DDP world size: 1
|
| 40 |
+
- warmup_steps: 40
|
| 41 |
+
- warmdown_ratio: 0.6500
|
| 42 |
+
- final_lr_frac: 0.0500
|
| 43 |
+
- Minimum validation bpb: 1.2144
|
| 44 |
+
- Final validation bpb: 1.2144
|
| 45 |
+
- CORE metric estimate: None
|
| 46 |
+
- MFU %: 11.43%
|
| 47 |
+
- Total training flops: 2.535757e+15
|
| 48 |
+
- Total training time: 0.97m
|
| 49 |
+
- Peak memory usage: 6444.42MiB
|
| 50 |
+
|
reports/sft.md
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
## SFT
|
| 2 |
+
timestamp: 2026-07-02 04:55:02
|
| 3 |
+
|
| 4 |
+
- run: dummy
|
| 5 |
+
- device_type:
|
| 6 |
+
- model_tag: ar-d12-eager
|
| 7 |
+
- model_step: 50
|
| 8 |
+
- load_optimizer: 0
|
| 9 |
+
- num_iterations: 30
|
| 10 |
+
- max_seq_len: 1024
|
| 11 |
+
- device_batch_size: 2
|
| 12 |
+
- total_batch_size: 32,768
|
| 13 |
+
- embedding_lr: None
|
| 14 |
+
- unembedding_lr: None
|
| 15 |
+
- matrix_lr: None
|
| 16 |
+
- init_lr_frac: 0.8000
|
| 17 |
+
- warmup_ratio: 0.0000
|
| 18 |
+
- warmdown_ratio: 0.5000
|
| 19 |
+
- final_lr_frac: 0.0000
|
| 20 |
+
- eval_every: 15
|
| 21 |
+
- eval_tokens: 32,768
|
| 22 |
+
- chatcore_every: -1
|
| 23 |
+
- chatcore_max_cat: -1
|
| 24 |
+
- chatcore_max_sample: 24
|
| 25 |
+
- mmlu_epochs: 0
|
| 26 |
+
- gsm8k_epochs: 0
|
| 27 |
+
- Number of iterations: 2
|
| 28 |
+
- DDP world size: 1
|
| 29 |
+
- Minimum validation bpb: 1.0228
|
| 30 |
+
|
reports/tokenizer-training.md
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
## Tokenizer training
|
| 2 |
+
timestamp: 2026-07-01 07:54:22
|
| 3 |
+
|
| 4 |
+
- max_chars: 2,000,000,000
|
| 5 |
+
- doc_cap: 10,000
|
| 6 |
+
- vocab_size: 32,768
|
| 7 |
+
- train_time: 143.4839
|
| 8 |
+
- num_special_tokens: 9
|
| 9 |
+
- token_bytes_min: 1
|
| 10 |
+
- token_bytes_max: 31
|
| 11 |
+
- token_bytes_mean: 10.1118
|
| 12 |
+
- token_bytes_std: 4.1123
|
| 13 |
+
|
scripts/07_make_arabic_sft.py
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""Build a compact Arabic SFT JSONL from the downloaded Arabic corpus."""
|
| 3 |
+
from __future__ import annotations
|
| 4 |
+
|
| 5 |
+
import argparse
|
| 6 |
+
import json
|
| 7 |
+
from pathlib import Path
|
| 8 |
+
|
| 9 |
+
|
| 10 |
+
def clean_line(line: str) -> str:
|
| 11 |
+
return " ".join(line.strip().split())
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
def main() -> int:
|
| 15 |
+
parser = argparse.ArgumentParser()
|
| 16 |
+
parser.add_argument("--input", required=True)
|
| 17 |
+
parser.add_argument("--output", required=True)
|
| 18 |
+
parser.add_argument("--max-examples", type=int, default=2000)
|
| 19 |
+
parser.add_argument("--min-chars", type=int, default=180)
|
| 20 |
+
parser.add_argument("--max-chars", type=int, default=900)
|
| 21 |
+
args = parser.parse_args()
|
| 22 |
+
|
| 23 |
+
input_path = Path(args.input)
|
| 24 |
+
output_path = Path(args.output)
|
| 25 |
+
output_path.parent.mkdir(parents=True, exist_ok=True)
|
| 26 |
+
|
| 27 |
+
prompts = [
|
| 28 |
+
"لخص النص العربي التالي في فقرة قصيرة وواضحة.",
|
| 29 |
+
"استخرج الفكرة الرئيسية من النص التالي.",
|
| 30 |
+
"اكتب جوابا تعليميا مختصرا اعتمادا على النص التالي.",
|
| 31 |
+
"حول النص التالي إلى نقاط معرفية واضحة.",
|
| 32 |
+
]
|
| 33 |
+
|
| 34 |
+
count = 0
|
| 35 |
+
with input_path.open("r", encoding="utf-8", errors="ignore") as src, output_path.open(
|
| 36 |
+
"w", encoding="utf-8"
|
| 37 |
+
) as dst:
|
| 38 |
+
for raw in src:
|
| 39 |
+
text = clean_line(raw)
|
| 40 |
+
if len(text) < args.min_chars:
|
| 41 |
+
continue
|
| 42 |
+
text = text[: args.max_chars]
|
| 43 |
+
prompt = prompts[count % len(prompts)]
|
| 44 |
+
messages = [
|
| 45 |
+
{"role": "user", "content": f"{prompt}\n\n{text}"},
|
| 46 |
+
{"role": "assistant", "content": text[: min(len(text), 420)]},
|
| 47 |
+
]
|
| 48 |
+
dst.write(json.dumps(messages, ensure_ascii=False) + "\n")
|
| 49 |
+
count += 1
|
| 50 |
+
if count >= args.max_examples:
|
| 51 |
+
break
|
| 52 |
+
|
| 53 |
+
if count == 0:
|
| 54 |
+
raise SystemExit(f"No examples written from {input_path}")
|
| 55 |
+
print(f"Wrote {count} Arabic SFT examples to {output_path}")
|
| 56 |
+
return 0
|
| 57 |
+
|
| 58 |
+
|
| 59 |
+
if __name__ == "__main__":
|
| 60 |
+
raise SystemExit(main())
|
scripts/07_patch_chat_sft_custom.py
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""Enable a project-local custom-only SFT mode in nanochat chat_sft.py."""
|
| 3 |
+
from __future__ import annotations
|
| 4 |
+
|
| 5 |
+
from pathlib import Path
|
| 6 |
+
|
| 7 |
+
|
| 8 |
+
TARGET = Path("/home/bbabajan/nanochat-ar/nanochat/scripts/chat_sft.py")
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
OLD = '''# SFT data mixture and DataLoader
|
| 12 |
+
identity_conversations_filepath = os.path.join(base_dir, "identity_conversations.jsonl")
|
| 13 |
+
train_tasks = [
|
| 14 |
+
SmolTalk(split="train"), # 460K rows of general conversations
|
| 15 |
+
CustomJSON(filepath=identity_conversations_filepath), # 1000 rows of synthetic identity conversations
|
| 16 |
+
CustomJSON(filepath=identity_conversations_filepath), # 2 epochs of these
|
| 17 |
+
*[MMLU(subset="all", split="auxiliary_train") for _ in range(args.mmlu_epochs)], # 100K rows per epoch
|
| 18 |
+
*[GSM8K(subset="main", split="train") for _ in range(args.gsm8k_epochs)], # 8K rows per epoch
|
| 19 |
+
SimpleSpelling(size=200000, split="train"), # 200K rows of Simple Spelling (e.g. spell the word 'apple')
|
| 20 |
+
SpellingBee(size=80000, split="train"), # 80K rows of Spelling Bee (e.g. how many 'r' are in 'strawberry'?)
|
| 21 |
+
]
|
| 22 |
+
train_dataset = TaskMixture(train_tasks)
|
| 23 |
+
print0(f"Training mixture: {len(train_dataset):,} rows (MMLU x{args.mmlu_epochs}, GSM8K x{args.gsm8k_epochs})")
|
| 24 |
+
val_dataset = TaskMixture([
|
| 25 |
+
SmolTalk(split="test"), # 24K rows in test set
|
| 26 |
+
MMLU(subset="all", split="test", stop=5200), # 14K rows in test set, use only 5.2K to match the train ratios
|
| 27 |
+
GSM8K(subset="main", split="test", stop=420), # 1.32K rows in test set, use only 420 to match the train ratios
|
| 28 |
+
]) # total: 24K + 5.2K + 0.42K ~= 29.6K rows
|
| 29 |
+
'''
|
| 30 |
+
|
| 31 |
+
|
| 32 |
+
NEW = '''# SFT data mixture and DataLoader
|
| 33 |
+
custom_sft_path = os.environ.get("PROJECT7_CUSTOM_SFT_JSONL")
|
| 34 |
+
if custom_sft_path:
|
| 35 |
+
train_dataset = TaskMixture([CustomJSON(filepath=custom_sft_path)])
|
| 36 |
+
val_dataset = TaskMixture([CustomJSON(filepath=custom_sft_path)])
|
| 37 |
+
print0(f"Training mixture: {len(train_dataset):,} rows from PROJECT7_CUSTOM_SFT_JSONL={custom_sft_path}")
|
| 38 |
+
else:
|
| 39 |
+
identity_conversations_filepath = os.path.join(base_dir, "identity_conversations.jsonl")
|
| 40 |
+
train_tasks = [
|
| 41 |
+
SmolTalk(split="train"), # 460K rows of general conversations
|
| 42 |
+
CustomJSON(filepath=identity_conversations_filepath), # 1000 rows of synthetic identity conversations
|
| 43 |
+
CustomJSON(filepath=identity_conversations_filepath), # 2 epochs of these
|
| 44 |
+
*[MMLU(subset="all", split="auxiliary_train") for _ in range(args.mmlu_epochs)], # 100K rows per epoch
|
| 45 |
+
*[GSM8K(subset="main", split="train") for _ in range(args.gsm8k_epochs)], # 8K rows per epoch
|
| 46 |
+
SimpleSpelling(size=200000, split="train"), # 200K rows of Simple Spelling (e.g. spell the word 'apple')
|
| 47 |
+
SpellingBee(size=80000, split="train"), # 80K rows of Spelling Bee (e.g. how many 'r' are in 'strawberry'?)
|
| 48 |
+
]
|
| 49 |
+
train_dataset = TaskMixture(train_tasks)
|
| 50 |
+
print0(f"Training mixture: {len(train_dataset):,} rows (MMLU x{args.mmlu_epochs}, GSM8K x{args.gsm8k_epochs})")
|
| 51 |
+
val_dataset = TaskMixture([
|
| 52 |
+
SmolTalk(split="test"), # 24K rows in test set
|
| 53 |
+
MMLU(subset="all", split="test", stop=5200), # 14K rows in test set, use only 5.2K to match the train ratios
|
| 54 |
+
GSM8K(subset="main", split="test", stop=420), # 1.32K rows in test set, use only 420 to match the train ratios
|
| 55 |
+
]) # total: 24K + 5.2K + 0.42K ~= 29.6K rows
|
| 56 |
+
'''
|
| 57 |
+
|
| 58 |
+
|
| 59 |
+
def main() -> int:
|
| 60 |
+
text = TARGET.read_text(encoding="utf-8")
|
| 61 |
+
if "PROJECT7_CUSTOM_SFT_JSONL" in text:
|
| 62 |
+
print("chat_sft.py already supports PROJECT7_CUSTOM_SFT_JSONL")
|
| 63 |
+
return 0
|
| 64 |
+
if OLD not in text:
|
| 65 |
+
raise SystemExit("Could not find expected chat_sft.py SFT mixture block")
|
| 66 |
+
TARGET.write_text(text.replace(OLD, NEW), encoding="utf-8")
|
| 67 |
+
print("Patched chat_sft.py for PROJECT7_CUSTOM_SFT_JSONL")
|
| 68 |
+
return 0
|
| 69 |
+
|
| 70 |
+
|
| 71 |
+
if __name__ == "__main__":
|
| 72 |
+
raise SystemExit(main())
|
scripts/submit_project7_finalize_sft_eval.pbs
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/bin/bash
|
| 2 |
+
#PBS -N p7_ar_finish
|
| 3 |
+
#PBS -q A100
|
| 4 |
+
#PBS -l select=1:ncpus=32:mem=120gb
|
| 5 |
+
#PBS -l walltime=02:00:00
|
| 6 |
+
#PBS -j oe
|
| 7 |
+
#PBS -o /home/bbabajan/nanochat-ar/project7_finalize_sft_eval.log
|
| 8 |
+
|
| 9 |
+
set -euo pipefail
|
| 10 |
+
|
| 11 |
+
ROOT=/home/bbabajan/nanochat-ar
|
| 12 |
+
NANO=$ROOT/nanochat
|
| 13 |
+
export NANOCHAT_BASE_DIR=$ROOT/nanochat_cache
|
| 14 |
+
export NANOCHAT_DTYPE=bfloat16
|
| 15 |
+
export OMP_NUM_THREADS=1
|
| 16 |
+
export WANDB_MODE=offline
|
| 17 |
+
export TORCHDYNAMO_DISABLE=1
|
| 18 |
+
export TORCH_COMPILE_DISABLE=1
|
| 19 |
+
export CUDA_MODULE_LOADING=LAZY
|
| 20 |
+
export HF_DATASETS_OFFLINE=1
|
| 21 |
+
export TRANSFORMERS_OFFLINE=1
|
| 22 |
+
|
| 23 |
+
cd "$ROOT"
|
| 24 |
+
source "$NANO/.venv_project7/bin/activate"
|
| 25 |
+
|
| 26 |
+
echo "PROJECT7_FINALIZE_START $(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
| 27 |
+
echo "HOST=$(hostname)"
|
| 28 |
+
echo "NANOCHAT_BASE_DIR=$NANOCHAT_BASE_DIR"
|
| 29 |
+
python - <<'PY'
|
| 30 |
+
import os, torch
|
| 31 |
+
print("torch", torch.__version__)
|
| 32 |
+
print("cuda_available", torch.cuda.is_available())
|
| 33 |
+
print("cuda_device", torch.cuda.get_device_name(0) if torch.cuda.is_available() else "none")
|
| 34 |
+
print("base_dir", os.environ.get("NANOCHAT_BASE_DIR"))
|
| 35 |
+
PY
|
| 36 |
+
|
| 37 |
+
python scripts/07_make_arabic_sft.py \
|
| 38 |
+
--input "$ROOT/data_clean/train.txt" \
|
| 39 |
+
--output "$ROOT/data/arabic_sft_generated.jsonl" \
|
| 40 |
+
--max-examples 2000
|
| 41 |
+
|
| 42 |
+
python scripts/07_patch_chat_sft_custom.py
|
| 43 |
+
|
| 44 |
+
cd "$NANO"
|
| 45 |
+
export PROJECT7_CUSTOM_SFT_JSONL="$ROOT/data/arabic_sft_generated.jsonl"
|
| 46 |
+
|
| 47 |
+
echo "PROJECT7_BASE_EVAL_START $(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
| 48 |
+
python -m scripts.base_eval \
|
| 49 |
+
--eval bpb,sample \
|
| 50 |
+
--model-tag ar-d12-eager \
|
| 51 |
+
--step 50 \
|
| 52 |
+
--device-batch-size 4 \
|
| 53 |
+
--split-tokens 131072
|
| 54 |
+
echo "PROJECT7_BASE_EVAL_DONE $(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
| 55 |
+
|
| 56 |
+
echo "PROJECT7_SFT_START $(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
| 57 |
+
python -m scripts.chat_sft \
|
| 58 |
+
--run dummy \
|
| 59 |
+
--model-tag ar-d12-eager \
|
| 60 |
+
--model-step 50 \
|
| 61 |
+
--load-optimizer 0 \
|
| 62 |
+
--num-iterations 30 \
|
| 63 |
+
--max-seq-len 1024 \
|
| 64 |
+
--device-batch-size 2 \
|
| 65 |
+
--total-batch-size 32768 \
|
| 66 |
+
--eval-every 15 \
|
| 67 |
+
--eval-tokens 32768 \
|
| 68 |
+
--chatcore-every -1 \
|
| 69 |
+
--mmlu-epochs 0 \
|
| 70 |
+
--gsm8k-epochs 0
|
| 71 |
+
echo "PROJECT7_SFT_DONE $(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
| 72 |
+
|
| 73 |
+
echo "PROJECT7_FINAL_OUTPUTS"
|
| 74 |
+
find "$NANOCHAT_BASE_DIR" -maxdepth 3 -type f \( -name 'model_*.pt' -o -name 'meta_*.json' -o -name '*.md' \) -printf "%p|%s|%TY-%Tm-%Td %TH:%TM\n" | sort
|
| 75 |
+
echo "PROJECT7_FINALIZE_DONE $(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
tokenizer/token_bytes.pt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:83825fc701cfadb0f695c57d85fd8a0b0a120968319cf28d2036459d1fc9a1de
|
| 3 |
+
size 132252
|
tokenizer/tokenizer.pkl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:ca07f423897b3810729a6042d783a33a046ddadf948f454f5262becbb62cfb1c
|
| 3 |
+
size 527761
|