解決的問題
官方 0.8B 基底在語意上已有一定水準,但中文輸出常混入簡體字形與非臺灣用語:FLORES ja→zhtw 方向約 43.6% 的句子含簡體專用字。v5e 將 en→zhtw / ja→zhtw 的簡體洩漏分別降至約 1.09% / 0.69%,同時六方向語意指標整體上升。
評測
- 基準:FLORES-200 devtest 全量 n=1012
- 解碼:
num_beams=4,並依目標語言套用防重複參數(見下文)
- 指標:chrF++ / BLEU(sacrebleu;日文
ja-mecab、中文 zh)、COMET(Unbabel/wmt22-comet-da)、簡體洩漏率(簡體專用字集比對)
- 對照:相同樣本與相同解碼設定下的官方
Qwen/Qwen3.5-0.8B
Table with columns: 方向, chrF++ (base → v5e), BLEU (base → v5e), COMET (base → v5e), 簡體洩漏 (base → v5e)| 方向 | chrF++ (base → v5e) | BLEU (base → v5e) | COMET (base → v5e) | 簡體洩漏 (base → v5e) |
|---|
| en→zhtw | 19.38 → 20.26 | 25.57 → 28.90 | 86.32 → 86.23 | 10.18% → 1.09% |
| zhtw→en | 47.78 → 50.33 | 19.34 → 23.72 | 84.79 → 85.27 | — |
| en→ja | 20.26 → 24.15 | 19.81 → 22.65 | 86.17 → 88.44 | — |
| ja→en | 45.67 → 50.17 | 16.67 → 22.70 | 84.85 → 86.20 | — |
| ja→zhtw |
COMET 均分約 +1.92;chrF++ 與 BLEU 六方向皆上升。
en→zhtw 語意與官方統計持平:paired bootstrap 95% CI 約 [−0.414, +0.225](跨 0)。其餘五個方向 COMET 提升約 +0.48 ~ +4.66。官方 en→zhtw 的 COMET 是在約 10% 簡體洩漏下取得的;COMET 對簡繁字形不敏感,兩邊產出的字形品質並不相同。
通用能力
Table with columns: 基準, 官方 0.8B, v5e| 基準 | 官方 0.8B | v5e |
|---|
| BELEBELE zh-TW / ja / en(閱讀理解,選項輪轉去偏,各 900 題) | 55.81 / 51.78 / 57.83 | 57.28 / 52.36 / 62.81 |
| 知識(TMMLU+ / MMMLU-JA / MMLU,各 900 題) | 30.67 / 36.08 / 43.67 | 30.53 / 36.64 / 43.81 |
| 自建通用問答(n=90,三語各 30) | 78.9 | 72.2 |
| 指令遵循 ifeval(n=90) | 53.3 | 48.9 |
BELEBELE 與知識軸六格皆不低於官方基底。自建問答與指令遵循略低——通用指令 replay 約 3.5 萬筆,且授權相容的繁中指令語料有限。本模型為翻譯特化,不建議作為通用助手。
選擇題基準採選項輪轉(×4)去除位置先驗:0.8B 級模型對答案字母常有強先驗。絕對分數僅供與官方基底相減比較,不宜單獨作為對外能力宣稱。
長文件翻譯(25 篇 × 6 方向)
Table with columns: 指標, 官方 0.8B, v5e| 指標 | 官方 0.8B | v5e |
|---|
| 行數對齊比(中位) | 1.375 ~ 1.500 | 1.000(六方向) |
| 尾段譯出比(中位) | 1.101 ~ 1.646 | 0.851 ~ 0.924 |
| 腰斬率(譯文 < 參考長度一半) | 0 ~ 4% | 0 ~ 4% |
官方模型常多生成 40–50% 的行並在尾段超譯;v5e 行數較精準對齊。早期微調版本曾有「長文只翻前兩段」的問題,v5e 已消除。
建議解碼參數
⚠ generation prompt 必須以空 think 區塊收尾
chat_template.jinja 在未開 thinking 時,會固定在 <|im_start|>assistant\n 之後補上
<think>\n\n</think>\n\n(token 248068, 271, 248069, 271)。訓練與評測全程帶著這 4 個 token,
少了就會掉出分布。完整的 prompt 應長成:
<|im_start|>system\nYou are a professional translator.<|im_end|>\n
<|im_start|>user\n翻譯成繁體中文:\n{原文}<|im_end|>\n
<|im_start|>assistant\n<think>\n\n</think>\n\n
- transformers:
apply_chat_template(..., add_generation_prompt=True) 會自動補,不必額外處理。
- llama.cpp 系:預設不補。
llama-cli 需加 --jinja;node-llama-cpp 內建的 QwenChatWrapper
是照 Qwen3 撰寫,其 thoughts 六個選項沒有任何一個會補上這段,需自行覆寫 generateContextState:
以下為與官方評測一致的 transformers 設定(GitHub scripts/evaluate.py):
Table with columns: 參數, 建議值| 參數 | 建議值 |
|---|
num_beams | 4 |
length_penalty | 1.2 |
do_sample | false |
eos_token_id | [248046, 248044](`< |
| 目標語 en / ja | repetition_penalty=1.1 + no_repeat_ngram_size=4 |
常見異常與處理
Table with columns: 現象, 常見原因, 處理| 現象 | 常見原因 | 處理 |
|---|
| 譯文憑空多出「說明:」「問:」「1. 」等前綴/專名被吃掉/生出原文沒有的年份 | generation prompt 少了 <think>\n\n</think>\n\n(僅 llama.cpp 系會發生) | 見上方警示;勿以 regex 剝前綴 |
| 譯完後持續生成至上限 | 只設定單一 EOS | 使用雙 EOS |
| 長口語/社群文 → 英文句級重複 | 未開 no_repeat_ngram_size;或 GGUF 僅 greedy | 依上表;GGUF 可加 repeat-penalty 並分段 |
| 譯文前綴出現思考/選項雜訊 | 未關閉 thinking | llama.cpp:--reasoning off --reasoning-budget 0 |
|
更完整的接入清單與檢查表:GitHub docs/INTEGRATION.md。
倉庫檔案
Table with columns: 路徑, 說明| 路徑 | 說明 |
|---|
| 倉庫根目錄 | LoRA adapter(adapter_model.safetensors + adapter_config.json,r=64 / α=128 / dropout 0.05,約 173MB;base = Qwen/Qwen3.5-0.8B)。library_name: peft 要求 adapter 置於根目錄 |
merged-bf16-v5e/ | 合併後 bf16 全模型(約 1.7GB,可不依賴 peft) |
gguf-v5e/ | GGUF:Q8_0 / Q4_K_M / f16 |
import torch
from transformers import AutoTokenizer, AutoModelForImageTextToText
from peft import PeftModel
BASE = "Qwen/Qwen3.5-0.8B"
ADAPTER = "RX5950XT/LinguaForge-Qwen3.5-0.8B-zhTW-en-ja"
tok = AutoTokenizer.from_pretrained(BASE)
model = AutoModelForImageTextToText.from_pretrained(
BASE, dtype=torch.bfloat16, attn_implementation="sdpa").cuda()
model = PeftModel.from_pretrained(model, ADAPTER).eval()
EOS = [tok.convert_tokens_to_ids(t) for t in ("<|im_end|>", "<|endoftext|>")]
INSTR = {"zhtw": "翻譯成繁體中文:", "en": "翻譯成英文:", "ja": "翻譯成日文:"}
DECODE = {
"ja": {"repetition_penalty": 1.1, "no_repeat_ngram_size": 4},
"en": {"repetition_penalty": 1.1, "no_repeat_ngram_size": 4},
"zhtw": {"no_repeat_ngram_size": 4},
}
def translate(text, tgt="zhtw"):
convs = [
{"role": "system", "content": "You are a professional translator."},
{"role": "user", "content": f"{INSTR[tgt]}\n{text}"},
]
inputs = tok.apply_chat_template(
convs, add_generation_prompt=True, return_dict=True, return_tensors="pt"
).to("cuda")
with torch.no_grad():
gen = model.generate(
**inputs,
max_new_tokens=256,
num_beams=4,
length_penalty=1.2,
do_sample=False,
eos_token_id=EOS,
pad_token_id=tok.pad_token_id,
**DECODE[tgt],
)
return tok.decode(
gen[0][inputs["input_ids"].shape[1]:], skip_special_tokens=True
).strip()
print(translate("The patient should take this medication twice a day.", "zhtw"))
量化推論(GGUF)
Table with columns: 檔案, 大小| 檔案 | 大小 |
|---|
gguf-v5e/linguaforge-v5e-0.8b-Q8_0.gguf | 約 812M |
gguf-v5e/linguaforge-v5e-0.8b-Q4_K_M.gguf | 約 529M |
gguf-v5e/linguaforge-v5e-0.8b-f16.gguf | 約 1.5G |
llama-cli -m linguaforge-v5e-0.8b-Q8_0.gguf --jinja -st -ngl 99 --temp 0 \
--reasoning off --reasoning-budget 0 \
-sys "You are a professional translator." \
-f prompt.txt
# prompt.txt 內容示例:
# 翻譯成繁體中文:
# The night market is crowded on weekends.
# → 週末的夜市人聲鼎沸。
實測(RTX 5060 Ti,-ngl 99):Q8_0 約 186 t/s,Q4_K_M 約 171–217 t/s。
GGUF 與上方評測路徑的差異
llama-cli 通常沒有 beam search,也常無法設定 no_repeat_ngram_size,預設為 greedy。上方 FLORES 表格則是以 beam=4 + 目標語防重複參數量測。因此:
- 追求與評測一致的穩定性與品質:請使用 PEFT 或合併 bf16 + 上表參數。
- GGUF 適合低記憶體與高吞吐;建議加
--repeat-penalty 1.1,長文分段翻譯,並對繁中輸出做 OpenCC 後處理。
FLORES en→zhtw 前 100 句對照(同 runtime):
Table with columns: 系統, chrF++, BLEU, 簡體洩漏| 系統 | chrF++ | BLEU | 簡體洩漏 |
|---|
| GGUF f16(greedy) | 20.50 | 27.83 | 2.00% |
| GGUF Q8_0 | 20.21 | 27.28 | 2.00% |
| GGUF Q4_K_M | 19.49 | 26.07 | 2.00% |
| bf16 + beam=4(評測路徑) | 20.00 | 28.48 | |
- 量化會單調降低字面分數(相對 GGUF f16:Q8_0 約 −0.29 chrF++,Q4_K_M 約 −1.01)。
- greedy 本身未造成明顯漏譯;主要代價是簡體洩漏約 0% → 2%(同一行內混用字形)。
- GGUF 輸出建議經 OpenCC
s2twp:實測洩漏 2.00% → 0.00%,chrF++ 約只降 0.04。
from opencc import OpenCC
cc = OpenCC("s2twp")
print(cc.convert(llama_output))
其他注意:
--jinja 不可省:省略時 llama-cli 不會補空 think 區塊(見上方警示),品質會明顯下降。
自行組 prompt 的 runtime(node-llama-cpp、Ollama 等)需自行確認這 4 個 token 有進去。
- 精度建議 Q8_0:Q4_K_M 實測會把罕見專名音譯掉(
Kimi→金剛、Sol→索爾),f16 與 Q8_0 則保留;
這是量化本身的代價,與上述 think 區塊無關。
- 關閉 thinking:舊旗標
--chat-template-kwargs '{"enable_thinking":false}' 在現行 llama.cpp 可能被靜默忽略;請使用 --reasoning off --reasoning-budget 0。
- CJK 提示詞:Windows 上請用
-f prompt.txt(UTF-8),避免 -p 經 cp950 破壞輸入。
- 轉檔:Qwen3.5 含 MTP 層;部分 llama.cpp 版本若未加
--no-mtp,runtime 可能報 missing tensor 'blk.24.attn_norm.weight'。基底含未訓練視覺塔,GGUF 為純文字轉檔。
重現 GGUF 對照表:GitHub 倉庫中 uv run python scripts/eval_gguf.py --direction en2zhtw --limit 100。
訓練摘要
- 資料:六方向各約 80,000 句,合計 502,993 筆(COCT、TED2020、WikiMatrix、JParaCrawl、KFTT、GlobalVoices、KDE4、OpenSubtitles 等)+ 通用指令 replay 35,177 筆。清洗包含評測集污染閘、LaBSE 雙語語意過濾(閾值 0.65)、OpenCC 統一臺灣正體等。
- LoRA:r=64、α=128、dropout 0.05;目標含標準注意力、MLP 與 Qwen3.5 線性注意力層(
in_proj_qkv/z/a/b、out_proj)。
- 其他:bf16、不使用 packing、token 預算組 batch、
max_length 1408、lr 1e-4 cosine、單 epoch 5,677 步;final eval_loss 1.7708。
- 成本:單張 RTX 5060 Ti 16GB,峰值 VRAM 約 4.00GB,約 10.5 小時。
較大 rank(r=128)曾使 COMET 再升約 0.18,但 BELEBELE 中日文明顯退步,故發布版維持 r=64。設定檔見 GitHub configs/sft_lora_v5e.yaml。
限制
- 0.8B 容量有限;最高語意品質請考慮更大模型。
- en→zhtw 與官方基底語意統計持平(其餘五方向領先);該方向瓶頸尚未完全定位。
- 通用問答與指令遵循低於官方基底——翻譯特化,非通用助手。
- 多行且各行互不相關的輸入(規格表、清單、UI 字串)常只譯出第一行:訓練語料中的多行樣本皆為連貫段落,此為分布外情形。請逐行送入。
- 2023 年後的 AI 領域術語未學到(如
open weight、agentic coding),會被逐字直譯。
- 含未訓練視覺塔,僅供文字翻譯。
- 主要評測為 FLORES-200 單一測試集;COMET 差異在約 ±0.4 以內時宜視為雜訊。
授權
模型與程式碼 Apache-2.0(繼承自 Qwen3.5-0.8B)。訓練語料各依原始來源授權;本庫僅發布微調權重,不轉發語料。重建資料請使用 GitHub 專案之 scripts/download_data.py 與 prepare_data.py。
連結