Mac mini M1 ARM CPU 與 CoreML / CreateML 簡單測試

Seachaos
tree.rocks
Published in
13 min readNov 18, 2020

--

前言

在 11/10 的時候, Apple 發表了新的 M1 chip (處理器),是自家設計的 ARM 晶片;平日我使用的 iPad Pro 與 iPhone 其實就可以感受到 Apple CPU 的厲害,所以一看到 Mac mini arm 版本發表馬上就下訂一台。

之所以選擇 Mac mini 是因為我相信有主動散熱(風扇)且無電源顧慮( 非電池 )的情況下,應該更能發揮 Apple M1 CPU 的效能,所以也想做些測試,順便比較一下 MacBook Pro 2019 / iPhone 12 Pro Max / 11 Pro Max / 7 Plus 的效能 。

相信常見的跑分網路上已經很多了,其實本來有打算順便在上面執行 Tensorflow 的 Machine Learning 來測試速度,但是發現很多 Library 還有相依性問題,所以這邊先略過,並且使用 Apple 自家的 Core ML 來作為測試 ( 就沒有套件相依問題 )。

其實也沒什麼好開箱的,就一個盒子一條電纜

注意:本測試為本人使用自己設備測試,所以不代表任何公正與客觀,僅供參考。

另外整場發表會影片不停地聽到 Faster. Faster. Faster…
讓我想到 Within Temptation 的音樂

先上結論

本篇文章重點就是看看這次效能如何

以下是 Core ML 分別執行 VGG 16 與 MobileNetV2 在不同設備的時間
(越低表示越快 )

毫無意外 Mac Mini 是最快,另外可以看到 Mac mini M1 chip 即便使用 rosetta 依然比我的 i9 MacBook Pro 快 ( 這應該也歸功於內建的 Neural Engine 晶片)

但是 iPhone 12 Pro Max 卻在小 Model 略輸給 iPhone 11 Pro Max ,這是比較奇妙的地方,不知道是不是省電考量 ?

但是更驚人的地方來了,左圖是執行 Create ML 的時間

在執行的時候我也嚇了一跳, Apple 官方宣稱於 Machine Learning 上的速度確實有大幅增加,在執行 600 張平均大小為 1200 pixel 的圖片於 Create ML

MacBook Pro 約花了 3 分鐘
Mac mini M1只花了 18 秒多

(下圖為 Create ML 參數)

Create ML 的設定

接下來是 Core ML部分

測試方法

注意:本測試為本人使用自己設備測試,所以不代表任何公正與客觀,僅供參考

測試範圍

這邊使用 XCode 與 Core ML 在不同的機器上測試,然後使用 MobileNetV2 與 VGG16 (皆來自 Keras 與官方範例 )

測試設備

以下為本人這次測試使用的設備 ( 手機就不列出規格了,容量 iPhone 7 為 128G,其餘皆為 256G )

  • Mac mini :
    macOS Big Sur
    Apple M1 chip with 8GB RAM
  • MacBook Pro 2019:
    macOS Catalina / Big Sur ( 先跑 Catalina 後來升級 Big Sur )
    Intel i9 2.4GHz 8-Core
    64 GB 2667 MHz DDR4
    AMD Radeon PRo 5500M 8GB

Core ML 測試

這邊使用 XCode 來進行測試

皆使用相同的 Model ( MobileNetV2, VGG16 為自行調整),來自官方範例 :
https://coremltools.readme.io/docs/introductory-quickstart

下圖為比較一下硬體資源狀況 ( 不代表執行中狀態 )

macbook pro cpu / gpu 使用率示意圖
mac mini cpu / gpu 使用率示意圖

XCode 部分,圖片預先縮放成 224 pixel ,計時部分如下:

let m = TestModel()
let start = CFAbsoluteTimeGetCurrent()
for i in 0...50000 {
m.perform()
}
let diff = CFAbsoluteTimeGetCurrent() - start
print("runtime \(diff) sec")

Test Model 如下 :

class TestModel {
var model: VNCoreMLModel
var handler: VNImageRequestHandler?
var request: VNCoreMLRequest?
init() {
do {
let model = try VNCoreMLModel(for: MobileNetV2().model)
self.model = model
self.prepareRequest()
}catch {
fatalError("Failed to load Vision ML model: \(error)")
}
}
func prepareRequest () {
guard let theimageurl = loadImgData() else {
fatalError("Failed to load image")
}
let request = VNCoreMLRequest(model: model, completionHandler: self.onVisionRequestComplete)
request.imageCropAndScaleOption = .centerCrop
self.request = request
let handler = VNImageRequestHandler(data: imgData, options: [:])
self.handler = handler
}
func perform() {
guard let request = self.request else {
fatalError("Failed to run request")
}
guard let handler = self.handler else {
fatalError("Failed to run handler")
}
try? handler.perform([request])
}
func onVisionRequestComplete(request: VNRequest, error: Error?) {
}
}

載入 img 部分 :

func loadImgData () -> Data?{
let name = "img_224"
#if os(iOS) || os(watchOS) || os(tvOS)
guard
let
image = UIImage(named: name),
let data = image.pngData()
else { return nil }
#else
guard
let
img = NSImage(named: name),
let data = img.tiffRepresentation
else { return nil }
#endif
return data
}

得出的分數記錄如下 :

core_ml_xcode_VGG16 = {
"mac_mini_m1": [1.7340099811553955, 1.730589032173156, 1.7289729118347168],
"mac_mini_m1(rosetta)": [4.263499021530151, 4.4160239696502686, 4.235645055770874],
'mbp_2019_xcode': [5.758417010307312, 5.486600041389465, 5.238188028335571],
'iphone_7_plus': [9.666514039039612, 9.84310793876648, 8.52833092212677],
'iphone_11_pro_max': [3.0652589797973633, 2.8743739128112793, 2.7184410095214844],
'iphone_12_pro_max': [2.8480180501937866, 2.8508739471435547, 2.8416229486465454],
}
core_ml_xcode_MobileNetV2 = {
"mac_mini_m1": [1.7541369199752808, 1.7162950038909912, 1.7272679805755615],
"mac_mini_m1(rosetta)": [4.174805998802185, 4.223266959190369, 4.173293948173523],
'mbp_2019_xcode': [5.555397987365723, 5.493206977844238, 5.280913949012756],
'iphone_7_plus': [7.818480968475342, 7.834130048751831, 7.99383008480072 ],
'iphone_11_pro_max': [1.8998539447784424, 1.8868529796600342, 1.8896420001983643],
'iphone_12_pro_max': [2.578321933746338, 2.5781190395355225, 2.633913993835449],
}

同場加映 Tensorflow 於 MBP 測試

其實本人亦有準備好使用 Tensorflow 來測試 Training Model
( 本來想說 Mac Mini 到貨可以比較,但是目前太多相依問題要解決所以殘念… )

這邊使用 Tensorflow 與官方範例
(參考 :https://www.tensorflow.org/tutorials/images/cnn )

其中桌機執行在 RTX 2060 時候有做一些調整 ( 參考 https://medium.com/@JeansPantRushi/fix-for-tensorflow-v2-failed-to-get-convolution-algorithm-b367a088b56e )

gpu_num = len(tf.config.experimental.list_physical_devices('GPU'))
print("Num GPUs Available: ", gpu_num)
if gpu_num > 0:
physical_devices = tf.config.experimental.list_physical_devices('GPU')
# physical_devices
tf.config.experimental.set_memory_growth(physical_devices[0], True)

然後 batch size 分別為 64, 128, 256

以跑訓練 CIFAR10 來作為基準,但是目前暫時無法安裝在 Mac mini M1 上,所以也可以當參考一下其他設備的差異

( 上圖越低越快 )

然後這是 model 的 summary

Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d (Conv2D) (None, 30, 30, 32) 896
_________________________________________________________________
max_pooling2d (MaxPooling2D) (None, 15, 15, 32) 0
_________________________________________________________________
conv2d_1 (Conv2D) (None, 13, 13, 64) 18496
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 6, 6, 64) 0
_________________________________________________________________
conv2d_2 (Conv2D) (None, 4, 4, 64) 36928
_________________________________________________________________
flatten (Flatten) (None, 1024) 0
_________________________________________________________________
dense (Dense) (None, 64) 65600
_________________________________________________________________
dense_1 (Dense) (None, 10) 650
=================================================================
Total params: 122,570
Trainable params: 122,570
Non-trainable params: 0
_________________________________________________________________

結語

目前很多軟體環境都還是辨識為 i386 或是 x64,導致編譯不少軟體都失敗,另外 Visual Studio Code 倒是可以透過 Rosetta 順利執行。

這機器的 Neural Engine 晶片 速度可以說是相當驚人 ( 如果要跑 ML/AI/DL )
但是如果有要入手開發的人,除非動手能力很強,不然建議可以再等等 ( 第三方套件支援度 )

另外這邊是於 M1 ARM 架構上之 React-Native / Python / 執行 Mac x86 指令的目前安裝環境筆記

--

--