1.ROCm-RV生态分析
2.pytorch源码学习03 nn.Module 提纲挈领
3.北京大数据竞赛一等奖方案-漆面缺陷检测
4.编程分为哪几种
5.3d稀疏卷积——spconv源码剖析(三)
6.视频和视频帧:Intel GPU(核显)的底层代码编解码故事
ROCm-RV生态分析
ROCm(Radeon Open Compute)是一个开放源代码的软件平台,其核心功能在于支持AMD GPU的源码并行计算与加速计算任务。该平台提供了一系列工具和库,底层代码方便开发者利用AMD GPU性能进行高性能计算、源码深度学习和机器学习等任务。底层代码然而,源码彩票 源码交易ROCm的底层代码成熟度相对CUDA而言有所不足。ROCm主要针对Linux系统,源码而CUDA则广泛兼容包括Windows、底层代码Linux和macOS等操作系统平台。源码
ROCm的底层代码底层结构基于Linux的admgpu Driver,而RV生态的源码基础则是Linux显卡驱动。此驱动包含部分闭源代码,底层代码且目前尚不完全清楚RV生态下的源码开源GPU已达到何种程度。在开始讨论RV硬件生态环境之前,底层代码我们先来看看AMD通过ROCm支持的GPU硬件设备。
AMD的ROCm支持涵盖AMD Instinct、AMD Radeon PRO和AMD Radeon三个GPU系列。国内开发者主要接触到的是AMD Radeon PRO和AMD Radeon两个系列,分别面向专业工作站和消费市场。ROCm未来将淘汰的GPU型号,开发者在RV生态开发时可将其置于次要优先级。
接下来,我们探讨RV生态的移植平台分析。市面上的SG处理器基本满足桌面端与服务端需求,具备单路与双路实现能力。以XTX为例,其需要PCIe 4.0 X通道,SG能够满足这一需求,因此硬件环境符合要求。
至于RV生态中对GPU的支持情况,RISC-V已全面支持旧款GCN架构显卡,并正在支持Navi架构GPU。当前Linux内核版本已更新至V6.9,对于Navi架构GPU的支持可进行验证。同时,老款GCN架构显卡在ROCm中被舍弃,需要特定版本支持特定GPU。
综上所述,RV生态支持ROCm需同时考虑软硬件配合。当前硬件环境基本满足要求,但不如X或ARM平台丰富。对于软件开发者而言,在RV环境下运行ROCm,可能需关注以下几点。
考虑到RV生态的建设任重道远,硬件和软件都需要大量开发才能实现多元化发展。
pytorch源码学习 nn.Module 提纲挈领
深入理解 PyTorch 的 nn.Module:核心概念与底层逻辑 掌握核心思想,探索底层逻辑,分销分红源码网通过解析 PyTorch 的 nn.Module 来构建深度学习模型。此模块是 PyTorch 的基石,封装了一系列函数和操作,构成计算图,是构建神经网络的首选工具。 nn.Module 初始化(__init__) 在定义自定义模块时,__init__ 方法是关键。通过调用 super().setattr 方法,设置 nn.Module 的核心成员变量,如训练状态、参数、缓存等,这决定了模块的主要功能。这些设置包括:控制训练/测试状态
初始化参数集合
初始化缓存集合
设置非持久缓存集
注册前向和反向钩子
初始化子模块集合
理解这些设置对于高效初始化模块至关重要,避免了默认属性设置的冗余和潜在的性能影响。 训练与测试模式(train/val) nn.Module 通过 self.training 属性区分训练和测试模式,影响模块在不同状态下的行为。使用 model.train() 和 model.eval() 设置,可使模块在训练或测试时表现不同,如控制 Batch Normalization 和 Dropout 的行为。 梯度管理 requires_grad_ 和 zero_grad 函数管理梯度,用于训练和微调模型。requires_grad_ 控制参数是否参与梯度计算,zero_grad 清理梯度,释放内存。正确设置这些函数是训练模型的关键。 参数转换与转移 通过调用 nn.Module 提供的函数,如 CPU、type、CUDA 等,可以轻松转换模型参数和缓存到不同数据类型和设备上。这些函数通过 self._apply 实现,确保所有模块和子模块的参数和缓存得到统一处理。 属性增删改查 模块属性管理通过 add_module、register_parameter 和 register_buffer 等方法实现。这些方法不仅设置属性,还管理属性的生命周期和可见性。直接设置属性会触发 nn.Module 的 __setattr__ 方法。 常见属性访问 nn.Module 提供了方便的访问器,如 parameters、buffers、children 和 modules,用于遍历模块中的参数、缓存、子模块等。这些访问器通过迭代器简化了对模块属性的访问。 前向过程与钩子 nn.Module 中的前向过程与钩子管理了模块的执行顺序。forward_pre_hooks、x站源码系统forward_hooks 和 backward_hooks 用于在模块的前向和后向计算阶段触发特定操作,实现如内存管理、中间结果保存等高级功能。 模型加载与保存 模型的保存与加载通过 hook 机制实现,确保在不同版本间兼容。使用 state_dict() 和 load_state_dict() 函数实现模型状态的导出和导入,支持模块及其子模块参数的保存与恢复。 通过深入理解 nn.Module 的设计与实现,可以更高效地构建、优化和管理深度学习模型,实现从概念到应用的无缝过渡。北京大数据竞赛一等奖方案-漆面缺陷检测
传统制造业在检测喷涂颜色件的漆面质量时,大多依赖人工目视检查,这种方法受环境、视觉能力和人员状态等不可控因素影响较大,存在观察难度大、缺陷漏检、质量难以保证和效率低等问题。借助机器视觉技术,如深度学习,实现常见漆面缺陷的自动检测识别,对于提高检测的可靠性、经济性和效率具有重要意义。
除了人工目视和边缘检测算子加机器学习,基于深度学习的机器视觉技术在近年来逐渐受到关注。然而,现有的深度学习缺陷检测方法大多只是将缺陷框出(目标检测),而将缺陷区域像素级别提取出来(语义分割)更贴近实际应用场景需求,同时也更具挑战性。
大赛网址:北京大数据技能大赛
比赛提供了张含有缺陷的图像,要求实现对缺陷的像素级别提取。
像素级缺陷提取存在诸多难点。
3. 方案
3.1 轻量化的MobileUNet+
由于缺陷面积小,样本数量少,如果模型深度太深和参数太多,容易造成过拟合。因此,我们设计了一种全卷积神经网络MobileUNet+来分割漆面瑕疵。Unet总体框架可以更好地融合高层和底层特征,恢复精细边缘。我们使用mobilenetV2作为编码器,利用倒残差结构在控制参数量的同时提高特征提取能力。
3.2 空间通道注意力
为了解决与缺陷相似的非缺陷误区域误检测问题,我们在解码器中嵌入空间通道联合注意力机制scSE,实现对特征的正向校正。
3.3 损失函数
大量的简单背景样本可能会淹没整个交叉熵损失,我们利用OHEM过滤掉交叉熵小于设定阈值的样本点。为进一步缓解正负样本数量不均衡现象,淘宝注册源码下载加入Dice损失。
3.4 数据增强
数据增强可以扩充数据,减轻模型过拟合现象。除了常规的亮度变换、翻转旋转、平移缩放之外,我们开发了一种针对漆面缺陷的K-means约束的copy-paste增强方法。由于漆面一般是曲面,图像中有些区域比较亮,有些区域比较暗,如果直接复制粘贴不同光线分布的缺陷实例,可能会对模型学习产生负面影响。因此,我们首先对图像进行K-means聚类,在复制粘贴时只粘贴到相同光线分布的区域。这样一来,在降低copy-paste可能带来的负面影响的同时,增加正样本的数量和背景多样性。
3.5 随机权重平均SWA
随机权重平均SWA:在优化的末期取k个优化轨迹上的checkpoints,平均他们的权重,得到最终的网络权重,这样会缓解权重震荡问题,获得一个更加平滑的解,相比于传统训练有更泛化的解。我们在训练的最后5轮使用了SWA集成多个模型的权重,得到最终模型结果。
3.6 torch转ONNX
为什么要转ONNX(Open Neural Network Exchange,开放式神经网络交换):直接原因是比赛统一要求;根本原因是ONNX支持大多数框架下模型的转换,便于整合模型,并且还能加速推理,更可以方便地通过TensorRT或者openvino部署得到进一步提速。
3.6.1 安装onnx和onnxruntime
onnxruntime-gpu需要和cuda版本对应,在此处查询。
验证是否可用:
ONNX的providers说明:Pypi上的官方Python包仅支持默认CPU(MLAS)和默认GPU(CUDA)执行提供程序。对于其他执行提供程序(TensorrtExecutionProvider),您需要从源代码构建。请参阅构建说明。Official Python packages on Pypi only support the default CPU (MLAS) and default GPU (CUDA) execution providers. For other execution providers, you need to build from source. Please refer to the build instructions. The recommended instructions build the wheel with debug info in parallel.
3.6.2 模型转换
4. 结果
大赛要求的基准精度为IoU不能小于%,而我们的模型IoU达到了%,增量达到了%。模型精度得分达到了%。更可喜的是,模型的推理速度特别快,单张推理时间为9.1ms,意味着每秒可以处理张图像。除了可以定位检测外,缺陷的面积、长宽等属性也会一并提取出来,phpcms系统源码会中这将为后续处理提供更多实用信息。%的模型精度、FPS的推理速度、加上丰富的缺陷形态信息,我们的方案完全可以满足实际应用场景的需求。
5. 代码开源
6. 答辩视频参考
编程分为哪几种
编程可以分为以下几种:
1. 机器级语言:用于直接控制计算机硬件的底层语言,如汇编语言和机器码。
2. 高级语言:相对于机器级语言,更接近人类自然语言的编程语言,如C、C++、Java、Python等。
3. 脚本语言:一种不需要编译的高级语言,如Python、JavaScript、Perl等,更适合用于快速开发和小规模计算任务。
4. 面向对象编程语言:以对象为基本单位进行编程,通过封装、继承和多态等机制实现代码重用和灵活性,如Java、C++、Python等。
5. 函数式编程语言:将计算视为函数求值的过程,函数是编程的主要组件,强调无副作用和函数的纯粹性,如Haskell、Clojure、Scala等。
6. 并行编程语言:用于开发并行计算的语言,可以同时运行多个任务或处理多个数据,如CUDA、OpenCL等。
7. 领域特定语言(DSL):为特定领域而设计的编程语言,用于解决该领域特定问题,如SQL用于数据库查询、HTML和CSS用于网页设计等。
8. 虚拟机语言:在虚拟机上运行的语言,需要虚拟机将其翻译成机器码执行,如Java、C#等。
9. 编译型语言:需要将源代码编译成机器码才能执行的语言,如C、C++等。
. 解释型语言:不需要编译,通过解释器逐行执行的语言,如Python、JavaScript等。
这只是一些常见的编程分类,实际上编程的分类还有很多其他维度和特性可以进行划分。
3d稀疏卷积——spconv源码剖析(三)
构建Rulebook
下面看ops.get_indice_pairs,位于:spconv/ops.py
构建Rulebook由ops.get_indice_pairs接口完成
get_indice_pairs函数具体实现:
主要就是完成了一些参数的校验和预处理。首先,对于3d普通稀疏卷积,根据输入shape大小,kernel size,stride等参数计算出输出输出shape,子流行稀疏卷积就不必计算了,输出shape和输入shape一样大小
准备好参数之后就进入最核心的get_indice_pairs函数。因为spconv通过torch.ops.load_library加载.so文件注册,所以这里通torch.ops.spconv.get_indice_pairs这种方式来调用该函数。
算子注册:在src/spconv/all.cc文件中通过Pytorch提供的OP Register(算子注册的方式)对底层c++ api进行了注册,可以python接口形式调用c++算子
同C++ extension方式一样,OP Register也是Pytorch提供的一种底层扩展算子注册的方式。注册的算子可以通过 torch.xxx或者 tensor.xxx的方式进行调用,该方式同样与pytorch源码解耦,增加和修改算子不需要重新编译pytorch源码。用该方式注册一个新的算子,流程非常简单:先编写C++相关的算子实现,然后通过pytorch底层的注册接口(torch::RegisterOperators),将该算子注册即可。
构建Rulebook实际通过python接口get_indice_pairs调用src/spconv/spconv_ops.cc文件种的getIndicePairs函数
代码位于:src/spconv/spconv_ops.cc
分析getIndicePairs直接将重心锁定在GPU逻辑部分,并且子流行3d稀疏卷积和正常3d稀疏卷积分开讨论,优先子流行3d稀疏卷积。
代码中最重要的3个变量分别为:indicePairs,indiceNum和gridOut,其建立过程如下:
indicePairs代表了稀疏卷积输入输出的映射规则,即Input Hash Table 和 Output Hash Table。这里分配理论最大的内存,它的shape为{ 2,kernelVolume,numAct},2表示输入和输出两个方向,kernelVolume为卷积核的volume size。例如一个3x3x3的卷积核,其volume size就是(3*3*3)。numAct表示输入有效(active)特征的数量。indiceNum用于保存卷积核每一个位置上的总的计算的次数,indiceNum对应中的count
代码中关于gpu建立rulebook调用create_submconv_indice_pair_cuda函数来完成,下面具体分析下create_submconv_indice_pair_cuda函数
子流线稀疏卷积
子流线稀疏卷积是调用create_submconv_indice_pair_cuda函数来构建rulebook
在create_submconv_indice_pair_cuda大可不必深究以下动态分发机制的运行原理。
直接将重心锁定在核函数:
prepareSubMGridKernel核函数中grid_size和block_size实则都是用的整形变量。其中block_size为tv::cuda::CUDA_NUM_THREADS,在include/tensorview/cuda_utils.h文件中定义,大小为。而grid_size大小通过tv::cuda::getBlocks(numActIn)计算得到,其中numActIn表示有效(active)输入数据的数量。
prepareSubMGridKernel作用:建立输出张量坐标(通过index表示)到输出序号之间的一张哈希表
见:include/spconv/indice.cu.h
这里计算index换了一种模板加递归的写法,看起来比较复杂而已。令:new_indicesIn = indicesIn.data(),可以推导得出index为:
ArrayIndexRowMajor位于include/tensorview/tensorview.h,其递归调用写法如下:
接着看核函数getSubMIndicePairsKernel3:
位于:include/spconv/indice.cu.h
看:
上述写法类似我们函数中常见的循环的写法,具体可以查看include/tensorview/kernel_utils.h
NumILP按默认值等于1的话,其stride也是gridDim.x*blockDim.x。索引最大值要小于该线程块的线程上限索引blockDim.x * gridDim.x,功能与下面代码类似:
参考: blog.csdn.net/ChuiGeDaQ...
视频和视频帧:Intel GPU(核显)的编解码故事
一般提及基于“显卡或多媒体处理芯片对视频进行解码”为硬解码,本文将探讨如何利用Intel的核显,即集成GPU实现硬解码。提及QSV,全称为Quick Sync Video,Intel在年发布Sandy Bridge CPU时,一同推出了这项基于核显进行多媒体处理,包括视频编解码的技术。集成核显,官方称HD Graphics,最早在Sandy Bridge前一代制程已推出,但性能提升及充分发挥在Sandy Bridge时期。Haswell及后续制程发布更高级的Iris架构。最近Intel宣布将开发独立显卡,核显发展具体走向未知。
接手QSV项目时,预期会有很多相关资料,实则相反。因此,将记录自己学习过程。
本文将介绍:
I. Intel的核显(集成GPU):
了解核显很有必要,几个月前,作者对CPU的认识还停留在“南北桥”架构。以下内容若有不准确之处,欢迎指正。
查看Gen CPU结构图,首先看CPU核心部分。在整块CPU芯片中,核显占比不小,算力不容小觑。在没有独立显卡的笔记本上,可以运行大量大型游戏,虽偶有卡顿、掉帧情况,整体表现已相对不错。
接下来,看官方给出的GPU内部结构图。GPU内部远比图上所示复杂,图中介绍的仅为部分Subslice芯片结构。GPU分为Slice部分和Un-Slice部分,Slice部分已介绍,接下来介绍Un-Slice部分。
作者找到了一张图,展示了在MFF上进行视频处理的流程:1) 首先在MFX/VDBOX模块上进行编解码;2) 接着送到VQE/VEBOX上做图像增强和矫正处理;3) 然后送到SFC上做scale和transcode;4) 最后送出到显示屏上展示。是否完全正确,作者这里做个记录。
推荐知乎文章《转》Intel Gen8/Gen9核芯显卡微架构详细剖析,深入浅出,关于thread dispatch的说明即出自该文。
最后,总结Intel集成GPU/核显结构图。
注意,这是skylake架构下的GT2/GT3/GT4 GPU结构图,X数字越大,集成的Slice和Unslice芯片更多,能力越强,价格也更高。
II. Quick Sync Video(QSV)技术:
QSV是Intel推出的将视频处理任务直接送到GPU上进行专门负责视频处理的硬件模块处理的软件技术。与CPU或通用GPU上的视频编码不同,QSV是处理器芯片上的专用硬件核心,这使得视频处理更为高效。
要了解QSV如何驱动GPU的MFF,首先看官方Intel® Video and Audio for Linux上的图。在介绍QSV之前,提及Intel在FFmpeg上提供的插件,包括ffmpeg-qsv、ffmpeg-vaapi和ffmpeg-ocl。详细描述如下:
· FFmpeg-vaapi提供基于低级VAAPI接口的硬件加速,在VA API标准下在Intel GPU上执行高性能视频编解码器、视频处理和转码功能。
· FFmpeg-qsv提供基于Intel GPU的硬件加速,基于Intel Media SDK提供高性能视频编解码器、视频处理和转码功能。
· FFmpeg-ocl提供基于工业标准OpenCL在CPU/GPU上的硬件加速,主要用于加速视频处理过滤器。
接下来,介绍QSV在ffmpeg2.8及以上版本的支持,经过MSDK、LibVA、UMD和LibDRM。分层进行分析:
· MSDK:Intel的媒体开发库,支持多种图形平台,实现通用功能,可用于数字视频的预处理、编解码和不同编码格式的转换。源码地址为Intel® Media SDK,在Linux平台上编译使用。
· VA-API:Video Acceleration API,提供类unix平台的视频硬件加速开源库和标准。Intel源码地址在Intel-vaapi-driver Project,在Linux平台上使用。
· UMD:User Mode Driver的缩写,指VA-API Driver。Intel提供了两个工具:intel-vaapi-driver 和 intel-media-driver,推荐使用后者。
· LibDRM:Direct Rendering Manager,解决多个程序协同使用Video Card资源问题,提供一组API访问GPU。与VA-API,LibDRM是一套通用的Linux/Unix解决方案。
· Linux Kernel:Intel的Kernel是i driver,描述了libDRM和Kernel Driver之间的关系。
至此,整个关系图较为清晰。
III. FFMPEG+QSV解码:
QSV硬解的任务主要包括:
关于3-4步操作的详细实现,底层库会帮助完成。但作为一个优秀的工程师,研究FFMPEG源码依然十分重要。接下来,介绍如何使用FFmpeg API中的h_qsv解码器插件。
提及FFmpeg命令行使用方法,推荐阅读官方资料《QuickSync》或《Intel_FFmpeg_plugins》。
关于示例代码,作者曾遇到许多坑,总结为:多数中文博客不可靠,官方demo最可信。官方代码提供了两份可用:qsvdec.c和hw_decode.c。作者最早使用的是第一段代码,核心部分如下:
然而,这段代码存在问题。测试发现,对于赛扬系列一款CPU,在p视频上MSDK达到fps,理论上h_qsv平台上限也应为fps,但实际测试不到fps。排查后发现是av_hwframe_transfer_data()性能较弱。
最终,与Intel一起解决了性能问题。那么,性能提升方案为何是GPU-COPY技术做Memory-Mapping?
解释GPU和CPU渲染图像的过程,包括坐标系转化、纹理叠加等,仅需了解两点:
后者的数据组织方式能充分利用GPU的并行特性,加速图像处理、渲染。尽管存在一些纹理叠加的技术难题,但性能提升足以补偿。
接下来,解释Memory-Mapping:从Intel CPU架构图中可见,GPU和CPU位于同一芯片上,各自寄存器/缓存区有限,视频数据主要存储在内存上。GPU和CPU的数据组织方式不同,同一帧数据存于内存同一位置,数据格式不同,因此需要做Memory-Mapping。Memory-Mapping相较于Memory-Copy,减少了数据从内存区域A移动到区域B的操作,已经是优化。进一步优化:GPU完成Memory-Mapping以及数据从GPU到内存和CPU的操作。
在av_hwframe_transfer_data()内部,Memory-Mapping由CPU完成,性能受限于CPU,只能并行。修改后,整体性能从不到fps提升至fps,虽然与理想fps仍有差距,但满足性能需求。
据悉,Intel将在FFmpeg 4.3开源出这个解决方案。
写在后面:
了解GPU底层对应用开发人员帮助不大,毕竟了解芯片布线的重新设计、制程工艺提升、GPU-COPY技术的数据I/O提升等,也不能做什么。最终,芯片架构是芯片工程师的事,底层逻辑实现是嵌入式工程师的事。应用开发人员无法做出实质贡献,但作为知识库扩充或休闲阅读,了解也无妨。
希望有机会接触CUDA的编解码,深入学习N卡设计。
感谢因《视频和帧》系列文章结识的朋友,热心指出文章描述不准确的地方。文中如有不严谨之处,欢迎指正。