type
status
date
slug
summary
tags
category
icon
password

前言

由于N卡旧卡矿多,新卡太贵,而且咱一个臭打游戏的,游戏需求显然比炼丹需求要大得多,因此去年在装新电脑时,我捡了一张600块的5700XT先用着,而没有向矿老板和老黄屈服。虽然不能确定它有没有矿过,但是买回来之后拆开看过,显存、挡板、接口什么的都比较新,也没有修过的痕迹,用个一年半载我觉得问题应该是不大的。
notion image
5700XT这张卡虽然现在也算是老家伙了,但是对付游戏显然是绰绰有余,不过要炼丹的时候,就十分的痛苦了。在这个CUDA满天下的时代,放眼望去,没几个重大成果是A卡跑出来的。要说A卡为了对抗CUDA出了个ROCm,那可真的是依托答辩。虽然ROCm提供了一键安装脚本,但是用起来那可真叫一个痛苦。
notion image
首先吧,ROCm只支持Linux。别说什么用Linux写代码不是天经地义,我就一台电脑,无论是使用国产软件还是打游戏,基本都是离不开Windows的,双系统虽然能用,但是每次切换要重启,数据同步起来还不方便。其次,PyTorch对ROCm的支持现在是5.2版本(截至本文编写时最新版本已是5.4.2),而当你尝试在Ubuntu 22.04.1 LTS上安装的时候,会发现一堆依赖还是旧版本的,要不你就用20.04,要不你就去折腾旧依赖。后来使用ROCm官方提供的Docker镜像的时候,出现了PyTorch跑不出结果的情况,显存也吃了,GPU占用率也始终99%,但是就是不出结果。看来AMD不光是驱动依托答辩,ROCm也是答辩依托,配起来麻烦还不好使。

DirectML初体验

那AMD炼丹真就没办法了吗?也不是,22年10月份的时候,我找到了一个玩意叫DirectML。
notion image
Direct Machine Learning(DirectML)是用于机器学习的低级API。它有一个熟悉的(原生C++、nano-COM)编程界面和DirectX 12风格的工作流。您可以将机器学习推理工作负载集成到游戏、引擎、中间件、后端或其他应用程序中。所有DirectX 12兼容硬件都支持DirectML。
DirectML在Windows 10 1903版和相应版本的Windows SDK中引入。
根据微软的介绍,所有兼容DX12的显卡都可以使用DirectML,那理论上无论是AMD还是NVIDIA,甚至Intel Arc(?),应该都可以使用DirectML进行机器学习的加速。最重要的是,它可以在Windows上运行!乍一看这仿佛是AMD的大救星,直接让AMD在机器学习领域上轻松的赶上了Nvidia一截。
理论是美好的,现实却是残酷的。我的DirectML初体验时,这玩意并不能完全正常工作。
从官方的安装步骤我们就可以看出,PyTorch的DirectML支持其实是微软自己通过魔改实现的,你需要先安装普通的PyTorch版本,然后卸载它,再安装魔改版。
当时接了一单作业,替换一个网络的backbone以提高acc。想着正好来试试DirectML好不好使,替换完就用它跑了。当时那个网络大概有个1M左右的参数吧,跑得飞快,我还在高兴:这么好使啊,效率也太高了!但是训练完几个epoch之后我就傻了,训练集的acc奇高,但是验证集的acc低的离谱。我当时怀疑是我替换backbone出了问题,改了好久,然后无意中发现:无论网络有多大,它训练的都是飞快???!
后来我还是远程实验室的2080super跑了下,才发现一个epoch还需要跑挺久的,训练集和测试集的acc也比较正常,这才怀疑上了pytorch-directml的问题。
把单子做完之后,我才又回来研究这DirectML。好家伙,这不研究不知道,一研究才发现,不说他为啥计算有问题,这玩意还有34个算子不支持,是个半成品,难怪有毛病!于是我也就懒得研究为啥一个CNN它都算不明白了,不过官方说是3个月左右能完成所有算子的实现。我心想:好吧,那等等他做完再说吧,到时候应该能把乱七八糟的BUG修一修了吧。

DirectML再体验

2023年了,也是有同学找我做毕设,我就心血来潮研究一下ROCm,看看这玩意好不好使,于是便有了开头的结论——依托答辩。不过这个时候我突然想起来了DirectML,三个月过去了,这玩意好使了吗?

安装与使用

首先是他的安装步骤,一改之前魔改的方式,采用了插件的形式:
在使用的时候也从之前的
变成了

硬件配置

  • CPU:AMD Ryzen 5 5600 6-Core Processor
  • 内存:DDR4 3200MHz 8Gx2
  • 显卡:AMD Radeon RX 5700 XT

推理测试

先来点最简单的测试,看看能不能正常进行预训练模型的推理。我写了个简单的测试脚本进行测试,通过np.random.rand随机生成数据集,然后使用预训练的ResNet50和ViT-base模型进行推理。
由于之前遇到过DirectML“乱算”的情况,因此这次我不光测试DirectML的推理速度,还对比了它和CPU推理的结果是否存在差异。
结果如下:
可见使用DirectML以FP32精度进行GPU推理还是有十分明显的加速效果的,并且与CPU计算结果一致,不会出现乱算的情况
但是在使用FP16精度时,ResNet并没有很明显的加速效果,且ViT根本无法以半精度模式运行(顺便吐槽一下开发人员的目录命名规则)。
脚本在编写的时候参考了AutoDL的性能实测,不过由于测试平台并不相同,我的测试结果与他们的没有太大的可比较性,大家图一乐就好。

训练测试

接下来进行训练测试,同样是编写了一个简单的脚本,分别使用ResNet18和ViT-tiny在CIFAR-10上进行训练。
这次还会出现“乱算”的情况吗?很遗憾,答案是:会的
ResNet18的测试结果如下:
可以看到训练集的loss呈下降趋势,但是测试集却基本没有变化。为了排除代码和数据集的问题,我又租了台3090跑了下,结果如下:
同样的代码,使用CUDA训练的测试集loss是在下降的,而DirectML的loss却基本没有变化。
简单搜索一下,似乎有不少人也遇到了和我相同的问题

而ViT-tiny的测试情况问题就更大了,在batch_size为32以上且并没有爆显存的情况下,驱动直接崩溃,如图:
notion image
而在将batch_size降为16之后,可以进行训练,但是速度及其缓慢,且在训练过程中,系统会规律性的卡顿,任务管理器GPU占用率如下:
notion image
而使用CUDA的3090就能正常训练,结果如下:
以及使用DirectML的RTX A4000,在batch_size=64的情况下,每一次需要782个batch,每个batch大概是3.45s附近,粗略计算得一个epoch大概需要2697.9s。而使用CUDA的话每个batch大概是0.08左右,一个epoch只需要大概62.56s。可以看出DirectML的性能损失还是非常严重的,只有显卡厂商自家的计算库才能发挥其性能。

总结

综上所述,DirectML目前来说还是一个半成品,使用它进行预训练模型的推理应该是问题不大,而且相较于PyTorch with DirectML,ONNX Runtime on DirectML的完成度更加高一些,毕竟ONNX Runtime是微软亲儿子。而在训练方面,DirectML基本处于一个不能用的状态,希望微软再接再厉吧。
这么看来,AMD目前在上炼丹依旧是依托答辩的状态。
哦对了,测试用的脚本在这呢:Github

2023/01/22更新

torch-directml更新至0.1.13.1.dev230119,”乱算“问题已在新版本中解决(见Issue #364),但是ViT训练的问题依旧存在
新的ResNet18训练测试结果如下(batch_size有调整):
5700XT训练速度接近3090并不能说明很大问题,我又租了台3060跑了下测试,训练时间也没有明显变长很多,我怀疑瓶颈在于GPU与CPU的数据交换速度上,3060测试结果如下:

2023/03/02更新

torch-directml更新至0.1.13.1.dev230119,FP16推理可用,有明显加速效果。ViT训练仍然保持最初问题,batch_size不能超过16,且系统卡顿。
新的推理测试结果如下:

2023/04/25更新

torch-directml更新至0.1.13.1.dev230413,不知道更新了啥,DirectML.dll变大了,估计是增加了一些op支持,但是ViT训练依旧如上。
新增OpenAI Whisper测试,毫不意外的不可用。
工业大数据分析指南笔记未来降雨概率API