| --- |
| license: mit |
| datasets: |
| - jslin09/wikipedia_tw |
| - flytech/python-codes-25k |
| - jslin09/wikisource_tw |
| language: |
| - zh |
| --- |
| # 魁星 KuiXing — 繁體中文預訓練語言模型 |
|
|
| <p align="center"> |
| <img src="https://img.shields.io/badge/語言-繁體中文-red?style=flat-square" /> |
| <img src="https://img.shields.io/badge/架構-Decoder--Only Transformer-blue?style=flat-square" /> |
| <img src="https://img.shields.io/badge/參數量-1.37B-green?style=flat-square" /> |
| <img src="https://img.shields.io/badge/框架-PyTorch%20%7C%20MLX-orange?style=flat-square" /> |
| <img src="https://img.shields.io/badge/授權-MIT-lightgrey?style=flat-square" /> |
| </p> |
|
|
| **魁星(KuiXing)** 是一個從零開始、以繁體中文語料預訓練的 Decoder-Only 大型語言模型。取名自中國傳統文化中掌管文章與科舉的神祇「魁星」,象徵對中文語言理解能力的追求。本專案目前僅公開模型權重供各界批評指教,原始訓練程式碼,可在 Apple Silicon(MLX)或 NVIDIA GPU(CUDA)上執行,並輸出與 HuggingFace `transformers` 相容的模型格式。但在 Apple Silicon(MLX)上因訓練效能因素,僅供作可行性驗證,如果真的要在 MLX 上預訓練,粗估一個 epoch 大概要180天,這部分要特別注意。 |
|
|
| --- |
|
|
| ## 目錄 |
|
|
| - [模型概覽](#模型概覽) |
| - [模型架構詳情](#模型架構詳情) |
| - [參數量統計](#參數量統計) |
| - [訓練資料](#訓練資料) |
| - [訓練超參數](#訓練超參數) |
| - [環境需求](#環境需求) |
| - [安裝](#安裝) |
| - [訓練程式用法](#訓練程式用法) |
| - [CLI 參數說明](#cli-參數說明) |
| - [輸出格式與載入方式](#輸出格式與載入方式) |
| - [接續訓練與 Replay Buffer](#接續訓練與-replay-buffer) |
| - [模型存檔策略](#模型存檔策略) |
| - [程式限制](#程式限制) |
| - [目錄結構](#目錄結構) |
| - [授權事項](#授權事項) |
| - [引用](#引用) |
|
|
| --- |
|
|
| ## 模型概覽 |
|
|
| | 項目 | 內容 | |
| |------|------| |
| | 模型名稱 | KuiXing(魁星) | |
| | 模型類型 | Decoder-Only Transformer(自迴歸語言模型) | |
| | 主要語言 | 繁體中文(Traditional Chinese)/ 英文 | |
| | 參數量 | **1.37B**(13.7 億) | |
| | 詞彙量 | 109,568(SentencePiece BPE) | |
| | 最大序列長度 | 1,024 tokens | |
| | 訓練框架 | PyTorch(CUDA)/MLX(Apple Silicon) | |
| | 輸出格式 | HuggingFace `safetensors` + `config.json` | |
| | 授權 | MIT | |
|
|
| --- |
|
|
| ## 模型架構詳情 |
|
|
| KuiXing 採用標準 Pre-Norm Decoder-Only Transformer 架構,設計重點在於繁體中文的高效表示與訓練穩定性。 |
|
|
| ### 整體架構 |
|
|
| ``` |
| 輸入 token IDs |
| ↓ |
| Token Embedding(vocab_size × d_model) |
| + Position Embedding(max_seq_len × d_model) |
| + Embedding Dropout |
| ↓ |
| × 16 Transformer Blocks(Pre-Norm) |
| ├── RMSNorm |
| ├── Multi-Head Self-Attention(Causal Mask) |
| │ ├── Q / K / V Projection(無 bias) |
| │ ├── Scaled Dot-Product(float32 精度) |
| │ ├── Causal Mask(上三角 -1e4,非 -inf) |
| │ ├── Softmax → Attention Dropout |
| │ └── Output Projection(無 bias) |
| ├── Residual + Dropout |
| ├── RMSNorm |
| ├── Feed-Forward Network(SiLU) |
| │ ├── Linear: d_model → d_ff(無 bias) |
| │ ├── SiLU Activation |
| │ ├── Dropout |
| │ └── Linear: d_ff → d_model(無 bias) |
| └── Residual + Dropout |
| ↓ |
| Final RMSNorm |
| ↓ |
| LM Head(d_model → vocab_size,**與 Token Embedding 共享權重**) |
| ↓ |
| Logits(float32) |
| ``` |
|  |
|
|
| ### 關鍵設計決策 |
|
|
| **Pre-Norm(前置正規化)** |
| Norm 層置於 Attention 與 MLP 之前,訓練更穩定,梯度流動更順暢,特別適合深層網路。 |
|
|
| **RMSNorm 取代 LayerNorm** |
| Root Mean Square Normalization 省去均值計算,計算效率更高,且在語言模型中表現與 LayerNorm 相當。 |
|
|
| **Causal Mask 使用 -1e4 而非 -inf** |
| 避免 bfloat16 下 `-inf` 經過 softmax 產生 `NaN` 的數值不穩定問題。 |
|
|
| **Attention Score 以 float32 計算** |
| 即使在 bfloat16 訓練模式下,Q·Kᵀ 的縮放點積與 softmax 仍升型至 float32 進行,確保精度。 |
|
|
| **Weight Tying(權重綁定)** |
| LM Head 與 Token Embedding 共享同一組權重矩陣,減少約 2.63 億參數,並有助於語意一致性。 |
|
|
| **無 Bias 的線性層** |
| 所有 Q/K/V/O Projection 及 FFN 的線性層均不使用 bias,符合現代大型語言模型的主流做法。 |
|
|
| **Dropout 正則化** |
| Embedding dropout、Attention dropout 及殘差連接處均加入 dropout(預設 0.1),有效防止過擬合。 |
|
|
| ### 架構超參數 |
|
|
| | 參數 | 數值 | 說明 | |
| |------|------|------| |
| | `n_layers` | 16 | Transformer Block 層數 | |
| | `d_model` | 2,400 | 隱藏層維度 | |
| | `n_heads` | 32 | 注意力頭數 | |
| | `d_head` | 75 | 每個注意力頭的維度(d_model / n_heads) | |
| | `d_ff` | 9,600 | Feed-Forward 中間層維度(4× d_model) | |
| | `max_seq_len` | 1,024 | 最大序列長度 | |
| | `vocab_size` | 109,568 | BPE 詞彙量 | |
| | `dropout` | 0.1 | Dropout 比率 | |
| | `activation` | SiLU | FFN 激活函數 | |
| | `norm` | RMSNorm | 正規化層類型 | |
| | `pos_encoding` | Learned | 可學習的位置嵌入 | |
|
|
| --- |
|
|
| ## 參數量統計 |
|
|
| | 模組 | 參數量 | |
| |------|--------| |
| | Token Embedding | 262,963,200(263.0M) | |
| | Position Embedding | 2,457,600(2.5M) | |
| | Attention(×16 層) | 368,640,000(368.6M) | |
| | Feed-Forward(×16 層) | 737,280,000(737.3M) | |
| | RMSNorm(×33 個) | 79,200 | |
| | LM Head | 0(與 Token Embedding 共享) | |
| | **合計** | **1,371,420,000(≈ 1.37B)** | |
|
|
| > **儲存大小估算:** |
| > - float32(訓練 / safetensors 輸出):≈ **5.5 GB** |
| > - bfloat16(推理建議):≈ **2.7 GB** |
|
|
| --- |
|
|
| ## 訓練資料 |
|
|
| | 項目 | 內容 | |
| |------|------| |
| | 主要語料 | [jslin09/wikipedia_tw](https://huggingface.co/datasets/jslin09/wikipedia_tw)(台灣維基百科) | |
| | | [Skylion007/openwebtext](https://huggingface.co/datasets/Skylion007/openwebtext)| |
| | 語言 | 繁體中文 / 英文 | |
| | Tokenizer | SentencePiece BPE,從語料訓練,詞彙量 109,568 | |
| | 資料處理 | 全文 tokenize → 串接為長序列 → 切成固定長度 chunk(1,025 tokens/chunk)→ 打散 | |
| | BOS / EOS | 每篇文章前後分別加入 `<s>` / `</s>` token | |
|
|
| 訓練支援多資料集接續(Continual Training),可在訓練完成後以不同語料繼續微調,無需重新初始化模型。 |
|
|
| --- |
|
|
| ## 訓練超參數 |
|
|
| | 超參數 | 數值 | 說明 | |
| |--------|------|------| |
| | `batch_size` | 48 | 每步實際 mini-batch 大小 | |
| | `accum_steps` | 32 | 梯度累積步數 | |
| | 有效 Batch Size | 1,536 | `batch_size × accum_steps` | |
| | `learning_rate` | 3×10⁻⁴ | AdamW 峰值學習率 | |
| | LR Schedule | Linear Warmup + Cosine Decay | | |
| | `warmup_steps` | 500 | 線性暖身步數 | |
| | `weight_decay` | 0.1 | AdamW L2 正則化係數 | |
| | `betas` | (0.9, 0.95) | AdamW 動量係數 | |
| | `eps` | 1×10⁻⁶ | AdamW 數值穩定項 | |
| | `grad_clip` | 1.0 | 全局梯度裁剪閾值(L2 norm) | |
| | `epochs` | 3 | 訓練回合數 | |
| | `steps` | 30,000 | 每 epoch 最大步數 | |
| | 混合精度 | bfloat16(CUDA)/float32(MPS)/bfloat16(MLX) | | |
|
|
| **Weight Decay 策略:** 僅對 `dim ≥ 2` 的權重矩陣施加 weight decay;bias、RMSNorm 參數不衰減。 |
|
|
| --- |
|
|
| ## 環境需求 |
|
|
| ### 必要條件 |
|
|
| 本程式**不支援純 CPU 執行**,需要以下其中一種硬體加速環境。以下規格為**最低需求**,不符合者將無法完成訓練: |
|
|
| | 環境 | 最低需求 | 建議機型範例 | |
| |------|----------|-------------| |
| | Apple Silicon Mac | 統一記憶體(RAM)**≥ 128 GB**,需安裝 MLX | Mac Studio / Mac Pro(M2 Ultra 192GB、M3 Ultra 192GB) | |
| | NVIDIA GPU | 單卡 GPU RAM **≥ 92 GB**,CUDA 11.8 或以上 | H100 NVL(94 GB)、H200(141 GB) | |
| | 主機記憶體(RAM) | **≥ 64 GB**(兩種環境皆適用) | — | |
|
|
| > ⚠️ **重要:** 訓練環境低於以上任一最低需求,程式將因記憶體不足而無法執行完整訓練。 |
| > |
| > **需求說明:** |
| > - float32 模型權重 ≈ 5.5 GB;加上梯度與 AdamW 狀態(各一份,共 3× 權重大小),訓練峰值 GPU RAM 約 **90 GB 以上**。 |
| > - Apple Silicon 的統一記憶體由 CPU 與 GPU 共用,128 GB 為能在 MLX bfloat16 模式下穩定訓練的最低配置。 |
| > - 主機記憶體(系統 RAM)需 ≥ 64 GB,以容納資料集 tokenize、chunk 建構及 PyTorch 的系統側暫存空間。 |
|
|
| ### Python 套件 |
|
|
| ``` |
| torch >= 2.2.0 |
| mlx >= 0.12.0 # 僅 Apple Silicon 需要 |
| sentencepiece >= 0.1.99 |
| datasets >= 2.14.0 |
| transformers >= 4.38.0 |
| safetensors >= 0.4.0 |
| numpy >= 1.24.0 |
| matplotlib >= 3.7.0 |
| tqdm >= 4.65.0 |
| ``` |
|
|
| --- |
|
|
| ## 安裝 |
|
|
| ```bash |
| # 1. 複製專案 |
| git clone https://github.com/jslin/KuiXing.git |
| cd kuixing |
| |
| # 2. 建立虛擬環境(建議) |
| python -m venv venv |
| source venv/bin/activate # Windows: venv\Scripts\activate |
| |
| # 3. 安裝 PyTorch(依據您的硬體選擇) |
| # CUDA 12.1: |
| pip install torch --index-url https://download.pytorch.org/whl/cu121 |
| # Apple Silicon(CPU/MPS fallback): |
| pip install torch |
| |
| # 4. 安裝 MLX(Apple Silicon 專用,建議安裝以獲得最佳性能) |
| pip install mlx |
| |
| # 5. 安裝其餘相一套件 |
| pip install sentencepiece datasets transformers safetensors numpy matplotlib tqdm |
| ``` |
|
|
| --- |
|
|
| ## 訓練程式用法 |
|
|
| ### 互動模式(無參數,推薦初次使用) |
|
|
| ```bash |
| python KuiXing_Trainer.py |
| ``` |
|
|
| 程式會自動偵測硬體環境,若有既有模型則詢問是否接續訓練及使用哪個資料集;若無既有模型則從頭開始訓練。 |
|
|
| ### 常用指令 |
|
|
| ```bash |
| # 從頭訓練(強制忽略已存在的模型) |
| python KuiXing_Trainer.py --from-scratch |
| |
| # 直接接續訓練(不互動詢問,使用 config 預設資料集) |
| python KuiXing_Trainer.py --resume |
| |
| # 接續訓練並切換到新資料集 |
| python KuiXing_Trainer.py --resume --dataset jslin09/other_dataset --column text |
| |
| # 以新資料集從頭訓練 |
| python KuiXing_Trainer.py --from-scratch --dataset your_org/dataset_name --column article |
| |
| # 獨立繪圖模式(讀取訓練記錄後生成曲線圖,不啟動訓練) |
| python KuiXing_Trainer.py --plot |
| |
| # 訓練摘要模式(顯示 loss / perplexity 統計後結束,不啟動訓練) |
| python KuiXing_Trainer.py --summary |
| |
| # 從頭訓練,tokenizer 加入英文語料,預訓練也同步加入 |
| python KuiXing_Trainer.py.py --from-scratch \ |
| --tok-extra Skylion007/openwebtext:text \ |
| --extra Skylion007/openwebtext:text |
| |
| # Tokenizer 加入需要 name 參數的資料集(繁中維基) |
| python KuiXing_Trainer.py.py --from-scratch \ |
| --tok-extra Skylion007/openwebtext:text wikimedia/wikipedia:text:20231101.zh-tw |
| |
| # 只新訓練 tokenizer(刪掉舊的再跑),預訓練用預設資料集 |
| python KuiXing_Trainer.py.py \ |
| --tok-extra Skylion007/openwebtext:text |
| |
| # 接續預訓練,同時加入兩個額外資料集 |
| python KuiXing_Trainer.py.py --resume \ |
| --extra Skylion007/openwebtext:text jslin09/news_tw:content |
| ``` |
|
|
| --- |
|
|
| ## CLI 參數說明 |
|
|
| | 參數 | 類型 | 說明 | |
| |------|------|------| |
| | `--from-scratch` | flag | 強制從頭訓練,忽略已存在的 checkpoint 與模型 | |
| | `--resume` | flag | 直接接續上次訓練,跳過互動詢問 | |
| | `--dataset NAME` | string | 指定 HuggingFace 資料集名稱(如 `jslin09/wikipedia_tw`) | |
| | `--column COL` | string | 指定資料集中的文章欄位名稱(如 `article`、`text`) | |
| | `--plot` | flag | 讀取 JSONL 訓練記錄,生成四格訓練曲線圖後結束 | |
| | `--summary` | flag | 讀取 JSONL 訓練記錄,顯示訓練摘要統計後結束 | |
| | `--tok-extra` | flag | 只新訓練 tokenizer(刪掉舊的再跑),預訓練用預設資料集 | |
| | `--extra` | flag | 增加額外的資料集 | |
|
|
| > **注意:** `--from-scratch` 與 `--resume` 互斥,不可同時使用。 |
| > `--plot` 與 `--summary` 為獨立模式,不觸發硬體偵測或訓練流程。 |
|
|
| ### 訓練摘要輸出範例(`--summary`) |
|
|
| ``` |
| ============================================================ |
| 🏁 KuiXing 訓練完成摘要 |
| ============================================================ |
| 訓練 Epoch : 3 |
| Optimizer-updates/epoch : 937 |
| 總 Optimizer-updates : 5,109 |
| Tokens / epoch : 1,965,031,424 (1.965B) |
| Tokens total : 5,895,094,272 (5.895B) |
| 學習率範圍 : 0.00e+00 → 3.00e-04 |
| 梯度被裁剪次數 : 64 次(佔 1.3%) |
| ============================================================ |
| 最終 Loss : 3.577671 |
| 最終 Perplexity : 35.7901 |
| ============================================================ |
| 最佳 Loss : 3.461087 (第 4,879 次 optimizer-update) |
| 最佳 Perplexity : 31.8516 |
| ============================================================ |
| 末 100 次 update 平均 Loss : 3.536700 |
| 末 100 次 update 平均 PPL : 34.3534 |
| ============================================================ |
| ``` |
| |
| --- |
| |
| ## 輸出格式與載入方式 |
| |
| 訓練完成後,程式自動將模型輸出至 `./kuixing_model/`,包含以下檔案: |
| |
| ``` |
| kuixing_model/ |
| ├── model.safetensors # float32 模型權重(HuggingFace 格式) |
| ├── config.json # 模型架構設定 |
| ├── modeling_kuixing.py # 自訂架構定義(含 AutoModel 支援) |
| ├── tokenizer_config.json # Tokenizer 設定 |
| └── tokenizer.model # SentencePiece BPE tokenizer |
| ``` |
| |
| ### 載入方式 |
| |
| **方式一:直接使用自訂類別(推薦)** |
| |
| ```python |
| from modeling_kuixing import KuiXingForCausalLM |
|
|
| model = KuiXingForCausalLM.from_pretrained("./kuixing_model") |
| model = model.eval() |
| ``` |
| |
| **方式二:bfloat16 推理(節省記憶體)** |
| |
| ```python |
| import torch |
| from modeling_kuixing import KuiXingForCausalLM |
| |
| model = KuiXingForCausalLM.from_pretrained("./kuixing_model") |
| model = model.to(torch.bfloat16).eval() |
| ``` |
| |
| **方式三:透過 HuggingFace AutoModel** |
| |
| ```python |
| from transformers import AutoModelForCausalLM |
| |
| model = AutoModelForCausalLM.from_pretrained( |
| "./kuixing_model", |
| trust_remote_code=True, |
| ) |
| ``` |
| |
| **方式四:從 HuggingFace Hub 載入** |
|
|
| ```python |
| from transformers import AutoModelForCausalLM |
| |
| model = AutoModelForCausalLM.from_pretrained( |
| "jslin09/kuixing", |
| trust_remote_code=True, |
| ) |
| ``` |
|
|
| --- |
|
|
| ## 接續訓練與 Replay Buffer |
|
|
| ### 災難性遺忘問題 |
|
|
| 以 `--resume` 接續訓練指定新資料集時,若不加任何防護,模型容易忘記原始語料(如台灣維基百科)的語法與知識,只學會新資料集的風格,此現象稱為**災難性遺忘(Catastrophic Forgetting)**。 |
|
|
| ### Replay Buffer 機制 |
|
|
| KuiXing 訓練程式內建 **Replay Buffer** 機制,在接續訓練時自動於每個 mini-batch 中混入一定比例的舊語料樣本,使模型同時學習新舊知識,有效緩解遺忘問題。 |
|
|
| ``` |
| 每個 mini-batch(batch_size = 48): |
| ┌─────────────────────────────────────┐ |
| │ 新語料樣本 × 3 (80%,n_new) │ |
| │ 舊語料樣本 × 1 (20%,n_replay) │ ← Replay Buffer |
| └─────────────────────────────────────┘ |
| 混合後隨機打散順序,再送入模型 |
| ``` |
|
|
| ### 啟動條件(全自動,無需額外 CLI 參數) |
|
|
| Replay Buffer 在以下條件**同時成立**時自動啟用,無需任何額外操作: |
|
|
| | 條件 | 說明 | |
| |------|------| |
| | 使用 `--resume` 接續訓練 | 從頭訓練(`--from-scratch`)不啟用 | |
| | 新資料集與 `replay_dataset` **不同** | 相同資料集接續時自動略過並印出提示 | |
| | `replay_ratio > 0.0` | 設為 `0.0` 可手動停用 | |
|
|
| 啟用後,程式會在訓練開始前印出確認訊息: |
|
|
| ``` |
| 🔁 Replay Buffer 已啟用:每批 4 筆中 1 筆來自舊語料(20%),3 筆來自新語料。 |
| ``` |
|
|
| ### 舊語料快取機制 |
|
|
| 為避免每次接續訓練都重新下載並 tokenize 舊語料,Replay Buffer 採用磁碟快取: |
|
|
| - **第一次**:自動下載舊語料、tokenize、切塊,儲存為 `.npy` 快取檔 |
| - **之後每次**:直接讀取快取,秒速完成,無需重新處理 |
|
|
| 快取儲存於 `./kuixing_replay_cache/`,檔名包含資料集名稱與 chunk size,可安全保留供多次訓練共用。 |
|
|
| ### 相關設定參數(`KuiXingConfig`) |
|
|
| | 參數 | 預設值 | 說明 | |
| |------|--------|------| |
| | `replay_ratio` | `0.2` | 每個 mini-batch 中舊語料所佔比例(0.0 = 停用) | |
| | `replay_dataset` | `"jslin09/wikipedia_tw"` | 舊語料的 HuggingFace 資料集名稱 | |
| | `replay_column` | `"article"` | 舊語料的文章欄位名稱 | |
| | `replay_cache_dir` | `"./kuixing_replay_cache"` | 舊語料 chunk 快取目錄 | |
|
|
| > **調整比例:** `replay_ratio = 0.2` 代表 20% 舊語料、80% 新語料,一般建議範圍為 0.1–0.3。比例過高會拖慢新語料的學習速度;過低則防遺忘效果有限。 |
| |
| ### 操作範例 |
| |
| ```bash |
| # 以新資料集接續訓練(Replay Buffer 自動啟用,混入 20% 維基百科舊語料) |
| python KuiXing_Trainer.py --resume --dataset jslin09/other_dataset --column text |
| |
| # 若想停用 Replay Buffer,在 KuiXingConfig 中將 replay_ratio 設為 0.0 |
| # self.replay_ratio = 0.0 |
| ``` |
| |
| --- |
| |
| ## 模型存檔策略 |
| |
| ### 概覽 |
| |
| KuiXing 訓練程式同時維護兩種存檔,各有不同用途: |
| |
| | 檔案 | 存放位置 | 用途 | 保留數量 | |
| |------|----------|------|----------| |
| | `ckpt_ep*_step*.pt` | `kuixing_checkpoints/` | 意外中斷後接續訓練 | 最多 3 份(滾動刪除) | |
| | `ckpt_best.pt` | `kuixing_checkpoints/` | 最終 HuggingFace 輸出來源 | 固定 1 份(覆蓋更新) | |
| | `mlx_ckpt_best.npz` | `kuixing_checkpoints/` | MLX 路徑的最佳版本 | 固定 1 份(覆蓋更新) | |
|
|
| ### 最佳模型判斷:滑動平均 loss |
|
|
| 程式以**近 100 個 optimizer step 的 loss 平均值**作為判斷依據,而非單步 loss。採用滑動平均的原因: |
|
|
| - 單步 loss 受 batch 取樣影響,存在隨機雜訊 |
| - 單步最低 ≠ 泛化能力最好;滑動平均能反映模型真實的學習趨勢 |
| - 有效過濾掉「剛好抽到簡單 batch」所造成的虛假最低點 |
|
|
| ### 觸發條件 |
|
|
| 每次常規存檔(每 `save_interval = 2000` 步)時同步比較: |
|
|
| ``` |
| if optimizer_step >= best_ckpt_min_steps (預設 100): # 跳過冷卻期 |
| avg_loss = mean(losses[-100:]) # 計算滑動平均 |
| if avg_loss < 歷史最佳滑動平均 loss: |
| 覆蓋寫入 ckpt_best.pt # 僅此時才有 I/O |
| 印出 🏆 更新訊息 |
| else: |
| 不做任何事(零 I/O) |
| ``` |
|
|
| **冷卻期設計(`best_ckpt_min_steps = 100`):** 訓練初期 loss 快速下降但尚未穩定,冷卻期內不觸發最佳存檔,避免存到不具代表性的早期版本。 |
| |
| ### I/O 影響評估 |
| |
| | 情境 | 實際 I/O 頻率 | 說明 | |
| |------|--------------|------| |
| | 訓練初期(loss 快速下降) | 每 2000 步最多一次 | 受 `save_interval` 限制 | |
| | 訓練中後期(loss 趨於平穩) | 幾乎不觸發 | 滑動平均鮮少繼續改善 | |
| | 沒有改善時 | 零 I/O | 完全不寫入 | |
| |
| 結論:**不會成為 I/O bound 程式**,對訓練速度的影響可忽略不計。 |
| |
| ### 最終輸出行為 |
| |
| 訓練完成後,程式**優先載入 `ckpt_best.pt`** 再進行 HuggingFace 格式輸出,而非直接使用記憶體中訓練結束當下的模型: |
|
|
| ``` |
| 訓練迴圈結束 |
| ↓ |
| 嘗試載入 kuixing_checkpoints/ckpt_best.pt |
| ├── 成功 → 印出 🏆 最佳滑動平均 loss 數值,以最佳版本輸出 |
| └── 失敗或不存在 → 印出 ℹ️ 提示,以當前模型 fallback 輸出 |
| ↓ |
| _export_model() → kuixing_model/model.safetensors |
| ``` |
|
|
| ### 相關設定參數(`KuiXingConfig`) |
|
|
| | 參數 | 預設值 | 說明 | |
| |------|--------|------| |
| | `save_interval` | `2000` | 常規 checkpoint 存檔間隔(步數) | |
| | `max_checkpoints` | `3` | 常規 checkpoint 最多保留份數 | |
| | `best_ckpt_window` | `100` | 滑動平均視窗大小(optimizer steps) | |
| | `best_ckpt_min_steps` | `100` | 開始比較最佳 loss 的最小步數(冷卻期) | |
|
|
| ### 注意事項 |
|
|
| > ⚠️ **接續訓練時的最佳 checkpoint 覆蓋問題** |
| > |
| > 使用 `--resume` 接續訓練時,若舊的 `ckpt_best.pt` 仍存在於 `kuixing_checkpoints/`,新一輪訓練的滑動平均 loss 必須**低於舊輪次的最佳值**才會觸發覆蓋。 |
| > |
| > 若新語料訓練後 loss 整體偏高(例如難度較高的領域語料),有可能整輪訓練都不觸發更新,最終輸出的仍是前一輪的最佳版本。這在大多數情況下是**正確行為**(舊版本確實更好),但若您明確希望輸出新語料訓練的版本,請在接續訓練前手動刪除 `kuixing_checkpoints/ckpt_best.pt`。 |
|
|
| --- |
|
|
| ## 程式限制 |
|
|
| 使用本訓練程式前,請了解以下限制: |
|
|
| **硬體限制** |
| - 不支援純 CPU 執行。程式於啟動時偵測硬體,若未找到 MPS 或 CUDA 裝置,將直接終止並提示錯誤。純 CPU 模式因速度過慢(預估為 GPU 的 50–200 倍)而刻意排除。 |
|
|
| **記憶體需求為硬性限制** |
| - 訓練峰值 GPU RAM(含模型權重、梯度、AdamW 狀態)約需 **90 GB 以上**。NVIDIA GPU 需單卡 GPU RAM ≥ 92 GB(如 H100 NVL 94 GB),Apple Silicon 需統一記憶體 ≥ 128 GB,主機 RAM 需 ≥ 64 GB。低於上述任一門檻者將因記憶體不足而無法完成訓練,此為硬性限制,無法透過縮減 `batch_size` 解決(梯度累積步數已補償批次大小,GPU RAM 瓶頸在於模型本身與優化器狀態)。 |
|
|
| **MPS 平台限制** |
| - Apple Silicon 使用 MPS 後端(無 MLX)時,MPS 尚不支援 `torch.autocast`,因此以 float32 全精度訓練,速度與記憶體效率低於 MLX 路徑。建議安裝 MLX 以獲得最佳性能。 |
|
|
| **多 GPU 不支援** |
| - 本程式目前僅支援單一 GPU 訓練,未實作 DDP(DistributedDataParallel)或 FSDP,無法直接用於多卡並行訓練。 |
|
|
| **Checkpoint 跨平台相容性** |
| - PyTorch(CUDA/MPS)與 MLX(Apple Silicon)的 checkpoint 格式不同,無法直接互換。MLX checkpoint 以 `.npz` 儲存,PyTorch checkpoint 以 `.pt` 儲存。 |
|
|
| **Tokenizer 字型依賴** |
| - 訓練曲線繪圖功能依賴本地安裝的繁體中文字型(Noto Sans TC),字型路徑與檔名硬編碼於程式中。若路徑或檔名不符,繪圖將失敗或顯示亂碼。 |
| - 字型下載網址:[Noto Sans TC — Google Fonts](https://fonts.google.com/noto/specimen/Noto+Sans+TC?preview.script=Hant) |
| - ⚠️ **使用者需自行將字型檔案安裝至本機,並修改程式碼中對應的字型檔案路徑與檔名**,使其與實際安裝位置一致,繪圖功能方可正常運作。 |
|
|
| **資料集格式** |
| - 目前僅支援 HuggingFace `datasets` 格式的文字資料集,需指定文字欄位名稱。不支援本地 jsonl、txt、csv 直接輸入(需先上傳至 HuggingFace 或自行修改 `build_chunks()` 函式)。 |
|
|
| **推理功能** |
| - 本程式為**預訓練專用訓練器**,不包含文字生成(inference)功能。推理請使用輸出的 HuggingFace 格式模型搭配 `transformers` 的 `generate()` 方法。 |
|
|
| --- |
|
|
| ## 目錄結構 |
|
|
| 執行訓練後,工作目錄將產生以下結構: |
|
|
| ``` |
| ./ |
| ├── KuiXing_Trainer.py # 主訓練程式 |
| │ |
| ├── kuixing_tokenizer/ # Tokenizer 檔案(自動生成) |
| │ ├── tokenizer.model |
| │ └── tokenizer.vocab |
| │ |
| ├── kuixing_checkpoints/ # 訓練 Checkpoint(自動生成) |
| │ ├── ckpt_ep0_step500.pt # 常規 checkpoint(最多保留 3 份) |
| │ ├── ckpt_ep0_step1000.pt |
| │ ├── ...(保留最新 3 個) |
| │ ├── ckpt_best.pt # 滑動平均 loss 最佳版本(PT/CUDA/MPS) |
| │ └── mlx_ckpt_best.npz # 滑動平均 loss 最佳版本(MLX) |
| │ |
| ├── kuixing_logs/ # 訓練記錄(自動生成) |
| │ ├── training_log.jsonl # 每步指標(loss, lr, grad_norm, ...) |
| │ └── training_curves.png # 訓練曲線圖(每 200 步更新) |
| │ |
| ├── kuixing_replay_cache/ # Replay Buffer 快取(接續訓練時自動生成) |
| │ └── replay_jslin09_wikipedia_tw_1025.npy # 舊語料 chunk 快取 |
| │ |
| └── kuixing_model/ # 最終輸出(訓練完成後生成) |
| ├── model.safetensors |
| ├── config.json |
| ├── modeling_kuixing.py |
| ├── tokenizer.json |
| ├── tokenizer_config.json |
| └── tokenizer.model |
| ``` |
|
|
| --- |
|
|
| ## 授權事項 |
|
|
| ### 程式碼授權 |
|
|
| 本專案訓練程式碼(`KuiXing_Trainer.py` 及相關檔案)以 **MIT License** 授權,允許自由使用、修改與散布,包含商業用途,惟需保留原始版權聲明。 |
|
|
| ``` |
| MIT License |
| |
| Copyright (c) 2026 Chun-Hsien Lin |
| |
| Permission is hereby granted, free of charge, to any person obtaining a copy |
| of this software and associated documentation files (the "Software"), to deal |
| in the Software without restriction, including without limitation the rights |
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| copies of the Software, and to permit persons to whom the Software is |
| furnished to do so, subject to the following conditions: |
| |
| The above copyright notice and this permission notice shall be included in all |
| copies or substantial portions of the Software. |
| |
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
| ``` |
|
|
| ### 模型權重授權 |
|
|
| 訓練完成的模型權重(`model.safetensors`)以 **MIT** 授權發布。 |
|
|
| **您可以:** |
| - ✅ 分享:以任何媒介或格式複製、散布本模型 |
| - ✅ 改作:修改、轉換本模型,以其為基礎進行創作(如微調) |
| - ✅ 學術研究與個人使用 |
|
|
| 特此授予任何人免費獲得本軟體及其相關文件文件(「軟體」)的副本的許可,允許其不受限制地處理本軟體,包括但不限於使用、複製、修改、合併、發布、分發、再許可和/或出售本軟體的副本,並允許向其提供本軟體的人員這樣做。 |
|
|
| 本軟體以「現況」提供,不提供任何形式的明示或暗示的保證,包括但不限於適銷性、特定用途適用性和不侵權保證。在任何情況下,作者或版權所有者均不對任何索賠、損害或其他責任承擔責任,無論該責任是因合約、侵權或其他原因引起的,也無論該責任是因本軟體或其使用或交易而引起的。 |
|
|
| 完整授權條款請見:https://opensource.org/license/MIT |
|
|
| ### 訓練資料聲明 |
|
|
| 本模型以台灣維基百科(`jslin09/wikipedia_tw`)及維基文庫(`jslin09/wikisource_tw`)為主要訓練語料,該語料源自維基媒體基金會,依據 [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/) 授權。使用者在引用本模型產出內容時,亦應留意上游授權要求。 |
| 完整授權條款請見:https://creativecommons.org/licenses/by-nc/4.0/ |
|
|
| ### 免責聲明 |
|
|
| 本模型為研究性質的預訓練語言模型,**不保證輸出內容的正確性、完整性或安全性**。使用者需自行評估並承擔模型輸出的風險。作者不對因使用本模型造成的任何直接或間接損失負責。 |
|
|
| --- |
|
|
| ## 引用 |
|
|
| 若您在研究或作品中使用了 KuiXing,請引用本專案: |
|
|
| ```bibtex |
| @misc{lin2026kuixing, |
| author = {Chun-Hsien Lin}, |
| title = {KuiXing: A Traditional Chinese Pre-trained Language Model}, |
| year = {2026}, |
| publisher = {HuggingFace}, |
| howpublished = {\url{https://huggingface.co/jslin09/kuixing}}, |
| } |
| ``` |
|
|
| --- |
|
|
| <p align="center"> |
| 以繁體中文為本,從零開始。<br> |
| <em>Built from scratch, for Traditional Chinese.</em> |
| </p> |