Section 10/161 menit
10. Model Optimization: Compute Units
10. Model Optimization: Compute Units
Memilih compute unit yang tepat memiliki dampak signifikan pada latensi, throughput, dan konsumsi baterai.
Benchmark Compute Units
swift
import CoreML
class ModelBenchmark {
func benchmark(modelURL: URL, sampleInput: MLFeatureProvider) async throws {
let computeUnits: [(MLComputeUnits, String)] = [
(.cpuOnly, "CPU Only"),
(.cpuAndGPU, "CPU + GPU"),
(.cpuAndNeuralEngine, "CPU + ANE"),
(.all, "All (Auto)")
]
for (unit, name) in computeUnits {
let config = MLModelConfiguration()
config.computeUnits = unit
let model = try MLModel(contentsOf: modelURL, configuration: config)
// Warm-up run (penting untuk benchmark yang akurat)
_ = try model.prediction(from: sampleInput)
// Benchmark 10 runs
let start = Date()
for _ in 0..<10 {
_ = try model.prediction(from: sampleInput)
}
let avgMs = Date().timeIntervalSince(start) * 100 // ms per run
print("\(name): \(String(format: "%.1f", avgMs))ms avg")
}
}
}
Model Quantization
Quantization mengurangi ukuran model dan mempercepat inferensi dengan trade-off akurasi minimal:
swift
# Script Python: quantize model sebelum distribute
import coremltools as ct
model = ct.models.MLModel("MyModel.mlpackage")
# Float16 quantization — ukuran 50% lebih kecil, minimal accuracy loss
config = ct.optimize.coreml.OptimizationConfig(
global_config=ct.optimize.coreml.OpLinearQuantizerConfig(
mode="linear_symmetric",
dtype="float16"
)
)
compressed_model = ct.optimize.coreml.linear_quantize_weights(model, config=config)
compressed_model.save("MyModel_Float16.mlpackage")
# Int8 quantization — ukuran 75% lebih kecil, sedikit accuracy loss
config_int8 = ct.optimize.coreml.OptimizationConfig(
global_config=ct.optimize.coreml.OpLinearQuantizerConfig(
mode="linear_symmetric",
dtype="int8"
)
)
compressed_int8 = ct.optimize.coreml.linear_quantize_weights(model, config_int8)
compressed_int8.save("MyModel_Int8.mlpackage")
Compute Plan API (iOS 17+): Inspect Before Execute
swift
// Inspect bagaimana Core ML akan mengeksekusi model SEBELUM load
func inspectComputePlan(modelURL: URL) async throws {
let config = MLModelConfiguration()
config.computeUnits = .all
// Dapatkan plan tanpa load model sepenuhnya
let plan = try await MLComputePlan.load(contentsOf: modelURL, configuration: config)
// Iterasi struktur model
for (index, layer) in plan.modelStructure.program?.functions["main"]?.block.operations.enumerated() ?? [].enumerated() {
let deviceUsage = plan.computeDeviceUsage(for: layer)
let device: String
switch deviceUsage?.preferred {
case .some(let cpu as MLCPUComputeDevice): device = "CPU"
case .some(let gpu as MLGPUComputeDevice): device = "GPU"
case .some(let ane as MLNeuralEngineComputeDevice): device = "ANE"
default: device = "Unknown"
}
print("Layer \(index): \(device)")
}
}