為什麼把翻譯模型搬回本機

沉浸式翻譯(Immersive Translate)這類瀏覽器擴充預設走雲端 API,品質夠用,但有三個煩人的地方:網路 round-trip 是延遲主因、開「網頁語言檢測」每開一個 tab 就燒掉上千 token、敏感內容也得送出去。

翻譯是少數很適合丟給小模型的任務——它不需要通用推理,只要把一段文字準確地搬到另一個語言。一顆 1~2B 的翻譯專用模型在 Apple Silicon 上就跑得飛快,延遲、成本、隱私三件事一次解決。

我原本用的是 Tencent 的 Hunyuan-MT v2 1.8B(Hy-MT2-1.8B Q4_K_M,量化後 1.13GB),搭 llama.cpp 跑在一台 16GB 的 M4 上。在 M4 16GB 上實測約 72 tok/s,日常網頁、技術文件、字幕都夠。但用久了會撞到它的天花板。

1.8B 的弱點:跟 7B 同句對照就現形

同系列除了 1.8B 還有一顆 7B(Hy-MT2-7B,Q4_K_M 量化後磁碟上約 4.3 GiB;HuggingFace 頁面標 4.62 GB,差在 GiB 與 GB 的進位——這篇剛好在講單位)。把同一句餵給兩顆,差距很直接。以下都是 M4 16GB 上的實測輸出,目標語言只給泛稱「Traditional Chinese」:

來源句1.8B Q4(~72 tok/s)7B Q4(~19 tok/s)
The Transformer is the backbone of……現代大型语言模型的核心组件…現代大型語言模型的核心
エヴァンゲリオン初号機にシンジが…希真登上 EVA 初号机出击真嗣駕駛初號機出擊
…about 1.1 gigabytes模型文件大小约为 1.1 吉字节模型檔案的大小約為 1.1 GB

差距落在三類。人名與單位是硬傷:日文人名「シンジ(真嗣)」1.8B 翻成不存在的「希真」、單位 gigabytes 翻成「吉字节」沒保留 GB;7B 兩個都對。這類要模型記得住約定俗成的譯名,1.8B 容量不夠,換 prompt 也救不回來。

軼事一則:1.8B 某次甚至把 backbone 翻成「背龍」,把「主幹」當成一條龍。這種低機率的崩法在 7B 上沒再出現過。

第三類是簡繁:上面 1.8B 那欄混著「语言/组件/文件/吉字节」一堆簡體字,7B 則穩定繁體。但簡繁這關其實是 prompt 問題,不全是模型能力。

簡繁這關,target 講清楚就壓掉了

1.8B 漏簡體,多半是因為目標語言只給了泛稱「Traditional Chinese」。把目標講死一點,同一顆 1.8B 的輸出就乾淨了:

target 講法1.8B 輸出
Traditional Chinese(泛稱)漏簡體:软件 / 网络 / 协议 / 复杂
繁體中文,臺灣用語 zh-TW純繁,還自動轉臺灣用語:軟體 / 網路 / 複雜
臺灣正體中文,不可出現簡體字純繁

所以簡繁 1.8B 是教得會的:沉浸式翻譯這類擴充若能自訂目標語言,把它寫成「繁體中文(臺灣)」會比「中文」乾淨很多。對照之下 7B 連泛稱 prompt 都直接給繁體,對隨便寫的 target 更穩——這也是多出來的參數買到的東西之一。

換 7B 的代價:速度

速度從 1.8B 的 ~72 tok/s 掉到 7B 的 ~19 tok/s,慢了大約 3.8 倍。但這個數字仍然遠高於人類閱讀速度,網頁翻譯的體感幾乎沒差別——畫面跳出譯文的瞬間你還在讀上一句。用 3.8 倍的時間換掉人名、單位、簡繁這些每天都會撞到的錯,對我來說這筆交易划算。

部署踩坑:-hf 對 7B 卡死

1.8B 我原本用 llama.cpp 內建的 -hf 自動下載:

llama-server -hf tencent/Hy-MT2-1.8B-GGUF:Q4_K_M \
  --host 127.0.0.1 --port 8080 \
  -c 4096 -ngl 99 -np 1 --cache-ram 0

換 7B 時把 repo 名一改,啟動就卡死了:log 一片空白、5 分鐘零下載、也不報錯。問題出在 llama.cpp 內建下載器對 HuggingFace 的 xet CDN 協定支援不完整——小檔有時能矇過去,4.3GB 的大檔就直接掛在那裡無進度。

解法是繞過內建下載器,自己用 curl 把 GGUF 抓下來,再用 -m 指本機檔:

# 直接下載(-C - 可續傳,xet CDN 走 302 → 正常 200)
curl -L -C - \
  "https://huggingface.co/tencent/Hy-MT2-7B-GGUF/resolve/main/Hy-MT2-7B-Q4_K_M.gguf" \
  -o ~/models/Hy-MT2-7B-Q4_K_M.gguf   # ~4.3GB

# 啟動(注意是 -m 本機檔,不是 -hf)
llama-server -m ~/models/Hy-MT2-7B-Q4_K_M.gguf \
  --host 127.0.0.1 --port 8080 \
  -c 4096 -ngl 99 -np 1 --cache-ram 0 \
  --temp 0.7 --top-p 0.6 --top-k 20 --repeat-penalty 1.05

幾個容易漏的點:

  • -ngl 99 把所有 layer 丟給 Metal GPU,Apple Silicon 一定要開,不然退化到 ~40 tok/s。
  • sampling 參數(--temp 那串)直接寫在 server 端,照官方 README 推薦值,不靠 client 黑盒。llama-server 預設是 temp=0.8 / top-k=40 / top-p=0.95,跟翻譯模型推薦值差很多,不覆寫翻出來會更發散。
  • 7B 接手原本 1.8B 用的 :8080,所以瀏覽器擴充那邊一個字都不用改,重啟 server 就生效。

launchd 切換與回退陷阱

兩顆模型我都用 launchd 管開機自啟。切到 7B 的同時要把 1.8B 停掉並 disable,免得重開機兩顆搶 :8080

UID=$(id -u)
# 暫停 1.8B(釋放 :8080 + disable 防重開機自啟)
launchctl bootout  gui/$UID/org.oracle.llama-server-hymt2
launchctl disable  gui/$UID/org.oracle.llama-server-hymt2
# 啟動 7B
launchctl bootstrap gui/$UID ~/Library/LaunchAgents/org.oracle.llama-server-hymt2-7b.plist

這裡有個 launchctl 的陷阱值得記一筆:被 disable 過的 service,之後直接 bootstrap 會被 disabled 狀態擋下、悄悄不啟動。回退到 1.8B 時必須enable 才能 bootstrap

launchctl bootout  gui/$UID/org.oracle.llama-server-hymt2-7b
launchctl disable  gui/$UID/org.oracle.llama-server-hymt2-7b
launchctl enable   gui/$UID/org.oracle.llama-server-hymt2   # 關鍵:少這行 bootstrap 會被擋
launchctl bootstrap gui/$UID ~/Library/LaunchAgents/org.oracle.llama-server-hymt2.plist

如果記憶體有餘裕,也可以讓兩顆並存:1.8B 留 :8080 給逐 tab 的高頻快翻、7B 改 :8081 給重要文件手動切,兩顆 Q4 加起來約 5.4GB,16GB 同時跑得下。我目前是先單跑 7B 試幾天再定。

延伸:Gemma 4 與 16GB 的硬體現實

換模型那幾天剛好 Gemma 4 補了新尺寸,順手查了一輪——結論是同一件事的另一面:參數量不是想開多大就多大,16GB 會幫你做選擇。

Gemma 4 這一代有五個尺寸,官方 benchmark 與量化後的硬體需求大致如下:

尺寸參數多模態Q4_K_M 記憶體
E2B5.1B (eff 2.3B)text+img+audio~3 GB
E4B8B (eff 4.5B)text+img+audio~4-5 GB
12B Unified11.95B densetext+img+audio7-8 GB
26B-A4B (MoE)25.2B (act 3.8B)text+img~15 GB
31B Dense30.7Btext+img(無 audio)17-20 GB

對應到一台 16GB 的 M4 base(iogpu.wired_limit_mb 預設,約 75% ≈ 12GB 給 GPU):

  • E4B(~4-5GB) 是甜蜜點,想要多模態又要常駐就選它。
  • 12B Q4(~7-8GB) 跑得動但擠,推估 ~10-15 tok/s,被記憶體頻寬綁住——拿來做批次或多模態可以,當互動聊天會嫌頓。
  • 31B Q4(17-20GB) 在 16GB 上直接塞不下,要 36GB 以上的機器,留給雲端就好。

12B 這顆的賣點其實是架構而不是分數:它是 encoder-free 設計(vision 用 35M embedder 直吃 patch、audio 切 40ms 直投),多模態延遲低、好 fine-tune,分數比 31B 低約 8pt 是正常的取捨。

順帶一提,如果你在找 uncensored 版:12B 才出沒幾天、架構又特殊,abliteration 工具還沒跟上,現成的是 E4B / 26B-A4B / 31B。而 abliterated 模型的能力損耗大多沒被量化、作者自己都標 “crude PoC”,不建議當日常主力,要用先 red-team。

小結

本機翻譯這件事,模型選擇基本上是「在你的記憶體預算內,買得起多少正確的專有名詞」。1.8B 夠快、日常無痛,但會在技術詞和片假名上穩定踩雷;7B 用 3.8 倍的時間把這些補回來,而那點時間差還是落在閱讀速度以下,所以划算。

再往上的 12B、31B 不是翻譯用不到,而是 16GB 這條線會先替你擋下來。與其糾結跑不動的大模型,不如把手上這台能穩定跑的那一顆調到最好。