FakeRockert543/ckip-coreml
044
CKIP BERT-base CoreML — 繁體中文 WS/POS/NER for iOS/macOS
Apple CoreML 版本的 CKIP BERT-base 繁體中文 NLP 模型,可在 iOS/macOS 上透過 Apple Neural Engine (ANE) 執行。
- 📦 原始碼:GitHub — FakeRocket543/ckip-coreml
- 🤗 模型權重:HuggingFace — FakeRockert543/ckip-coreml(本頁)
- 🧪 MLX 版本(桌面推薦):HuggingFace — FakeRockert543/ckip-mlx
從 ckiplab/ckip-transformers 轉換而來。CoreML fp16 是所有框架中最快的,比 CKIP 官方快 6.3 倍。
模型說明
所有模型支援動態序列長度 1–512。
可用版本
從零開始使用(完整步驟)
1. 環境準備
需要 macOS + Apple Silicon。CoreML Tools 目前需要 Python 3.13(不支援 3.14)。
# 取得原始碼
git clone https://github.com/FakeRocket543/ckip-coreml.git
cd ckip-coreml
# 建立虛擬環境(需要 Python 3.13)
python3.13 -m venv .venv && source .venv/bin/activate
# 安裝依賴
pip install coremltools numpy huggingface_hub2. 下載模型
# 從 HuggingFace 下載全部 .mlpackage
huggingface-cli download FakeRockert543/ckip-coreml --local-dir .下載後目錄結構:
ckip-coreml/
├── ckip_ws_fp16.mlpackage # 斷詞 fp16(推薦)
├── ckip_ws_fp32.mlpackage
├── ckip_ws_q8.mlpackage
├── ckip_pos_fp16.mlpackage # 詞性 fp16
├── ckip_pos_fp32.mlpackage
├── ckip_pos_q8.mlpackage
├── ckip_ner_fp16.mlpackage # 實體 fp16
├── ckip_ner_fp32.mlpackage
├── ckip_ner_q8.mlpackage
├── ckip_ws.mlpackage # 原始版本 (=fp32)
├── ckip_pos.mlpackage
└── ckip_ner.mlpackage3. 準備詞表
CoreML 模型不包含詞表,需要從 MLX 版本取得,或自行下載 BERT 中文詞表:
# 方法一:從 MLX repo 下載 vocab.txt
huggingface-cli download FakeRockert543/ckip-mlx models/vocab.txt --local-dir .
mv models/vocab.txt vocab.txt && rm -rf models
# 方法二:從原始 BERT 下載
# wget https://huggingface.co/bert-base-chinese/resolve/main/vocab.txt4. 執行斷詞(Python)
import coremltools as ct
import numpy as np
# 載入詞表
vocab = {}
with open("vocab.txt") as f:
for i, line in enumerate(f):
vocab[line.strip()] = i
# 載入模型(推薦 fp16)
model = ct.models.MLModel("ckip_ws_fp16.mlpackage")
# Tokenize(BERT 單字切分)
text = "台積電今天股價上漲三十元"
ids = [101] + [vocab.get(ch, 100) for ch in text] + [102] # 101=[CLS], 102=[SEP], 100=[UNK]
input_ids = np.array([ids], dtype=np.int32)
attention_mask = np.ones_like(input_ids, dtype=np.int32)
# 推論
out = model.predict({"input_ids": input_ids, "attention_mask": attention_mask})
preds = np.argmax(out["logits"], axis=-1)[0]
# 解碼斷詞結果(B=0: 詞首, I=1: 詞中)
words, cur = [], ""
for i, ch in enumerate(text):
p = preds[i + 1] # +1 跳過 [CLS]
if p == 0 and cur:
words.append(cur)
cur = ch
else:
cur += ch
if cur:
words.append(cur)
print(words)
# ['台積電', '今天', '股價', '上漲', '三十', '元']5. 執行詞性標注(Python)
import json
pos_model = ct.models.MLModel("ckip_pos_fp16.mlpackage")
out = pos_model.predict({"input_ids": input_ids, "attention_mask": attention_mask})
preds = np.argmax(out["logits"], axis=-1)[0]
# POS id2label 對照表(從 MLX config.json 取得,或用以下常見標籤)
# 完整對照表見 GitHub repo 的 models/pos/config.json
for i, ch in enumerate(text):
print(f"{ch} → label_id={preds[i + 1]}")6. 在 Swift / iOS 中使用
import CoreML
// 載入模型
let config = MLModelConfiguration()
config.computeUnits = .all // 使用 ANE + GPU + CPU
let model = try MLModel(contentsOf: modelURL, configuration: config)
// 準備輸入
let inputIds = try MLMultiArray(shape: [1, seqLen as NSNumber], dataType: .int32)
let attentionMask = try MLMultiArray(shape: [1, seqLen as NSNumber], dataType: .int32)
// 填入 token IDs([CLS] + 單字 IDs + [SEP])
for (i, id) in tokenIds.enumerated() {
inputIds[i] = NSNumber(value: id)
attentionMask[i] = 1
}
// 推論
let input = try MLDictionaryFeatureProvider(dictionary: [
"input_ids": inputIds,
"attention_mask": attentionMask
])
let output = try model.prediction(from: input)
let logits = output.featureValue(for: "logits")!.multiArrayValue!
// 取 argmax 得到預測標籤速度
測試環境:Apple M4 Max / 128GB / macOS 26.3.1 測試資料:維基百科「臺灣」條目,36,245 字,10 runs median
跨框架驗證
CoreML fp32 與 MLX fp32、HF Transformers fp32 的 WS/POS/NER 輸出完全一致,確認轉換正確。
授權
GPL-3.0,依循原始 ckiplab/ckip-transformers 授權。
致謝
- CKIP Lab, 中央研究院資訊科學研究所 — 原始模型
- Apple CoreML — 推論框架
