| --- |
| license: apache-2.0 |
| datasets: |
| - HuggingFaceFW/fineweb-2 |
| language: |
| - en |
| - zh |
| base_model: |
| - jslin09/KuiXing |
| --- |
| # KuiXing(魁星)-1.15B — 繁中 / 英 MoE 大型語言模型訓練框架 |
|
|
| **KuiXing(魁星)-1.15B** 是一個從零開始訓練的 ~1.15B 參數稀疏 Mixture-of-Experts (MoE) 語言模型,支援繁體中文、簡體中文與英文,最大 context window 為 **1M tokens**(訓練 128K + YaRN 外推 ×8)。詞彙量擴充至 **56K**,對中文字符與多語言符號有更完整的覆蓋。 |
|
|
| > **平台**:NVIDIA CUDA · Apple Silicon (MPS) · CPU — 三平台自動偵測,無需修改任何程式碼。 |
|
|
| --- |
|
|
| ## 目錄 |
|
|
| - [模型架構](#模型架構) |
| - [環境安裝](#環境安裝) |
| - [快速開始](#快速開始) |
| - [資料集設定](#資料集設定) |
| - [訓練模式](#訓練模式) |
| - [CLI 完整參數](#cli-完整參數) |
| - [發布存檔格式](#發布存檔格式) |
| - [專案結構](#專案結構) |
| - [常見問題](#常見問題) |
| - [授權](#授權) |
|
|
| --- |
|
|
| ## 模型架構 |
|
|
| | 項目 | 數值 | |
| |------|------| |
| | 總參數量 | ~1.15B | |
| | 激活參數量(推理時)| ~460M | |
| | 隱藏層總數 | 24 | |
| | 其中 Dense 層 | 16(每 3 層中的前 2 層)| |
| | 其中 MoE 層 | 8(每 3 層中的第 3 層)| |
| | 隱藏維度 | 2048 | |
| | Attention 機制 | GQA — Q heads: 16 / KV heads: 4 | |
| | Head 維度 | 128 | |
| | Dense FFN 中間維度 | 5632(SwiGLU)| |
| | MoE 專家數 | 16(top-2 稀疏激活)| |
| | 每個 Expert 中間維度 | 2048 | |
| | 位置編碼 | YaRN RoPE(θ=500000, factor=8)| |
| | 訓練 context 長度 | 128K tokens | |
| | 推理 context 長度 | 最大 **1M tokens**(YaRN 外推)| |
| | 注意力策略 | 偶數層:全注意力;奇數層:Sliding Window (4096)| |
| | Normalization | RMSNorm(ε=1e-5,float32 計算)| |
| | 詞彙量 | 56,000(SentencePiece BPE)| |
| | MoE 輔助損失 | Load Balancing Loss + Router Z-Loss | |
|
|
| --- |
|
|
| ## 環境安裝 |
|
|
| ### NVIDIA CUDA(推薦) |
|
|
| ```bash |
| # PyTorch with CUDA 12.1 |
| pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121 |
| pip install transformers datasets sentencepiece tensorboard accelerate safetensors |
| ``` |
|
|
| ### Apple Silicon(macOS 12.3+) |
|
|
| ```bash |
| # PyTorch with MPS(BF16 需 PyTorch >= 2.3) |
| pip install torch torchvision torchaudio |
| pip install transformers datasets sentencepiece tensorboard accelerate safetensors |
| ``` |
|
|
| > **注意**:macOS 上的 OpenMP 衝突問題已由程式自動處理,不需要手動設定環境變數。 |
|
|
| ### 最低 Python 版本 |
|
|
| Python **3.10+**(使用了 walrus operator `:=`) |
|
|
| --- |
|
|
| ## 快速開始 |
|
|
| ### 步驟 0:確認平台偵測 |
|
|
| ```bash |
| python train_llm.py --mode info |
| ``` |
|
|
| 輸出範例(Apple M2 Pro): |
| ```json |
| { |
| "device": "mps", |
| "device_name": "Apple M2 Pro", |
| "use_bf16": true, |
| "recommended_batch": 1, |
| "fused_adamw": false, |
| "dataloader_workers": 0 |
| } |
| ``` |
|
|
| ### 步驟 1:訓練分詞器(首次執行,只需一次) |
|
|
| ```bash |
| python train_llm.py --mode tokenizer --data_dir ./data |
| ``` |
|
|
| 從 FineWeb2 下載約 500 萬行語料訓練 SentencePiece BPE 分詞器(56K 詞彙,中英文及多語言 character coverage 99.95%)。 |
|
|
| ### 步驟 2:訓練模型 |
|
|
| ```bash |
| # 最簡單:使用預設 FineWeb2,所有超參數自動偵測 |
| python train_llm.py --mode train --model_name kuixing-1.15b |
| |
| # 使用自訂資料集設定 |
| python train_llm.py --mode train \ |
| --dataset_config dataset_config.json \ |
| --mix_strategy weighted \ |
| --model_name kuixing-1.15b |
| ``` |
|
|
| ### 步驟 3:推論測試 |
|
|
| ```bash |
| python train_llm.py --mode demo |
| ``` |
|
|
| --- |
|
|
| ## 資料集設定 |
|
|
| 支援三種方式指定訓練資料,可任意混合多個來源。 |
|
|
| ### 方式 1:JSON 設定檔(最彈性) |
|
|
| ```bash |
| python train_llm.py --mode train --dataset_config dataset_config.json |
| ``` |
|
|
| 參見 [`dataset_config.json`](dataset_config.json) 範例(FineWeb2 + Wikipedia 混合)。 |
|
|
| `dataset_config_local.json` 示範本地 JSONL 檔案的用法。 |
|
|
| **DatasetSource 完整欄位:** |
|
|
| | 欄位 | 型別 | 預設 | 說明 | |
| |------|------|------|------| |
| | `source` | str | `"huggingface"` | `huggingface` / `local_files` / `local_dir` | |
| | `path` | str | — | HF dataset id 或本地路徑(多檔用逗號分隔)| |
| | `name` | str | `""` | HF subset name,如 `"20231101.zh"` | |
| | `split` | str | `"train"` | HF split | |
| | `text_field` | str | `"text"` | 要讀取的欄位名稱 | |
| | `filter_field` | str | `""` | 過濾欄位(空=不過濾)| |
| | `filter_values` | list | `[]` | 允許通過的值清單 | |
| | `streaming` | bool | `true` | 串流載入(省記憶體)| |
| | `shuffle` | bool | `true` | 是否打亂 | |
| | `buffer_size` | int | `10000` | shuffle 緩衝大小 | |
| | `min_length` | int | `50` | 最短文字長度(字元)| |
| | `max_samples` | int | `0` | 最多取用樣本數(0=不限)| |
| | `weight` | float | `1.0` | weighted 混合時的取樣比例 | |
| | `file_format` | str | `"txt"` | 本地格式:`txt` / `jsonl` / `csv` | |
| | `glob_pattern` | str | `"**/*.txt"` | local_dir 模式的 glob | |
| | `csv_delimiter` | str | `","` | CSV 分隔符 | |
| | `seed` | int | `42` | 隨機種子 | |
| | `label` | str | _(path basename)_ | 日誌顯示標籤 | |
|
|
| ### 方式 2:CLI 快速指定 |
|
|
| ```bash |
| # HuggingFace 資料集 |
| python train_llm.py --mode train \ |
| --dataset_path "wikimedia/wikipedia" \ |
| --dataset_name "20231101.zh" \ |
| --text_field "text" |
| |
| # 本地 JSONL 檔案 |
| python train_llm.py --mode train \ |
| --dataset_path "/data/corpus.jsonl" \ |
| --source_type local_files \ |
| --file_format jsonl \ |
| --text_field "content" |
| |
| # 本地目錄(掃描所有 .txt) |
| python train_llm.py --mode train \ |
| --dataset_path "/data/articles/" \ |
| --source_type local_dir \ |
| --file_format txt |
| ``` |
|
|
| ### 方式 3:預設 FineWeb2(無需額外設定) |
|
|
| ```bash |
| # 預設語言:簡體中文 + 繁體中文 + 英文 |
| python train_llm.py --mode train |
| |
| # 自訂語言過濾 |
| python train_llm.py --mode train --langs "zho_Hans,eng_Latn" |
| ``` |
|
|
| ### 多來源混合策略 |
|
|
| ```bash |
| # sequential(預設):依序消耗每個來源 |
| python train_llm.py --mode train --dataset_config dataset_config.json |
| |
| # weighted:依 weight 比例同時交錯取樣(推薦多語料混訓) |
| python train_llm.py --mode train \ |
| --dataset_config dataset_config.json \ |
| --mix_strategy weighted |
| ``` |
|
|
| --- |
|
|
| ## 訓練模式 |
|
|
| ### 從頭訓練(Pretrain) |
|
|
| ```bash |
| python train_llm.py --mode train \ |
| --model_name kuixing-1.15b \ |
| --max_steps 1000000 \ |
| --seq_len 4096 \ |
| --lr 2e-4 |
| ``` |
|
|
| ### 接續訓練(Continue) |
|
|
| **從 Trainer Checkpoint 接續**(訓練中斷後繼續,保留優化器狀態與步驟): |
|
|
| ```bash |
| python train_llm.py --mode train \ |
| --train_mode continue \ |
| --resume_from_checkpoint ./checkpoints/checkpoint-50000 \ |
| --max_steps 1000000 |
| ``` |
|
|
| **從 Release Export 接續**(換資料集繼續預訓練,步驟重設): |
|
|
| ```bash |
| python train_llm.py --mode train \ |
| --train_mode continue \ |
| --resume_from_checkpoint ./checkpoints/release/kuixing-1.15b-20250101_120000/model \ |
| --dataset_path "wikimedia/wikipedia" \ |
| --dataset_name "20231101.zh" \ |
| --lr 1e-4 \ |
| --max_steps 200000 |
| ``` |
|
|
| ### 重新發布存檔 |
|
|
| 對已完成訓練的 checkpoint 重新打包(不需重新訓練): |
|
|
| ```bash |
| python train_llm.py --mode export \ |
| --output_dir ./checkpoints \ |
| --tokenizer_model ./data/spm_tokenizer.model \ |
| --model_name kuixing-1.15b |
| ``` |
|
|
| --- |
|
|
| ## CLI 完整參數 |
|
|
| ``` |
| --mode train | tokenizer | demo | info | export |
| --model_name 發布名稱前綴(預設: kuixing-1.15b) |
| --data_dir 分詞器語料目錄(預設: ./data) |
| --output_dir 訓練輸出目錄(預設: ./checkpoints) |
| --tokenizer_model SPM 模型路徑(預設: ./data/spm_tokenizer.model) |
| |
| 訓練模式: |
| --train_mode pretrain(預設)| continue |
| --resume_from_checkpoint 接續訓練的 checkpoint 路徑 |
| |
| 資料集(三選一): |
| --dataset_config JSON 設定檔路徑(最高優先) |
| --dataset_path 單一資料集路徑(HF id 或本地路徑) |
| --dataset_name HF subset name |
| --dataset_split HF split(預設: train) |
| --text_field 文字欄位名稱(預設: text) |
| --filter_field 過濾欄位名稱 |
| --filter_values 過濾值,逗號分隔 |
| --source_type huggingface | local_files | local_dir |
| --file_format txt | jsonl | csv |
| --langs FineWeb2 語言清單,逗號分隔(預設行為) |
| --mix_strategy sequential(預設)| weighted |
| --no_streaming 停用串流,完整下載後載入 |
| |
| 超參數: |
| --batch_size per-device batch size(-1=自動) |
| --grad_accum gradient accumulation steps(-1=自動) |
| --lr 學習率(預設: 2e-4) |
| --max_steps 總訓練步數(串流資料集用;預設 1,000,000) |
| 與 --num_epochs 同時指定時 epoch 模式優先 |
| --num_epochs 訓練 epoch 數(有限資料集用;-1=停用,改用 --max_steps) |
| 適合本地資料集或固定大小的 HuggingFace 資料集 |
| --seq_len 訓練序列長度(預設: 4096) |
| --warmup_steps warmup 步數(預設: 4000) |
| |
| Checkpoint 儲存(--save_steps 與 --save_total_limit 搭配使用): |
| --save_steps 每幾步儲存一個 checkpoint(預設: 5000) |
| --save_total_limit 最多同時保留幾份 checkpoint(預設: 3) |
| 0 = 無限制,保留所有 checkpoint |
| 例: --save_steps 2000 --save_total_limit 10 |
| |
| 精度: |
| --bf16 BF16:-1=自動,0=關,1=開 |
| --fp16 FP16:-1=自動,0=關,1=開 |
| |
| Loss 記錄: |
| --loss_log_file Training loss CSV 路徑 |
| 空字串 = 自動使用 {output_dir}/training_loss.csv |
| 接續訓練時自動 append,不覆蓋已有記錄 |
| |
| 其他: |
| --no_grad_ckpt 停用 gradient checkpointing |
| --workers DataLoader workers(-1=自動) |
| ``` |
|
|
| --- |
|
|
| ## Training Loss 記錄與繪圖 |
|
|
| ### CSV 格式 |
|
|
| 訓練過程中自動產生 `{output_dir}/training_loss.csv`(或 `--loss_log_file` 指定路徑): |
|
|
| ``` |
| step,epoch,loss,learning_rate,grad_norm,samples_seen,elapsed_sec |
| 100,0.0,8.312451,0.0002,1.2341,3200,45.2 |
| 200,0.0,7.891234,0.00019,1.1892,6400,89.7 |
| ... |
| 1000000,0.0,2.341200,2e-05,0.8123,3200000,18420.0 |
| 1000000,0.0,END,,,,18421.1 |
| ``` |
|
|
| - **接續訓練**:自動 append,`END` 行標記每段訓練結束,可區分多次訓練 |
| - **即時 flush**:每個 log step 寫入後立即 flush,中斷也不丟失記錄 |
|
|
| ### 繪圖工具 `plot_loss.py` |
| |
| ```bash |
| # 基本使用(讀取預設 CSV,輸出 PNG) |
| python plot_loss.py |
|
|
| # 指定路徑與輸出 |
| python plot_loss.py \ |
| --csv ./checkpoints/training_loss.csv \ |
| --out ./loss_curve.png |
| |
| # 印出訓練摘要統計(最終 loss、最低點、收斂步數) |
| python plot_loss.py --summary |
| |
| # 比較 pretrain + continue 兩段訓練 |
| python plot_loss.py \ |
| --csv ./run1/training_loss.csv ./run2/training_loss.csv \ |
| --labels "Pretrain" "Continue (Wikipedia)" \ |
| --out compare.png |
| |
| # 以訓練時間為 X 軸,顯示互動視窗 |
| python plot_loss.py --x_axis elapsed_sec --show |
| |
| # 過濾初期 spike,調整平滑視窗 |
| python plot_loss.py --max_loss 10.0 --smooth 100 |
| ``` |
| |
| 圖表包含三個面板: |
| |
| | 面板 | 內容 | |
| |------|------| |
| | Loss 曲線 | 原始 loss(半透明)+ 滾動平均平滑,自動標記最低點 | |
| | Learning Rate | Cosine decay + warmup 排程曲線 | |
| | Gradient Norm | L2 norm 趨勢(反映訓練穩定性)| |
| |
| --- |
| |
| ## 發布存檔格式 |
| |
| 訓練完成後自動產生(也可用 `--mode export` 手動觸發): |
| |
| ``` |
| checkpoints/release/{model_name}-{timestamp}/ |
| ├── model/ |
| │ ├── model.safetensors # 模型權重(SafeTensors,推薦) |
| │ ├── pytorch_model.bin # 模型權重(PyTorch bin,相容備用) |
| │ ├── config.json # 架構與超參數設定 |
| │ └── generation_config.json # 預設生成參數 |
| ├── tokenizer/ |
| │ ├── spm_tokenizer.model # SentencePiece 模型 |
| │ ├── spm_tokenizer.vocab # 詞彙表(piece + BPE score) |
| │ ├── tokenizer_config.json # HuggingFace tokenizer 設定 |
| │ └── special_tokens_map.json |
| ├── model_card.md # HuggingFace Hub 模型說明卡 |
| ├── manifest.json # 所有檔案 SHA-256 + 大小清單 |
| └── release_info.json # 訓練環境、超參數完整快照 |
| ``` |
| |
| --- |
| |
| ## 建議硬體配置 |
| |
| | 硬體 | batch | grad_accum | seq_len | 精度 | |
| |------|-------|------------|---------|------| |
| | A100 80G | 4 | 8 | 4096 | BF16 | |
| | A100 40G | 2 | 16 | 4096 | BF16 | |
| | RTX 4090 24G | 1 | 32 | 2048 | BF16 | |
| | RTX 3090 24G | 1 | 32 | 2048 | FP16 | |
| | M3 Max 128G | 2 | 16 | 4096 | BF16 | |
| | M2 Ultra 192G | 2 | 16 | 4096 | BF16 | |
| | M2 Max 96G | 1 | 32 | 2048 | BF16 | |
| | M1/M2 16-24G | 1 | 32 | 1024 | FP32 | |
| |
| > **1M context 推理**需搭配 Flash Attention 2(CUDA A100/H100)或足夠的 Apple Silicon Unified Memory。訓練時 `seq_len=4096` 即可;長上下文外推由 YaRN 在推理時自動完成。 |
|
|
| --- |
|
|
| ## 專案結構 |
|
|
| ``` |
| . |
| ├── train_llm.py # 主程式(分詞器 / 訓練 / 推論 / 存檔) |
| ├── plot_loss.py # Training loss 曲線繪圖工具 |
| ├── dataset_config.json # 多來源混合範例(FineWeb2 + Wikipedia) |
| ├── dataset_config_local.json # 本地 JSONL 資料集範例 |
| ├── requirements.txt # Python 套件需求 |
| ├── README.md # 本文件 |
| ├── CHANGELOG.md # 版本變更記錄 |
| ├── LICENSE # Apache 2.0 授權 |
| └── .gitignore # Git 排除規則 |
| ``` |
|
|
| --- |
|
|
| ## 常見問題 |
|
|
| **Q: macOS 出現 `OMP: Error #15: Initializing libomp.dylib` 然後 abort?** |
|
|
| A: 這是 macOS 上 PyTorch、sentencepiece 等套件各自靜態連結不同版本 libomp 所導致的衝突。本程式已在啟動時自動設定 `KMP_DUPLICATE_LIB_OK=TRUE` 等環境變數,理論上不會出現此問題。若仍發生,請確認您使用的是 `python train_llm.py` 而非直接 import 本模組。 |
|
|
| **Q: MPS 上訓練比 CPU 還慢?** |
|
|
| A: 部分運算(如 MoE router 的 scatter/gather)在 MPS 上會 fallback 至 CPU,導致額外的資料搬移開銷。可嘗試減小 `--seq_len` 或 `--batch_size` 以提高 Metal GPU 利用率。 |
|
|
| **Q: 1M context 真的能用嗎?** |
|
|
| A: 訓練時固定使用 `--seq_len 4096`(或自訂),推理時 YaRN 外推讓模型能處理更長序列。實際最大長度受限於可用記憶體:80GB A100 約可推理 128K–512K tokens(使用 Flash Attention + KV cache 量化)。 |
|
|
| **Q: `safetensors` 套件未安裝時怎麼辦?** |
|
|
| A: 程式會自動偵測。若未安裝,則跳過 SafeTensors 格式,仍輸出 `pytorch_model.bin`。建議安裝:`pip install safetensors`。 |
|
|
| **Q: 如何只訓練分詞器而不訓練模型?** |
|
|
| A: `python train_llm.py --mode tokenizer --data_dir ./data` |
|
|
| --- |
|
|
| ## 授權 |
|
|
| 本專案採用 **Apache License 2.0**。詳見 [LICENSE](LICENSE)。 |
|
|
| 訓練資料 FineWeb2 由 HuggingFace 提供,請遵守其[資料集授權](https://huggingface.co/datasets/HuggingFaceFW/fineweb-2)。 |
|
|