想象这样一个场景:你带着笔记本电脑出国出差,在酒店里想给手机充电,却发现墙上的插座是圆孔的,而你手上是国内的扁头充电器。你急得团团转时,同行伙伴递给你一个小东西——万能插座适配器。它一头插进任意国家的插座,另一头接上你的充电器,世界一下子通畅了。 AI开发者遇到的困境与此惊人地相似。训练好的AI模型就像一个“充电器”,而不同品牌的显卡——NVIDIA、AMD、Intel——就像不同国家的插座,各自有各自的标准接口。NVIDIA偏爱自己的一套接口(CUDA),AMD用另一套,Intel又不同。如果为每张显卡都适配一遍,开发工作量让人崩溃。 这时,微软带来了一个“万能插座适配器”——DirectML。它是Windows系统里的一层AI加速中间件,底层基于DirectX 12标准,自动适配各种显卡。你只需要把标准的AI模型交给它,它负责跟所有硬件打交道。照片App的人像抠图、视频会议里的背景虚化、工业相机上的缺陷检测,背后都可能有DirectML在调度显卡干活。

岗位关联

对AI从业者而言,了解DirectML意味着你掌握了Windows平台上“一次开发、处处运行”的AI部署能力。当需要把模型交付到五花八门的用户PC上运行时,这项知识能直接帮你节省数周适配工作,也让部署方案更具竞争力。

目录
  1. 可视化演示
  2. 初识DirectML
  3. DirectX 12底座
  4. 硬件抽象层
  5. 对比CUDA生态
  6. Windows AI生态
  7. ONNX Runtime集成
  8. AI 应用场景
  9. Python 演示
  10. 常见误区
  11. 面试题

可视化演示

展示DirectML通过硬件抽象层(HAL)将AI模型经ONNX Runtime、DirectX 12下发到GPU/NPU/CPU的跨硬件执行流程,并与CUDA生态对比。

本节配有交互动效(进入视口后自动加载,约 3KB)。

DirectML硬件抽象层架构 AI模型经ONNX Runtime标准化,由DirectML通过DX12下发到GPU等多种硬件后端 AI Model → ONNX RT → DirectML → DX12 → HW 虚线表示CUDA仅限NVIDIA GPU,DirectML覆盖全Windows生态

初识DirectML

深夜的机场候机厅里,你掏出手机想充电,却发现这个国家的插座形状和你的充电器不匹配。旁边一位常出差的老手笑着递来一个小盒子:“带上这个万能适配器,全世界任何插座都能插,你再也不用为不同国家的电源标准操心了。” DirectML就扮演着这个“万能适配器”的角色——只不过它适配的不是电源插座,而是计算机世界里形形色色的AI加速硬件。

在微软的AI方案版图中,DirectML是一个运行于Windows平台的机器学习加速API。你可以把它理解为“专门为AI计算设计的硬件万能适配器”:开发者只写一份代码,它就能在NVIDIA、AMD、Intel、Qualcomm等不同厂商的GPU、CPU乃至NPU上执行推理。哪怕你的用户用的是AMD集成显卡,只要安装了Windows系统,DirectML就能通过驱动层自动接上,不需要用户额外安装任何深度学习运行时。

概念过渡:DirectML处于系统架构中一个颇为“低调”的层级——AI Runtime系统的“执行提供者”层。许多开发者写的PyTorch或TensorFlow代码其实并不直接触碰硬件,而是先由框架翻译成中间表示(如ONNX),再交给像DirectML这样的执行提供者,由它在设备上真正运行计算。就好比你在餐厅点菜(编写模型),菜单经过传菜员(ONNX Runtime),最终由后厨的各个灶台(执行提供者)完成烹饪,而DirectML就是其中一个配备齐全、什么灶台都能开的“万能后厨”。

技术展开:为什么我们需要这样一个中间层?看看GPU加速的量化效果就明白了。假设同样一个图像分类模型,在普通CPU上推理耗时 \(T_{\text{cpu}}\) 毫秒,在GPU上耗时 \(T_{\text{gpu}}\) 毫秒:

DirectML的意义正在于:你不需要为每一类GPU单独写一份“加速代码”,它自动完成适配,让加速比尽可能逼近设备本身的理想值。就像万能适配器让同一部手机在德国、日本、美国都能充电,DirectML让同一个AI模型在不同显卡上都能跑起来——用户根本感觉不到中间有什么复杂的转换过程。对开发者而言,这意味着一个模型文件交付给千千万万台配置各异的Windows电脑,都能顺畅运行。

S=TcpuTgpuS = \frac{T_{\text{cpu}}}{T_{\text{gpu}}}
  1. 加速比 S衡量GPU相对CPU快了多少倍,值越大说明加速效果越好。例如CPU耗时200毫秒、GPU耗时20毫秒时,\(S=10\)。
    S=TcpuTgpuS = \frac{T_{\text{cpu}}}{T_{\text{gpu}}}
  2. CPU耗时 \(T_{\text{cpu}}\)模型在单个CPU核心上完成一次前向推理所需的毫秒数,通常数值较大。
    TcpuT_{\text{cpu}}
  3. GPU耗时 \(T_{\text{gpu}}\)模型在GPU上完成同一推理的毫秒数,当批处理较大时数值显著小于 \(T_{\text{cpu}}\)。
    TgpuT_{\text{gpu}}
  4. 比值含义\(S>1\) 表示GPU更快,但实际加速比受多种因素制约,包括数据搬运开销和内存带宽。
    TcpuTgpu>1\frac{T_{\text{cpu}}}{T_{\text{gpu}}} > 1

DirectX 12底座

万能适配器的神奇之处,除了“多插孔”的外型,更在于它内部有一套精心设计的统一电路——无论输入什么国家的电,它都能转化成充电器需要的稳定电流。DirectML内部也有这样一套“统一电路”,那便是DirectX 12(简称DX12)。要理解DirectML为什么能适配那么多显卡,就要先看看它脚下的这个底座。

DirectX 12是微软在Windows上的一套底层图形与计算API。最初它服务于游戏画面渲染,但后来被扩展成通用并行计算接口——这就像厨房里的“高功率灶台”起初只为烹饪大火爆炒,后来发现它同样适合慢炖熬汤。GPU这颗芯片本质上拥有数千个小计算核心,能同时处理海量简单运算。DX12让开发者直接操控这些核心进行大规模并行计算,而不必绕过一层又一层低效封装。DirectML正是站在这套“高功率灶台”上指挥AI推理的“主厨”。

概念过渡:为什么说DX12是DirectML的底座?因为DirectML的所有计算指令最终都翻译成DX12的底层API调用。DX12将GPU抽象为一个大规模并行处理器,允许DirectML把神经网络中的矩阵乘法、卷积等运算拆成成千上万个并行小任务,分配到GPU的各个计算单元上。简单比喻:DirectML把一道菜(一次推理)切成了无数小块(算子),DX12把众多灶台(计算核心)同时开火,料理速度自然惊人。

技术展开:阿姆达尔定律告诉我们,任何程序的加速都有天花板:如果整个流程中不可并行的部分占比为 \(p_{\text{serial}}\),那么无论增加多少计算核心:

回到万能适配器的比喻:适配器再精巧,也不能让电力的传输损耗归零。DirectML同样无法消除CPU与GPU之间的数据搬运开销,但它通过DX12的底层调度能力,尽可能把这些开销压缩到最小。这就好比适配器内部采用高纯度铜芯,用最好的材料让电流损耗降到最低——硬件科学家们正是在DX12这个“底座”上做了大量类似工作,才有了DirectML今天接近原生性能的表现。

Smax⁡=1pserialS_{\max} = \frac{1}{p_{\text{serial}}}
  1. 最大加速比 \(S_{\max}\)当并行部分可以无限提速时,整个程序能达到的理论加速上限。
    Smax⁡=1pserialS_{\max} = \frac{1}{p_{\text{serial}}}
  2. 串行比例 \(p_{\text{serial}}\)无法并行化、必须一条条执行的指令占总耗时的比例,如数据读取、内存分配等。
    pserialp_{\text{serial}}
  3. 公式含义比如串行比例是10%,\(S_{\max}=10\),意味着再快的GPU也无法让整体加速超过10倍;这解释了为什么DirectML在优化推理时格外关注数据搬运等“串行”环节。
    1pserial>1\frac{1}{p_{\text{serial}}} > 1

硬件抽象层

再仔细端详那只万能适配器:它的外形是一个小小的长方体,顶端有几个不同形状的插孔——有扁的、有圆的、还有带地线的三角孔。无论你把哪国插头怼进哪个孔,适配器都能识别并接通。DirectML里对应这个“多孔集线器”设计的概念,叫做硬件抽象层(Hardware Abstraction Layer,HAL)。

硬件抽象层是DirectML最核心的组件。它把底层硬件的差异“藏”了起来:NVIDIA有NVIDIA的张量核心,AMD有AMD的流处理器,Intel有Intel的执行单元——这些硬件在执行相同计算时,指令集、内存模型、线程调度方式各不相同。如果让开发者直接面对这些差异,适配工作量将是一场噩梦。硬件抽象层就像那位阅尽各国电力的旅行达人,把每种“电流规格”都记录在小本子上,看到插头就知道怎么接。

概念过渡:DirectML的硬件抽象层把“编写AI算法”与“硬件执行细节”分离。当你向DirectML提交一个推理请求时,HAL会分析当前有哪些可用设备,评估它们的算力与负载,然后把任务拆分配发给最合适的硬件执行。这一切对上层的应用开发者完全透明——你只告诉DirectML“我要跑这个模型”,至于它被分配给了哪张显卡、如何执行,你无需操心。这就好比你把充电器插进万能适配器,电流怎么被转换、怎么到达你的手机,你不需要知道,也根本察觉不到。

技术展开:硬件抽象层的高效性,取决于它对设备资源的调度能力。我们可以用一个简单的利用率公式来理解:

硬件抽象层就像适配器内部的“智能电路”,它知道什么时候用哪个插孔供电最稳、最省电。DirectML通过HAL收集各硬件的实时状态,动态调整任务分配策略,尽可能让每一块芯片都处于高利用率状态。一个需要时刻自问的比喻是:你的适配器是否真的让所有的“插孔”都高效运转,还是经常忙闲不均?DirectML的持续迭代,正是在不断优化这个“忙闲均衡”的调度算法。

U=TbusyTbusy+TidleU = \frac{T_{\text{busy}}}{T_{\text{busy}} + T_{\text{idle}}}
  1. 设备利用率 \(U\)硬件真正忙于计算的时间占比,\(U\) 越接近1说明硬件闲置越少。
    U=TbusyTbusy+TidleU = \frac{T_{\text{busy}}}{T_{\text{busy}} + T_{\text{idle}}}
  2. 忙碌时间 \(T_{\text{busy}}\)GPU等硬件执行算子时的耗时,高利用率意味着算子边界开销极低。
    TbusyT_{\text{busy}}
  3. 空闲时间 \(T_{\text{idle}}\)硬件等待数据、等待调度的时间,DirectML通过算子融合、异步传输让 \(T_{\text{idle}}\) 逼近0。
    TidleT_{\text{idle}}

对比CUDA生态

提起GPU加速,很多人的第一反应是NVIDIA的CUDA。CUDA像是你在某国买到的原装充电器——做工精良、性能出色,但它只适配这个国家标准的插座。如果你的目标是全球旅行,只带一个原装充电器显然不够用。DirectML则像文章开头那只万能适配器——也许在某一个插孔上不如原装充电器效率高,但它一物多用,解决问题的方式更灵活。

CUDA本质上是一整套由NVIDIA主导的并行计算平台与编程模型,要求硬件必须是NVIDIA自家的GPU。深度学习程序员可以在CUDA上使用cuDNN、TensorRT等库,获得极致的性能和丰富的优化工具。DirectML则走了一条完全不同的路线:它不做任何硬件上的绑定,凡是支持DirectX 12的设备(绝大多数现代Windows显卡)都可以跑。一个团队如果既有NVIDIA高端卡,又有AMD轻薄本的核显,DirectML一套代码就能同时覆盖,而CUDA做不到——AMD用户必须另配一套环境。

概念过渡:这两种技术路径各有拥趸,最准确的对比来自延迟模型。一次推理的总延迟可以拆解为两部分——数据从CPU搬到GPU的时间,以及GPU计算本身的时间:

这个公式揭示了DirectML与CUDA的真实关系:在计算环节,两者的差距并没有想象中悬殊;差异更多来自搬运开销和算子优化成熟度。在NVIDIA同一块显卡上,CUDA凭借多年生态沉淀通常表现更优;但在AMD、Intel平台上,DirectML是唯一能让你“开箱即跑”的选择。这就好比带一个原装充电器去德国会发现插不进墙,而万能适配器能救场——DirectML的存在,就是让AI推理在任何Windows设备上都不至于“没电”。

Ttotal=Ttransfer+TcomputeT_{\text{total}} = T_{\text{transfer}} + T_{\text{compute}}
  1. 总延迟 \(T_{\text{total}}\)从请求发出到拿到推理结果的完整耗时,用户感知到的“快与慢”就由它决定。
    Ttotal=Ttransfer+TcomputeT_{\text{total}} = T_{\text{transfer}} + T_{\text{compute}}
  2. 搬运时间 \(T_{\text{transfer}}\)输入数据从内存到显存、输出结果反传的时间,小模型推理时这部分开销占比常超50%。
    TtransferT_{\text{transfer}}
  3. 计算时间 \(T_{\text{compute}}\)GPU真正跑算子的时间,DirectML与CUDA在这个环节的差距往往不大。
    TcomputeT_{\text{compute}}

Windows AI生态

一只万能适配器再好用,也不会孤零零地待在行李箱里。旅行达人的装备包里还有转换线、多口充电头、收纳盒——这些东西组合在一起才构成完整的充电方案。微软也围绕DirectML搭建了一个完整的Windows AI生态,让开发者从不同入口都能享受跨硬件加速的便利。

Windows AI生态的核心是三层协作。最上层是Windows ML,它是Windows操作系统自带的一套AI推理接口,应用程序可以通过它直接调用系统级的机器学习能力,无需关心底层实现。中间层是ONNX Runtime,一个跨平台的推理引擎,负责把ONNX格式的模型图解析、优化后分配到不同的执行提供者。最底层就是我们的主角DirectML,作为执行提供者之一,把ONNX Runtime递过来的计算任务真正落到DX12支持的硬件上。三个组件各司其职,如同一支配合默契的接力队:Windows ML把“起跑枪”递给应用,ONNX Runtime负责中程奔跑,DirectML完成最后的冲刺。

概念过渡:这套生态最大的好处是“选择权在开发者手上”。如果应用的性能痛点主要在GPU计算,你可以跳过Windows ML,直接用ONNX Runtime加载模型并指定DirectML执行;如果只想快速集成,Windows ML会自动选择最优的执行提供者。生态内的每一个环节都遵循ONNX这一开放标准,这意味着从PyTorch等框架训练出来的模型,导出为ONNX后几乎可以无缝接入整条链路。就像充电器厂商统一了USB-C协议,任何品牌的充电头都能互插。

技术展开:衡量这套生态实际效果的最直接指标,是系统整体的推理吞吐量。当多个推理请求同时涌入时:

回到工具箱的比喻,DirectML不是工具箱里唯一的工具,却是让所有工具真正发挥效用的“适配核心”。当你把ONNX模型发布到Windows应用商店,用户的设备可能是集成显卡的轻薄本,也可能是带着RTX独显的游戏本。Windows AI生态会基于每个用户的实际硬件,用DirectML自动选择性能最优的执行路径。这正是“生态”的威力:单打独斗的适配器面对复杂环境略显单薄,而成套的旅行充电方案才能真正让你走遍天下都不怕。

Q=1TavgQ = \frac{1}{T_{\text{avg}}}
  1. 吞吐量 \(Q\)系统每秒能处理的推理请求数,是衡量AI服务能力的重要标准。
    Q=1TavgQ = \frac{1}{T_{\text{avg}}}
  2. 平均推理耗时 \(T_{\text{avg}}\)多个请求完成时间的平均值,包含排队、搬运与计算全部开销。
    TavgT_{\text{avg}}
  3. 反比关系平均耗时降低一半,吞吐量就翻倍。Windows ML + ONNX Runtime + DirectML三层协同的目的,就是让 \(T_{\text{avg}}\) 尽可能小。
    Q=1TavgQ = \frac{1}{T_{\text{avg}}}

ONNX Runtime集成

出发前,你把自己所有的电子设备——手机、相机、掌机——收进一个收纳包里,每样东西都放在它该在的格子中,出发时拎包即走。ONNX Runtime与DirectML的集成,做的正是这样一件“收纳打包”的事:它把各种深度学习框架训练出的模型,装进一个统一的“行李箱”——ONNX格式,然后在需要时快速取出、放到合适的硬件上运行。

ONNX Runtime本身是一个跨平台的推理引擎,它不清楚也不关心底层的GPU是什么品牌。真正与硬件打交道的工作,被抽象成了“执行提供者(Execution Provider)”这一插槽机制。在你创建ONNX Runtime推理会话时,可以指定一个或多个执行提供者,比如 DmlExecutionProvider 就是专门调用DirectML的插槽。框架结构上理解:ONNX Runtime好比行李箱的骨架,执行提供者是里面的分隔隔层,DirectML则是其中一个能适应各种“硬件形状”的弹性隔层——无论硬件长什么样,它都能把模型稳稳地放进去。

概念过渡:如果你的项目中已有PyTorch模型,集成DirectML的路径非常清晰:先把PyTorch模型导出为ONNX格式,再在Python或C++代码中创建带 DmlExecutionProvider 的推理会话,然后就可以调用推理。模型只转换一次,之后在所有支持DX12的设备上都能运行。这就好比用一套标准规格的打包盒装好所有行李,到了任何酒店都能直接放进衣柜,而不必买一堆不同品牌的收纳容器。

技术展开:ONNX Runtime在把模型交给DirectML之前,会先做一轮“优化整理”——对计算图进行算子融合(Operator Fusion),把相邻的多个算子合并成一个执行单元。这就像把行李箱里的分装瓶捆成一捆,减少翻找的麻烦。融合后涉及的核心算子在数量上显著减少:

一个开发者的亲身体验会告诉你:集成的代码量并不多,真正的工作量在“托管”——确保模型稳定运行、处理不同分辨率输入、监控推理性能。这就像旅行达人整理行李时,最花心思的不是把箱子合上的那一瞬间,而是之前对物品的分类归置。当你在Windows上看到自己训练的模型流畅运行在别人的AMD核显电脑上时,那一刻,你会真正理解DirectML作为“万能适配器”的优雅:它让一切AI推理都变得如此简单而通达。

Nfused<NorigN_{\text{fused}} < N_{\text{orig}}
  1. 原算子数 \(N_{\text{orig}}\)融合前计算图包含的算子总数,每个算子都有启动和等待开销。
    NorigN_{\text{orig}}
  2. 融合后算子数 \(N_{\text{fused}}\)融合后显著减少,如Conv+ReLU(卷积+激活)合并后只算一个算子。
    NfusedN_{\text{fused}}
  3. 不等式含义每少一个算子,就少一次内核启动和设备同步,直接降低了 \(T_{\text{idle}}\),也就是提升了硬件利用率。
    Nfused<NorigN_{\text{fused}} < N_{\text{orig}}

AI 应用场景

场景一:Windows相册应用的本地AI照片增强

阶段:推理部署

解决的问题:传统云端照片增强需要联网上传图片,既慢又涉及隐私风险。桌面应用如果直接调用CUDA,又只支持部分用户的NVIDIA显卡。DirectML让照片增强模型在本地跨硬件运行:无论用户是AMD显卡还是Intel核显,都能流畅完成老照片修复、人像背景虚化等任务,且图片不出本机,隐私无忧。

具体案例:Windows 11自带的照片应用在“背景模糊”功能中,通过Windows ML调用DirectML执行人像分割模型。用户点点鼠标,一张照片的陌生人背景就被自动虚化,整个过程在毫秒级完成,即使是最普通的集成显卡也能流畅响应。开发团队只需维护一个ONNX模型,便覆盖了所有Windows硬件组合。

场景二:视频会议软件的实时背景替换

阶段:实时流式推理

解决的问题:视频会议需要每帧做人像分割,对延迟要求极高(<50ms/帧)。直接在CPU上跑模型帧率不够,用CUDA又会把没有NVIDIA显卡的用户拒之门外。DirectML通过DX12的并行调度能力,在任意支持DX12的GPU上提供接近实时的推理性能,让千万级普通用户的笔记本也能在视频会议时美颜、换背景。

具体案例:某主流视频会议软件在Windows版本中,用ONNX Runtime加载人像分割模型并指定 DmlExecutionProvider。在用户启动“虚拟背景”功能时,DirectML自动识别当前硬件并调度推理。测试数据显示,在Intel Iris Xe核显上帧率达到28 FPS,已满足视频流畅度要求;在NVIDIA独显上则几乎无感。所有用户无需安装任何额外驱动或SDK。

场景三:工业质检设备的Windows工控机部署

阶段:边缘推理部署

解决的问题:工厂质检工控机的显卡老旧且品牌混杂——有的工控机标配AMD Radeon,有的则只有Intel集显。过去为每台设备编译调试不同加速后端,让算法团队苦不堪言。DirectML的硬件抽象层彻底解决了这一痛点:统一的ONNX模型发布包,工控机上自动适配任意GPU,显著降低了工厂产线的部署维护成本。

具体案例:一家电子元器件工厂在Windows工控机上部署了PCB缺陷检测模型,模型通过ONNX Runtime加载DirectML执行。由于工控机自带的是AMD嵌入式显卡,CUDA方案完全无法使用,团队在替换DirectML后一周内完成了产线的全部部署,检测速度从每件120ms降到50ms,成功率达99.2%。此后产线升级更换任何品牌硬件,模型代码零改动。

Python 演示

python35 行
import timeimport numpy as npimport onnxruntime as ort # 请将 model_path 替换为你的 ONNX 模型文件路径model_path = "resnet18.onnx" # 配置执行提供者:DirectML 优先,CPU 兜底providers = ["DmlExecutionProvider", "CPUExecutionProvider"] # 创建推理会话,ONNX Runtime 将把计算图交给 DirectML 执行session = ort.InferenceSession(model_path, providers=providers) # 读取模型输入信息input_name = session.get_inputs()[0].nameinput_shape = session.get_inputs()[0].shapeprint("输入名称:", input_name, "输入形状:", input_shape) # 构造一个符合输入要求的随机张量(模拟 224x224 的 RGB 图片)dummy_data = np.random.randn(1, 3, 224, 224).astype(np.float32) # 预热:让 DirectML 完成算子编译并缓存,避免首次调用过慢session.run(None, {input_name: dummy_data}) # 连续推理 10 次并统计平均耗时latencies = []for _ in range(10):    start = time.perf_counter()    outputs = session.run(None, {input_name: dummy_data})    latencies.append(time.perf_counter() - start) avg_ms = float(np.mean(latencies)) * 1000print("平均推理耗时: {:.2f} ms".format(avg_ms))print("输出形状:", outputs[0].shape)print("DirectML 跨硬件推理完成")
目的:演示如何用 ONNX Runtime 将纯 ONNX 模型无缝切换到 DirectML 执行提供者,实现跨硬件推理加速。
  1. providers = ["DmlExecutionProvider", "CPUExecutionProvider"]把 DirectML 排在最前面,如果当前设备不支持(如某些服务器),自动回退到 CPU。
  2. ort.InferenceSession(model_path, providers=providers)创建推理会话,加载 ONNX 模型并绑定执行提供者,这是集成的核心入口。
  3. session.get_inputs()[0].name查询模型输入张量的名称与形状,便于构造真实的输入数据。
  4. session.run(None, {input_name: dummy_data})执行一次推理,返回模型输出列表;这是开发中最常打交道的核心 API。
  5. time.perf_counter()高精度计时器,比 time.time() 更适合微秒级性能测试。
  6. outputs[0].shape查看输出张量形状,比如分类模型的 [1, 1000] 代表 1000 个类别的概率分布。

常见误区

误区“DirectML 是不是 N 卡专用的加速库?我听说游戏显卡都是 NVIDIA 的,那 AMD 和 Intel 的显卡应该不支持 DirectML 吧?”

正解恰恰相反,“跨硬件”正是 DirectML 的核心卖点。它基于 DirectX 12 标准,凡是支持 DX12 的 GPU(包括 NVIDIA、AMD、Intel 独显与核显)都能运行 DirectML。旧电脑没有独立显卡?CPU 也能作为兜底设备。就像万能插座适配器,它的设计初衷就是兼容各种规格的插座,而不是只为一种插座服务。

为何常见:市面上最流行的 AI 加速教程几乎都围绕 NVIDIA 的 CUDA 展开,很多人形成“AI 加速 = 用 N 卡”的思维定式,误以为所有 AI 加速库都只支持 N 卡。

误区“听说 DirectML 能加速 AI,那我不需要 PyTorch 了吧?直接在 Windows 上训练大模型?”

正解PyTorch 与 DirectML 属于不同层级:PyTorch 是深度学习框架,负责定义网络结构、实现自动求导与优化器;DirectML 更像一个“执行后端”,负责把张量运算落到硬件上。你依然要用 PyTorch(或 TensorFlow)定义模型、训练参数,只是可以在推理阶段让 DirectML 接管硬件加速。把它们比作出租车:PyTorch 是司机(负责规划路线),DirectML 是发动机(负责驱动车辆),你不能用发动机替代司机。

为何常见:“加速”一词在日常语境中容易让人误以为是端到端的全流程加速,而实际上训练与推理是两条不同的技术路线,DirectML 的主流场景是后者。

误区“ONNX Runtime 和 DirectML 都是微软的 AI 工具,那选一个用就行了吧?它们是不是互相竞争的两个框架?”

正解它们是协同关系而非竞争关系。ONNX Runtime 是推理引擎,负责模型图解析与优化;DirectML 是运行于其下的“执行提供者”,负责具体的硬件加速。打个比方:ONNX Runtime 是餐厅的前台(接单、排桌),DirectML 是后厨的执行队(切菜、炒菜)。两者配合,才能完成一次“推理盛宴”。在代码中你甚至需要同时引入两者:用 ONNX Runtime 创建会话,用 DirectML 提供硬件加速能力。

为何常见:微软同时维护多个 AI 项目,名称又相似(Windows ML、ONNX Runtime、DirectML),外界很容易把它们误看成彼此竞争的产品。

误区“既然 CUDA 是 N 卡原生的,那 DirectML 在任何硬件上应该都比 CUDA 慢很多吧?选择 DirectML 就等于放弃性能。”

正解在 NVIDIA 同一块显卡上,CUDA 凭借多年的生态积累通常表现更优,这是事实。但在 AMD、Intel 等非 N 卡平台上,CUDA 根本无法运行,DirectML 是唯一高效的通用选择。而且在很多场景下,DirectML 的性能已经接近可用水平——用延迟公式来思考:\(T_{\text{total}} = T_{\text{transfer}} + T_{\text{compute}}\),DirectML 与 CUDA 的主要差距更多来自算子优化成熟度,而并非物理极限。选型时应按“部署目标硬件”决定,而不是一概而论。

为何常见:网络上的性能评测大多基于高端 N 卡,媒体为了优化标题常常渲染“DirectML 不如 CUDA”的极端印象,让人忽略了它不可替代的兼容性价值。

面试题

Q1. DirectML 直接构建在哪个底层 API 之上?

单选题 · easy

  • A.OpenCL 并行标准
  • B.Vulkan 图形接口
  • C.DirectX 12 底层接口← 正确答案
  • D.OpenGL 图形接口

答案:C。DirectML 基于 DirectX 12,因为 DX12 是 Windows 平台统一的图形与计算接口,为 AI 推理提供底层并行计算能力。OpenCL、Vulkan、OpenGL 都不是微软的主要选择。就像万能适配器要基于统一的国际插座标准才能全球通用,DirectML 也要依托 DX12 这个 Windows 标准。

Q2. DirectML 在 AI 系统架构中位于哪个层级?

单选题 · easy

  • A.模型训练框架层
  • B.执行提供者层← 正确答案
  • C.应用界面展示层
  • D.数据存储管理层

答案:B。DirectML 是 AI Runtime 系统(尤其是 ONNX Runtime)中的执行提供者,负责把模型计算落到具体硬件上。训练框架是 PyTorch 等,应用界面和数据存储则完全不在它的职责范围内。好比万能适配器是“接通电源”的部件,而不是决定“充什么电”的电池。

Q3. ONNX Runtime 中调用 DirectML 加速的组件叫什么?

单选题 · mid

  • A.CPUExecutionProvider
  • B.DmlExecutionProvider← 正确答案
  • C.TensorRTExecutionProvider
  • D.OpenVINOExecutionProvider

答案:B。DmlExecutionProvider 是 ONNX Runtime 为 DirectML 设计的执行提供者,加载模型后把计算图交给 DirectML 执行。CPU、TensorRT、OpenVINO 分别对应 CPU 和后端硬件厂商的方案。选择 DmlExecutionProvider 就像在行李箱中用对了适配隔层,其他隔层装不下这类硬件。

Q4. 与 DirectML 相比,CUDA 的主要局限是什么?

单选题 · mid

  • A.计算速度始终低于CPU
  • B.只能运行在NVIDIA← 正确答案
  • C.无法执行深度网络
  • D.必须在云端部署

答案:B。CUDA 是 NVIDIA 的专属并行计算平台,因此只能在 NVIDIA 显卡上运行。DirectML 则借助 DX12 跨厂商支持 AMD、Intel 等硬件。这就像原装充电器只能配自家插座,而万能适配器几乎什么插座都能插——CUDA 的局限本质上是硬件的“生态围墙”。

Q5. 使用 ONNX Runtime 加 DirectML 时,模型应先转换为什么格式?

单选题 · mid

  • A.CoreML 模型格式
  • B.ONNX 模型格式← 正确答案
  • C.TensorRT 模型格式
  • D.TorchScript 模型格式

答案:B。ONNX Runtime 的核心输入格式就是 ONNX,PyTorch 或 TensorFlow 模型需先导出为 ONNX,再由 ONNX Runtime 加载并交给执行提供者。CoreML 属于 Apple 生态,TensorRT 属于 NVIDIA,TorchScript 则是 PyTorch 私有格式。如同行李箱需要标准规格的箱子,ONNX 就是这套标准规格。

Q6. 以下哪些硬件能够通过 DirectML 执行推理?

多选题 · mid

  • A.AMD 独立显卡← 正确答案
  • B.Intel 集成显卡← 正确答案
  • C.NVIDIA 独立显卡← 正确答案
  • D.SGX 安全芯片

答案:ABC。支持 DirectX 12 的 GPU 都可以,包括 AMD、Intel、NVIDIA 的产品。SGX 是 Intel 的安全芯片,不是通用计算硬件。DirectML 的跨硬件属性类似万能插头兼容各国插座,但再万能也不会尝试给手表充电。

Q7. 以下哪些组件属于 Windows AI 生态?

多选题 · mid

  • A.Windows ML 接口← 正确答案
  • B.ONNX Runtime← 正确答案
  • C.DirectML 加速层← 正确答案
  • D.CoreML 移动框架

答案:ABC。Windows ML、ONNX Runtime、DirectML 是微软 Windows AI 推理链路的三层协作组件。CoreML 是 Apple 的框架,不在 Windows 生态内。这让人想起旅行工具箱里的充电头、数据线和收纳包,而 CoreML 则是别人的品牌工具箱。

Q8. 关于 DirectML 硬件抽象层的作用,正确的是?

单选题 · hard

  • A.统一屏蔽不同显卡差异← 正确答案
  • B.让每张显卡单独写算子
  • C.只支持NVIDIA张量核心
  • D.替代操作系统内核调度

答案:A。硬件抽象层(HAL)的价值在于屏蔽不同 GPU 的指令集与资源管理差异,向上提供统一接口。如果开发者需要为每张显卡单独写算子,那恰恰是 HAL 要消除的“噩梦”,而它也绝不涉及操作系统内核调度。好比适配器把不同国家电压统一成你需要的电流,你看不见背后的复杂转换。

Q9. 在 NVIDIA 同款显卡上,CUDA 与 DirectML 的性能关系是?

单选题 · hard

  • A.性能始终与CUDA持平
  • B.CUDA通常更快但更通用← 正确答案
  • C.CUDA支持所有厂商硬件
  • D.DirectML无法运行在N卡

答案:B。在同一块 NVIDIA 显卡上,CUDA 凭借长期生态与成熟算子库通常性能更优,但 DirectML 依然可用且覆盖更广硬件。性能对比要看延迟组成:计算时间接近,差距更多来自优化成熟度。就像原装充电器与万能适配器同时接同一个插座,原装充得快些,万能适配器胜在哪儿都能用。

Q10. 以下哪些场景适合使用 DirectML 部署模型?

多选题 · hard

  • A.视频会议实时人像分割← 正确答案
  • B.工业质检一体机推理← 正确答案
  • C.相册应用本地照片增强← 正确答案
  • D.大型模型云端持续训练

答案:ABC。本地实时视频处理、工业一体机、相册增强都涉及“跨硬件推理部署”这一 DirectML 的强项,DirectML 在训练上并非主要方向。大型模型训练通常用 CUDA 集群等专用方案完成。这就好比万能适配器适合带给路上各种设备充电的人,却不是发电厂选用的设备。