⏱️iOS 本地 AI:衡量 Foundation Models 效能的策略

開發裝置端 AI 功能,測量效能是必要工作。首先介紹 Instruments 如何上手,觀察效能瓶頸。而為了能支援重複測試任意的 @Generable 型別,我寫了一個 SwiftUI View 作為工具,讓你可以快速把要生成的物件與畫面整合起來。

我們要怎麼知道 Foundation Models framework 運作的效能呢?一個方式是使用 Xcode 內建的 Instruments,另一個則是自己撰寫 benchmarking 的工具。

本文會先簡單介紹怎麼使用 Foundation Models Instrument,再分享一個我開發出來,方便重複執行模型任務的 SwiftUI BenchmarkingView

Instruments

Instruments 會清楚呈現 Foundation Models 運作過程中的每個階段所花的時間、用到的資源。這樣一來,我們就有機會改善效能。

在 Xcode 26 按下 Cmd + I (或使用以下影片的冷門技巧),就可以把當前要執行的 App 用 Instruments 打開。

冷門 Xcode 技巧:Run 按鈕可以長按,就會出現其他選項,並且可以固定在那邊。
冷門 Xcode 技巧:Run 按鈕可以長按,就會出現其他選項,並且可以固定在那邊。

不過,我們要跑什麼呢?就是要把 App 跑起來,按下執行生成的按鈕,然後觀察它的運作。

目前最快的方式,是把之前文章教過的 Streaming Response.swift 稍作修改。

private struct CatSelectionView: Viewprivate 移除,然後到 AIPlayground.swift,也就是放 App 的檔案,把它改成:

@main
struct AIPlayground: App {
  var body: some Scene {
    WindowGroup {
      CatSelectionView() // 原本可能是空的
    }
  }
}

這樣我們就可以在 Mac 或 iOS 裝置上執行這個 App,反覆測試生成 [CatProfile],並且在 Instruments 觀察。

剛打開 Instruments 時,會跳出 Template 視窗,這時候請選 Blank

選擇 Blank
選擇 Blank Template

接著,按下 + Instrument 按鈕,找到 Foundation Models。

新增 Foundation Models Instrument
新增 Foundation Models Instrument

加入成功以後,確認裝置與 App 無誤,就可以按下左上的 Record 按鈕。

按下 Record 按鈕,開始執行
按下 Record 按鈕,開始執行

在 App 中開始執行模型,就會看到 Instruments 的時間軸出現東西。記得先把它停下來,然後把時間軸放大,並且按箭頭展開,看 Session。

透過 Foundation Models Instrument 看 Session 細節
透過 Foundation Models Instrument 看 Session 細節

我們可以看到當前的 session 的整體時間、第一個 token 的時間、輸入與輸出用掉的 token 數量(也就是佔據的 context window)。

以下我示範兩種情境,展示前一篇文章提到的重要功能 prewarm(),能讓使用者感知的等待時間變短。

Run 1 沒有先執行 prewarm(),花了 4.85 秒,其中前面黃色的部分是在載入模型資源。

Run 2 則有在畫面剛打開時就先用 prewarm() 來偷跑。所以花在推理的時間只有 4.47 秒,省了大概半秒。

換言之,當使用者按下按鈕後,更快看到介面有更新(不論是使用 stream response 還是單次)。所以,這個技巧確實有用,而且 Instruments 精準地展現出來了。

關於 Instruments 的操作,我覺得最好的學習方式還是看影片,所以我再次推薦 Meet with Apple Code along with the Foundation Models framework 影片,參考 Chapter 6 。

另外我要提醒一個問題:⚠️ Instruments 的右下角面板有個坑!它有時候沒有更新,比如我從 Run 1 切到 Run 2 時,面板顯示的資料還是 Run 1 的。建議看清楚 Request ID。

Instruments 的 bug:切到 Run 2 時,右下角面板還在顯示 Run 1 的 Session 資料
Instruments 的 bug:切到 Run 2 時,右下角面板還在顯示 Run 1 的 Session 資料

使用 BenchmarkingView 來測試與開發

Foundation Models framework 在 #Playground 再怎麼方便,最終還是得搬到使用者介面上去操作。

而且,我們必須在實機上操作,最好能直接展示漸進式生成的效果。

而為了簡化操作與開發的過程,我親自寫了一個 BenchmarkingView(這次沒有用 AI 寫程式,自己寫還是很有樂趣的)。它可以做到這些功能:

  • 支援不同的 @Generable,也就是不同的 structured output
  • 直接展示 stream response 變成 UI 的過程
  • 顯示第一次回應的時間(stream response)
  • 顯示執行時間
  • 支援 iOS 與 Mac
  • 開關 prewarm()
  • 支援 stream response 或單次回應
  • 重複執行
  • 在 SwiftUI Preview 中使用(小技巧:可以選擇 iPhone 實機)
  • 可以搭配 Instruments 使用

開發出來以後,我覺得它的用途不只是測速,更是展示「裝置端模型在生成介面的漸進式過程」的工具,就像是實機、UI 版的 #Playground是個實用的開發工具。

以下附上程式碼,請貼到你的 AIPlayground 專案中。