如何检测苹果设备GPU/神经引擎支持及解决CoreML并发处理崩溃问题
无神经引擎设备上实现CoreML多图像并发处理的无崩溃方案
问题描述
配备神经引擎的设备(如iPhone 13)可同时处理5张图像,但无神经引擎的设备(如第6代iPad)仅能单次处理1张图像,尝试并发处理会因内存问题导致应用崩溃,需寻求无崩溃的多图像并发ML处理方法。
当前代码实现
func execModelFromQueue(){ for imageQueueObj in ImageQueueObjToAdd { imageQueueObj.status = .InProgress imageQueueObj.newStatus = true self.runPrediciton(imageURL: imageQueueObj.imageURL, imageName: imageQueueObj.fileName) { [weak self] fileName, imageHailResult, error in guard let self = self else { return } if let imageProccessed = self._imageQueue.filter({ $0.fileName == fileName }).first { imageProccessed.status = .Done imageProccessed.newStatus = false imageProccessed.mlResult = imageHailResult self.updateImageStatus(name: imageProccessed.fileName) } HailDamageHelper.storeHailDamage(jobId: self.jobId, fileName: fileName, imageMLHailResult: imageHailResult) self.delegate?.didFinishFile(filename: fileName, imageMLHailResults: imageHailResult) } } } private func runPrediciton(imageURL:URL, imageName:String, completion: @escaping (String, hailMLImageResult?, Error?) -> ()){ for tile in imageTileSet!.tiles! { self.analyzeImage(fileName: imageName, tile: tile, tileSet: imageTileSet!) {[weak self]imageName, myTile, myTileSet, error, result in guard error == nil, let self = self else { return } myTile.mlOutput = result myTile.proccessed = true } } private func analyzeImage(fileName: String, tile: hailMLImageTile, tileSet: hailMLImageTileSet, completion: @escaping (String, hailMLImageTile, hailMLImageTileSet, Error?, hail_v001Output?)->()){ if #available(iOS 13.0, *) { DispatchQueue.global(qos: .background).async { [weak self] in guard let self = self else { return } do { let startProcessDate = Date() if let model = self.getHailModel() { let input = try hail_v001Input(imageWith: tile.image!.cgImage!, iouThreshold: 0.6, confidenceThreshold: 0.4) let output = try model.prediction(input: input) let endProcessDate = Date() } }
解决方案
1. 动态控制并发数
根据设备硬件能力调整并发任务数量:
- 检测设备是否支持神经引擎:通过尝试初始化使用神经引擎配置的模型来判断。
- 无神经引擎设备强制设置最大并发数为1,避免内存过载;有神经引擎设备可保持5个并发任务。
2. 替换全局队列为动态配置队列
将analyzeImage中的全局并发队列替换为串行队列(无神经引擎)或有限并发队列(有神经引擎):
// 全局处理队列,根据设备动态配置 private lazy var processingQueue: DispatchQueue = { let hasNE = self.hasNeuralEngine if !hasNE { // 无神经引擎用串行队列 return DispatchQueue(label: "com.yourapp.ml.processing.serial") } else { // 有神经引擎用并发队列,设置最大并发数5 let queue = DispatchQueue(label: "com.yourapp.ml.processing.concurrent", attributes: .concurrent) queue.setMaxConcurrentOperationCount(5) return queue } }() // 检查设备是否支持神经引擎 private var hasNeuralEngine: Bool { let config = MLModelConfiguration() config.computeUnits = .neuralEngine do { _ = try hail_v001(configuration: config) return true } catch { return false } }
修改analyzeImage方法使用该队列:
private func analyzeImage(fileName: String, tile: hailMLImageTile, tileSet: hailMLImageTileSet, completion: @escaping (String, hailMLImageTile, hailMLImageTileSet, Error?, hail_v001Output?)->()){ if #available(iOS 13.0, *) { processingQueue.async { [weak self] in guard let self = self else { return } do { guard let model = self.getHailModel() else { DispatchQueue.main.async { completion(fileName, tile, tileSet, NSError(domain: "ModelError", code: -1, userInfo: [NSLocalizedDescriptionKey: "模型加载失败"]), nil) } return } let input = try hail_v001Input(imageWith: tile.image!.cgImage!, iouThreshold: 0.6, confidenceThreshold: 0.4) let output = try model.prediction(input: input) DispatchQueue.main.async { completion(fileName, tile, tileSet, nil, output) } } catch { DispatchQueue.main.async { completion(fileName, tile, tileSet, error, nil) } } } } }
3. 优化内存管理
- 瓦片处理完成后,及时释放图像资源:在
completion回调中设置tile.image = nil,减少内存占用。 - 避免一次性加载所有图像瓦片,按需加载并处理,处理完立即释放。
- 确保所有闭包使用
weak self,避免循环引用导致内存泄漏。
4. 内存预警降级
添加内存监控,收到内存警告时自动切换为串行队列:
private func setupMemoryMonitor() { NotificationCenter.default.addObserver(forName: UIApplication.didReceiveMemoryWarningNotification, object: nil, queue: .main) { [weak self] _ in guard let self = self else { return } // 切换为串行队列,暂停高并发处理 self.processingQueue = DispatchQueue(label: "com.yourapp.ml.processing.serial") } }
总结
通过动态配置并发队列、优化资源释放和内存监控,可在无神经引擎设备上实现多图像的无崩溃ML处理,同时在高性能设备上保持并发效率。
内容的提问来源于stack exchange,提问作者Ramesh Kumar
相关产品推荐
相关产品推荐

