CoreML / MLModelConfig的preferredMetalDevice - 理解设备放置启发式算法

18

是否有任何公共文件清楚地说明了在macOS上运行推断模型时,CoreML的GPU设备放置策略?它如何决定是否在集成、独立或CPU上运行?一个人能否可靠地“强制”一条路径?对于像新的Mac Pro那样具有多个独立GPU以及多个eGPU的系统,这会发生什么变化?

我在我的rMBP上进行的测试表明,答案是否定的,并且温度、电池、插入电源、自动图形设置以及应用程序支持甚至一些MLModel架构启发式都在设备放置中起着作用。

附带背景的较长内容:

我很好奇是否有任何公共文档介绍了CoreML的设备选择启发式。随着10.15的CoreML preferredMetalDevice API的添加,我想象可以强制运行MLModel/Vision请求所在的MTLDevice

在我的2018年rMBP上,通过使用集成、独立和eGPU进行测试,似乎只有eGPU在请求时始终运行CoreML模型。

我的CoreML模型是一个由多个输出(附加到自定义特征提取器的多头分类器)的MobileNet分类器组成的流水线模型。

出于几个原因,我很好奇了解设备选择偏好:

a) 我希望确保我的MLModel被提供由本地MTLTextures支持的CIImages图像,在执行推断的设备上限制PCI传输并仅在单个GPU设备上进行处理。

b) 实际上,我的模型被提供视频帧,并且WWDC'19 / 10.15引入了VideoToolbox和AVFoundation API,以帮助强制使用特定的视频编码器和解码器在特定的GPU上运行。

理论上,如果一切正常,我应该能够为视频解码、预处理、CoreML/Vision推断和后续编码指定相同的MTLDevice - 使所有基于IOSurfaceCVPixelBuffersCVMetalTextureRefsMPSImages等友好的对象都驻留在同一个GPU上。

苹果有一个Pro Apps WWDC视频,建议这是快速路径多GPU支持/后燃解码器支持未来的发展方向。

CoreML是否真正允许建议的设备放置工作?

我正在使用带有Vega 20 GPU的Retina MacBook Pro 2018,并尝试各种方法来启用Vega 20。

  • 禁用自动图形切换

  • 禁用自动图形切换/将NSSupportsAutomaticGraphicsSwitching设置为False

  • 禁用自动图形切换/将NSSupportsAutomaticGraphicsSwitching设置为True

  • 启用自动显卡切换/将NSSupportsAutomaticGraphicsSwitching设置为False

  • 启用自动显卡切换/将NSSupportsAutomaticGraphicsSwitching设置为True

  • 电池充满并插入我的苹果电源适配器

  • 电池充满并插入我的eGPU

  • 结果:

    • 如果我使用MLModelConfig中的preferredMetalDevice,则可以可靠地使eGPU每次都能运行我的MLModel

    • 如果请求,我可以相当可靠地让集成显卡运行推论,但在某些电池电量、插入状态或自动显卡切换选项的配置下,它不会运行。

    • 我无法在任何以上配置组合中可靠地使独立显卡始终运行 - 但我看到所有资源都驻留在GPU上(纹理等),并且CoreML已经配置为在那里运行。只是没有报告任何活动。

    我已经配置了我的info.plist以获得正确的eGPU支持,并且可以热插拔/检测设备更改并分派工作到eGPU,并支持检测设备移除请求。所有这些都有效。不起作用的是CoreML尊重我的设备位置!


    我非常想知道PyTorch或TensorFlow是否可以使用M1 Max GPU。 - Charlie Parker
    如果这些系统利用了金属后端,我相信是可能的。但如果他们不选择使用私有API(也许需要获得苹果的许可),或者通过在ML包或ML模型格式中嵌入CoreML模型并在Swift / Obj-C中使用CoreML API或使用Python中的coremltools进行预测来使用ANE,那么它们将无法利用ANE - 我相信现在已经可以在M1机器上进行推断了? - vade
    我已经回答了你的许多问题,但其他问题由于缺乏足够的信息,我们甚至无法猜测为什么事情不能按你的期望运作。 - Jeshua Lacock
    1个回答

    1

    目前没有公开的文档明确说明CoreML的GPU利用计划。请注意,您的问题似乎在问很多不同的问题,应该更加专注于每篇文章一个问题,但我会尽力回答。

    您可以“强制”它只在CPU上运行:

    let config = MLModelConfiguration()
    config.computeUnits = .cpuOnly
    

    或者CPU和GPU:

    config.computeUnits = .cpuAndGPU
    

    或者返回所有可用的计算单元,包括神经引擎(如果支持)以及如果 MLModel 层支持的话:

    config.computeUnits = .all
    

    当存在多个Metal设备时,您可以选择使用哪一个。请参阅此示例代码以在最高功率的Metal设备、外部GPU或不驱动显示器的GPU之间进行选择。

    您还可以选择允许低精度损失:

    config.allowLowPrecisionAccumulationOnGPU = true
    

    因为你的回答不够充分,而且有点显而易见。我知道你想要帮忙,所以我很感激。当处理多GPU系统时,以上内容都不是严格正确的,这也是我讨论的内容,即离散GPU、多GPU Mac Pros或同时具有集成、离散和eGPU的系统在CoreML设备放置启发式和首选金属设备方面表现出奇怪的行为。系统似乎会根据自己的意愿来转移负载,在拥有eGPU时,您的离散GPU大部分时间似乎不被优先考虑。 - vade
    此外,当系统服务(如媒体分析)运行时,您的设备放置请求可能会失败,因为在M1上似乎存在有限的ANE调度(或资源共享或配置?)。 - vade
    你应该意识到两件事情:(1)你的问题本来就应该被关闭,因为你问了很多不同的问题;(2)你没有提供源代码,却问为什么事情不按照你的期望工作。所以,如果我的回答质量不高,那是直接与你问题的质量低劣有关。 - Jeshua Lacock
    关于我的答案显然,他们直接回答了你的一些问题。如果它们很明显,为什么还要问这个问题呢? - Jeshua Lacock
    在我的2018年rMBP上使用Vega 20进行集成、独立和eGPU测试后,似乎只有eGPU在请求时能够始终运行CoreML模型。独立GPU并不总是在请求首选设备位置时工作。它会根据状态(电池/温度和运行的应用程序)偶尔工作,但如果您有eGPU,则可靠性较低。如果提供了eGPU,则往往可以工作,但似乎会根据系统状态和运行的应用程序而改变。集成显卡倾向于工作,但似乎会根据系统状态(电池/温度和运行的应用程序)而改变可用性。 - vade
    显示剩余6条评论

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接