马上注册,结交更多好友,享用更多功能,让你轻松玩转社区
您需要 登录 才可以下载或查看,没有账号?立即注册
×
多年来,领先的人工智能公司一直坚称,只有拥有庞大计算资源的公司才能推动前沿研究,这强化了这样一种观点:除非你拥有数十亿美元的基础设施投入,否则“不可能赶上”。但 DeepSeek 的成功却讲述了一个不同的故事:新颖的理念可以带来效率上的突破,从而加速人工智能的发展;规模更小但更专注的团队可以挑战行业巨头,甚至创造公平的竞争环境。
我们认为,DeepSeek 的效率突破预示着AI 应用需求的激增。如果 AI 要继续发展,就必须降低总体拥有成本 (TCO) ——通过扩大替代硬件的覆盖范围、最大限度地提高现有系统的效率以及加速软件创新。否则,未来 AI 的效益将面临瓶颈——要么是硬件短缺,要么是开发者难以有效利用现有的各种硬件。
这不仅仅是一个抽象的问题——这是我(指代本文作者Chris Lattner,下同)整个职业生涯都在努力解决的一个挑战。
过去 25 年来,我一直致力于为世界释放计算能力。我创立并领导了LLVM的开发,LLVM 是一项编译器技术,它为 CPU 在编译器技术的新应用领域打开了大门。如今,LLVM 已成为 C++、Rust、Swift 等性能导向型编程语言的基础。它支持几乎所有 iOS 和 Android 应用,以及 Google 和 Meta 等主要互联网服务的基础设施。
这项工作为我在苹果领导的几项关键创新铺平了道路,包括创建OpenCL(一个早期的加速器框架,现已被整个行业广泛采用)、使用LLVM重建苹果的CPU和GPU软件堆栈,以及开发Swift编程语言。这些经历强化了我对共享基础设施的力量、软硬件协同设计的重要性,以及直观、开发者友好的工具如何释放先进硬件的全部潜力的信念。
2017 年,我开始着迷于 AI 的潜力,并加入 Google,领导 TPU 平台的软件开发。当时,硬件已经准备就绪,但软件尚未投入使用。在接下来的两年半时间里,通过团队的共同努力,我们在 Google Cloud 上推出了 TPU,并将其扩展到每秒百亿亿次浮点运算 (ExaFLOPS),并构建了一个研究平台,促成了Attention Is All You Need和BERT等突破性成果。
然而,这段旅程也揭示了人工智能软件更深层次的问题。尽管 TPU 取得了成功,但它们仍然仅与 PyTorch 等人工智能框架半兼容——谷歌凭借巨大的经济和研究资源克服了这个问题。一个常见的客户问题是:“TPU 能开箱即用地运行任意人工智能模型吗?”真相是?不能——因为我们没有 CUDA,而 CUDA 是人工智能开发的事实标准。
我并非回避解决行业重大问题的人:我最近的工作是创建下一代技术,以适应硬件和加速器的新时代。这包括 MLIR 编译器框架(目前已被整个行业广泛采用的 AI 编译器),以及我们团队在过去 3 年中构建的一些特别的东西——但我们稍后会在合适的时机分享更多相关信息。
由于我的背景和在业界的人脉,我经常被问及计算的未来。如今,无数团队正在硬件领域进行创新(部分原因是NVIDIA 市值飙升),而许多软件团队正在采用 MLIR 来支持新的架构。与此同时,高层领导们也在质疑,为什么尽管投入了大量资金,AI 软件问题仍然悬而未决。挑战并非缺乏动力或资源。那么,为什么这个行业会感到停滞不前呢?
我不认为我们陷入了困境。但我们确实面临着一些棘手的基础性问题。
为了向前发展,我们需要更好地理解行业底层动态。计算是一个技术含量极高的领域,发展迅速,充斥着各种术语、代号和新闻稿,旨在让每一款新产品都听起来具有革命性。许多人试图拨开迷雾,只见树木不见森林,但要真正理解我们的发展方向,我们需要探究其根源——那些将一切联系在一起的基本构件。
首先,我们将以一种简单易懂的方式回答这些关键问题:
我希望本文能够激发有意义的讨论,并提升人们对这些复杂问题的理解。人工智能的快速发展——例如 DeepSeek 最近的突破——提醒我们,软件和算法创新仍然是推动行业发展的动力。对底层硬件的深入理解继续带来 “10 倍” 的突破。
人工智能正以前所未有的速度发展,但仍有诸多潜力有待挖掘。让我们携手突破,挑战固有认知,推动行业发展。让我们一起深入探索!
“CUDA”究竟是什么?
似乎在过去一年里,每个人都开始谈论 CUDA:它是深度学习的支柱,是新型硬件难以与之竞争的原因,也是英伟达护城河与市值飙升的核心。
DeepSeek 的出现让我们有了惊人的发现:它的突破是通过 “绕过” CUDA、直接进入 PTX 层实现的…… 但这究竟意味着什么呢?似乎每个人都想打破这种技术锁定,但在制定计划之前,我们必须先了解自己面临的挑战。
CUDA 在人工智能领域的主导地位不可否认,但大多数人并不完全理解 CUDA 究竟是什么。有人认为它是一种编程语言,有人称它是一个框架。许多人认为它只是 “英伟达用来让 GPU 运行更快的东西”。这些说法并非完全错误,也有很多杰出人士试图解释它,但没有一种能完全涵盖 “CUDA 平台” 的全貌。
CUDA 并非单一事物,它是一个庞大的分层平台,是一系列技术、软件库和底层优化的集合,共同构成了一个大规模的并行计算生态系统。它包括:
- 一种底层并行编程模型,开发者可以用类似 C++ 的语法利用 GPU 的原始计算能力。
- 一套复杂的库和框架,这些中间件支持人工智能等关键垂直应用场景(例如用于 PyTorch 和 TensorFlow 的 cuDNN 库 )。
- 像 TensorRT-LLM 和 Triton 这样的高级解决方案,它们能在不需要开发者深入了解 CUDA 的情况下,支持人工智能工作负载(例如大语言模型服务)。
而这只是冰山一角。
在本章节中,我们将深入剖析 CUDA 平台的关键层级,探究其发展历程,并解释它为何对如今的人工智能计算如此重要。这为我们系列文章的下一部分内容奠定了基础,届时我们将深入探讨 CUDA 如此成功的原因。提示:这与其说是技术本身的原因,不如说和市场激励因素有很大关系。 让我们开始吧!
CUDA 发展之路:从图形处理到通用计算
在 GPU 成为人工智能和科学计算的强大引擎之前,它们只是图形处理器,是专门用于渲染图像的处理器。早期的 GPU 将图像渲染功能硬编码在硅芯片中,这意味着渲染的每个步骤(变换、光照、光栅化)都是固定的。虽然这些芯片在图形处理方面效率很高,但缺乏灵活性,无法用于其他类型的计算。
2001 年,英伟达推出 GeForce3,这一切发生了改变。GeForce3 是第一款带有可编程着色器的 GPU,这在计算领域是一次重大变革:
- 在此之前:固定功能的 GPU 只能应用预定义的效果。
- 在此之后:开发者可以编写自己的着色器程序,解锁了可编程图形管线。
这一进步伴随着 Shader Model 1.0 的推出,开发者可以编写在 GPU 上执行的小程序,用于顶点和像素处理。英伟达预见到了未来的发展方向:GPU 不仅可以提升图形性能,还能成为可编程的并行计算引擎。
与此同时,研究人员很快就提出了疑问:“如果 GPU 能运行用于图形处理的小程序,那我们能否将其用于非图形任务呢?”
斯坦福大学的 BrookGPU 项目是早期对此进行的重要尝试之一。Brook 引入了一种编程模型,使 CPU 能够将计算任务卸载到 GPU 上,这一关键理念为 CUDA 的诞生奠定了基础。
这一举措具有战略意义且极具变革性。英伟达没有把计算当作一项附带实验,而是将其列为首要任务,将 CUDA 深度融入其硬件、软件和开发者生态系统中。
CUDA 并行编程模型
2006 年,英伟达推出 CUDA(统一计算设备架构),这是首个面向 GPU 的通用编程平台。CUDA 编程模型由两部分组成:“CUDA 编程语言” 和 “英伟达驱动程序”。
CUDA 是一个分层堆栈,需要从驱动程序到内核的深度集成
CUDA 语言源自 C++,并进行了扩展,以直接暴露 GPU 的底层特性,例如 “GPU 线程” 和内存等概念。程序员可以使用该语言定义 “CUDA 内核”,这是一种在 GPU 上运行的独立计算任务。下面是一个非常简单的示例:
CUDA 内核允许程序员定义自定义计算,这些计算可以访问本地资源(如内存),并将 GPU 用作高速并行计算单元。这种语言会被翻译成 “PTX”,PTX 是一种汇编语言,是英伟达 GPU 支持的最低级接口。
但是程序究竟如何在 GPU 上执行代码呢?这就要用到英伟达驱动程序了。它充当 CPU 和 GPU 之间的桥梁,负责处理内存分配、数据传输和内核执行。以下是一个简单示例:
请注意,这些操作都非常底层,充满了繁杂的细节(如指针和 “幻数(magic numbers)”)。如果出现错误,通常会以难以理解的程序崩溃形式提示。此外,CUDA 还暴露了许多英伟达硬件特有的细节,例如 “warp 中的线程数”(这里暂不深入探讨)。
尽管存在这些挑战,但这些组件让整整一代硬核程序员能够利用 GPU 强大的计算能力来解决数值问题。例如,2012 年 AlexNET 点燃了现代深度学习的火种。它之所以能够实现,得益于用于卷积、激活、池化和归一化等人工智能操作的自定义 CUDA 内核,以及 GPU 提供的强大算力。
虽然大多数人听到 “CUDA” 时,通常想到的是 CUDA 语言和驱动程序,但这远不是 CUDA 的全部,它们只是其中的一部分。随着时间的推移,CUDA 平台不断发展,涵盖的内容越来越多,而最初的首字母缩写词(CUDA)已经无法准确描述其全部意义。
高级 CUDA 库:让 GPU 编程更易上手
CUDA 编程模型为通用 GPU 计算打开了大门,功能强大,但它带来了两个挑战:
- CUDA 使用难度较大。
- 更糟糕的是,CUDA 在性能可移植性方面表现不佳。
为第 N 代 GPU 编写的大多数内核在第 N + 1 代 GPU 上仍能 “继续运行”,但性能往往较差,远达不到第 N + 1 代 GPU 的峰值性能,尽管 GPU 的优势就在于高性能。这使得 CUDA 成为专业工程师的有力工具,但对大多数开发者来说,学习门槛较高。这也意味着每次新一代 GPU 推出时(例如现在新出现的 Blackwell 架构),都需要对代码进行大量重写。
随着英伟达的发展,它希望 GPU 对那些在各自领域是专家,但并非 GPU 专家的人也有用。英伟达解决这一问题的方法是开始构建丰富而复杂的闭源高级库,这些库抽象掉了 CUDA 的底层细节,其中包括:
- cuDNN(2014 年推出)—— 加速深度学习(例如卷积、激活函数运算)。
- cuBLAS—— 优化的线性代数例程。
- cuFFT—— 在 GPU 上进行快速傅里叶变换(FFT)。
- 以及许多其他库。
有了这些库,开发者无需编写自定义 GPU 代码就能利用 CUDA 的强大功能,英伟达则承担了为每一代硬件重写这些库的工作。这对英伟达来说是一项巨大的投资,但最终取得了成效。
cuDNN 库在这一过程中尤为重要,它为谷歌的 TensorFlow(2015 年推出)和 Meta 的 PyTorch(2016 年推出)铺平了道路,推动了深度学习框架的兴起。虽然此前也有一些人工智能框架,但这些是首批真正实现规模化应用的框架。现代人工智能框架中包含数千个 CUDA 内核,每个内核都极难编写。随着人工智能研究的爆发式增长,英伟达积极扩展这些库,以涵盖重要的新应用场景。
CUDA 上的 PyTorch 建立在多层依赖关系之上
英伟达对这些强大的 GPU 库的投入,使得全球开发者能够专注于构建像 PyTorch 这样的高级人工智能框架,以及像 HuggingFace 这样的开发者生态系统。他们的下一步是打造开箱即用的完整解决方案,让开发者完全无需了解 CUDA 编程模型。
全面的垂直解决方案助力AI和GenAI快速发展
人工智能的热潮远远超出了研究实验室的范畴,如今它无处不在。从图像生成到聊天机器人,从科学发现到代码助手,生成式人工智能(GenAI)在各个行业蓬勃发展,为该领域带来了大量新应用和开发者。
与此同时,出现了一批新的人工智能开发者,他们有着截然不同的需求。在早期,深度学习需要精通 CUDA、高性能计算(HPC)和底层 GPU 编程的专业工程师。如今,一种新型开发者(通常称为人工智能工程师)在构建和部署人工智能模型时,无需接触底层 GPU 代码。
为了满足这一需求,英伟达不仅提供库,还推出了交钥匙解决方案,将底层的一切细节都抽象掉。这些框架无需开发者深入了解 CUDA,就能让人工智能开发者轻松优化和部署模型。
- Triton Serving—— 一种高性能的人工智能模型服务系统,使团队能够在多个 GPU 和 CPU 上高效运行推理。
- TensorRT—— 一种深度学习推理优化器,可自动调整模型,使其在英伟达硬件上高效运行。
- TensorRT-LLM—— 一种更专业的解决方案,专为大规模大语言模型(LLM)推理而构建。
- 以及许多(众多)其他工具。
NVIDIA 驱动程序和 TensorRT-LLM 之间存在多个层 这些工具完全屏蔽了 CUDA 的底层复杂性,让人工智能工程师能够专注于人工智能模型和应用,而无需关注硬件细节。这些系统提供了强大的支持,推动了人工智能应用的横向扩展。
整体的 “CUDA 平台”
CUDA 常被视为一种编程模型、一组库,甚至仅仅是 “英伟达 GPU 运行人工智能所依赖的东西”。但实际上,CUDA 远不止如此。它是一个统一的品牌,是一个真正庞大的软件集合,也是一个经过高度优化的生态系统,所有这些都与英伟达的硬件深度集成。因此,“CUDA” 这个术语含义模糊,我们更倾向于使用 “CUDA 平台” 这一表述,以明确我们所谈论的更像是 Java 生态系统,甚至是一个操作系统,而不仅仅是一种编程语言和运行时库。
CUDA 的复杂性不断扩大:涵盖驱动程序、语言、库和框架的多层生态系统
从核心来看,CUDA 平台包括:
- 庞大的代码库:经过数十年优化的 GPU 软件,涵盖从矩阵运算到人工智能推理的所有领域。
- 广泛的工具和库生态系统:从用于深度学习的 cuDNN 库到用于推理的 TensorRT,CUDA 涵盖了大量的工作负载。
- 针对硬件优化的性能:每次 CUDA 发布都会针对英伟达最新的 GPU 架构进行深度优化,确保实现顶级效率。
- 专有且不透明:当开发者与 CUDA 的库 API 交互时,底层发生的很多操作都是闭源的,并且与英伟达的生态系统紧密相连。
CUDA 是一套强大且庞大的技术体系,是整个现代 GPU 计算的软件平台基础,其应用甚至超越了人工智能领域。
既然我们已经了解了 “CUDA” 是什么,接下来就需要明白它为何如此成功。提示一下:CUDA 的成功并非真的取决于性能,而是战略、生态系统和发展势头。在下一篇文章中,我们将探讨是什么让英伟达的 CUDA 软件塑造并巩固了现代人工智能时代。
CUDA 如何取得成功?
如果作为一个生态系统,我们希望取得进展,就需要了解 CUDA 软件帝国是如何占据主导地位的。理论上,存在一些替代方案,比如 AMD 的 ROCm、英特尔的 oneAPI、基于 SYCL 的框架等,但在实际应用中,CUDA 仍然是 GPU 计算领域无可争议的王者。
这一切是如何发生的呢?
答案并不仅仅在于卓越的技术,尽管技术确实起到了一定作用。CUDA 是一个开发者平台,它的成功得益于出色的执行、深入的战略投资、连贯性、生态系统锁定,当然,还有一点点运气。 本章节将深入剖析 CUDA 如此成功的原因,探究英伟达的层层战略 —— 从早期对通用并行计算的押注,到与 PyTorch 和 TensorFlow 等人工智能框架的紧密结合。归根结底,CUDA 的主导地位不仅是软件的胜利,更是长期平台思维的典范。
CUDA 的早期发展
构建一个计算平台的关键挑战之一,是吸引开发者学习并投入其中。如果只能针对小众硬件,就很难形成发展势头。在一期精彩的《Acquired》播客节目中,黄仁勋分享了英伟达早期的一个关键战略,即保持 GPU 的跨代兼容性。这使得英伟达能够利用其已广泛普及的游戏 GPU 用户基础,这些 GPU 最初是为运行基于 DirectX 的 PC 游戏而销售的。此外,开发者可以在低价的台式电脑上学习 CUDA,之后再扩展到价格高昂、性能更强大的硬件上。
这在如今看来或许显而易见,但在当时却是一个大胆的举措:英伟达没有为不同的应用场景(笔记本电脑、台式机、物联网、数据中心等)打造单独优化的产品线,而是构建了一条连续统一的 GPU 产品线。这意味着要做出一些权衡,比如在功耗或成本效率方面有所牺牲,但作为回报,它创建了一个统一的生态系统,开发者在 CUDA 上的投入可以从游戏 GPU 无缝扩展到高性能数据中心加速器。这种策略与苹果维护和推动 iPhone 产品线发展的方式颇为相似。
这种方法有两个好处:
- 降低准入门槛:开发者可以使用已有的 GPU 学习 CUDA,便于进行实验和采用。
- 产生网络效应:随着越来越多的开发者开始使用 CUDA,更多的软件和库被开发出来,这让该平台变得更有价值。
这种早期的用户基础使 CUDA 的应用范围从游戏领域扩展到科学计算、金融、人工智能和高性能计算(HPC)领域。一旦 CUDA 在这些领域获得关注,它相较于其他替代方案的优势就变得很明显:英伟达持续的投入确保了 CUDA 始终处于 GPU 性能的前沿,而竞争对手却难以构建一个与之相媲美的生态系统。
抓住并乘上人工智能软件的浪潮
随着深度学习的爆发,CUDA 的主导地位得以巩固。2012 年,开启现代人工智能革命的神经网络 AlexNet,是使用两块英伟达 GeForce GTX 580 GPU 进行训练的。这一突破不仅表明 GPU 在深度学习方面速度更快,还证明了它们对人工智能的发展至关重要,使得 CUDA 迅速成为深度学习的默认计算后端。
随着深度学习框架的出现,尤其是谷歌在 2015 年推出的 TensorFlow 和 Meta 在 2016 年推出的 PyTorch,英伟达抓住机遇,大力投入优化其高级 CUDA 库,以确保这些框架在其硬件上尽可能高效地运行。正如我们在第 2 部分所讨论的,英伟达积极优化 cuDNN 和 TensorRT,而不是让人工智能框架团队自行处理底层的 CUDA 性能调优。
这一举措不仅使 PyTorch 和 TensorFlow 在英伟达 GPU 上的运行速度大幅提升,还让英伟达能够紧密整合其硬件和软件(这一过程被称为 “硬件 / 软件协同设计”),因为这样减少了与谷歌和 Meta 之间的协调成本。英伟达每推出新一代的主要硬件,就会发布一个新版本的 CUDA,以利用新硬件的功能。人工智能领域渴望速度和效率,非常愿意将这项工作交给英伟达,这直接导致这些框架与英伟达硬件紧密绑定。
但谷歌和 Meta 为什么会任由这种情况发生呢?实际上,谷歌和 Meta 并非专注于构建一个广泛的人工智能硬件生态系统,它们更关注利用人工智能来推动营收增长、改进产品以及开展新的研究。它们的顶尖工程师优先处理那些对公司内部指标有重大影响的项目。例如,这些公司决定打造自己的专有 TPU 芯片,将精力投入到为自家的硬件进行优化上。因此,把 GPU 相关的事务交给英伟达处理也就顺理成章了。
替代硬件制造商则面临着艰巨的挑战,他们试图复制英伟达庞大且不断扩展的 CUDA 库生态系统,但却没有像英伟达那样专注于硬件整合。竞争对手不仅进展艰难,还陷入了一个恶性循环,总是在追赶英伟达硬件上的下一个人工智能进展。这也影响了谷歌和 Meta 的内部芯片项目,催生了包括 XLA 和 PyTorch 2 在内的众多项目。我们会在后续文章中深入探讨这些内容,但如今可以看到,尽管人们抱有一些期望,却没有什么能让硬件创新者具备与 CUDA 平台相媲美的能力。
英伟达凭借每一代新硬件不断扩大领先优势。然后,在 2022 年末,ChatGPT 突然爆火,随之而来的是,生成式人工智能和 GPU 计算走向了主流。
利用生成式人工智能的热潮
几乎在一夜之间,对人工智能计算的需求急剧飙升,它成为了价值数十亿美元产业、消费级应用以及企业竞争战略的基础。大型科技公司和风险投资公司向人工智能研究初创企业和资本支出建设投入了数十亿美元,而这些资金最终都流向了英伟达,因为只有它能够满足不断激增的计算需求。
随着对人工智能计算需求的激增,企业面临着一个严峻的现实:训练和部署生成式人工智能模型的成本高得惊人。每一点效率的提升,无论多么微小,在大规模应用时都能转化为巨大的成本节约。由于英伟达的硬件已经在数据中心根深蒂固,人工智能公司面临着一个艰难的抉择:针对 CUDA 进行优化,否则就会落后。几乎一夜之间,整个行业都转向编写特定于 CUDA 的代码。结果是,人工智能的突破不再仅仅由模型和算法驱动,现在还取决于从经过 CUDA 优化的代码中榨取每一分效率的能力。
以 FlashAttention - 3 为例,这项前沿的优化技术大幅降低了运行 Transformer 模型的成本,但它是专门为 Hopper GPU 打造的,通过确保只有在英伟达最新的硬件上才能获得最佳性能,进一步强化了英伟达的技术锁定。持续的研究创新也遵循着同样的模式,比如 DeepSeek 直接采用 PTX 汇编语言,在尽可能低的层面上实现对硬件的完全控制。随着英伟达新的 Blackwell 架构即将推出,可以预见整个行业又要重新编写所有代码了。
强化 CUDA 主导地位的循环
这个系统正在加速发展并形成自我强化的态势。生成式人工智能已成为一股不可阻挡的力量,推动着对计算能力的无尽需求,而英伟达掌握着所有的优势。庞大的用户基础确保了大多数人工智能研究都是基于 CUDA 进行的,这反过来又促使人们对优化英伟达的平台进行投资。
英伟达每一代新硬件都带来新的功能和更高的效率,但这也需要重新编写软件、进行新的优化,并且对英伟达的技术堆栈产生更深的依赖。未来似乎不可避免:在这个世界里,CUDA 对人工智能计算的掌控只会越来越紧。
然而,CUDA 并非完美无缺。
巩固 CUDA 主导地位的这些因素,也正逐渐成为瓶颈,带来技术挑战、效率低下的问题,还阻碍了更广泛的创新。这种主导地位真的对人工智能研究领域有益吗?CUDA 是对开发者有利,还是仅仅对英伟达有利呢?
让我们退一步思考:我们已经了解了 CUDA 是什么以及它为何如此成功,但它真的好吗?我们将在下面章节探讨这个问题。
CUDA占据主导地位,但它真的好吗?
回答 CUDA 是否 “好” 这个问题,远比听起来要棘手。我们讨论的是它的原始性能?它的功能特性?还是它在人工智能开发领域更广泛的影响呢?
CUDA 是否 “好”,这取决于你问的是谁以及他们的需求是什么。在本章节中,我们将从那些日复一日使用它的人,也就是在生成式人工智能(GenAI)生态系统中工作的人的角度来评估 CUDA:
- 对于在 CUDA 基础上进行开发的人工智能工程师来说,它是必不可少的工具,但同时也伴随着版本管理的麻烦、驱动行为不透明以及对平台的深度依赖等问题。
- 对于为英伟达硬件编写 GPU 代码的人工智能工程师而言,CUDA 提供了强大的优化能力,但要获得顶级性能,就必须承受其中的痛苦。
- 对于那些希望自己的人工智能工作负载能在多家厂商的 GPU 上运行的人来说,CUDA 与其说是解决方案,不如说是一个障碍。
- 还有英伟达公司本身,它围绕 CUDA 积累了巨额财富,获取了巨额利润,并巩固了其在人工智能计算领域的主导地位。
那么,CUDA 到底 “好不好” 呢?让我们深入探讨每个角度来寻找答案!
AI工程师
如今,许多工程师在人工智能框架(如 LlamaIndex、LangChain 和 AutoGen 等智能库)的基础上构建应用程序,而无需深入了解底层硬件细节。对于这些工程师来说,CUDA 是强大的助力。它在行业内的成熟度和主导地位带来了显著优势:大多数人工智能库都设计为能与英伟达硬件无缝协作,而且大家都聚焦于单一平台,促进了整个行业的合作。
然而,CUDA 的主导地位也带来了一系列长期存在的挑战。其中最大的障碍之一是管理不同 CUDA 版本的复杂性,这简直是一场噩梦。这种无奈成为了众多梗图的主题:
这可不只是个梗图,对许多工程师来说,这是他们真实的经历。这些人工智能从业者需要不断确保 CUDA 工具包、英伟达驱动和人工智能框架之间的兼容性。不匹配的情况可能会导致令人沮丧的构建失败或运行时错误,无数开发者都有过切身体会:
“我无法使用最新的英伟达 PyTorch Docker 镜像构建系统。原因是通过 pip 安装的 PyTorch 是基于 CUDA 11.7 构建的,而容器使用的是 CUDA 12.1。” 或者:“管理英伟达 GPU 驱动和 CUDA 开发软件可能很有挑战性。升级 CUDA 版本或更新 Linux 系统可能会导致诸如 GPU 驱动损坏等问题。”
遗憾的是,这类麻烦并不罕见。解决这些问题通常需要深厚的专业知识和耗费大量时间进行故障排查。英伟达依赖不透明的工具和复杂的设置流程,这让新手望而却步,也减缓了创新的速度。
为应对这些挑战,英伟达历来都是在更高层级提供个别针对性的解决方案,而不是解决 CUDA 层本身这一根本问题。例如,它最近推出了 NIM(英伟达推理微服务),这是一套容器化的微服务,旨在简化人工智能模型的部署。虽然这可能会简化某一特定用例,但 NIM 也将底层操作抽象化了,增加了用户对其技术的依赖,限制了对底层优化和创新的接触,而这些恰恰是 CUDA 价值主张的关键所在。
在 CUDA 基础上构建应用的人工智能工程师面临着兼容性和部署方面的挑战,而那些更接近硬件底层工作的人员,即人工智能模型开发者和性能工程师,则要应对一系列截然不同的权衡取舍。
AI模型开发者和性能工程师
对于致力于突破人工智能模型极限的研究人员和工程师来说,CUDA 既是必不可少的工具,也是令人沮丧的限制因素。对他们而言,CUDA 不是一个简单的 API,而是他们编写的每一个对性能至关重要的操作的基础。这些工程师在底层进行优化工作,编写自定义 CUDA 内核,调整内存访问模式,尽可能地从英伟达硬件中榨取每一分性能。生成式人工智能的规模和成本要求他们这么做。但 CUDA 是赋予了他们能力,还是限制了他们的创新能力呢?
尽管 CUDA 占据主导地位,但它也逐渐显露出不足。它设计于 2007 年,远在深度学习出现之前,更不用说生成式人工智能了。从那以后,GPU 发生了巨大的变化,张量核心(Tensor Cores)和稀疏特性成为人工智能加速的核心要素。CUDA 早期的贡献是让 GPU 编程变得容易,但它并没有随着现代 GPU 为实现 Transformer 和生成式人工智能性能所必需的特性而发展。这就迫使工程师们不得不绕过它的局限性,才能获得工作负载所需的性能。
CUDA 无法充分发挥现代 GPU 的全部功能
像 FlashAttention-3(示例代码 )和 DeepSeek 的创新技术等前沿技术,要求开发者绕过 CUDA,使用英伟达更低级的汇编语言 PTX。PTX 的文档并不完善,在不同硬件代际之间不断变化,对开发者来说实际上就是个黑箱。
更麻烦的是,PTX 比 CUDA 更依赖英伟达,而且可用性更差。然而,对于追求前沿性能的团队来说,别无选择,他们只能绕过 CUDA,承受诸多不便。
张量核心:提升性能的关键,但使用难度大
如今,人工智能模型的大部分浮点运算(FLOPs)来自 “张量核心”,而非传统的 CUDA 核心。然而,直接对张量核心进行编程并非易事。虽然英伟达提供了一些抽象工具(如 cuBLAS 和 CUTLASS),但要充分发挥 GPU 的性能,仍需要晦涩难懂的知识、反复的试验和测试,而且常常需要逆向工程一些未文档化的行为。随着每一代新 GPU 的推出,张量核心都会发生变化,但相关文档却未能及时更新。这使得工程师在充分挖掘硬件潜力时资源有限。
人工智能用 Python,而 CUDA 用 C++
另一个主要限制是,编写 CUDA 代码基本上需要使用 C++,而现代人工智能开发大多是用 Python 完成的。使用 PyTorch 进行人工智能模型和性能开发的工程师并不想在 Python 和 C++ 之间来回切换,这两种语言的编程思路差异很大。这种不匹配减缓了迭代速度,造成了不必要的阻碍,还迫使人工智能工程师在本应专注于模型改进的时候,却要去考虑底层性能细节。此外,CUDA 对 C++ 模板的依赖导致编译时间极长,而且经常会出现难以理解的错误信息。
如果你乐于专门为英伟达硬件进行开发,就会面临上述这些挑战。但如果你关注的不只是英伟达呢?
开发可移植软件的工程师和研究人员
并非所有人都愿意开发锁定英伟达硬件的软件,其中的挑战显而易见。CUDA 无法在其他厂商的硬件上运行(比如我们口袋里的手机芯片这类硬件 ),而且没有其他方案能在英伟达硬件上提供与 CUDA 相同的性能和功能。这就迫使开发者针对多个平台多次编写人工智能代码。
在实际操作中,许多跨平台人工智能开发工作都困难重重。早期版本的 TensorFlow 和 PyTorch 有 OpenCL 后端,但在功能和速度上都远远落后于 CUDA 后端,这使得大多数用户还是选择使用英伟达的产品。维护多条代码路径(CUDA 用于英伟达,其他方案用于其他平台)成本高昂,而且随着人工智能的快速发展,只有大型机构才有资源进行这样的工作。
CUDA 造成的这种分化形成了一个自我强化的循环:由于英伟达拥有最大的用户群体和最强大的硬件,大多数开发者首先会针对 CUDA 进行开发,并期望其他方案最终能赶上来。这进一步巩固了 CUDA 作为人工智能默认平台的主导地位。
接下来,我们探讨 OpenCL、TritonLang 和 MLIR 编译器等替代方案,并了解为什么这些选项没有对 CUDA 的主导地位造成影响。
CUDA 对英伟达自身有好处吗?
答案当然是肯定的:“CUDA 护城河” 造就了赢者通吃的局面。到 2023 年,英伟达占据了数据中心 GPU 市场约 98% 的份额,巩固了其在人工智能领域的主导地位。正如我们在之前的文章中所讨论的,CUDA 是连接英伟达过去和未来产品的桥梁,推动了像 Blackwell 这样的新架构的应用,维持了英伟达在人工智能计算领域的领先地位。
然而,像Jim Keller这样的传奇硬件专家认为,“CUDA 是片泥沼,而非护城河”,他将其与拖累英特尔的 X86 架构相类比。
Jim Keller认为, “ CUDA 是沼泽,而不是护城河”
CUDA 怎么会成为英伟达的问题呢?这存在几个挑战。
CUDA 的可用性对英伟达影响最大
黄仁勋曾说过,英伟达雇佣的软件工程师比硬件工程师还多,其中很大一部分人都在编写 CUDA 相关代码。但 CUDA 在可用性和可扩展性方面的挑战减缓了创新速度,迫使英伟达大量招聘工程师来解决这些问题。
CUDA 的庞大体量影响新硬件的推出
CUDA 在英伟达自身不同代际的硬件之间无法实现性能的可移植性,而且其庞大的库规模是一把双刃剑。当推出像 Blackwell 这样的新一代 GPU 时,英伟达面临一个选择:重写 CUDA,或者推出无法充分发挥新架构性能的硬件。这就解释了为什么每一代新硬件在推出时性能都不是最优的。扩展 CUDA 的功能既昂贵又耗时。
创新者的困境
英伟达对向后兼容性的坚持,这曾是 CUDA 早期的卖点之一,如今却成了 “技术债务”,阻碍了其自身的快速创新。虽然对老一代 GPU 的支持对开发者群体至关重要,但这迫使英伟达优先考虑稳定性,而非进行革命性的变革。这种长期支持耗费时间和资源,可能会限制其未来的灵活性。
尽管英伟达向开发者承诺会保持连续性,但 Blackwell 如果不打破与 Hopper PTX 的兼容性,就无法实现其性能目标,现在一些 Hopper PTX 操作在 Blackwell 上无法运行。这意味着那些绕过 CUDA 而选择 PTX 的高级开发者可能需要为下一代硬件重写代码。
尽管存在这些挑战,但英伟达在软件方面的出色执行和早期的战略决策,为其未来的增长奠定了良好的基础。随着生成式人工智能的兴起,以及基于 CUDA 构建的生态系统不断发展,英伟达有望继续处于人工智能计算的前沿,并已迅速成长为全球最具价值的公司之一。
CUDA 的替代方案在哪里?
总之,CUDA 既是恩赐也是负担,这取决于你处于生态系统的哪一方。它的巨大成功推动了英伟达的主导地位,但它的复杂性、技术债务以及对供应商的锁定,给开发者和人工智能计算的未来带来了重大挑战。
随着人工智能硬件的快速发展,一个自然而然的问题出现了:CUDA 的替代方案在哪里?为什么其他方案还没有解决这些问题呢?在接下来的章节中,我们将探讨最具代表性的替代方案,分析阻碍它们突破 CUDA 护城河的技术和战略问题。
像 OpenCL 这样的 CUDA C++ 替代方案怎么样?
生成式人工智能(GenAI)或许是新事物,但 GPU 可不是!多年来,许多人尝试用 C++ 创建可移植的 GPU 编程模型,从 OpenCL 到 SYCL,再到 OneAPI 等等。这些本是最有可能替代 CUDA 的方案,旨在实现人工智能计算的民主化,但你可能从未听说过它们,因为它们在人工智能领域并未发挥重要作用。
这些项目都为计算领域做出了有意义的贡献,但如果我们真想为未来解锁人工智能计算,就必须认真审视那些阻碍它们发展的错误,而不能只盯着成功之处。从宏观层面看,问题源于 “开放式竞合” 的挑战,即行业参与者既合作又竞争,以及过程中特定的管理失误。让我们深入探讨一下。
CUDA C++ 的替代方案:OpenCL、SYCL 等
有许多项目致力于实现 GPU 编程,其中我最了解的是 OpenCL。和 CUDA 一样,OpenCL 旨在为程序员提供类似 C++ 的编程体验,以便在 GPU 上运行代码。这背后还有我的一段个人经历:2008 年,我是苹果公司负责实现 OpenCL 的首席工程师之一(这是我当时构建的 Clang 编译器首次投入实际应用)。在我们完成开发后,做出了一个关键决定,将其贡献给 Khronos Group,以便在整个行业得到采用和标准化。
这一决定使得 OpenCL 在行业内得到广泛应用(见相关标识 ),尤其在移动和嵌入式设备领域。如今,它依然非常成功,为安卓等平台以及数字信号处理器(DSP)等专业应用中的 GPU 计算提供支持。与 CUDA 不同,OpenCL 从一开始就设计为具有可移植性,旨在支持 CPU、GPU 和其他加速器之间的异构计算。OpenCL 还启发了其他系统,如 SyCL、Vulkan、SPIR-V、oneAPI、WebCL 等等。
然而,尽管 OpenCL 在技术上有优势且应用广泛,但它从未成为主导的人工智能计算平台。主要原因有以下几点:开放式竞合中固有的矛盾、由此产生的技术问题、人工智能不断变化的需求,以及英伟达针对 TensorFlow 和 PyTorch 的统一战略。
委员会决策速度下的 “竞合” 问题
2008 年,苹果在个人电脑领域还只是个小角色,当时认为行业标准化能让其接触到更多开发者。虽然 OpenCL 确实在硬件制造商中得到广泛采用,但其发展很快遇到了一个重大障碍:委员会驱动的开发速度太慢。对苹果来说,这种缓慢、依赖共识的决策过程是个大问题:我们希望快速推进平台发展,添加新功能(比如添加 C++ 模板),并展现苹果平台的差异化。我们面临着一个残酷的现实 —— 委员会制定标准的弊端在于,一切都按照委员会达成共识的速度推进,而这个速度就像冰川移动一样缓慢。
硬件供应商们认识到统一软件生态系统的长期益处,但在短期内,他们又是激烈的竞争对手。这就引发了一些微妙却很严重的问题:参与者们不会向委员会透露正在研发的硬件特性(以免让竞争对手抢占先机),而是会在硬件发布后才公开这些创新,并且只有在这些特性成为通用功能后才会进行讨论(转而使用特定供应商的扩展)。
合作竞争:竞争对手之间的“合作”
这种情况对苹果来说是个大麻烦,因为苹果想要快速秘密推进项目,以便在产品发布时大放异彩。因此,苹果决定放弃 OpenCL,推出了 Metal 替代它,从未在 iOS 系统中引入 OpenCL,后来还在 macOS 系统中弃用了它。其他公司虽然继续使用 OpenCL,但这些结构性挑战持续限制着它,使其无法跟上前沿人工智能和 GPU 创新的步伐。
OpenCL 的技术问题
虽然苹果大胆地将 OpenCL 标准贡献给了 Kronos,但并没有全力以赴:苹果贡献的只是 OpenCL 的技术规范,而没有完整的参考实现。尽管编译器前端(Clang)的部分是开源的,但没有共享的 OpenCL 运行时,这就迫使供应商们开发自己的定制版本并完善编译器。每个供应商都必须维护自己的实现(即 “分支”),由于缺乏共享且不断发展的参考标准,OpenCL 变成了一个由特定供应商的分支和扩展拼凑而成的产物。这种碎片化最终削弱了它原本旨在实现的可移植性。
此外,由于供应商们隐瞒差异化特性,或者将这些特性分离成数量众多的特定供应商扩展,导致 OpenCL(及其衍生项目)碎片化,侵蚀了它作为一个统一的、与供应商无关的平台的能力。
OpenCL 在兼容性和一致性测试方面的不足,更是加剧了这些问题。最重要的是,它还存在我们之前提到的所有 “C++ 相关问题”。
开发者们想要的是稳定且得到良好支持的工具,但 OpenCL 的碎片化、薄弱的一致性测试以及不一致的供应商支持,让使用它成为了一件令人沮丧的事。一位开发者总结说,使用 OpenCL “就像拥抱仙人掌一样难受”!太扎心了。
一位开发人员将使用 OpenCL 描述为“就像拥抱仙人掌一样难受”。
就在 OpenCL 受困于碎片化和缓慢的发展速度时,人工智能在软件框架和硬件性能方面都在迅速进步。这使得 OpenCL 所能提供的功能与现代人工智能工作负载的需求之间的差距越来越大。
AI研究和AI GPU硬件不断变化的需求
TensorFlow 和 PyTorch 的推出掀起了人工智能研究的革命,不断完善的基础设施和大型企业大量资金的涌入为其提供了强大动力。这给 OpenCL 带来了巨大挑战。虽然 OpenCL 支持 GPU 计算,但缺乏大规模训练和推理所需的高级人工智能库和优化。与 CUDA 不同,它没有对矩阵乘法、Flash Attention 或数据中心规模的训练等关键操作的内置支持。
尽管将 TensorFlow 和 PyTorch 扩展以使用 OpenCL 的跨行业努力有明显的需求,但很快就遇到了根本性的障碍。那些坚持使用 OpenCL 的开发者很快发现了一个残酷的现实:如果无法充分发挥新硬件的性能,那么对新硬件的可移植性就毫无意义。由于无法实现可移植的特定硬件增强功能,再加上竞合关系破坏了合作,相关进展陷入了停滞。
一个明显的例子是,OpenCL 至今仍未对张量核心(Tensor Cores)提供标准化支持,而张量核心是现代 GPU 和人工智能加速器中实现高效矩阵乘法的专用硬件单元。这意味着,与使用 CUDA 或其他碎片化的特定供应商原生软件相比,使用 OpenCL 通常会导致性能降低 5 到 10 倍。在生成式人工智能领域,计算成本已经高得惊人,性能降低 5 到 10 倍可不只是不方便的问题,而是根本无法接受。
英伟达针对 TensorFlow 和 PyTorch 的战略举措
当 OpenCL 在碎片化管理的重压下艰难前行时,英伟达采取了截然不同的策略。正如我们前面讨论过的,英伟达的策略是严格控制、极具战略性且卓有成效的。英伟达积极与 TensorFlow 和 PyTorch 共同设计 CUDA 的高级库,确保这些框架在英伟达硬件上始终能达到最佳运行效果。由于这些框架原生就构建在 CUDA 之上,英伟达一开始就占据了巨大优势,并且通过优化使其性能从一开始就出类拔萃。
英伟达虽然保留了 OpenCL 的实现,但从战略上对其进行了限制(比如无法使用张量核心),这就确保了 CUDA 的实现始终是必要的。随着英伟达在行业内的主导地位不断巩固和提升,它不断加大对 CUDA 实现的投入。久而久之,OpenCL 的支持逐渐减少,直至消失,而 CUDA 则巩固了其作为无可争议的行业标准的地位。
我们能从这些 C++ GPU 项目中学到什么?
经历过这些的人都很清楚上述历史,但真正的价值在于从过去中吸取教训。基于此,我认为成功的系统必须具备以下几点:
- 提供参考实现,而不只是一份书面规范和 “兼容性” 测试。一个可用、可采用且可扩展的实现才应定义兼容性,而不是一份 PDF 文档。
- 由维护参考实现的团队提供强有力的领导和明确的愿景。
- 在行业领先企业的硬件上实现顶级性能,否则它永远只能是二流的替代方案,无法成为统一行业的标准。
- 快速发展以满足不断变化的需求,因为人工智能研究不会停滞不前,人工智能硬件创新仍在加速。
- 提供出色的可用性、工具和快速的编译时间,以此赢得开发者的青睐。另外,在人工智能领域,“类似 C++” 可不是什么卖点!
- 建立开放的社区,因为没有广泛的采用,技术实力再强也无济于事。
- 避免碎片化,一个分裂成不兼容分支的标准,无法为软件开发人员提供有效的统一框架。
这些就是我认为像 OpenCL 这样由委员会推动的项目永远不会成功的根本原因。这也是为什么我对英特尔的 OneAPI(现 UXL Foundation)等项目更加怀疑,这些项目名义上是开放的,但实际上由单一硬件供应商掌控,而该供应商又与其他所有供应商存在竞争关系。
AI编译器呢?
在 C++ 相关方案未能为硬件制造商统一人工智能计算的同时,人工智能行业面临着一个更大的挑战,即使是在英伟达硬件上使用 CUDA 也存在问题。如果所有代码都需要人工编写,我们要如何实现人工智能计算的扩展呢?芯片种类繁多,人工智能算法层出不穷,工作负载的组合更是不计其数,靠人工优化根本无法完成。
随着人工智能的影响力不断扩大,它不可避免地引起了系统开发者和编译器工程师(包括我在内)的关注。在下一篇文章中,我们将深入探讨广为人知的 “人工智能编译器” 栈,如 TVM、OpenXLA 和 MLIR,分析哪些成功了,哪些失败了,以及我们能从中吸取什么教训。遗憾的是,这些教训与上面提到的并没有太大不同:
历史不会简单重复,但总会押着相同的韵脚。—— 马克・吐温
人工智能编译器(TVM 和 XLA)怎么样?
在人工智能硬件发展的早期阶段,编写高性能的 GPU 代码虽然繁琐,但仍在可掌控范围内。工程师们可以用 C++ 为所需的关键操作精心编写 CUDA 内核,英伟达再将这些内核整合到像 cuDNN 这样的库中,以此巩固其行业地位。但随着深度学习的不断发展,这种方式完全行不通了。
神经网络规模越来越大,架构愈发复杂,研究人员对迭代周期的速度要求也越来越高。像 PyTorch 这样的框架中,独特算子的数量呈爆发式增长,如今已达数千个。要为每个新的硬件目标手动编写并优化每个算子?这根本不可能。
PyTorch 运算符按版本计数
这一挑战促使行业发生了根本性转变:既然手动编写内核不可行,那要是有一个编译器能自动生成内核会怎么样呢?人工智能编译器应运而生,旨在解决这一难题,这标志着从人工编写 CUDA 代码向机器生成、硬件优化计算的转变。
但历史表明,构建一个成功的编译器栈不仅是技术上的挑战,更是生态系统、碎片化和控制权的争夺战。那么,哪些成功了?哪些失败了?我们能从 TVM 和 OpenXLA 等项目中学到什么呢?
什么是 “AI编译器”?
人工智能编译器的核心是一个系统,它能够将像 PyTorch 或 TensorFlow 中的高级操作,自动转换为高效的 GPU 代码。它执行的最基本优化之一叫做 “内核融合”。为了理解其重要性,我们来看一个简单的例子:先将两个矩阵相乘(“矩阵乘法”),然后应用 ReLU(修正线性单元)激活函数。这些是常见神经网络中简单却重要的操作。
简单方法:两个独立内核
最直接(但效率低下)的做法是先进行矩阵乘法,将结果存储在内存中,然后再次读取该结果以应用 ReLU 函数。
对于可能编写 CUDA 内核的工程师来说,这些操作非常熟悉(不过要记住,CUDA 使用的是复杂的 C++ 语法!),并且有许多提高效率的实现技巧。
虽然上述方法简单且模块化,但这样执行操作的速度极慢,因为在matmul()之后,整个矩阵C被写入内存,然后在relu()中又再次读取。这种内存数据传输严重影响性能,在 GPU 上尤其如此,因为在 GPU 中,内存访问的成本比本地计算更高。
融合内核:一次遍历,无额外内存传输
解决方案很简单:我们可以将这两个操作 “融合” 为一个内核,消除冗余的内存访问。在matmul()之后,我们不再存储C,而是在同一循环中立即应用relu():
虽然这种转换带来的性能提升因硬件和矩阵大小而异,但效果可能非常显著:有时性能可提升两倍!为什么会这样呢?通过融合操作:
- 我们消除了一次额外的内存写入 / 读取操作,减轻了内存带宽的压力。
- 我们将数据保留在寄存器或共享内存中,避免了缓慢的全局内存访问。
- 由于中间缓冲区被移除,我们减少了内存使用以及分配 / 释放内存的开销。
这只是内核融合的一个简单示例:还有许多更强大的转换方法,人工智能内核工程师一直在挑战优化的极限(了解更多 )。随着生成式人工智能对计算需求的不断攀升,这些优化比以往任何时候都更加关键。
卓越性能,但复杂度呈指数级增长!
对于那些追求低成本和最前沿性能的人来说,实现这类优化既令人兴奋又充满乐趣,但背后隐藏着一个事实:这种方法无法扩展。
现代机器学习工具包包含数百种不同的 “操作”,如矩阵乘法、卷积、加法、减法、除法等,除了 ReLU 之外,还有数十种激活函数。每个神经网络需要以不同方式组合这些操作,这导致需要实现的组合数量呈爆炸式增长(数百种操作 × 数百种操作 = 多得数不清)。英伟达的库(如 cuDNN)提供了一个固定的选项列表供选择,但无法满足新研究的通用性需求。
此外,还有其他方面的复杂性增长:新的数值数据类型(如 “float8”)不断涌现,当然,人工智能需要支持的硬件种类也在激增。
复杂性的三个维度
早期人工智能编译器:TVM
人工智能编译器有很多,其中最早且最成功的之一是 TVM(Tensor Virtual Machine:张量虚拟机)。这个系统获取来自 TensorFlow/PyTorch 的模型,并针对不同硬件进行优化,即自动应用内核融合技术。该项目大约在 2016 年由华盛顿大学的陈天奇和路易斯・塞泽教授发起,2018 年一篇概述 TVM 架构的论文介绍了其多项创新成果和性能优势。TVM 后来开源并融入了 Apache 项目。
在其发展过程中,TVM 被众多硬件制造商采用(包括 ARM、高通、Facebook、英特尔等公司的公开贡献 ),应用于嵌入式、数字信号处理(DSP)等多个领域。TVM 的核心贡献者后来创立了 OctoAI,英伟达在 2024 年末收购了该公司,从而控制了许多 TVM 的原始开发者,这也可能影响该项目的未来发展。
TVM 是人工智能编译器行业的重要一步,但我们能从中学到什么呢?以下是我的关键收获。免责声明:虽然 TVM 使用了 LLVM,我也对其很感兴趣,但我从未直接参与其中。这是我作为局外人的观点。
无法在现代硬件上实现最佳性能
TVM 在现代人工智能硬件上难以实现最佳性能,尤其是随着 GPU 向张量核心(TensorCores)和其他专用加速技术发展。虽然 TVM 后来增加了对新硬件的支持,但往往滞后,无法充分释放硬件性能。因此,它和 OpenCL 有同样的问题:如果无法充分利用硬件,就无法实现高性能。
商业利益冲突导致碎片化
与 OpenCL 不同,TVM 不仅仅是一个规范,它有实际的实现。这使得它开箱即用的实用性更强,吸引了众多硬件供应商。但碎片化问题依然存在:供应商们对代码进行分叉,做出不兼容的更改,并且难以保持同步,这减缓了项目进展。这导致架构变更的执行出现摩擦(因为下游供应商抱怨他们的分叉版本被破坏),进而阻碍了开发。
需要敏捷应对人工智能的快速发展
最后一个挑战是,TVM 出现得比较早,但它周围的人工智能创新速度极快。由于得到谷歌、Meta 和英伟达等大型公司的支持,TensorFlow 和 PyTorch 迅速发展,性能不断提升,这也改变了 TVM 的性能对比基准。而生成式人工智能的出现更是给 TVM 带来了致命一击,改变了整个行业格局。TVM 是为 “传统人工智能(TradAI)” 设计的,处理的是相对简单的需要融合的算子,而生成式人工智能涉及与硬件深度集成的大型复杂算法,如 FlashAttention3。随着行业的发展,TVM 逐渐落后。
相对没那么重要(但仍然不可忽视)的是,TVM 还存在技术问题,比如由于过度自动调优导致编译时间极长。这些问题共同导致项目发展放缓。
如今,英伟达雇佣了许多 TVM 的原核心成员,这使得 TVM 的未来充满不确定性。与此同时,谷歌则通过 OpenXLA 践行自己的理念……
谷歌的 XLA 编译器:一个名称下的两个不同系统
与起源于学术项目的 TVM 不同,XLA 是由谷歌开发的。谷歌是最先进的人工智能公司之一,资金雄厚,在人工智能硬件领域有着重大利益。谷歌开发 XLA 是为了在其(如今已取得成功的)TPU 硬件中取代 CUDA,确保为自身人工智能工作负载实现紧密集成和最佳性能。2017 年,我加入谷歌大脑团队,帮助将 TPU(以及 XLA)从一个实验项目扩展为全球第二成功的人工智能加速器(仅次于英伟达)。
Google TPU
谷歌有数百名工程师参与 XLA 的开发(具体人数因统计方式而异),其发展迅速。谷歌增加了对 CPU 和 GPU 的支持,并最终成立了 OpenXLA 基金会。XLA 被用作多个重要硬件项目的人工智能编译器基础,包括 AWS 的 Inferentia/Trainium 等。
除了代码生成,XLA 最大的成就和贡献之一是能够处理大规模机器学习模型。在超大规模场景下,使用数千个芯片进行训练的能力至关重要。如今,最大的实用模型开始需要先进技术将其在多台机器上进行分区,XLA 开发出了简洁有效的方法来实现这一点。
既然投入如此巨大,为什么像 PyTorch 和 vLLM 这样的领先项目不在 GPU 上使用 XLA 呢?答案是,XLA 实际上是两个不同的项目,只是品牌名称合并了,其背后存在工程师激励结构问题、管理难题以及技术问题,这些使得 XLA 在实际应用中存在困难。
谷歌使用 XLA-TPU,而 OpenXLA 面向其他用户
需要理解的最重要一点是,XLA 有两种形式:1)内部闭源的 XLA-TPU 编译器,为谷歌的人工智能基础设施提供支持;2)OpenXLA,这是面向 CPU 和 GPU 的公共项目。这两个版本有部分代码(“StableHLO”)是共享的,但 XLA 的绝大部分代码(以及相应的工程工作)是针对谷歌 TPU 的,属于闭源专有代码,并不用于 CPU 或 GPU。如今,在 GPU 上使用 XLA 通常需要调用标准的 CUDA 库来提升性能。
这就导致了严重的激励结构问题 —— 谷歌的工程师可能想要构建一个出色的通用人工智能编译器,但他们的收入与 TPU 的性能表现挂钩。领导层没有太多动力为 GPU 或其他替代硬件优化 XLA,一切都以保持 TPU 的竞争力为目标。以我的经验来看,如果某项设计变更可能影响 TPU 性能,XLA 就不会优先考虑那些对其他芯片有利的改变。
结果就是,XLA 在 TPU 上表现出色,但在其他地方却不尽如人意。
OpenXLA 的管理
XLA 很早就作为开源项目发布,但明确由谷歌控制。谷歌凭借在人工智能领域的早期领先地位和 TensorFlow,使得 XLA 被行业内其他团队采用。2023 年 3 月,该项目更名为 OpenXLA,并宣布独立。
尽管进行了更名,但谷歌仍然控制着 OpenXLA(从其管理结构可以看出),而且似乎也没有持续投入:社区贡献不断减少,OpenXLA 的官方账号自 2023 年起就不再活跃。
XLA 的技术挑战
和 TVM 一样,XLA 也是围绕一组固定的预定义算子(StableHLO)设计的。这种方法在 2017 年处理像 ResNet-50 这样的传统人工智能模型时效果很好,但在应对现代生成式人工智能工作负载时却力不从心,因为现代生成式人工智能在数据类型、自定义内核和特定硬件优化方面需要更高的灵活性。如今,这是一个关键问题,现代生成式人工智能算法在数据类型上需要创新(见下图),或者像 DeepSeek 所展示的那样,在硬件层面和新型通信策略上进行创新。
vLLM 0.7 中按硬件类型支持的数据类型
因此,XLA(和 TVM 一样)也被生成式人工智能甩在了后面:如今,许多关键工作负载都是在像 Pallas 这样的实验性系统中编写的,即使在 TPU 上也绕过了 XLA 编译器。核心原因是,为了简化人工智能编译,XLA 对硬件进行了过多的抽象。这在早期人工智能模型中可行,但生成式人工智能需要对加速器进行细粒度控制,而这正是 XLA 天生不具备的能力。所以,和 TVM 一样,XLA 也逐渐被淘汰。
从 TVM 和 XLA 中吸取的教训
我为我们在 XLA-TPU 中取得的技术成就感到自豪:XLA 为许多代际研究突破提供了支持,包括 Transformer 的发明、无数的模型架构,以及在其他地方看不到的研究和产品扩展。显然,它是英伟达之外最成功的训练和推理硬件,支撑着谷歌众多领先的人工智能产品和技术。虽然我对 TVM 了解较少,但我非常尊重它对编译器研究、自动调优以及为许多早期人工智能系统提供支持所做出的贡献。
即便如此,我们还是能从这两个项目中学到很多。回顾从 OpenCL 项目中吸取的教训:
- “提供参考实现”:它们都提供了实用的实现,而不像 OpenCL 那样只是一个技术规范。👍
- “拥有强大的领导力和愿景”:它们都有明确的领导团队和背后的愿景。👍 然而,OpenXLA 的愿景与希望采用它的硬件团队并不一致。和许多谷歌的项目一样,其长期前景不明朗,依赖它存在风险。👎
- “在行业领先企业的硬件上实现顶级性能”:如果不调用 CUDA 库,XLA 和 TVM 都无法充分发挥英伟达 GPU 的性能,因此,如果没有类似的库可供调用,它们在其他人工智能加速器上的性能表现也存疑。👎 XLA 在 TPU 上确实展现了 TPU 硬件的强大能力以及比英伟达硬件更好的扩展性。👍
- “快速发展”:这两个项目都是为传统深度学习构建的,但生成式人工智能打破了它们的设想。向大规模模型、复杂内存层次结构和新型注意力机制的转变,需要新的硬件 - 软件协同设计水平,而这是它们无法应对的。👎 这最终使得那些希望在支持生成式人工智能的现代硬件上使用它们的人对其兴趣大减。👎👎
- “赢得开发者的喜爱”:XLA 的优势在于提供了一个简单清晰、易于理解的模型,这使得 JAX 框架等得以兴起。👍👍 TVM 技术很酷,但由于编译时间长且与流行的人工智能模型不兼容,使用体验不佳。👎
- “建立开放的社区”:TVM 建立了开放的社区,OpenXLA 也有此目标。因此,它们都从行业应用中受益。👍
- “避免碎片化”:这两个项目都没有做到 ——TVM 被下游广泛分叉和修改,XLA 的代码库从不接受对非 CPU/GPU 硬件的支持,所有支持的硬件都是下游自行添加的。👎
AI编译器技术的优缺点
像 TensorFlow 和 PyTorch 1.0 这样的第一代人工智能框架严重依赖手工编写的 CUDA 内核,无法适应快速发展的人工智能工作负载。作为第二代方法,TVM 和 XLA 通过自动编译解决了这一问题。然而,这样做的同时,它们牺牲了第一代框架的关键优势:自定义算法的可扩展性、对硬件的细粒度控制以及动态执行能力,而这些特性对于生成式人工智能至关重要。
除了从 OpenCL 项目中吸取的教训,我们还可以提出一些期望:
- 实现完全可编程性:如果对开发者隐藏芯片的强大功能,就无法实现人工智能的民主化。如果你花费 1 亿美元购买特定类型的 GPU 集群,你肯定希望充分释放芯片的全部性能,而不受限于简化的接口。
- 充分利用 AI 的复杂性:AI 编译器的主要优势在于,它允许开发者无需手动编写大量代码,即可扩展到 AI 的指数级复杂性(运算符、数据类型等)。这对于解锁下一代研究至关重要。
- 支持大规模应用:XLA 的变革性能力在于能够轻松扩展到多个加速器和节点。这项能力对于轻松支持最大规模、最具创新性的模型至关重要。这是 CUDA 从未真正突破的领域。
尽管这些 AI 编译器各有优劣,但它们都未能完全释放 GPU 性能或实现 AI 计算的大众化。相反,它们强化了各自为政:XLA 仍然以 TPU 为中心,而 TVM 则分裂成互不兼容的特定供应商分支。它们的失败,恰恰是 CUDA 替代方案本应获得成功的方式!
也许 Triton“语言”会拯救我们?
然而,就在这些编译器苦苦挣扎的同时,一种不同的方法正在形成。它并非试图取代 CUDA,而是旨在拥抱 GPU 编程,同时使其更具可编程性。 Triton 和新一波 Python eDSL 的出现,试图弥合 CUDA 的原始强大功能与 Python 的易用性之间的差距。在下一篇文章中,我们将深入探讨这些框架,看看它们的优势所在,不足之处,以及它们是否最终摆脱了过去的错误。
当然,你已经知道答案了。CUDA帝国依然占据主导地位。但为什么呢?更重要的是——我们能做些什么呢?
那些不记得过去的人注定会重蹈覆辙。——乔治·桑塔亚那
也许有一天,编译器技术能够在不剥夺我们能力的情况下减轻我们的痛苦。
Triton 和 Python eDSL 怎么样?
人工智能编译器面临着一个根本性的权衡:它们旨在通过抽象底层细节来提升易用性和可扩展性,但现代生成式人工智能工作负载需要可编程性和硬件控制权,才能实现顶级性能。CUDA C++ 能提供这种控制水平,但其使用难度大是出了名的。与此同时,人工智能开发大多在 Python 环境中进行,因此,行业自然试图将 GPU 编程与 Python 结合起来,以弥合两者之间的差距。
但这里有个问题:Python 无法在 GPU 上运行。为了填补这一空白,研究人员开发了嵌入式领域特定语言(eDSLs),这是一种基于 Python 的抽象语言,表面上看起来像 Python,但实际上在底层会编译成高效的 GPU 代码。其理念很简单:让工程师们在无需忍受 C++ 复杂性的情况下,就能获得 CUDA 的强大功能。但它真的有效吗?
在本章节中,我们将深入剖析 Python eDSLs 的工作原理、优缺点,并仔细研究 Triton(该领域最受欢迎的方法之一)以及其他一些工具。Python eDSLs 能否同时兼顾性能和易用性,还是说它们只是实现人工智能计算民主化道路上的又一次弯路?
什么是嵌入式领域特定语言(eDSL)?
当某个特定领域拥有独特的表达方式,能提高开发者的工作效率时,就会用到领域特定语言,其中最广为人知的或许就是 HTML、SQL 和正则表达式。“嵌入式领域特定语言(eDSL)” 是一种复用现有语言语法,但通过编译器技术改变代码运行方式的领域特定语言。eDSL 广泛应用于许多系统,从分布式计算(PySpark)到深度学习框架(TensorFlow、PyTorch),再到 GPU 编程(Triton)。
例如,PySpark 允许用户用 Python 表达数据转换操作,然后构建一个优化的执行计划,使其能在集群上高效运行。同样,TensorFlow 的tf.function和 PyTorch 的torch.fx会将类似 Python 的代码转换为优化的计算图。这些 eDSL 抽象掉了底层细节,让开发者无需具备分布式系统、GPU 编程或编译器设计方面的专业知识,就能轻松编写高效代码。
eDSL 是如何工作的?
eDSL 的神奇之处在于,它会在 Python 代码运行前捕获代码,并将其转换为可处理的形式。它们通常利用装饰器(Python 的一个特性)在函数运行前拦截函数。当你使用@triton.jit时,Python 会将函数交给 Triton 处理,而不是直接执行它。 下面是一个简单的 Triton 示例:
当 Triton 接收到这段代码时,它会将函数解析为抽象语法树(AST),该树表示函数的结构,包括操作和数据依赖关系。这种表示方式使 Triton 能够分析代码模式、应用优化,并生成执行相同操作的高效 GPU 代码。
通过复用 Python 现有的语法和工具,eDSL 的开发者可以专注于构建编译器逻辑,而无需设计一门全新的语言,也不用编写自己的解析器、语法和工具链。
eDSL 的优势
eDSL 为构建领域特定编译器的人带来了巨大优势:通过将语言嵌入 Python,开发者可以专注于编译器逻辑,而不必重新发明一门完整的编程语言。设计新语法、编写解析器和构建集成开发环境(IDE)工具是一项浩大的工程,而借助 Python 现有的语法和 AST 工具,eDSL 开发者可以跳过这些步骤,直接解决眼前的问题。
eDSL 的用户也能从中受益:Python eDSL 让开发者可以在熟悉的环境中工作。他们可以使用相同的 Python IDE、自动补全功能、调试工具、包管理器(如pip和conda)以及库生态系统。开发者无需学习像 CUDA C++ 这样全新的语言,只需用 Python 编写代码,eDSL 会在底层引导代码执行。
然而,这种便利性也伴随着重大的权衡,对于期望 eDSL 表现得像常规 Python 代码的开发者来说,可能会感到沮丧。
eDSL 面临的挑战
当然,天下没有免费的午餐。eDSL 存在一些权衡取舍,其中一些问题可能会让开发者深感困扰。
看起来像 Python,但并非真正的 Python 这是 eDSL 中最令人困惑的部分。虽然代码看起来像常规 Python,但它的行为在某些关键方面并不像 Python:
为什么会这样呢?因为 eDSL 并不是在执行 Python 代码,而是捕获并将函数转换为其他形式。它决定支持哪些结构,许多常见的 Python 特性(如动态列表、异常处理或递归)可能根本无法使用。这可能会导致一些在 Python 中本应正常工作的代码突然出现无声失败或难以理解的错误。
错误和工具限制
调试 eDSL 代码可能是一场噩梦。当代码出现故障时,你通常不会得到熟悉的 Python 友好错误信息。相反,你看到的是来自编译器内部深处的晦涩堆栈跟踪信息,几乎无法判断哪里出了问题。更糟糕的是,像 Python 调试器这样的标准工具通常根本无法使用,你只能依赖 eDSL 提供的调试功能(如果有的话)。此外,虽然 eDSL 存在于 Python 环境中,但它们不能直接使用 Python 库。
表达能力有限
eDSL 通过复用 Python 的语法来工作,这意味着它们无法引入可能对其领域有用的新语法。像 CUDA C++ 这样的语言可以添加自定义关键字、新结构或特定领域的优化,而 eDSL 则局限于 Python 的子语言,这限制了它的清晰表达能力。
最终,特定 eDSL 的质量决定了这些权衡带来的困扰程度。实现良好的 eDSL 可以提供流畅的体验,而设计不佳的 eDSL 则可能是一个充满挫折的 “雷区”,总是与开发者的预期相悖。那么,像 Triton 这样的 eDSL 是否能做到恰到好处呢?它与 CUDA 相比又如何呢?
Triton:OpenAI 用于 GPU 编程的 Python eDSL
Triton 最初是哈佛大学菲利普・蒂莱(Philippe Tillet)的一个研究项目,在从事 OpenCL 相关工作多年后,于 2019 年首次发表(详见我之前关于 OpenCL 的文章 )。蒂莱加入 OpenAI 后,该项目获得了巨大的发展动力,PyTorch 2 决定采用它,更是让其影响力大增。
与通用人工智能编译器不同,Triton 在注重 Python 开发者易用性的同时,仍允许进行深度优化。它在高级简洁性和低级控制权之间取得了平衡,为开发者提供了足够的灵活性来微调性能,而不会让他们陷入 CUDA 的复杂性中。
让我们来探究一下 Triton 如此实用的原因。
以块为中心的编程模型
传统的 GPU 编程要求开发者从单个线程的角度思考问题,手动管理同步和复杂的索引。Triton 通过在块级别进行操作简化了这一过程,因为 GPU 本身就是以块为单位处理工作的,这样就消除了不必要的底层协调工作:
这种模型抽象掉了线程管理,简化了基本索引,同时也让利用张量核心(GPU 中负责大部分浮点运算的专用硬件)变得更加容易:
在 CUDA 中需要几十行复杂代码才能实现的功能,在 Triton 中只需一个函数调用,同时还能实现高性能。Triton 会自动处理数据布局转换和特定硬件的优化。
简化的优化
CUDA 最令人头疼的方面之一是处理多维数据时复杂的索引计算。Triton 极大地简化了这一过程:
这些数组操作类似于 NumPy,但会编译成高效的 GPU 代码,且没有运行时开销。
Triton 还包括编译器驱动的优化(如向量化),并支持简化的双缓冲和软件流水线技术,这些技术可以使内存传输与计算重叠进行。在 CUDA 中,使用这些技术需要深入了解 GPU 知识;而在 Triton 中,非专业人员也能轻松使用这些技术。如需深入了解,OpenAI 提供了详细的教程。 Triton 使 GPU 编程变得更加容易上手,但这种易用性也有代价。让我们来看看它面临的一些关键挑战。
Triton 的不足之处
Triton 在某些情况下应用广泛且非常成功(例如,研究前沿模型训练的研究人员和特定的专业应用场景)。然而,它并没有在所有应用中得到广泛采用,特别是在对效率要求极高的人工智能推理场景中,Triton 并不适用。此外,尽管多年前行业领导者曾做出预测,但 Triton 既没有统一生态系统,也未能挑战 CUDA 的主导地位。让我们深入了解一下,除了所有 eDSL 都存在的普遍限制(前面已描述)之外,Triton 还面临哪些挑战。
与 CUDA C++ 相比,GPU 性能和总体拥有成本(TCO)显著下降
Triton 为了提高开发效率而牺牲了性能(正如其创建者所解释的那样)。虽然这使得编写 GPU 代码变得更加容易,但也导致 Triton 无法实现最佳效率。性能下降的幅度各不相同,但在当今主导人工智能计算的英伟达 H100 上,性能损失 20% 是很常见的情况。
问题出在哪里呢?编译器的优化效果比不上熟练的 CUDA 开发者,尤其是对于如今先进的 GPU。在我数十年构建编译器的过程中,从未见过 “足够智能的编译器” 这种说法真正实现过!这就是为什么包括 DeepSeek 在内的领先人工智能实验室,在处理高要求的工作负载时,仍然依赖 CUDA 而不是 Triton:在生成式人工智能领域,20% 的性能差异是无法接受的;在大规模应用中,这意味着云服务账单会从 10 亿美元增加到 8 亿美元!
管理问题:OpenAI 的控制和关注点
Triton 是开源的,但它的发展路线图由 OpenAI 掌控。这就产生了问题,因为 OpenAI 与其他前沿模型实验室直接竞争,这引发了一个问题:它会优先考虑更广泛的人工智能社区的需求,还是只关注自身的需求呢?
许多工程师都抱怨很难为 Triton 贡献改进内容,尤其是当这些更改与 OpenAI 的内部优先级不一致时。一个常见的抱怨是,对替代硬件的支持远远落后,因为 OpenAI 没有动力为自己不使用的加速器进行优化。Triton 的开发团队也承认,“对新用户的支持几乎不存在”,而且他们没有精力满足社区的需求。
工具和调试器支持不足
CUDA 虽然复杂,但它拥有成熟的工具生态系统,如 Nsight Compute、分析器 API 和内存调试器,这些工具能帮助开发者深入了解性能瓶颈。Triton 无法与这些工具协同工作。从设计上看,eDSL 旨在抽象掉底层细节。因此,当出现问题时,开发者无法确定问题的根源,只能猜测编译器做了什么。尽管 Triton 的编程模型更简单,但这种缺乏可观测性的问题使得在 Triton 中进行性能调试比在 CUDA 中更具挑战性
GPU 可移植性,但缺乏性能可移植性和通用性
用 Triton 编写的 GPU 代码,如果是为某一特定 GPU 编写的,运行起来 “相当快”,但在不同类型的 GPU 上,即使是英伟达的不同硬件,代码运行速度也会变慢。例如,为 A100 优化的 Triton 代码在 H100 上的性能往往较差,因为更新的架构需要不同的代码结构才能达到 80% 的性能,而 Triton 并没有对流水线和异步内存传输等进行抽象。
Triton 内核需要针对新一代 NVIDIA 硬件进行重写才能释放其性能。
迁移到 AMD GPU 上的情况更糟。虽然 Triton 在技术上支持 AMD 硬件,但在性能和功能对等方面远远落后于英伟达,使得跨厂商的可移植性难以实现。对于非 GPU 人工智能加速器(如 TPU、Groq 芯片或 Cerebras 晶圆)来说,情况更糟。这些架构不遵循 Triton 所假设的单指令多线程(SIMT)执行模型,这会导致性能严重下降,或者需要大量的变通方法,使得这种方法变得事倍功半。
最终,“一次编写,随处运行” 的承诺通常变成了 “一次编写,随处运行,但在替代平台上性能会大幅下降”。
Triton 表现如何?
在我们之前的文章中,我们开始列出对人工智能编程系统的期望。按照这些期望来衡量,Triton 有几个显著的优势,但也面临一些挑战:
- “提供参考实现”:Triton 提供了完整的实现,而不仅仅是规范,还有实际示例和教程。👍
- “拥有强大的领导力和愿景”:Triton 在 OpenAI 的领导下有明确的方向,但优先考虑的是 OpenAI 的需求,而非更广泛的社区需求。长期的管理问题仍然令人担忧,特别是对于竞争的人工智能实验室来说。👍👎
- “在行业领先企业的硬件上实现顶级性能”:Triton 在英伟达硬件上运行良好,但与优化后的 CUDA 相比,通常存在约 20% 的性能差距。它在支持像 FP8 和 TMA 这样的最新硬件特性方面也存在困难。👎
- “快速发展”:Triton 已经适应了一些生成式人工智能的需求,但在支持前沿硬件特性方面仍有滞后。其发展速度取决于 OpenAI 的内部优先级,而非行业需求。👎
- “赢得开发者的喜爱”:Triton 提供了简洁的、基于 Python 的编程模型,许多开发者认为它直观且高效。它与 PyTorch 2.0 的集成扩大了其应用范围。👍👍👍
- “建立开放的社区”:虽然 Triton 是开源的,但它的社区受到 OpenAI 对路线图控制的限制。外部组织的贡献面临重大障碍。👎
- “避免碎片化”:Triton 本身针对英伟达 GPU 是统一的 👍,但其他硬件供应商对它进行了广泛的分叉,不同版本存在不同的限制和权衡。👎
- “实现完全可编程性”:Triton 在标准操作方面提供了良好的可编程性 👍,但无法访问 / 控制所有硬件特性,尤其是最新加速器的功能。👎
- “应对人工智能的复杂性”:Triton 能够高效处理常见模式,简化了开发过程 👍。但它不支持自动融合,无法解决指数级增长的复杂性问题。👎
- “支持大规模应用”:Triton 专注于单设备内核,缺乏对多 GPU 或多节点扩展的内置支持,但它与 PyTorch 的集成很好地解决了这个问题。👍
总体而言,很明显 Triton 是人工智能开发生态系统中非常有价值的一部分,尤其是在针对英伟达 GPU 进行开发时。话虽如此,虽然 Triton 因其与 PyTorch 的集成而成为最知名的 eDSL,但其他项目,如 Pallas、CUTLASS Python 和 cuTile,正在探索在开发效率、性能和硬件支持之间进行不同的权衡。这些替代方案都基于类似的理念,但在解决 GPU 可编程性问题上采取了独特的方法。
其他 Python eDSL:Pallas、CUTLASS Python、cuTile 等
Python eDSL 的目的并非追求极致性能,而是让编译器开发者更容易将产品推向市场。因此,这类工具众多,Triton 只是其中最知名的。以下是一些常被问到的工具(免责声明:我没有直接使用过这些工具)。
谷歌 Pallas
谷歌 Pallas 是 JAX 的一个子项目,旨在支持自定义操作,特别是针对 TPU。它深受 Triton 的启发,但与提供高级、用户友好的 API 不同,它更多地暴露了底层编译器细节。
从外部来看,Pallas 功能强大但使用难度较大,需要深入了解 TPU 硬件和编译器内部原理。它的文档中强调了许多潜在的风险,很明显这是一个面向具有底层知识的专家的工具。因此,它在谷歌之外的应用范围有限。
CUTLASS Python 和cuTile
在GTC 2025 大会上,NVIDIA 宣布了两款新的 Python eDSL:CUTLASS Python和cuTile。目前这两款产品尚未提供下载,但以下是一些初步印象:
- CUTLASS Python –本次 GTC 演讲中介绍的CUTLASS Python 似乎深受 Google Pallas 的启发。它公开了底层编译器细节,需要深厚的硬件知识,并且没有 CUDA 开发人员所依赖的工具或调试器。它首先在 Blackwell 上发布,我怀疑 NVIDIA 是否会将其开源或支持其他硬件供应商。我也很好奇 Python 缺乏静态类型,在编写此类底层系统代码方面效果如何。
- cuTile – 这款产品在 X (示例)上被广泛转发,但除了几张幻灯片外,关于其上市日期和技术细节一无所知。它似乎被定位为 Triton 的专有替代品。NVIDIA 承认cuTile 比 TRT-LLM 慢约 15%。鉴于 NVIDIA 专注于峰值性能,目前尚不清楚它是否会使用 cuTile 构建自己的 CUDA 库。如果它正式上市,那么NVIDIA 内部的真正采用将是真正的考验。
这些 eDSL 只是 NVIDIA 庞大的 Python GPU 生态系统的一部分。在GTC 2025 大会上,NVIDIA 表示:“没有单一的工具——你需要根据工作选择合适的工具。” NVIDIA 甚至举办了一场名为“用 Python 编写 CUDA 内核的 1001 种方法”的会议——光是想想如何选择正确的路径就感觉像是一场噩梦。
NVIDIA 表示:“没有任何单一工具能够适用于所有应用程序。”(来源:NVIDIA GTC 2025,CUDA:新功能及未来)
作为一名开发者,我认为几十个带有微妙权衡的选项对我没有帮助。我们需要更少、更高效地使用工具,而不是一个不断增加的选择清单。NVIDIA 正在分裂其自身的开发者生态系统。
MLIR:AI 编译器的统一未来?
在我于 2017 年和 2018 年致力于扩展 Google TPU 的过程中,我发现了一种模式:第一代 AI 框架(例如 TensorFlow 和 PyTorch)缺乏可扩展性,而第二代 AI 编译器(例如XLA)则牺牲了灵活性。为了打破这种循环,我带领团队构建了全新的MLIR 编译器框架——一个模块化、可扩展的编译器框架,旨在支持 AI 快速发展的硬件格局。
它成功了吗?MLIR 推动了整个行业的突破——Triton 、cuTile 等Python DSL都建立在其之上,重新定义了 GPU 编程。但与之前的TVM 和 XLA一样,MLIR 也面临着治理挑战、碎片化以及企业利益冲突。真正统一的AI 编译器堆栈的愿景似乎仍然遥不可及,几十年来一直困扰着这个行业的权力斗争依然存在。
碎片化似乎不可避免,抵抗也徒劳无功。统一的编译器技术真的能帮助人工智能计算民主化吗?
MLIR 编译器基础设施怎么样?
到 2018 年,人工智能软件出现了系统碎片化问题。TensorFlow、PyTorch、JAX、Glow、ONNX、TensorFlow-Lite、XLA、TVM,这样的框架名单越来越长,每个框架都构建了自己错综复杂的 “人工智能图”,其中包含不同的 “操作(ops)”。整个生态系统分裂成一个个孤岛,每个都竞相针对不同硬件进行优化,只是在细微差异中重复发明相同的概念。复杂性呈爆炸式增长,必须有所改变。
当时,我正在协助谷歌扩展 TPU(以及其他一些内部专用集成电路),以支持 TensorFlow。很明显,我们不能为每个项目都从头开始重新构建编译器基础设施,我们需要一个更好的基础。幸运的是,我有多年构建 LLVM 的经验,而且我的上司是杰夫・迪恩(Jeff Dean)。杰夫是一位传奇工程师,本身也是编译器领域的博士,他也看到了同样的问题。
在一次一对一的交谈中,杰夫大概是这么说的:“嘿,克里斯,我也觉得我们存在编译器方面的问题。你为什么不构建一个新的编译器来整顿这一混乱局面呢?”
于是,MLIR 应运而生,它是一个模块化、可扩展的编译器基础设施,旨在为这场混乱带来秩序。它提供了一个能够跨硬件平台、软件框架,以及满足机器学习快速发展需求的基础。它的目标是统一这些系统,并提供一个能协调众多不同硬件制造商计算资源的技术平台。
但实现统一并非易事。这个原本的技术项目很快演变成了一个战场:开源治理、企业竞争以及相互冲突的愿景交织在一起。这本可以是一场简单的工程胜利,却变得复杂得多。
如今,MLIR 几乎嵌入了每一个主要的人工智能技术栈中,包括 CUDA,但它仍未实现人工智能计算民主化的梦想。
这就是 MLIR 的故事:它如何诞生、带来了哪些改变,以及一路走来的权力斗争。
MLIR 的起源故事
现代人工智能系统依赖于复杂的操作图,如矩阵乘法、卷积、注意力机制等,所有这些都串联成计算流水线。正如第 6 部分所讨论的,要高效地优化和转换这些操作,需要一个坚实的编译器基础。
但在 2018 年,大多数人工智能框架都在重新发明编译器技术,而且往往做得并不好。许多框架都缺失了像静态单赋值(SSA)这样的基本技术。每个框架都有自己临时拼凑的图系统,用一些无法扩展的方法组合在一起。结果就是一个碎片化、低效率的生态系统,充斥着大量重复内容。
我知道我们需要一种更好的方法,所以我召集了四位志同道合的同事,在谷歌的一个小房间里展开讨论。我们花了好几天时间在白板上进行头脑风暴,勾勒出一个适用于人工智能的现代、可扩展的编译器基础设施可能的样子。我们的核心问题是:我们能否构建一种统一的表示形式,以支持每一个人工智能框架、每一个硬件后端,以及从代数简化到多面体分析等各种优化?
大约 2018 年:我和四位同事聚集在白板前,集思广益,构思下一代编译器
我们提出的突破性想法如今被称为 MLIR 方言(MLIR dialects),这是一种将特定领域的问题与编译器核心基础设施清晰分离的方法。与强制每个用户采用僵化、一刀切的中间表示形式(如 LLVM 和其他编译器)不同,MLIR 允许编译器工程师定义自己的表示形式,包括自定义操作、类型和语义,以适应各自的领域。
在当时,这与大多数编译器的构建方式截然不同。传统的基础设施是一体化的,将所有前端和处理过程都纳入单一、僵化的模型中。但 MLIR 从一开始就接纳异构性,它允许不同层次的抽象共存、转换,并实现无缝互操作。
这种模块化是关键所在。MLIR 为开发者提供了一个共享基础,无论他们处理的是 TensorFlow 图、PyTorch 中间表示(IR),还是自定义 TPU 操作,都无需反复重新实现相同的基础设施。这使得构建专用编译器无需从头开始,并且实现了人工智能编译器栈的真正可组合性。
MLIR 不仅仅是又一个编译器,它是一个用于构建众多编译器的框架。
MLIR 在谷歌内部及外部的发展
MLIR 最初是谷歌大脑(Google Brain)内部的一个研究项目,一个专注的团队试图重新思考人工智能编译器应有的工作方式。我的团队专注于基础工作:设计中间表示(IR)、实现转换,并验证核心想法是否可行。与此同时,谷歌的开放文化和 MLIR 的模块化设计,使得其他人很容易接触并尝试使用它。没过多久,MLIR 就开始独立发展起来。
在谷歌内部,致力于定制专用集成电路(ASIC)的团队看到了它的潜力。MLIR 为他们提供了一种结构化的方式来表达和优化特定硬件的操作。专注于应用的团队开始将其用于移动人工智能领域,TensorFlow 团队则将 MLIR 引入了 TensorFlow Lite。甚至一些对 MLIR 的灵活性感兴趣的独立研究人员,也开始用它来为新颖的编译器技术制作原型。
随之而来的是各种应用场景的小爆发。每一个新应用都带来了新的反馈,而那时我们往往还处于深入迭代阶段。关键的是,这验证了我们以方言为优先的方法,证明了 MLIR 可以在从边缘设备到数据中心加速器等截然不同的领域中进行扩展。最终,我们达到了一个临界点:MLIR 成为了众多项目中至关重要的基础设施。
我们很多人都希望 MLIR 能充分发挥潜力,超越谷歌内部的应用场景。
MLIR 社区内著名的 meme,内容大概为 MLIR 能解决很多问题 (图片来源:Mehdi Amini)
所以我们迈出了重要一步:将 MLIR 开源,并贡献给 LLVM 基金会,让整个行业都能使用。为了推动其被采用,我们定期组织 “开放设计会议”,外部贡献者可以参与 MLIR 的演进,并从背后的工程投入中受益。这种开放协作促进了 MLIR 在全球范围内的发展势头,尤其受到渴望拥有现代基础设施的编译器开发者的欢迎。
在这一推动下,MLIR 迅速发展。如今,它是许多重要人工智能项目的基础,如 OpenXLA、Triton,甚至 CUDA 的部分内容也基于它。它还为量子计算、硬件设计(通过 CIRCT )等许多其他领域的编译器提供支持。从新兴的创业公司到超大规模企业,全球众多公司都开始使用 MLIR 构建下一代编译器。MLIR 早期的发展和成功,很大程度上要归功于谷歌的领导和开放的方式,我认为这一点在行业中仍未得到充分认可。
然而,尽管取得了这些成功,宏伟的愿景仍然遥不可及。生态系统依旧碎片化,CUDA 仍然占据主导地位。真正实现人工智能计算民主化的梦想,依然只是一个梦想。
那么,发生了什么呢?为什么 MLIR 在技术上取得了成功,却未能打破 CUDA 的垄断呢?
要理解这一点,我们需要探讨影响 MLIR 发展的政治因素、权力斗争和妥协。
竞相打造端到端人工智能解决方案
从一开始,MLIR 就被设想为通用编译器基础设施,这是一个旨在支持特定领域编译器的框架。其目标是实现灵活性和模块化,MLIR 从来都不仅仅是关于机器学习的。事实上,MLIR 中的 “ML” 代表的并非机器学习(没错,编译器相关的笑话就是这么专业!)。然而,人工智能领域渴望得到更多,他们想要一个端到端的编译器,能够将 TensorFlow 或 PyTorch 模型顺利映射到各种硬件上。
打造首个基于 MLIR 的端到端 AI 解决方案的竞赛已经开始
于是,各方开始竞相在 MLIR 的基础上构建端到端的人工智能解决方案。包括 OpenXLA、TritonLang 等在内的其他项目,都将 MLIR 作为实现细节,以强化自身的技术栈。这就引发了一个问题:每个人都想成为下一代人工智能技术栈,那么谁会率先成功呢?
这场竞赛就此开始。多年后,我们得到了一个令人遗憾的答案:没有人成功。
MLIR 人工智能方言的激增
将 MLIR 贡献给 LLVM 基金会极大地推动了它的应用。这为企业提供了一个共享基础,也让编译器工程师有机会在所在组织中展现自己的影响力。
LLVM 基金会负责监督和处理法律事务,但不干预技术设计,这方面由社区自行组织。
以谷歌为首,整个行业的工程师们开始贡献与人工智能相关的方言,包括算术(arith)、线性代数(linalg)和张量(tensor)等,为构建现代人工智能编译器栈提供了一些有用的部分。最初是谷歌的研究团队率先接触到 MLIR 并进行贡献,但这开创了一个先例:许多 “可能有用” 的贡献被纳入上游代码库,而管理机制有限,项目负责人很难从原则上拒绝。
不幸的是,这种方言的激增在 MLIR 设计的早期就发生了,而且其中许多设计决策并不符合生成式人工智能不断发展的需求。例如,早期的很多工作都围绕改进 TensorFlow 和构建 OpenXLA 展开,所以这些方言在设计时并没有将对 PyTorch 和生成式人工智能的一流支持纳入考虑(正如我们在本系列前面所讨论的)。
虽然许多努力都实现了最初的目标,但世界已经发生了变化。
竞争性 “竞合” 带来的问题
由于各种原因,几乎所有早期参与 MLIR 开发的人员(包括我自己)都离开了谷歌,其中很多人去了硬件公司。MLIR 知识的传播本是一个积极成果,意味着这项技术会得到更广泛的应用,但它也带来了新的挑战。
问题在于,MLIR 的成功使得其核心开发者分散到了整个行业。曾经的盟友和同事如今在相互竞争的公司工作,他们开始在共享的 MLIR 方言基础上构建专有的人工智能技术栈。原本的开放协作很快与商业竞争产生了冲突。由于缺乏中央协调,这些团队之间的沟通逐渐中断。相互冲突的优先级引发了紧张局势,MLIR 曾经统一的愿景开始支离破碎。
MLIR 的身份危机:机器学习解决方案还是编译器框架?
MLIR 如今面临着身份危机:它是适用于任何领域的通用编译器框架,还是一个人工智能解决方案呢?如今,作为通用的、可复用的基础设施,MLIR 的地位无可比拟,它支持从硬件设计到量子计算等各个领域。另一方面,内置的与人工智能相关的方言存在争议且并不完善,但对许多开源和专有的下游技术栈来说仍至关重要。
这感觉就像 OpenCL 的情况再次上演:没有参考技术栈、硬件供应商相互竞争,而且竞争环境表面上一团和气,就像当年的 Khronos 委员会一样。
新的希望:改进 MLIR 治理
这些紧张局势已经持续了多年,在更广泛的 LLVM 和 MLIR 社区中都能深切感受到。
幸运的是,出现了新的希望:LLVM 社区秉持精英管理的理念,在协调工程师方面有着良好的记录,即便这些工程师所在的公司在市场上处于竞争关系。MLIR 社区中有许多优秀的工程师,他们多年来全身心投入到项目改进中,努力应对这些挑战,并且现在已经取得了一些进展!
MLIR 现在有了一个新的领域团队来指导其发展,同时还有新的组织结构、章程和管理小组。章程定义了不同的领域小组:MLIR 核心(与领域无关的基础设施)和各种方言(如与机器学习相关的部分)。我非常感谢每一位花时间改进 MLIR、解决这些问题的人,这样的工作对构建这个生态系统的所有人以及下游用户都有着深远的影响。
如果我能许一个愿望,我希望 “MLIR” 能明确指代与领域无关的编译器基础设施,而这些方言能有一个新的、不同的名字(比如 “TensorIR”?)。这样可以减少对 “MLIR” 实际含义的混淆!
从 MLIR 中吸取的教训
我从 MLIR 项目中得到的最大教训是,在核心基础尚未完全稳固时过早进行扩展,可能会引发长期问题。早期的浓厚兴趣和大量贡献令人兴奋,但这也意味着许多设计决策是并行做出的,缺乏明确的指导和协调。我们快速完成了很多工作,却牺牲了在每个层面做到极致的机会,结果陷入了海勒姆定律(Hyrum's Law)的困境。
这也让我再次体会到在其他项目中得到的管理经验:当有太多聪明的工程师朝着不同方向快速前进时,后期很难掌控项目方向,即便项目有着设计精美的中间表示(IR)。就 MLIR 而言,虽然我在 LLVM/MLIR 社区仍有一定影响力,但我意识到这种影响力无法与雇主提供的薪酬相抗衡,薪酬会促使贡献者将自己的工作纳入代码库,以便继续进行下一个错误修复或项目。
另一个教训与有宏大目标的基础设施项目有关。我对 MLIR 的目标是统一编译器的实现,它的成功超出了我的预期。但我也鼓励并推动其他人追求更高目标,大家都乐观地认为社区主导的项目能够推动世界前进。但结果并不理想,这让我更加深刻地认识到,在我参与构建的其他具有行业影响力的项目(LLVM、Clang、Swift 和 “MLIR 核心”)中得到的一个教训:小团队最擅长凝聚在一个成功愿景下并推动其实现。只有在项目的定位稳固确立之后,再向更广泛的社区扩展才有意义。
MLIR 有许多方言,但很多都有争议或不完整。
按照我此前的惯例,我将根据对下一代人工智能解决方案的期望特性清单,来评估 MLIR 的人工智能方言。以下是我的看法:
- “提供参考实现”:虽然 MLIR 在通用编译器基础设施方面表现出色,但它并没有提供一个可以直接用于人工智能工作负载的端到端解决方案,只是提供了一些需要 “自行组装” 的有用构建模块。👎
- “拥有强大的领导力和愿景”:早期,MLIR 的人工智能方言缺乏明确的领导,贡献往往由个人或不同团队推动,导致方向分散,核心定位也不清晰。虽然现在有了强有力的领导趋势,但问题仍未解决。👎
- “在行业领先企业的硬件上实现顶级性能”:虽然 MLIR 核心为优化提供了坚实的基础,但据我所知,基于 MLIR 人工智能方言构建的下游实现,在英伟达 GPU 上运行生成式人工智能大语言模型(LLMs)时,性能都无法与 CUDA 相媲美(包括 Triton 或 cuTile,它们的性能会比 CUDA 低 15 - 20%)。👎
- “快速发展”:MLIR 的发展速度令人瞩目,来自广泛社区的贡献源源不断。其灵活的设计使其能够快速适应新的应用场景和领域。👍
- “赢得开发者的喜爱”:MLIR 确实赢得了编译器工程师和系统研究人员的青睐,为构建定制编译器提供了灵活而强大的工具包。👍 然而,人工智能开发者,尤其是机器学习领域的开发者,认为学习曲线陡峭,而且它与现有机器学习框架的集成也不够无缝。👎
- “建立开放的社区”:MLIR 建立了一个真正开放且蓬勃发展的社区。定期的设计会议、开放的贡献机制以及跨公司的合作,帮助它获得了众多行业参与者的广泛采用和投入。👍👍
- “避免碎片化”:这是 MLIR 最薄弱的环节。早期方言和贡献的激增,再加上缺乏强有力的中央管理,导致下游系统出现碎片化。由于相互竞争的项目走向不同方向,统一人工智能编译方法的愿景难以维持。👎👎👎
归根结底,正如我们之前讨论的,用这种方式来衡量 “MLIR 核心” 作为编译器构建工具包是极不公平的,MLIR 被数十个系统广泛使用,它无疑实现了最初的使命。MLIR 人工智能方言的成功,最好通过它对无数使用它的下游人工智能实现的影响来衡量,只是我不确定该如何衡量。
硬件公司为何难以开发人工智能软件?
在本系列文章的这个阶段,一种模式逐渐显现:无论是 OpenCL/OneAPI、TVM/XLA、MLIR,还是其他一些出发点良好的项目,我们看到了众多构建统一人工智能基础设施的有力尝试,但没有一个能提供让开发者满意的解决方案。项目走向碎片化,承诺落空,使用替代硬件的用户手中的工具总是不尽如人意。
残酷的事实是:只有英伟达真正解决了这个问题。CUDA 不仅仅是基础设施,它是一种策略,背后有紧密的垂直整合、一线的应用工程师,以及对实际性能的不懈追求。它既不开放,也不完美,但对英伟达来说却非常有效,即便 “创新者的困境” 在英伟达总部圣克拉拉(Santa Clara)依然存在。
那么,为什么其他硬件公司做不到呢?为什么这个行业中最聪明的人,在数十亿美元资金的支持下,开发出的软件却没人想用呢?当你与一个根基深厚、垂直整合的行业领导者竞争时,局势对你极为不利,而且行业和企业内部的激励机制也影响着最终结果。
“告诉我激励机制,我就能告诉你结果。”—— 查理・芒格(Charlie Munger)
我们将在下一章节深入探讨这个问题。在此之前,愿每一种方言都能规范发展!
为什么硬件公司难以构建人工智能软件?
自 2023 年 ChatGPT 推出以来,生成式人工智能重塑了科技行业,但 GPU 并非一夜之间突然出现。十多年来,硬件公司在人工智能芯片上投入了数十亿美元,研发出几十种架构,耗费了无数的工程工时。然而,英伟达依旧占据着主导地位。
这是为什么呢?
因为 CUDA 不仅仅是一个软件开发工具包(SDK)。它是一座旨在让你深陷其中的开发者体验堡垒,也是一种精心策划的商业策略,让竞争对手永远落后两年。它并不招人喜欢,也不够优雅。但它行之有效,其他产品难以望其项背。
在本系列文章中,我们追溯了那些充满希望的替代方案的兴衰历程,如 OpenCL 和 SyCL、TVM 和 XLA、Triton、MLIR 等等。模式很明显:技术抱负远大,早期令人兴奋,但最终走向碎片化。与此同时,CUDA 的护城河却越来越深。
让硬件行业领导者夜不能寐的万亿美元难题是:鉴于巨大的机遇,以及开发者对替代方案的迫切需求,为什么我们无法突破困境呢?
答案并非是硬件公司无能。这些公司里不乏才华横溢的工程师和经验丰富的高管。问题出在结构上:激励机制不合理、优先事项相互冲突,而且严重低估了在这个领域进行软件开发所需的投入。在这个行业,你需要的不只是芯片,而是一个平台。构建平台意味着要做出艰难、不受欢迎的长期赌注,而且还不能保证会有人买账。
在本文中,我们将揭示硬件公司所处的无形约束矩阵,这个系统从设计上就使得构建具有竞争力的人工智能软件变得几乎不可能。
我在硬件 / 软件协同设计领域的职业生涯
我热衷于创新硬件领域,阅读各类刊物,只要是关于塑造未来的芯片、技术栈和系统的内容,我都不放过。几十年来,我痴迷于硬件 / 软件协同设计的精妙之处:当协同设计发挥作用时,就像变魔术一样神奇;而当它失效时…… 这正是本系列文章探讨的主题。
我从中也收获了一些经验:
- 我在科技行业的第一份真正工作是在英特尔,为奔腾 MMX(第一款支持 SIMD 指令的个人电脑处理器)优化首发游戏。在那里,我学到了关键一课:没有经过优化的软件,即便芯片性能再卓越,也无法充分发挥其速度优势。这段早期对硬件 / 软件相互作用的体验让我印象深刻。
- 在苹果公司,我参与构建了编译器基础设施,助力苹果过渡到自研芯片。苹果让我明白,真正的硬件 / 软件整合需要卓越的组织纪律。苹果之所以成功,是因为各个团队有着统一的愿景,没有任何业务部门能够凌驾其上,而不是仅仅满足于妥协。
- 在谷歌,我与硬件和人工智能研究团队共同扩展 TPU 软件栈。凭借看似无限的资源和紧密的硬件 / 软件协同设计,我们利用对工作负载的了解,充分发挥了专用芯片的强大性能,打造出一艘令人惊叹的定制人工智能竞赛游艇。
- 在 SiFive 公司,我完全转换了视角,在这家硬件公司领导工程团队的经历,让我深刻认识到硬件商业模式和组织价值观的残酷现实。
从这些经历中,有一点变得很清晰:软件团队和硬件团队使用不同的 “语言”,工作节奏不同,衡量成功的标准也不同。但还有更深层次的因素在起作用,我逐渐发现了一个无形的约束矩阵,它影响着硬件公司对待软件的方式,也解释了为什么软件团队在开发人工智能软件时尤其艰难。
在深入探讨之前,让我们先站在硬件公司高管的角度思考,这样就能逐渐看清这个约束矩阵。
人工智能硬件公司的思维方式
硬件公司并不缺乏聪明才智。问题不在于智商,而在于思维模式。
如今,人们对人工智能芯片的架构要素已经有了充分的了解:脉动阵列、张量核心、混合精度计算、特殊的内存层级等。制造芯片仍然极具挑战性,但它已不再是取得成功的瓶颈。真正的挑战在于让别人使用你的芯片,而这意味着需要配套软件。
生成式人工智能工作负载的发展速度极快。硬件公司不仅要着眼于当下的热门需求,更要为开发者未来两年的需求进行设计。然而,他们仍困在与现实脱节的思维模式中,就像试图用陆地文化在开阔水域中竞赛一样。
有趣的事实:LLVM 的吉祥物是一只飞龙,有点像前面没有爪子的龙。
在 CPU 时代,软件相对简单:为 LLVM 构建一个后端,你的芯片就能融入一个生态系统,Linux 系统、浏览器、编译后的应用程序等都能适配。但人工智能领域没有这样的便利条件,既没有统一的编译器,也没有通用的操作系统。你要为一个混乱且变化迅速的技术栈开发软件,包括 PyTorch、vLLM,以及本周流行的各种智能体框架,而你的客户却在使用英伟达的工具。你需要让这些软件在人工智能工程师眼中就像原生应用一样易用,而这些工程师既不了解你的芯片,也不想去了解。
尽管如此,芯片仍然是硬件公司的核心产品,利润表将这一点体现得淋漓尽致。软件、文档、工具、社区建设呢?这些都被视为开销。这是约束矩阵的第一个限制:从结构上来说,硬件公司无法将软件生态系统视为一个独立的产品。高管们往往优先优化资本支出、物料清单成本和芯片流片时间。软件虽然也有预算,但总是不够,尤其是随着人工智能软件需求的不断增加。结果就形成了一种以演示为驱动的文化:推出芯片,编写一些内核,运行几个基准测试,再制作一个华丽的主题演讲来证明芯片的浮点运算性能。
结果我们再熟悉不过了:芯片在技术上令人印象深刻,但配套软件却无人问津。软件团队承诺在下一个周期进行改进,可他们上次也是这么说的。这不是个人的失败,而是整个行业围绕芯片而非生态系统构建所导致的激励机制和资源配置的系统性失调。
为什么生成式人工智能软件如此难以开发且成本高昂?
开发生成式人工智能软件不仅困难重重,而且就像在不断移动的山坡上,逆着跑步机跑步一样艰难。与其说这是一个工程挑战,不如说是碎片化、不断演进的研究和严苛期望共同构成的一场 “完美风暴”,而这些都是约束矩阵的组成部分。
碎片化的人工智能研究创新带来的困境
人工智能工作负载并非一成不变,而是一个不断变化的 “动物园”。这周流行 Transformer,下周可能就是扩散模型、混合专家模型(MoEs)或大语言模型智能体。接着又会出现新的量化技巧、更好的优化器,或者某个研究团队坚持要立即实现最高性能的晦涩算子。
大家都知道,硬件创新是实现差异化的关键,但常常被忽视的是,每一项硬件创新都会随着不断变化的应用场景增加软件的开发负担。每一项硬件创新都要求软件工程师深入理解它,同时还要紧跟快速发展的人工智能研究,并知道如何将两者结合起来。
结果就是,你不是在构建一个简单的 “技术栈”,而是在构建一个模型 × 量化格式 × 批量大小 × 推理 / 训练 × 云端 / 边缘 × 本周流行框架的交叉产物。
这种组合的复杂性呈爆炸式增长,这就是为什么除了英伟达,其他公司都难以跟上节奏。最终,生态系统图变得错综复杂,就像下面这样:
兼容性矩阵凸显了 vLLM 的复杂性。资料来源: vLLM
你竞争的对象不只是 CUDA,而是整个行业 真正的问题不只是 CUDA,而是整个人工智能生态系统都在为英伟达的硬件编写软件。每一个框架、学术论文和库都是针对英伟达最新的张量核心进行优化的,每一项优化也都是先在英伟达的硬件上实现。这就是我们在第 3 部分探讨过的恶性循环:CUDA 就像一个软件引力阱,将整个行业的努力都吸引到英伟达的硬件上。
对于其他硬件来说,仅仅实现兼容性是不够的,你必须超越全球为英伟达芯片优化的开源团队。首先,你的硬件要能 “运行” 工作负载,其次,性能还必须优于他们现有的硬件 + 软件组合。
软件团队总是人手不足
无论你有多少软件工程师,面对强大的竞争对手,都远远不够。无论他们多么才华横溢、全力以赴,都难以与之抗衡。他们的收件箱里满是客户的紧急问题、内部的功能需求,以及对基准测试结果的急切请求。他们疲于应对各种突发状况,而没有时间构建预防问题的工具。每一次重大成功都只是让他们更清楚还有多少工作要做。
他们有很多想法,想要投资基础设施建设、构建长期的抽象模型、明确公司的软件理念。但他们无法做到,因为他们无法停下手中当前芯片的相关工作,为下一款芯片做准备。与此同时……
商业部门总是 “追逐大客户”
当有大客户带着资金和特定需求出现时,商业部门往往会欣然接受。这些客户手握话语权,追逐他们在短期内确实有意义。
但这也有高昂的代价:每争取到一个大客户,都会让团队离构建可扩展平台的目标更远。团队没有时间去制定一个可扩展的整体策略,而这种策略可能在未来吸引众多小客户。这样一来,软件团队就被迫像咨询公司一样运作,而不是成为一个产品型公司。
一开始,这种情况可能并不明显,但很快,工程师们就会采用一些临时解决方案、进行代码分叉、部分集成,虽然能让某一项功能变快,但却会破坏其他五项功能。最终,软件栈变成了一个充满技术债务和内部特定知识的 “鬼屋”,难以调试、扩展困难,而且几乎没有文档记录 —— 谁有时间写文档呢?要是理解这些代码的工程师离职了,又该怎么办呢?
在硬件竞赛中取得领先的挑战
这些问题并非个例,而是开发生成式人工智能软件面临的普遍现实。这场竞赛不是短跑,而是一场帆船赛:混乱、不可预测,受外部环境的影响和工程技术一样大。大家都在同一片海域航行,但乘坐的船只却截然不同。
快艇:初创公司追求基准测试结果,而非通用性和易用性
初创公司处于生存模式,他们的目标是证明芯片可用、速度快,并且有人愿意购买。这意味着选择几个基准测试工作负载,想尽办法让它们高效运行,哪怕使用一些技巧或非常规手段。通用性和易用性并不重要,唯一重要的是证明芯片在当下真实可用且具有竞争力。他们不是在构建软件栈,而是在制作商业演示文稿。
定制竞赛游艇:专注单一芯片的公司构建垂直技术栈
大型科技公司(Mag7)和先进的初创公司采取了不同的策略。他们打造定制的 “TPU 竞赛游艇”,通过定制设计在特定竞赛中获胜。这些芯片可能速度很快且设计精良,但往往需要专业的团队、操作手册,甚至专属的模型才能发挥作用。由于这些芯片突破了 GPU 的常规设计,它们必须从头开始构建定制的软件栈。
他们不得不掌控整个技术栈,结果呢?这给人工智能工程师带来了更多的碎片化问题。选择其中一款芯片,可能意味着理论上的浮点运算性能更优且成本更低,但却要牺牲英伟达生态系统带来的发展动力。对这些公司来说,最有前景的策略是锁定几个大客户,比如前沿实验室或对浮点运算性能有需求、又不想支付英伟达 “专利费” 的主权云服务提供商。
远洋班轮:行业巨头受限于传统和规模
然后是行业巨头,如英特尔、AMD、苹果、高通等,这些公司拥有数十年的芯片研发经验和庞大的产品组合,包括 CPU、GPU、NPU,甚至 FPGA,产品出货量达数十亿。但这种规模也带来了问题:软件团队分散在众多代码库和优先事项中,精力分散。他们的客户甚至都搞不清所有的软件和版本,不知从何下手。
一种看似诱人的方法是通过翻译器兼容 CUDA,这样能实现 “兼容性”,但性能却始终无法达到最佳。现代 CUDA 内核是针对英伟达 Hopper 架构的张量核心、张量内存加速器(TMA)和内存层级设计的,将这些内核翻译适配到你的架构上,无法让你的硬件脱颖而出。
遗憾的是,在这种规模下,最好的结果也不过像英特尔的 OneAPI 那样:开放、可移植且由社区管理,但缺乏发展动力和灵魂。OneAPI 在生成式人工智能领域没有获得关注,原因和 OpenCL 一样:它是为上一代 GPU 工作负载设计的,而人工智能发展太快,它根本跟不上。只有与时俱进,开放才有意义。
英伟达:主宰比赛的航空母舰
英伟达就像领航的航空母舰:庞大、协调有序,周围还有补给船、战斗机和卫星通信设备支持。当其他公司还在为一款芯片的软件开发苦苦挣扎时,英伟达已经向任何可能超越它的对手发起了挑战。当其他公司还在为某个基准测试进行优化时,全世界都在为英伟达的产品进行优化,甚至外部环境都仿佛在配合它的发展。
如果你参与这场竞赛,就会受到它的影响。问题不在于你是否在进步,而在于与它的差距是在缩小还是在扩大。
突破困境
在 “实现人工智能计算的民主化” 这个系列文章中,我们已经剖析了行业现状。CUDA 的主导地位并非偶然,它是持续投资、平台控制和市场反馈循环的结果,而这些是其他公司难以复制的。其他公司在替代方案上也投入了大量资金:大型科技公司构建了垂直整合的技术栈,行业巨头推出了开放平台,充满活力的初创公司也尝试了创新方法,但都未能成功打破英伟达的垄断。
但我们现在不再迷茫。我们已经看清了这个约束矩阵:这些因素是如何相互作用的,陷阱在哪里,为什么即使是最优秀的软件团队在硬件公司也难以取得突破。现在的问题不再是我们为什么被困住,而是我们能否突破困境。
小孩:“不要试图折弯勺子,那是不可能的。相反…… 你只需认清一个事实。” 尼奥:“什么事实?” 小孩:“根本没有勺子。然后你就会明白,弯曲的不是勺子,而是你自己。”
如果我们想实现人工智能计算的民主化,就必须有人挑战我们一直以来遵循的固有观念。前进的道路不是渐进式的改进,而是彻底改变游戏规则。
|