1.TVM源语-Compute篇
2.ONNX-Runtime一本通:综述&使用&源码分析(持续更新)
3.极智开发 | 解读英伟达软件生态 一切的基础CUDA
TVM源语-Compute篇
本文探讨TVM源码中的计算相关(primitives)模块,深入讲解如何在非神经网络场景下,如基于张量的密集计算中,通过TVM的原生指令实现算法。通过分解计算与调度,TVM提供了一种灵活高效的毕设源码并行计算框架。本文将首先通过向量相加(Vector Addition)实例,展示如何将算法数学表达式转化为TVM指令,实现输出矩阵的生成。接着,以矩阵乘法(GEMM)为例,说明TVM如何通过三层for循环来处理矩阵操作,并引入te.compute和te.reduce_axis等关键指令。进一步,通过简化卷积实现,解释了如何使用TVM DSL(数据描述语言)来处理多通道输入和输出特征图的卷积操作。最后,文章总结了TVM DSL的使用方式,强调其功能性编程风格,以及lambda表达式和reduce_axis在隐藏for循环细节、天庭战争源码增强算法理解与优化后端性能方面的优势。
在向量相加(Vector Addition)部分,我们定义数组长度n,两个数组A和B,通过lambda表达式将每个元素相加,存储到数组C中。TVM的te.compute指令用于指定输出结果的形状,lambda表达式则对应于循环逻辑,create_schedule构建出计算流程。利用tvm.lower将生成的schedule映射至IR(中间表示)上,展示与常规C代码相似的流程。
矩阵乘法(GEMM)示例中,我们定义了矩阵A、B和C的维度,通过三层for循环实现矩阵乘法和加法。引入te.reduce_axis指令以优化循环结构,展示矩阵乘法运算的关键步骤和优化潜力。进一步,通过简化卷积实现,聊天板源码我们深入探讨了如何处理单通道输入图像和滤波器的卷积运算,解释了补零操作和使用te.compute处理多输入的实现方式。最终,总结了TVM DSL在表达计算逻辑、隐藏低级循环细节、优化算法性能方面的优势,以及其功能性编程风格对理解与优化算法带来的便利。
ONNX-Runtime一本通:综述&使用&源码分析(持续更新)
ONNX-Runtime详解:架构概览、实践与源码解析
ONNX-Runtime作为异构模型运行框架,其核心机制是先对原始ONNX模型进行硬件无关的图优化,之后根据支持的硬件选择相应的算子库,将模型分解为子模型并发在各个平台执行。它提供同步模式的计算支持,暂不包括异步模式。ORT(onnx-runtime缩写)是主要组件,包含了图优化(graph transformer)、执行提供者(EP)等关键模块。
EP是执行提供者,它封装了硬件特有的轨宽源码内存管理和算子库,可能只支持部分ONNX算子,但ORT的CPU默认支持所有。ORT统一定义了tensor,但EP可有自定义,需提供转换接口。每个推理会话的run接口支持多线程,要求kernel的compute函数是并发友好的。
ORT具有后向兼容性,能运行旧版本ONNX模型,并支持跨平台运行,包括Windows、Linux、macOS、iOS和Android。安装和性能优化是实际应用中的重要步骤。
源码分析深入到ORT的核心模块,如框架(内存管理、tensor定义等)、图结构(构建、搜源码网排序与修改)、优化器(包括RewriteRule和GraphTransformer),以及平台相关的功能如线程管理、文件操作等。Session是推理流程的管理核心,构造函数初始化模型和线程池,load负责模型反序列化,initialize则进行图优化和准备工作。
ORT中的执行提供者(EP)包括自定义实现和第三方库支持,如TensorRT、CoreML和SNPE。其中,ORT与CoreML和TensorRT的集成通过在线编译,将ONNX模型传递给这些框架进行计算。ORT通过统一的接口管理元框架之上的算子库,但是否支持异构运算(如SNPE与CPU库的混合)仍有待探讨。
总结来说,ONNX-Runtime处理多种模型格式,包括原始ONNX和优化过的ORT模型,以适应多平台和多设备需求。它通过复杂的架构和优化技术,构建了可扩展且高效的推理软件栈,展示了flatbuffer在性能和体积方面的优势。
附录:深入探讨ORT源码编译过程的细节。
极智开发 | 解读英伟达软件生态 一切的基础CUDA
欢迎关注我的公众号 [极智视界],获取我的更多经验分享
大家好,我是极智视界,本文来介绍一下 解读英伟达软件生态 一切的基础CUDA。
邀您加入我的知识星球「极智视界」,星球内有超多好玩的项目实战源码下载,链接: t.zsxq.com/0aiNxERDq
CUDA,全称为 Compute Unified Device Architecture,是英伟达于 年推出的一个平行计算平台和应用编程接口 API 模型。CUDA 之于英伟达的重要性主要体现在下面几个方面:
所以,解读英伟达软件生态,必须要从 CUDA 说起。虽然 CUDA 再往下还有如 PTX 的指令集加速层级,但是PTX 的普及程度其实并不高,甚至可能很多朋友都没听说过 PTX,其实也算正常,因为基本上的 N 卡开发者,根本没必要接触到 PTX,把 CUDA 学好就足够够的了。
把 CUDA 作为标杆,似乎是很多 AI 芯片厂商 "共同的做法",比较有代表性的是升腾的 Ascend C、寒武纪的 Bang C,但是其实这几个之间有相似但又有不相似的地方。相似的地方在于不管是升腾还是寒武纪都想提供一套类似 CUDA 的可以充分调用自己 NPU 硬件加速的对外接口,提高客制化的灵活性。不相似的地方一方面在于我们是在学人家,很多接口其实是为了贴近 CUDA 的接口而进行的高级封装,毕竟大部分开发者其实已经形成了 CUDA 的开发习惯,这个时候让大家切换起来更加顺手的做法就是 "模仿",而要做这种程度的 "模仿" 势必要协调好硬件架构和软件接口的映射;不相似的另外一方面体现在软件生态的层次清晰度,这个拿升腾来专门说,升腾 Ascend C 的发布时间在 年 5 月 6 日,而反观英伟达 CUDA 的发布时间是 年。什么意思呢,很明显可以看到英伟达的软件生态是以 CUDA 为基础然后层层往上叠的,而升腾是先有了 CANN,先有了 MindSpore 这些 "高层建筑",然后往下才有了 Ascend C,这种软件生态的层次结构就没有那么清晰,当然这种说法也只是基于时间上的,这并不影响它在空间上还是具备不错的软件生态层次结构。
再回到 CUDA 本身,需要清楚的一点是,CUDA 其实一开始主要是面向优化计算密集型计算 (Compute-Bound),因为不管是最开始的通用科学计算还是后来的以 CNN 为主流的深度学习计算都是计算密集型,但是后来 Transformer 又逐渐流行,所以 CUDA 也是不断在 "与时俱进" 在做平衡、做兼顾,比如在 A 开始,CUDA 新增了从 L1 Cache 到 HBM Global Memory 数据直接异步拷贝的指令,其实也是在丰富自身对于访存密集型计算 (Memory-Bound) 的优化。
我之前写过挺多关于 CUDA 的分享,罗列一些,
CUDA 是一种硬件强相关的编程模型,要掌握好 CUDA,需要先看懂 GPU 硬件架构,从而映射到 CUDA 内存模型、线程模型上,这点跟 C 语言、跟 C++ 这类 "高级" 编程语言就很不一样,所以很多朋友会觉得 CUDA C 比较难写,特别是要写出高性能的 CUDA C,比较难。确实,这是事实,特别是对于写出高性能的 CUDA C,会涉及资源的高效调度,比如 Shared Memory、L1 Cache 等的调度;会涉及适应硬件架构超参的配置,比如 Thread、Block、Grid 等的配置。
总之,对于 CUDA 的深入学习,是一门 "稳挣不亏" 的 "买卖",原因不再过多赘述,主要体现在它的重要性上。
好了,以上分享了 解读英伟达软件生态 一切的基础CUDA,希望我的分享能对你的学习有一点帮助。
公众号传送