尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

Elliot CUDA 编程笔记(二)

Elliot CUDA 编程笔记(二) 反向传播线性层梯度deflinear_backward(dout,x,w):dwnp.dot(x.T,dout)dbnp.sum(dout,axis0,keepdimsTrue)dxnp.dot(dout,w.T)returndx,dw,db通过实现这些函数并组合成训练循环我们可以用纯NumPy复现PyTorch的训练过程准确率同样能达到约90%。移植到C语言 ⚙️上一节我们在NumPy中理解了所有操作本节中我们将其移植到C语言为后续的CUDA加速做准备。C语言实现需要手动管理内存和循环。以下是核心数据结构和函数定义神经网络结构体typedefstruct{float*weights1;float*bias1;float*weights2;float*bias2;float*grad_weights1;float*grad_bias1;float*grad_weights2;float*grad_bias2;intinput_size;inthidden_size;intoutput_size;}NeuralNetwork;矩阵乘法函数voidmatmul(float*a,float*b,float*c,intm,intn,intk){for(inti0;im;i){for(intj0;jn;j){floatsum0.0f;for(intp0;pk;p){suma[i*kp]*b[p*nj];}c[i*nj]sum;}}}前向传播函数voidforward(NeuralNetwork*net,float*input,float*hidden,float*output,intbatch_size){// 第一层: input - hiddenmatmul(input,net-weights1,hidden,batch_size,net-hidden_size,net-input_size);add_bias(hidden,net-bias1,batch_size,net-hidden_size);relu_forward(hidden,batch_size*net-hidden_size);// 第二层: hidden - outputmatmul(hidden,net-weights2,output,batch_size,net-output_size,net-hidden_size);add_bias(output,net-bias2,batch_size,net-output_size);softmax(output,batch_size,net-output_size);}反向传播和参数更新反向传播需要计算每一层的梯度并按照链式法则传递。参数更新则遵循梯度下降公式weight weight - learning_rate * gradient。通过完整的C语言实现我们可以在CPU上运行MNIST训练虽然速度较慢但为理解CUDA并行化打下了坚实基础。使用CUDA加速 ⚡上一节我们完成了CPU上的C语言实现本节中我们利用CUDA将其加速。CUDA实现的核心是将计算密集的操作如矩阵乘法移植到GPU上并行执行。我们主要修改以下部分设备内存管理使用cudaMalloc和cudaMemcpy在主机和设备间传输数据。核函数编写为矩阵乘法、ReLU、Softmax等操作编写并行核函数。启动配置合理设置线程块和网格大小以最大化GPU利用率。一个简单的矩阵乘法核函数示例__global__voidmatmul_kernel(float*a,float*b,float*c,intm,intn,intk){introwblockIdx.y*blockDim.ythreadIdx.y;intcolblockIdx.x*blockDim.xthreadIdx.x;if(rowmcoln){floatsum0.0f;for(inti0;ik;i){suma[row*ki]*b[i*ncol];}c[row*ncol]sum;}}主机端调用// 设置启动配置dim3blockDim(16,16);dim3gridDim((nblockDim.x-1)/blockDim.x,(mblockDim.y-1)/blockDim.y);// 启动核函数matmul_kernelgridDim,blockDim(d_a,d_b,d_c,m,n,k);通过将前向传播、反向传播和参数更新中的所有关键操作都实现为CUDA核函数我们可以显著提升训练速度。在相同的超参数下CUDA版本可以在更短的时间内达到与CPU版本相近的准确率约90%。总结 本节课中我们一起学习了如何从零开始实现并训练一个MNIST多层感知机。我们首先使用PyTorch快速搭建了模型理解了高级API的便捷性。然后我们深入NumPy从零实现前向传播、损失计算、反向传播和梯度下降揭示了神经网络训练的核心原理。接着我们将算法移植到C语言处理了内存管理和循环优化为性能提升做准备。最后我们利用CUDA进行并行加速将计算密集型任务分配给GPU实现了显著的性能提升。https://github.com/OpenDocCN/dsai-notes-pt1-zh/raw/master/docs/elliot-cuda-prog/img/ae3ba39c4a447415d3fed36690a00a69_11.png通过这个完整的项目我们不仅掌握了MNIST分类任务更深入理解了从高级框架到底层硬件加速的完整深度学习流水线。你可以在此基础上尝试优化CUDA核函数、调整网络结构或探索其他数据集。12下一步方向 https://github.com/OpenDocCN/dsai-notes-pt1-zh/raw/master/docs/elliot-cuda-prog/img/a4063da9cdbb2b488ffb61a88b4b82bf_0.png在本节课中我们将总结整个课程并为希望继续深入学习的你指明方向。我们将介绍一些高级优化概念、推荐学习资源以及活跃的社区帮助你进一步提升CUDA和GPU编程技能。如果你已经坚持学到这里请给自己一些鼓励。这基本上就是本课程的终点了。你做到了做得很好。我们接下来将快速浏览一些提示为你指明继续深入的方向。你可能很难完全掌握所有内容这完全可以理解。但如果你希望继续这里有一些额外的资源可以支持你。在课程的README文件中有一个关于统一内存和内存架构的章节我认为这很有用你可能会感兴趣。但此刻我想主要介绍的是“深入探索”部分。如果你想更进一步真正了解如何在CUDA和GPU编程尤其是在深度学习领域应用深度优化和先进技术你可以这样做。以下是几个关键方向量化技术量化是指从高精度数据类型如FP32转换到低精度数据类型如FP16或INT8的过程。即使从FP32降到INT8模型仍能保持相当好的性能和精度质量。实现这一点有一些特定的技巧。很多技巧与数值范围有关。例如如果你的数值范围被限制在-10到10之间你就不必担心很多指数值的问题。如果权重初始化稳定且训练过程中数值不会超出这个范围你可以直接将其作为精度上限这将是它能达到的最大值。量化本质上就是这种将高精度数字转换为低精度数字的艺术然后利用这些低精度数字进行非常快速的操作。INT8运算比FP32快得多不仅仅是四倍。我们在比较kblas与kblas_lt的32位与16位性能时已经看到了显著的提升。你可以想象INT8会更快因为它只涉及整数运算无需担心浮点数或小数点。量化技术很酷被广泛应用于当前模型中例如GPT-4或Llama 4/5B。很多模型实际上都使用了量化很可能是BF16、FP8甚至Float4。这很酷。张量核心https://github.com/OpenDocCN/dsai-notes-pt1-zh/raw/master/docs/elliot-cuda-prog/img/a4063da9cdbb2b488ffb61a88b4b82bf_2.png张量核心非常棒。我虽然已经提到过但不能不提。我之所以没有在本课程中详细覆盖是因为这更像是一个入门课程。我试图在有限的课时内塞入尽可能多的内容以便你能消化。如果你想继续深入张量核心显然是下一步。稀疏性稀疏性是一个很酷的概念。你可以这样理解稀疏性假设我有一个数组它可能像这样[0, 0, 0, 0, -7, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0]。这就是稀疏的含义存在大量零值偶尔出现一些代表重要信息的大数值。这里的核心思想是你可以用更少的内存来存储这些数据。这更多是关于内存和计算性能的优化而不仅仅是质量提升。我们可以使用两个矩阵一个存储非零值如[-7, 6]另一个存储这些值对应的坐标如[4, 11]。这样我们只需要存储4个整数而不是原来的16个整数大大减少了存储需求。https://github.com/OpenDocCN/dsai-notes-pt1-zh/raw/master/docs/elliot-cuda-prog/img/a4063da9cdbb2b488ffb61a88b4b82bf_4.png想象一下当你扩展到2D或3D结构时你将节省数个数量级的内存这可以非常高效。因此在设计高性能神经网络时需要考虑是否能利用稀疏性。如果外部编写神经网络架构的人例如使用PyTorch时鼓励稀疏性并且模型在这方面运行良好那么这对你来说就非常有利会让你的工作更轻松。稀疏性是一种性能优化技巧有机会就应该采用。推荐资源与项目上一节我们介绍了一些高级优化概念本节中我们来看看一些具体的学习资源和实践项目它们能帮助你巩固知识并探索更广阔的领域。以下是几个值得探索的资源《CUDA by Example》这是一本通用GPU编程入门书籍。我通过谷歌搜索找到了它它就像一个电子书网站。里面包含了很多内容例如GPU计算的崛起、CUDA架构等。本课程压缩了其中的许多重要部分但显然不是全部。我本人没有读过这本300页的书但你会发现书中的很多内容都被浓缩到了本课程中。分布式训练文章这是Anthropic公司的Simon撰写的一篇关于深度学习模型数据并行分布式训练的文章。在我们之前讨论如何让大型算法在多个实例上训练的章节中这是一个很好的例子。分布式训练目前是一个大问题涉及将数据中心整合到一个紧凑的空间。这方面有相关研究致力于减少分布式方面的开销。当你拥有一个包含大量模型的大型数据中心并且需要让许多GPU或者说让模型以特定方式相互通信时这很困难。这篇文章深入探讨了这一点。我不会通读全文但它确实涉及更多性能优化例如用于实际优化过程的all-reduce操作。这里有很多需要考虑的因素但我甚至没有集群来训练这个所以我无法真正教授这部分内容。MNIST CUDA项目这是一个很酷的小项目名为mnist-cuda它使用CUDA和cuDNN在MNIST数据集上进行训练。我相信它使用了卷积神经网络。如果你在Windows上这可能更容易上手。例如你可以查看网络部分的C文件。我不会深入挖掘这个项目但它是我在GitHub搜索mnist-cuda时发现的一个很酷的小项目你可以随意使用它。Micrograd CUDA这与micrograd或micropathy非常相似。这是我之前提到过的东西你应该重点复习或理解反向传播等机制是如何工作的。它本质上就像一个非常微型的PyTorch Autograd。如果我们查看它的文件里面有一个引擎。例如有用于数值操作的类当你使用双星号**进行幂运算时它会调用__pow__方法加法操作会调用__add__方法。在引擎之外还有实际的神经网络Python代码它抽象了从神经元到层的过程。例如一个具有一组权重的单一神经元接收所有不同的X值进行点积运算然后输出一个值。这就是一个神经元。然后有一个层它包含一堆神经元。接着是多层感知机即多个这样的层堆叠在一起。而micrograd-cuda就是将其用CUDA实现。肯定有人这么做所以你可以随意探索并从中获得乐趣。它应该更快可以帮助你在计算统一设备架构的层面上理解事物。它包含了所有CUDA操作例如移动到GPU的malloc和memcpy。你可以想象PyTorch与此类似可能性能更优。你肯定不希望每次移动数据或使用数据时都进行原生的malloc、memcpy或编写朴素的内核。总之这是一个很酷的项目。https://github.com/OpenDocCN/dsai-notes-pt1-zh/raw/master/docs/elliot-cuda-prog/img/a4063da9cdbb2b488ffb61a88b4b82bf_6.pnghttps://github.com/OpenDocCN/dsai-notes-pt1-zh/raw/master/docs/elliot-cuda-prog/img/a4063da9cdbb2b488ffb61a88b4b82bf_8.pngGPU Puzzles这是我发现的另一个有趣的项目排名第二。你可以使用cupy库。CuPy是一个开源的使用Python进行GPU加速计算的库本质上就是CUDA但你可以通过Python接口使用它这非常棒。它的GitHub页面上有很多很酷的东西。你只需要导入它然后就可以创建形状并进行操作类似于PyTorch或NumPy。这些GPU谜题就像解决逻辑问题我们之前用内核解决问题但这里提供了很多不同的例子。除了矩阵乘法里面还有很多其他内容你可能会觉得练习起来很有趣。CUDA Mode 社区最后我决定压轴介绍的是cuda-mode。他们有自己的GitHub、YouTube频道和Discord服务器。这里包含的很多材料都超出了我的课程范围。我的课程更偏向视频辅助但cuda-mode背后的社区非常棒。这里有真正优秀的工程师和研究人员不断构建酷炫的东西社区成员也非常活跃。这是一个绝佳的地方我绝对推荐你去看看。他们有很多章节例如Flash Attention、Cutlass、Triton、BEED Kernels、数据处理、张量核心等等。我推荐你加入他们的Discord服务器你可以在这里找到。里面有很多很酷的小组例如#beginners频道。超级活跃比如今天的最后一条消息甚至是几小时前发布的而这只是一个频道。往下翻最后一条消息可能就在一小时前。本节课中我们一起学习了CUDA编程课程的总结与进阶方向。我们回顾了量化、张量核心和稀疏性等高级优化概念并介绍了《CUDA by Example》、分布式训练文章、MNIST CUDA、Micrograd CUDA、GPU Puzzles以及活跃的CUDA Mode社区等宝贵的学习资源和实践项目。希望这些内容能为你继续探索高性能GPU计算世界提供坚实的基础和明确的方向。13课程结束与后续资源 在本节课中我们将回顾整个CUDA编程课程并了解如何获取更多学习资源、加入社区以及联系课程讲师。课程概述在之前的课程中我们系统性地学习了CUDA编程的核心概念从GPU并行计算的基础到高性能计算的实践技巧。本节是课程的结尾部分主要介绍课程结束后的学习路径和资源获取方式。后续学习与社区如果您喜欢本课程可以在其他多个平台找到讲师和相关资源。以下是主要的联系平台和社区YouTube可以找到讲师的频道观看更多相关视频内容。X/Twitter可以在X原Twitter上关注讲师获取最新动态。Discord讲师拥有一个Discord服务器里面聚集了许多志同道合的人。这个社区不仅讨论CUDA也广泛涉及其他学习主题鼓励协作与交流。LinkedIn可以在LinkedIn上联系讲师。资源获取方式上述所有平台的链接通常会在视频描述中提供。如果描述中没有也可以在下方描述中提到的GitHub代码仓库里找到相关链接。课程总结本节课中我们一起学习了在CUDA编程课程结束后如何继续深入学习。我们了解了可以通过YouTube、X/Twitter、Discord和LinkedIn等多个平台联系讲师并加入学习社区同时明确了相关资源的获取途径。希望本课程为您的高性能计算之旅奠定了坚实的基础。
返回列表