WinML术语中的“半浮点支持”如何转换为DX功能?

时间:2019-12-28 15:52:29

标签: machine-learning windows-machine-learning

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

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

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

1 个答案:

答案 0 :(得分: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;