2

对于一个项目,我们使用 WinML 使用全卷积网络进行推理。我们查询平台上的所有适配器,并将 d3d12 设备显式传递给学习会话。出于性能原因,我们将权重转换为半浮点格式,我们发现某些 GPU 不支持它。创建学习会话时实际上有两种情况:

  • 对于某些 GPU(Intel HD 4600),WinML 会抛出异常,指出设备不支持半浮点格式。对我来说,这不清楚需要什么,据我了解,WinML 不会强制使用在 Nvidia Pascal 及更高版本和 AMD Polaris 及更高版本中发现的特殊 ALU,所以我怀疑这种支持只涉及纹理或缓冲区格式。据我所知,每个 dx11 gpu 都支持 r16f 纹理格式,所以不清楚这里的确切要求是什么,以及是否有预先查询它的方法。目前,我们尝试使用另一个可用设备重新创建会话,如果没有,则回退到 cpu,但这并不是一个真正干净的方法。
  • 对于其他一些 GPU(Nvidia Kepler 代),会发生“未知异常”。它没有明确说不支持半浮点格式,我不知道发生了什么。

任何帮助/见解将不胜感激。问候,文森特

4

1 回答 1

1

Windows 机器学习实现使用各种检查来确定特定 GPU 是否支持 Float16。

看看这里的实现: https ://github.com/microsoft/onnxruntime/blob/bfa996b5fa1ce87d2501abd8371ec5612d288cac/winml/lib/Common/CommonDeviceHelpers.cpp#L140

它包含一个阻止列表的组合:

bool CheckAdapterFP16Blocked(bool isMcdmAdapter, uint32_t vendorId, uint32_t majorVersion, uint32_t minorVersion) {
  switch (vendorId) {
    case c_intelVendorId: {
      if (isMcdmAdapter) {
        return false;
      }

      // Check Intel GPU driver version
      return (majorVersion < 25) || (majorVersion == 25 && minorVersion < 6574) || (majorVersion == 26 && minorVersion < 6572);
    }
  }
  return false;
}

以及对 DML 设备的查询以指示底层硬件是否支持 float16。

 winrt::com_ptr<IDMLDevice> dmlDevice;
  winrt::check_hresult(DMLCreateDevice(
      device,
      DML_CREATE_DEVICE_FLAG_NONE,
      IID_PPV_ARGS(dmlDevice.put())));

  DML_FEATURE_QUERY_TENSOR_DATA_TYPE_SUPPORT float16Query = {DML_TENSOR_DATA_TYPE_FLOAT16};
  DML_FEATURE_DATA_TENSOR_DATA_TYPE_SUPPORT float16Data = {};

  winrt::check_hresult(dmlDevice->CheckFeatureSupport(
      DML_FEATURE_TENSOR_DATA_TYPE_SUPPORT,
      sizeof(float16Query),
      &float16Query,
      sizeof(float16Data),
      &float16Data));
  return float16Data.IsSupported;
于 2021-06-07T18:06:20.307 回答