文件導航

轉換說明

本頁描述普通的 Core ML 匯出。單獨重寫的 ANE 圖和可選的權重調色盤化記錄在 ANE_ENGINEERING.md 中。

匯出把 原始 Laya checkpoint 載入進 FP32 PyTorch 模組,嚴格檢查所有 state-dict 鍵,追蹤一個只做推理的實現,並儲存為一個 Core ML ML Program。已釋出的 checkpoint 檔案本身以 FP16 張量為主;這裡的 FP32 指的是匯出/參考計算,而不是更高精度的源權重。不做訓練、剪枝或權重量化。FP16 是一種轉換精度選擇;診斷時可選用 FP32。

執行時使用 checkpoint 的 tokenizer、prompt 佈局、選項標記、問題型別 embedding、decision head、action head 和校準溫度。Choice、score、noul、結構化 criteria、token 計賬和零生成 token 都遵循上游 API。編碼器是雙向的:每個問題仍然各跑一遍自己的編碼器序列。沒有共享狀態的隱藏狀態快取。

已驗證的轉換選擇

  • coremltools==9.0、torch==2.7.0、numpy==2.1.3、Python 3.12。
  • TorchScript 追蹤,帶圖檢查、評估模式,原始權重載入進 FP32 模組。
  • ML Program,部署目標為 macOS 15 / iOS 18。實際執行是在執行 macOS 27.2 的 M3 Max 上測試的;iPhone/iPad 和更早的 macOS 上的執行未測試。
  • 預設序列長度從 16、32、64、96、128、192、256、384、512、768、1024 中選取,並以 checkpoint 的上下文上限為界。執行時會補齊到可用的最小長度,並把這些新增的 token 掩掉。
  • 預設批大小為一,帶 32 個標記槽。更多問題會分塊執行。--batch-size 和 --max-options 會產生不同的匯出簽名。
  • 對於已知的工作負載,可以使用固定形狀。超出某個匯出長度或選項容量的輸入會報錯;它們不會被靜默截斷去遷就更小的匯出。原始 checkpoint 的上下文截斷被保留。

Apple 記錄了 TorchScript 轉換 和 列舉輸入形狀。多個列舉輸入需要相同數量的形狀,並按索引配對;本匯出據此把 input ID 和 attention mask 配對。

為可復現性保留的失敗

這些是在本機和本作業系統上的觀察,不是對每個 Core ML 版本的說法。

  1. PyTorch 的 __or__ 布林運算子沒有被轉換。顯式的 torch.logical_or / torch.logical_and 保留了相同的 mask 語義。
  2. NumPy 2.5 拒絕了 coremltools 9.0 內部一處已棄用的陣列轉標量轉換。專案支援的依賴被釘在 NumPy 2.2 以下。PyTorch 被釘在轉換器測試過的 2.7.0 版本,而不是 2.7.1。
  3. 強制 CPU_AND_GPU 的 RangeDim 產生了很大的數值誤差,且對重複的相同輸入給出不同結果。原始 SDPA 匯出只匹配了 47/63 個參考答案,顯式的 matmul/softmax 注意力只匹配 20/63。FP32 未能解決觀察到的短輸入 GPU 失敗。CPU / 自動選擇為 SDPA 圖給出了正確的輸出。
  4. 列舉長度恢復了 GPU 保真度與可重複性。隨後一個單獨的小型迴歸測試在切分一個常量布林區域性注意力矩陣時暴露出 MPSGraph 編譯器的 SIGTRAP。診斷指名為 ElementsAttr::getValues<bool> / FoldStridedSliceOp。
  5. 最終實現切分 整數位置,之後再構造布林區域性掩碼。這消除了編譯器陷阱。它並沒有治好普遍的 RangeDim GPU 失敗:後續實驗仍然只匹配 49/63,且不可重複。列舉長度仍是預設。

執行時會拒絕 RangeDim + cpu_gpu,除非為診斷實驗顯式允許。要復現那個失敗的配置:

laya-coreml convert laya-multilingual models/range-experiment --shape-mode range
python -m benchmarks.validate models/range-experiment \
  --name laya-multilingual --compute-units cpu_gpu --allow-unvalidated-gpu \
  --repeats 10 --output artifacts/range-experiment.json

該測試在實測環境中預期會失敗。失敗與成功的原始報告都保留在 benchmarks/results/;包含 "passed": false 的報告不得被引用為已驗證的配置。

裝置證據

CPU_AND_NE 表示 CPU 和 Neural Engine 是被允許的,而不是每個運算元都在 Neural Engine 上執行。基準記錄 Core ML 計算計劃的首選/支援裝置和估計開銷。這是一個預期的計劃,不是 Instruments 的執行時硬體 trace、功耗測量,也不是獨佔 Neural Engine 執行的證明。

載入 Hub 快照

釋出冒煙測試發現了一個單獨的打包問題:從共享 Hugging Face 快取載入一個符號連結的權重檔案,會讓 Core ML 的原生編譯器報告缺失 model.mlmodelc/weights/weight.bin。所有六個等價的本地包都成功載入。執行時現在會在構造 MLModel 之前,把由符號連結支撐的包複製到一個內容定址的普通檔案快取。複製前後以及複用時都會檢查雜湊;快取發生變化或損壞會報錯。普通檔案的本地包不走這條複製路徑。快取位置和覆蓋方式見 USAGE.md。

可復現性

每次匯出都包含 coreml_config.json:原始權重 SHA256、源版本、形狀、精度、注意力實現、工具版本、轉換時間,以及每個包/tokenizer/配置檔案的雜湊。匯出拒絕覆蓋已存在的目錄。失敗的匯出只會刪除它新建的輸出目錄。

提交進倉庫的 golden reference 是用 FP32 PyTorch MPS 從未修改的上游 Laya 版本 573e5b62696ba441230cd6be71d593331b5d23af 生成的。它包含完整的輸入 token ID 和未取整的 logits。驗證會逐位元組比較這些 token,並檢查選定答案、校準機率、動作機率、token 計賬和重複的公開結果。

要在與上游相容的環境中重新生成 golden reference:

git clone https://github.com/NandhaKishorM/laya .upstream
git -C .upstream checkout 6a5819129eb220570792e417e49723d697efd76f
python -m benchmarks.reference --upstream .upstream --model-root /path/to/original/checkpoints

確切的參考依賴記錄在生成的 JSON 中。它們與釘定的匯出環境相互獨立;Transformers 不是 laya-coreml 的執行時或匯出依賴。