• [资产园地] 人脸检测-RetinaFace 支持Pytorch, GPU训练, 支持CPU,GPU推理
    描述RetinaFace(人脸检测/Pytorch)注:本算法支持多卡训练、单卡混合精度训练,但在多卡情况下不支持混合精度1. 概述此模型基于RetinaFace: Single-stage Dense Face Localisation in the Wild中提出的模型结构实现,该算法会载入在WiderFace 上的预训练模型,在用户数据集上做迁移学习。我们提供了训练代码和可用于训练的模型,用于实际场景的微调训练。训练后生成的模型可直接在ModelArts平台部署成在线服务。人脸检测的评估手段一般使用mAP指标,详细说明请参考:https://github.com/Cartucho/mAP本算法的其他信息如下表所示:项目说明参考论文RetinaFace: Single-stage Dense Face Localisation in the Wild使用框架Pytorch-1.4.0训练集WIDERFACE 中的 WIDER_train训练总epoch数100训练batch_size使用混合精度单卡训练,batch_size=16训练硬件及耗时单卡v100,O1混合精度,训练大约31小时测试集WIDERFACE 中的WIDER_val推理硬件及速度CPU 10.3s/pic ,GPU2080ti 0.5s/pic–1.5s/pic ,modelarts平台V100 GPU:3226张图片总共耗时24分钟(target_size = 1600,max_size = 2150)输入图像尺寸训练:1024*1024 推理:target_size = 1600,max_size = 2150(保证图片等比例缩放,使用最小一条边缩放到target_size的缩放比例;如果此时最大边超过了max_size,则使用最大边缩放到max_size的缩放比例)原论文准确率RetinaFace-R50 Easy 96.5, Medium 95.6, Hard 90.4本算法准确率RetinaFace-R50 Easy 95.52, Medium 94.43, Hard 90.062、训练2.1. 算法基本信息任务类型:人脸检测支持的框架引擎:PyTorch-1.4.0-python3.6算法输入:存储在OBS上的数据集,必须按照WIDERFACE 数据集的格式进行存储,详情请查看下文第4节案例指导WIDERFACE 预训练模型,在WIDERFACE 上的mAP是 Easy 95.52, Medium 94.43, Hard 90.06算法输出:用于Pytorch推理的pth模型,CPU推理速度:10.3s/pic GPU2080ti推理速度:0.5s/pic–1.5s/pic ,modelarts平台V100 GPU:3226张图片总共耗时24分钟(target_size = 1600,max_size = 2150)2.2. 训练参数说明名称默认值类型是否必填是否可修改描述data_urldata/WIDERFACE/WIDER_trainstring是是训练或者评估输入的数据集 (如果使用文件夹形式的数据,则填写该文件夹在OBS上的访问路径;如果使用zip压缩包形式的数据,则填写该压缩包的父目录在OBS上的访问路径)train_urloutput/string是是训练或者评估结果输出路径data_formatzipstring否是可选值zip(上传数据为zip压缩包)或者dir(上传数据为目录形式),压缩包和目录的具体格式请查看下面《ModelArts AI市场算法RetinaFace使用指导》所附连接networkresnet50string否是模型的backbone网络,可选值 mobile0.25 、resnet50 或者resnet152num_workers1int否是数据加载的worker数量lr0.001string否是训练的初始学习率momentum0.9string否是优化器的动量系数load_weightweight/best_model.pthstring否是可加载的预训练模型,当eval=True时,该参数为必填项 ;默认值是以resnet50为backbone在WiderFace数据集上的预训练模型,该预训练模型已经包含在本算法中weight_decay0.0005string否是优化器中的正则化权重衰减量gamma0.1string否是分段衰减学习率中每次学习率衰减的比例(new_lr=lr*gamma),仅当use_cosine_decay=False该参数有效img_size1024int否是训练数据的分辨率confidence_threshold0.02string否是nms时的置信度阈值nms_threshold0.4string否是nms时的IOU阈值num_gpu1int否是当num_gpu=1时,使用单个GPU训练;当num_gpu>1时,使用机器上所有的GPU进行训练batch_size16int否是训练时的batch_size,可根据GPU的显存进行调整epoch100int否是训练的epoch数量use_backboneTruestring否是训练时是否使用backbone网络在ImageNet数据集上的预训练参数use_mixedTruestring否是是否使用混合精度进行训练,使用混合精度一定程度上可以降低显存消耗,也可能提高训练速度amp_levelO1string否是混合精度的设置,可选值:O0,O1,O2,O3warmup_epoch10int否是训练开始时,使用warmup学习率的epoch数量,warmup_epoch=-1表示不使用warmupdecay150int否是分段衰减学习率的第一次学习率降低的epoch数,仅当use_cosine_decay=False时有效decay280int否是分段衰减学习率的第二次学习率降低的epoch数,仅当use_cosine_decay=False时有效use_cosine_decayTruestring否是是否使用余弦衰减学习率,设置为False则使用分段衰减学习率optimizersgdstring否是sgd 或者 adam优化器evalFalsestring否是eval=True,则进行评估;eval=False进行训练2.3. 训练输出文件训练完成后的输出文件如下:|- RetinaFace_Resnet50_Final.pth |- deploy_scripts |- model |- data |- layers |- models |- retinaface_utils |- config.json |- customize_service.py |- save_model.pth3. GPU/CPU推理元模型来源 选择 保存在OBS上的对应路径下的deploy_scripts文件夹。注意:推理配置文件model/config.json中的runtime字段为pytorch1.4-python3.6,表示该模型可同时在CPU或GPU运行。4. 案例指导本算法的详细使用方法,请查看《ModelArts AI Gallery算法RetinaFace使用指导》。交付交付方式华为云ModelArts交付区域华北-北京一、华北-北京四、华东-上海一、华南-广州、亚太-**
  • [技术干货] AIOT时代的编程语言、编译器与指令集架构:机遇、挑战与技术分享
    本次分享来自遇见未来系列讲座——与曾建江老师探讨AIOT时代的编程语言、编译器与指令集架构:机遇、挑战与展望。编译器、编程语言以及指令集架构都是一个软件生态的根基,此次给大家介绍软件生态根基上的语言编译器以及指令集架构,有哪些机遇挑战以及一些最新的技术课题。B站视频:https://www.bilibili.com/video/BV17C4y1a74c一 趋势与挑战(一) 处理器发展趋势软件都是在处理器上执行的,首先我们看下处理器的发展。下图[1]统计了从70年代中期开始到2018年,执行软件的微处理器的发展趋势。它从几个维度统计了这些处理器的发展:微处理器发展趋势(1970-2020)1. 晶体管的数量(橙色所示):依据40多年前提出的摩尔定律,晶体管数量一直在提升。此外2018年业界发布了一个很有意思的芯片——Cerebras的芯片,该芯片晶体管数量远远超出这个趋势图里面的范畴,是一个非常惊人的数字:1.2万亿个晶体管(当然这不是商用上非常经济的设计)。但是可以看到在用来运行软件的处理器中,所包含晶体管的数量还是持续追随着摩尔定律在增长。2. 单线程(单核)的性能(蓝色所示):这里的单核性能指的是当前单核能够提供的整数计算性能。从40年前开始,性能几乎还是能够沿着摩尔定律的发展而持续地提升。但是从21世纪特别是21世纪10年代开始,单核性能的发展几乎停滞了,或者说是发展缓慢。发展缓慢意味着用来运行软件的单个处理器的性能提升,从10年前开始就是非常有限的。3. 频率(绿色所示):频率的趋势更加平缓,从2000年开始,就没有跟随摩尔定律,这里有工艺限制的因素,很大原因是物理实现上的限制。频率的走缓几乎是更早于性能的走缓。这里蓝色性能和绿色频率的差别意味着芯片开发者或者架构开发者做出了非常大的努力,让处理器在频率不增长的情况下,能够持续地为软件性能提升提供贡献,这是非常不容易的一件事情。4. 处理器的功耗(红色所示):几乎从2000年开始,处理器功耗就不再大规模增长了。这里有个非常重要的原因是芯片的物理分装有相应的物理限制,从单位的物理分装里能够散发出来的热量是有限的。据统计,按照能量密度来算,处理器上运行软件所耗费的能量,能量密度已经超过了核反应堆。这是一个非常惊人的情况,所以从功耗上来说,微处理器能够耗散的功耗,已经达到了目前工艺或者说现在生产的极限。明显从很早开始,电池以及功耗就开始限制我们微处理器的发展。5. 处理器核数(黑色所示):处理器核数的增长从05年左右开始,跟随着摩尔定律中晶体管数量的逐步增长,单个芯片上所集成的处理器核数变得越来越多,几乎是和晶体管数量同步的发展趋势,意味着未来所使用的芯片里集成的核会更多。那这些核是不是都在做一个有意义的事情?下面我们来看下这些核本身的形态是怎样发展的。有个论断[2]是通用计算的时代结束了,回顾我们刚才讲的趋势,从2000年初开始,性能提升已经开始逐步走缓。如何获取更多的性能,这里有一个非常重要的趋势,就是处理器在变得越来越专用,专用是指如何进行处理器的定制化以及专用化的设计,通过对计算本身并行的特征,以及它的访存内存使用的特征,来发掘计算的模式里是否有利用定制化的硬件,来提升特定模式计算的性能,或者是降低所使用的功耗的手段,这种叫做定制化。最典型的例子是现在非常热的AI处理器,比如现在华为手机里集成的达芬奇 AI芯片,就是定制化的设计。为了让应用跑得更快,现在采取了更多的手段。如下图所示,蓝色这块区域就是用定制化的设计来提升应用的性能,降低完成计算所需要的功耗。(二) 指令集架构的演进实现定制化,这里又回到处理器,用来实现软件或者运行软件非常重要的软件和硬件的接口,叫做指令集。如下图所示,这是一个比较传统的指令集的分类。指令集从60年代的复杂指令集(Complex Instruction Set Computer, CISC)开始发展,到70年代有了精简指令集(reduced instruction set computer, RISC)的分类。一直到80年代开始,业界开始探索一种称为超长指令集(Very Long Instruction Word,VLIW)的指令级并行架构。90年代时还有非常多不同种类的指令集存在。指令集架构的演进但随着时间的演变,到今天为止,市面上现在主流用到的指令集已经不多了,非常多指令集已停止发展。留在市面上的还有一些特定领域的大型机的指令集。通用指令集领域的话,有Intel X86指令集、IBM power指令集和SPARC指令集。但是手机上主要是用ARM 指令集,还有最近比较热的RISC-V 指令集,可数的就这几种。指令集在处理器发展上所起到的最重要的作用,就是让软件和硬件实现他们的界面以及交互。现存的通用指令集有这样的趋势:这些不同的指令集,会相互借鉴、相互汲取各自设计上的优点。举个例子,Intel X86指令集,虽然是一个复杂指令集的设计,但是一些具体指令汲取了很多RISC的设计概念,包括它内部的实现,借用了一些 RISC指令集的设计理念;IBM Power指令集,照说它应该是一个精简指令集的架构,但随着 Power指令集的逐步发展,内部也引入了指令组合的概念。指令组合从逻辑上来看,其设计思想与超长指令集VLIW有些接近,思路上是相通的。一直到今天为止,现在市面上能够用到的指令集,虽然还是各自有多样化,但是种类已经减少了,此外它的设计也不再严格区分复杂指令集、精简指令集以及超长指令集,有相互借鉴发展的趋势。(三) 处理器架构与编译技术的演进为了让软件能够变成用指令集描述的指令序列,编译器在此过程中起到了非常关键的作用。随着架构的发展,我们来看下编译器和架构是怎样的演进路径。处理器架构与编译技术的演进2000年以前,大部分处理器都是单核的,所以当时单核优化是编译器以及编译技术的重点。面向不同的指令集,编译技术也在不停演进及发展,比如说循环优化、指针分析、数据重组,面向单核的编译优化等是在该时期发展的。可以看到,编译器本身的优化,是和处理器的实现紧密相关的。随着多核处理器的发展(如果大家还记得前面多核处理器的发展趋势是从2000年到2010年中开始的),编译优化逐渐转向了多核优化的方向。多核处理器中,芯片的性价比(performance/dollar)是一个非常重要的衡量指标。也就是说当单核性能提升到了一定程度时,不得不通过多核来提升整个芯片的性能,然后让软件通过多核架构来获取更进一步的性能提升。到10年代中期,多核的优化又变成了重点。随着技术的持续发展,2010年以后性能提升逐步走向异构的优化(或者叫做超异构的优化)。和多核不同,异构的多核就是处理器的形态从通用的CPU转向了GPU以及现在的AI芯片这样专用的设计。前面也提到了一个趋势是说通用计算的时代已经结束了,现在已经处于异构计算(或者定制化计算)的时代。在这个时代,处理器的形态非常多:DSP、GPU、AI, 甚至于FPGA,像这样不同种类的核在一个系统里协同工作,对整个系统开发或者系统的架构也产生了非常大的挑战。(四) 超异构时代软件开发趋势对于编译优化,问题是这么多不同指令的软件,如何在一个系统里进行协作,让它们能够把整个系统的晶体管利用起来,来做有意义的(或者说是有效的)计算。进一步来看,在现在的异构以及超异构架构时代(或者说是后摩尔时代)整个芯片架构走向异构,快速演进的芯片和高复杂度的应用,对软件开发效率以及兼容性提出了前所未有的挑战。业界提到现在是软件灾难(software disaster)的时代:因为有这么多核,怎样让一份软件能够在不同芯片上运行起来。David Patterson与John Hennessy指出“The easy ride of software is over”:在异构计算时代,想要完全释放出异构芯片的计算能力,程序员必须既懂上层应用算法,又懂底层硬件模型,才能写出高效高质量代码,未来的编程工作会比现在更复杂。业界趋势下图[3]显示了过去40年来的处理器性能。按照目前的速度,标准处理器基准测试的性能在2038年之前不会翻一番。处理器性能(1980-2015)1. 不同领域的计算需要越来越多的异构资源。我们举个例子,现在的天河-2(这是一个大型机的例子)里面集成了intel Phi 芯片,也有通用的处理器。此外还有GPU的集群,在GPU集群里也集成了大量GPU核,但CPU的软件是不能够运行在GPU上的,如何让这两者协同起来,就是一个非常巨大的挑战。2. 出现面向特定领域定制的体系结构(DSA)。这里再给大家介绍下TPU,TPU是谷歌推出的针对AI计算的处理器,该处理单元于2015年首次部署,目前为超过10亿人提供服务。它运行深度神经网络(DNN)的速度是类似技术中当代CPU和GPU的15到30倍,能效是当代CPU和GPU的30到80倍,该处理器使用的是自己的指令集。我们现在所在的超异构时代是针对领域定制的架构,也就是说在超异构时代,异构走向了根据领域定制的趋势,不再是仅有CPU和GPU甚至于以后的XPU(X PU指该处理器定制设计用途未知)。开发者痛点从软件开发者角度来看,软件如何为这么多的处理器架构开发,有几个问题是容易遇到的。1. 开发效率问题不同的处理器其实是有自己的开发技巧的,比如DSP有DSP的优化技巧,GPU有GPU的优化套路,FPGA有自己专用的开发语言。普通开发者在上层应用算法和底层硬件模型无法做到两者皆懂,无法利用芯片能力实现程序性能的提升。如何让这些软件高效地为不同处理器架构进行开发,这是软件开发者需要解决或面对的问题。此外,目前缺乏有效的轻量化实时编译方案,无法做到运行时代码生成。2. 兼容性问题a) 异构处理器核之间的兼容性:怎么理解呢?就是我写一份软件,这款软件是否可以跑在其他不同的处理器上。如果这个程序下载了或完成开发以后,可以不经过任何修改,直接一份可执行的程序就可以在不同的处理器上运行,这就是二进制的兼容。二进制的兼容性在异构处理器时代非常难,芯片快速演进,开发者针对多芯片需要多次开发,代码移植成本很高。b) 源代码的兼容性:在当前时代里,源码兼容性是一个非常大的挑战。体系结构层出不穷,开发者无法通过DSL语言,快速适配多形态芯片进行迭代式开发。举个例子,英伟达GPU的开发,通用GPU的计算开发是使用专用的OpenCL编程语言来进行的。针对不同的GPU,虽然能够用同一种编程语言完成针对不同GPU的软件开发,但是并不能够保证在不同的GPU上性能都是一致的、都是最高的。这就导致了软件在进行移植时,在不能保证二进制兼容性的情况下,能够保证代码的兼容性。但是如果保证了代码的兼容性,对性能的可移植性又不能够满足,所以在这个过程当中,软件移植的成本是非常高的。这也是当前超异构时代软件编程一个非常重要的问题。这里总结一下就是产能Productivity、性能Performance、可移植性Portability的3P问题。超异构时代软件开发趋势如何解决3P问题(Productivity、Performance、Portability),支撑快速演进的芯片可编程性和解决软件兼容性问题,助力开发者实现高质量快速编程,降低代码迁移成本,下面介绍从开发者视角看到的如何对现在超异构时代软件进行开发的趋势(并不是解决方案)。1. 声明式开发:所见即所得的交互式编程。针对普通的应用开发,比如现在手机上比较热门的APP开发,有声明式开发的趋势,那这里的趋势是什么样的?针对手机这种界面型的开发,有一种称为所见即所得的交互式编程。所见即所得这个词原来是用在文本编辑里面的,大家经常使用Word的话,应该知道Word中你在屏幕上打出来是什么样的字,在打印机上打印出来就是什么样。这就叫做所见即所得的文本编辑。这里所见即所得的交互式编程是指:手机终端的应用开发者,在写代码的时候就能够在当前环境内直接看到它未来应用所呈现的样子。比如苹果公司基于SwiftUI开发的AppKit、UIKit、TVUIKit、WatchKit。“UI即代码、代码即UI”的可视化编程理念一直是一种趋势,提供新UI开发机制,所见即所得的实时预览、多端预览、提升UI开发体验和效率是声明式开发的关键挑战。2. 协同式开发:多人协作/端云协同编程。我们认为未来这会是一个比较重要的趋势,所谓协同式开发是和现在软件工程规模非常相关的一个问题。在一个小的软件项目里,可能有5-10位开发者,但是大规模的软件开发,经常有上百个开发者在同一个项目里开发,这时对软件开发提出非常大的挑战:如何让这么大规模的团队同时高效地开发,避免冲突?不同于结对编程,协同式开发使开发者能一起工作,同时保留多人信息,并与他人实时协作编辑和调试,提供新开发模式,即时安全共享项目,联合调试,实现多设备体验一致是协同式开发的关键挑战。3. 智慧化开发:AI辅助编程/AI可视化编程。把重复的劳动交给工具,让开发者专注于逻辑、业务的编写,智能化编程应用而生。智慧化开发的意思是在写代码时会有一些代码提示。原来传统的IDE所实现的代码提示是一种代码逻辑的提示。未来在异构时代,有一个很重要的问题:我们所写的代码对性能会有什么样的影响?传统的开发过程是很难在写代码的时候界面就给出一些性能的预估。未来通过智慧化编程,开发者在代码开发过程当中就能够看到代码的性能预估以及潜力。此外在安全方面,如果代码有一些安全漏洞,在软件开发前期就能解决。面向新创新场景,解决软件工程效率问题和AI编程领域可视化调试和性能分析问题是智慧化编程的关键挑战。代码补全在向智能、深度的方向发展二 产业案例接下来通过编译器和编程语言在昇腾产品里的应用案例给大家介绍下,现在编译器和编程语言技术是如何在产品中发挥作用。2019年9月18日HC2019,副董事长胡厚崑宣布,AI基础软件59.8s完成ResNet-50@imageNet模型训练,超越原世界纪录10s,并现场展示基于MindSpore实现10.02s内20万天体识别,成功发布全球最快的AI训练集群Atlas 900。为了实现这样的世界纪录,编译器在其中贡献了一些非常关键的技术。1. Super Kernel优化技术:在二进制层面实现算子Kernel融合调度,最大化减少TS调度Kernel开销,Resnet50训练E2E性能提升2~3s,助力整体性能突破60s。该技术所解决的是编译性能(应用软件最终编译出来的软件的性能)问题。这对于编译(最终的软件)来说是非常关键的。如果没有该技术,软件所运行的速度突破60秒还是一个非常大的问题。2. 并行编译、ccache优化(Compiler cache的优化):库上CCE算子构建时间从15min+降到4min,提升构建速度3倍。该技术从编译的角度来看,解决的是编译时间的问题:如何把需要编译构建的软件尽快编译出来。从开发的视角来看,大家都不愿意写了一行代码然后要花一小时进行编译。但有时候因为软件上的依赖关系,如果是在非常底层的代码里进行了一次改动,有可能会需要把整个工程进行重构。这个时候,全工程的全量重构的时间就会非常影响开发效率,上述提到的技术就是用于解决这样的开发效率问题。3. 算子优化编译和代码生成:突破循环优化、同步算法、内存复用、多核多batch等优化技术,数量级提升TBE算子性能,TBE成为D算子开发的统一框架。这也是用于解决性能问题。在整个昇腾的案例里面,希望大家记住的是两点:编译在这里解决的,第一个是性能的问题,第二个是开发时间/编译时间的问题。三 技术案例互动分享到这里大家可能会好奇:像这样的编译技术是如何来实现的?接下来就通过一些技术的案例分享给大家讲解。(一) 编译器和编程语言的设计和实现中关注的问题深入到具体单点技术之前,先来看下编译器和编程语言的设计和实现中关注的问题。设计中主要关注如下三点:1. 表达力强现在C的编译器可能很少,C语言应该是底层还在使用。我想本科有可能还会教授C语言编程这门课,但是 AI领域已经进入到大量使用Python语言的阶段。为什么呢?这里有一个很重要的问题,在上层语言中,Python语言对于AI领域的表达能力是比C语言更强的。也就是说在进行编程语言的设计或实现时,会想如何更加容易地描述计算或应用业务的逻辑。只有非常容易描述这些计算以及业务的逻辑,开发者才能够更加高效地把想实现的功能描述出来。2. 容易使用在语言层面,当你想用一个语言来进行表达的时候,语言好学与否,也是需要考虑的一个非常重要的问题。如何让语言变得更加容易使用:好学、好写、好读,还有不容易出错。3. 不易出错、代码安全不容易出错也是在语言设计上非常重要的一个考量,在设计一门语言时,需要注意这个语言是否会让开发者写出一个错误的逻辑,在这点上有可能一些早期的语言做的不是很好,但是新的这些语言在不易出错这个功能上会考虑的更多一些。因为在现在这个万物互联的时代有太多的程序要写,如果很容易出错,程序员会觉得用这个语言太麻烦。然后现在在很多设备的编程上,代码安全也是非常重要的考量,这等于说是在进行软件开发时,使用的语言会有很多的考量,那在实现的过程当中,编译器就是把语言实现,让芯片能够看懂并且执行的工具。而在实现中,为了让芯片看懂并执行,需要关注如下三点:首先是上述商用产品案例中关注的两个问题:一个是性能问题,如何通过编译,让软件运行时间尽可能短。另一个是占用资源少的问题,占用资源少的话可以省出空间资源,编译出来的软件不要太大,比如大家不希望自己下载一个小小的记事本软件,就要占用整个手机的存储空间。在这个过程当中编译器所要完成的目标就是让编译出来的程序越小越好,占用的资源越少越好。其次是平台无关性,如何让我的软件可以在尽可能多的平台上能够运行。举个例子,做APK或者说做移动APP开发的同学,有可能写了一个程序,但是这个程序应用APP无法在所有型号手机上运行,这是非常现实的问题。现在谷歌的应用市场,以及华为的应用市场里,已经有非常多的应用程序了。这些应用开发者所面临的问题是开发一个程序以后,能否让这个应用程序在尽可能多的不同手机上运行,因为只有让程序在尽可能多的不同型号手机上运行,才可能获取更多的用户,这个手机应用才有可能去变现。平台无关性对于开发者来说是最现实的问题。(二) 编译的基本过程上述编译器和编程语言的设计和实现中关注的问题又是如何通过编译过程来解决的?下面给大家介绍下整个编译器编译的基本过程,看它是如何一步步把我们前面讲到的编程语言变成可执行代码的。语言的问题是由上层设计来解决的,和芯片相关的这部分实现就是通过编译器完成的。和芯片相关的部分有:一是怎么让编程语言编译到我们的执行环境上,二是怎么让编译出的代码尽可能跑得快,还要跨平台。(因为时间受限,我在这里做一些大致的介绍,不具体深入。)首先大家知道,我们现在所写的源程序是字符串的形式,字符串本质上是一些文本,它是可以打印出来的,但编译器无法理解这些文本本身的意义是什么。举个简单的例子,像古埃及的文字,现在有许多语言学家正在研究它,对于语言学家而言,这些古埃及的文字也是一些符号构成的文本,我们不能一下就弄懂这些文本到底是什么意思,得需要仔细地翻译。类似的,编译器把源程序文本变成处理器可以理解的二进制格式的过程也是一个翻译的过程。编译的基本过程翻译的第一步是词法语法解析的过程。程序的源代码通常是英文字母、数字和一些其它符号构成的文本。词法分析就是要识别出哪个或者哪几个连续的符号是一个词。多个词又构成了句子。检查句子是否通顺,就需要语法检查了。如果句子也通顺了,看句子表达的意思对不对,前后是否衔接连贯,就是语义检查了。如果经过语法检查,语义检查,句子通顺,意思也没有问题。那么编译器就对目前解析的结果生成一个中间的表示,我们叫它抽象语法树。生成中间表示是一个非常重要的点,往后不同的编译器就会有不同的方式去执行。下面进一步给大家介绍这三种执行方式的差别。解释执行、编译执行及字节码虚拟机的形象解释第一种是解释执行。所谓解释执行就是把程序告诉编译器所要执行的这些逻辑放到可以执行的工具上运行,该工具可以运行这些逻辑。好比同声翻译,你说一句,我翻译一句。解释执行就是你翻译一句,我理解这句意思后就去执行这一句。这样的方式比较灵活但不是很高效。第二种是编译执行。这种方式下编译器会把源程序完整编译成机器能够直接执行的二进制代码,然后再由用户或者其它程序调用执行。在这种编译的过程中,编译器会进行各种性能,资源占用等方面的优化,使得生成的程序性能和大小更优。编译执行是一种静态的,我们称它为静态是因为它是一次性编译生成的。它的特点是程序跑得快,相比而言,解释执行这样的方式就显得非常低效。第三种就是字节码虚拟机执行。字节码虚拟机执行是介于解释执行和编译执行之间的一种方式。Java实现了这样的运行方式。Java的编译器把程序源代码编译成了字节码的格式,然后通过虚拟机来执行(稍微澄清下,这里的虚拟机不是通常意义上的安装虚拟操作系统的虚拟机,而是用来运行字节码的虚拟机)。虚拟机执行还有另一种方式,就是把字节码实时编译成机器码,然后由硬件直接执行。这种方式会比通过虚拟机执行要快,但仍然没有直接在硬件上执行快。(三) 编译优化案例下面为大家介绍两个编译优化的案例。1. Auto-Tuning这里分析一个案例:在静态编译的过程中,如何改善已经编译出来的程序性能。该技术名为Auto-Tuning,也就是自动调优。举个例子,有个优化技术是循环展开。编译器为生成的代码在循环体末尾加一个跳转指令跳转到循环体开始,从而再次进行循环体的执行。这种跳转不利于处理器高效运行。循环展开就是把循环体多复制几分,比如说循环体一共要运行4次,编译器就复制4份相同的代码,中间没有任何跳转,那么执行效率就会比原来的高。通常的静态编译,通过一次编译,把源代码编译成二进制文件,在这个过程中软件要达到性能更优会有一些障碍。有统计数据显示,工业上用到的编译器有上百个参数,这些参数如何设置,如何互相组合,都有不同的策略,通过一次编译而获取更优的性能还是很难的。另一方面,我们的软件要在不同的处理器上运行,不同的处理器指令集不同,各种指令执行效率都有差异,通过一次编译而获取在多个处理器上达到较优性能的效果也是很难的。Auto-Tuning技术,是为了让整个编译策略更优、更友好地适配运行环境。它有3个组件:编译器,Search Driver, Profiler。下图是Auto-Tuning编译的流程图。Auto-Tuning编译技术整体流程在左边的黄色源代码,经过中间绿色的词法、语法、语义分析和优化等步骤最终生成黄色的可执行文件,在开启Auto-Tuning后,过程中除了正常操作外还会把编译过程中应用到的需要调整的参数都完全暴露给外面的控制程序,就是前面提到的Search Driver。接下来为了解编译完成的程序的性能到底如何,我们需要把这个程序运行在执行平台上,可以是硬件平台,或者是仿真的平台。程序运行过程中会生成体现性能的一些指标,包括热点代码、指令的执行效率、内存访问是否高效等。这些指标会提供给第三个组件——Profiler。Profiler会评估当前这个程序执行是否高效,感知程序在执行过程中是否有瓶颈,是否还有更好的优化空间。在Profiler给出进一步的优化建议后,开始再次编译、运行和评估。整个过程相当于在编译器的整个参数调优空间里进行搜索,这也是Search Driver组件名称的来由。从理论上来说这是一个NP完备的问题,计算量非常大。采用这个技术,我们认为可以达到一个相对优的编译的解,这就是Auto-Tuning技术。2. 128比特位宽原子操作指令优化案例另一种提升程序性能的手段是通过指令来对软件应用进行优化,该案例讲的是如何使用一个128比特位宽的原子操作指令来优化数据库的应用,举一反三,你也可以通过特定场景的问题驱动指令集的设计。数据库有大量数据在多个核上运行,而现在的处理器有很多的核,比如鲲鹏有64-128个核,甚至以后会更多。现代数据库例如PostgreSQL等在高并发业务场景下,均采用预写日志系统(Write Ahead Logging)对事务进行提交和记录。总体思想为数据文件的修改必须发生在这些修改已经记录在日志文件中之后,因此在生成该事务提交的日志记录时 ,需要原子性的预留数据写入磁盘的全局位置信息,否则在并发情况下后台线程会将数据写到错误的地址上。通过原子锁完成位置信息的预留,会引入跨CPU访存延迟、Cache一致性代价等问题引起的性能瓶颈。全局位置信息包括一个64位起始地址和一个64位的结束地址,若想通过Lock-Free无锁操作完成位置信息的预留,则需引入双寄存器原子指令。使用双寄存器原子指令原子性完成全局位置信息预留(示例代码如下),多个lock-free线程可以同时访问同一数据而不产生数据竞争或者损坏,同时某个线程在执行数据访问时挂起不会阻碍其他的线程继续执行。cas: ldxp x7, x6, [x8] # 使用ldxp指令读取全局位置信息 eor x7, x7, x2 # 判断Start Position x7是否等于期望值x2 eor x6, x6, x3 # 判断End Position x6是否等于期望值x3 orr x6, x7, x6 # 判断Start & End Position是否均保留有效 cbnz x6, fail # 若无效,则其他线程已修改 stxp w7, x4, x5, [x8] # 反之有效,stxp指令更新全局位置信息 cbnz w7, cas # 若写入失败,则重新尝试 fail: # 位置保留失败,根据程序逻辑执行指令这里的LDXP/STXP指令用以执行一对通用寄存器的原子存储操作,指令语义如下所示:LDXP , , [<Xn|SP>] // Load Exclusive Pair of Registers STXP , , , [<Xn|SP>] // Store Exclusive Pair of registersLDXP:从Memory中读取一对双字数据到目标寄存器Xt1,Xt2中,同时对Memory地址注册一个监控保留状态。STXP:有条件的将Xt1,Xt2一对双字字数据写入到Memory中,仅当此地址的监控保留状态有效时才执行成功,如果STXP执行成功,将零值写入Ws。如果STXP执行失败,将非零值写入Ws。在我们的实验中,上述优化为某数据库的Measured tpmTOTAL性能提升10%。四 挑战课题接下来讲我们这个领域里有哪些挑战的课题,这些课题想解决的问题是什么样的。1.通用语言扩展机制研究,以及新型AI编程语言的设计和实现AI编程以及AI语言的研究一直是我们团队关注的重点,我们要解决如何提升AI编程的体验和效率,充分发挥硬件的潜力,最大化AI程序的性能。例如基于昇腾芯片,如何让AI编程更高效、性能更优。这方面的课题内容是构建一套面向AI算法开发的编程语言,实现语言原生自动微分、动静态图融合、稀疏矩阵编程等核心技术。对于通用编程语言,如何扩充现有编程语言和编译器能力,如何构建嵌入式领域的相关语言(eDSL),还有快速满足各种应用场景的定制需求。这方面的课题内容是探索和构建通用编程语言各种可扩展机制的设计和实现:包括但不限于元编程、跨语言互操作、eDSL及其类型系统、可扩展编译器框架。2.基于开放体系架构下的DSA设计与编译工具链技术研究领域定制架构(Domain Specific Architecture DSA)是计算机架构的发展趋势,针对应用领域定制的软硬件架构,解决摩尔定律无法持续的危机,在硬件变化基本稳定的情况下通过领域定制架构持续提升软件性能。现在是超异构的时代,未来的架构,芯片的专用性会越来越强。在数据中心、AI&视觉计算等不同的场景下,随着业务性能的需要,例如数据库查询性能、HPC算法能力等需求下,专用架构、专用芯片的使用会越来越多。基于这样的趋势,如何设计与研发相对应的编译工具链也是一个挑战课题。课题内容具体如下所示:1)DSA设计:突破已有计算机架构的限制,利用RISC-V等开放架构,设计特定场景的软硬件系统,如视觉分析,AI计算,图形处理,HPC计算等;2)DSA编译优化自动化:高级语言到汇编指令之间的转换需手工开发编译器翻译。当前大量DSA的出现,让编译优化的开发成为瓶颈,需要探索新的方法;3)DSA高效建模:对DSA快速构建性能模型,通过仿真,FPGA原型等手段,快速评估DSA设计效果;3. 对AI芯片编译器技术的研究AI芯片支持全场景,包括不同的芯片规格,需要在端、边、云场景下发挥出极致算力,对编译技术有较高挑战。面临不同场景下算法的侧重不同,芯片SOC级别的内存带宽不同,计算单元的算力不同以及上层框架的要求不同等问题,需要挑战编程语言表达完备性、优化技术如何实现、如何进行POLYHEDRAL循环优化、超轻量在线编译、多场景性能优化、融合算子最优切分策略求解、计算单元最优调度等业界难题。4. 面向应用的统一IR(公共中间表示)的研究多核和异构是未来计算系统的发展趋势,从应用角度看,多种业务融合、互相协同开发和调优的需求会逐渐增加。从硬件来看,如何协同多种算力高效执行是一个挑战课题,特别是在人工智能领域出现了越来越多的IR(编译器中间表示),彼此之间互相割裂无法统一优化和调试。在新硬件架构下,如何利用整体算力来完成应用的高效执行已经成为一个挑战的课题。我们需要确定一个统一的异构编程语言、探索出一个方便易用的异构编程框架、开发相应的编译优化技术及运行时支持,给开发者提供易用性的同时充分挖掘硬件潜力。同时本课题瞄准支持多语言公共表示和抽象,支持多层 IR同时也支持其他IR和中间语言,实现跨语言高效互通,为全程序优化打下基础;提供一个可沉淀不同领域优化技术的公共基础设施、动静态各种优化技术模块化,并可按不同场景需要自适应自组合,如在昇腾AI领域,支持更好的算子融合优化。通过该课题研究,达成多编程语言支持,降低 “语言墙” 开销,构建业界领先的编译优化基础设施(含传统应用和AI模型算法),并支持更多功能(如程序分析、安全检测)。今天的课题介绍就到这里了。以上是我给初学者的建议和分享,谢谢。参 考[1] https://www.karlrupp.net/2018/02/42-years-of-microprocessor-trend-data/[2] https://www.nextplatform.com/2019/02/05/the-era-of-general-purpose-computers-is-ending/[3] https://dl.acm.org/doi/fullHtml/10.1145/3154484原文转载自毕昇编译-AIOT时代的编程语言、编译器与指令集架构:机遇、挑战与技术分享扫码关注毕昇编译公众号
  • [HPC] 鲲鹏HPC解决方案 lxd容器安装GPU驱动与CUDA
    为容器添加GPU设备容器外执行lxc config device add 容器名称gpu gpu例如本文中的容器名称是template:lxc config device add template gpu gpu进入容器并检查gpu设备:ls /dev | grep nvidia容器安装NVIDIA驱动容器内安装编译器基础环境yum install gcc-toolset-9*source /opt/rh/gcc-toolset-9/enable容器内下载适用于linux_arm64的NVIDIA驱动:wget https://us.download.nvidia.com/tesla/470.82.01/NVIDIA-Linux-aarch64-470.82.01.run安装驱动sh ./NVIDIA-Linux-aarch64-470.82.01.run --no-kernel-module检查驱动安装CUDA容器内下载适用于Centos8_arm64的cuda安装包:wget https://developer.download.nvidia.com/compute/cuda/11.4.3/local_installers/cuda_11.4.3_470.82.01_linux_sbsa.run 安装CUDA,注意驱动已经安装,需要取消安装驱动的选项安装完成后,检查自带测试用例,矩阵乘法
  • [HPC] 鲲鹏HPC解决方案 Ubuntu OS 安装GPU驱动与CUDA
    禁用系统自带驱动系统自带的nouveau驱动与NVIDIA冲突,需要禁用vim /etc/modprobe.d/blacklist.conf添加两行blacklist nouveauoptions nouveau modeset=0 sudo update-initramfs -u重启生效,并检查nouveau确实已经禁用sudo rebootlsmod | grep nouveau (禁用后,输出应该是空)下载cuda安装包并安装适用于ubuntu20.04_arm64的cuda安装包:https://developer.download.nvidia.com/compute/cuda/11.4.3/local_installers/cuda_11.4.3_470.82.01_linux_sbsa.runcuda安装包已经包含了NVIDIA驱动,宿主机直接安装即可(后续容器中安装,需要单独下载驱动包)sudo sh ./cuda_11.4.3_470.82.01_linux_sbsa.run检查宿主机是否安装成功nvidia-smi自带测试用例,矩阵乘法
  • [问题求助] 模拟器如何使能gpu
    泰山服务器跑模拟器如何使能atlas gpu,启动参数-gpu host发现显卡占用一点没变
  • [其他] 大规模训练模型
    大规模模型训练涉及多GPU时的并行、通讯以及模型过大等问题。并行方式对于n个GPU数据并行:不同的GPU输入不同的数据,运行相同的完整的模型。模型并行:不同的GPU运行模型的不同部分,比如多层网络的不同层;如果模型能够放进单个GPU的显存中,可以使用数据并行加速。如果模型不能够放进单个GPU的显存中,但可以放进多个GPU显存,可以考虑模型并行。模型并行加速:pipeline对于模型并行,如果只是简单将模型不同部分放在不同GPU上,对GPU利用率很低。如下图所示。此时可以采用流水线技术,将一个batch数据切分为多个mini-batch,每个GPU运行完一个mini-batch就将数据传输到下一阶段GPU,然后继续运行下一个mini-batch,可成倍提高GPU利用效率。如下图所示:GPipe提供了一种模型并行流水线的实现 https://arxiv.org/abs/1811.06965通讯算法对于n个GPUParameter Server:GPU 0将数据分成n份分到各个卡上,每张卡负责自己的那一份batch的训练,得到grad后,返回给GPU 0上做累积,得到更新的权重参数后,再分发给各个卡。Ring AllReduce:n张以环形相连,每张卡都有左手卡和右手卡,一个负责接收,一个负责发送,循环n-1次完成梯度累积,再循环n-1次做参数同步。分为Scatter Reduce和All Gather两个环节。Parameter Server是一种更通用的通讯算法,对于很多分布式机器学习算法都适用。但是在deep learning这一通讯量巨大的特定场景中,负责汇总的parameter server容易成为通讯瓶颈。假设有N个GPU,通信一次完整的参数所需时间为K,那么使用PS架构,其通信成本为 T=2(N−1)*K。因此Ring AllReduce被提出来,分为Scatter Reduce和All Gather两个环节。Scatter Reduce过程:首先,我们将参数分为N份,相邻的GPU传递不同的参数,在传递N-1次之后,可以得到每一份参数的累积(在不同的GPU上)All Gather:得到每一份参数的累积之后,再做一次传递,同步到所有的GPU上。其通信成本仅为 T=2(N−1)/N*K 。
  • [技术干货] 【PyTorch】多GPU并行训练DistributeDataParallel(Linux版)
    前言常见的多GPU并行的方法有model parallel 和 data parallel两种,这里主要讲的是data parallel:并行训练数据,相当于增大了batch_size.主要需要注意的几点:    数据集如何在不同的设备间分配    误差梯度如何在不同的设备间通信    BatchNormalization如何在不同的设备间同步(使用会提升一点,但是会降低一点并行速度)一、DataParalled和DistributeDataParallel    DataParalled只能用于单机多卡,而DistributeDataParallel可以用于单机多卡,多机多卡    单机情况下通常DataParalled要慢于DistributeDataParallel二、多GPU训练常见启动方式    torch.distributed.launch: 代码少,启动速度快(用的多)    注意: 如果开始训练后,手动强制终止程序,有小概率会出现进程没有杀掉的情况,最好看下GPU占用情况。# 其中nproc_per_node为并行GPU的数量python -m torch.distributed.launch --nproc_per_node=2 --use_env train_multi_gpu_using_launch.py    torch.multiprocessing: 代码多点,速度慢点,但是拥有更好的控制和灵活性(这里不讲)三、torch.distributed.launch代码讲解3.1、main中添加了几个新的变量注意: 这里一般只需要手动选择syncBN即可,后面三个参数不要动,系统会自动选择    # 是否启用SyncBatchNorm BN在多个GPU上同步    parser.add_argument('--syncBN', type=bool, default=True, help="同步BatchNormalization")    # 不要改该参数,系统会自动分配    parser.add_argument('--device', default='cuda', help='device id (i.e. 0 or 0,1 or cpu)')    # 开启的进程数(注意不是线程),不用设置该参数,会根据nproc_per_node自动设置    parser.add_argument('--world-size', default=4, type=int,                        help='number of distributed processes')    parser.add_argument('--dist-url', default='env://', help='url used to set up distributed training')3.2、初始化各进程环境# 初始化各进程环境init_distributed_mode(args=args) def init_distributed_mode(args):    # 使用python -m torch.distributed.launch --nproc_per_node=2 --use_env train_multi_gpu_using_launch.py指令    # --use_env这个参数,他就会在我们os环境中(os.environ)存入RANK、WORLD_SIZE、LOCAL_RANK    if 'RANK' in os.environ and 'WORLD_SIZE' in os.environ:        # 多机多卡:WORLD_SIZE代表使用几台机器,RANK代表第几台机器,LOCAL_RANK代表某台机器上第几块GPU设备        # 单机多卡:WORLD_SIZE代表有几块GPU,RANK=LOCAL_RANK代表哪块GPU        args.rank = int(os.environ["RANK"])        args.world_size = int(os.environ['WORLD_SIZE'])        args.gpu = int(os.environ['LOCAL_RANK'])    elif 'SLURM_PROCID' in os.environ:  # 一般不执行        args.rank = int(os.environ['SLURM_PROCID'])        args.gpu = args.rank % torch.cuda.device_count()    else:  # 一般不执行        print('Not using distributed mode')        args.distributed = False        return    args.distributed = True    torch.cuda.set_device(args.gpu)    args.dist_backend = 'nccl'  # 通信后端,nvidia GPU推荐使用NCCL    print('| distributed init (rank {}): {}'.format(        args.rank, args.dist_url), flush=True)    # 创建进程组(重要)    # backend:通信后端  init_method:使用默认(env://) world_size:几块GPU  rank:当前进程处于哪块GPU    # 注意:对于不同的进程而言,它的world_size是相同的,但是rank是不相同的    dist.init_process_group(backend=args.dist_backend, init_method=args.dist_url,                            world_size=args.world_size, rank=args.rank)    dist.barrier()  # 等待每一块GPU都运行到这个地方之后再接着往下走  3.3、调整学习率学习率要根据并行GPU的数量进行倍增,这里方法不一定,有很多种这里暴力增加,直接乘以GPU个数# 学习率要根据并行GPU的数量进行倍增  world_size = GPU数量args.lr *= args.world_size # 也可以写成这样args.lr *= max(1., args.world_size * args.batch_size / 64)3.4、在第一个进程中进行打印和保存等操作 if rank == 0:  # 在第一个进程中打印信息,并实例化tensorboard        print(args)        print('Start Tensorboard with "tensorboard --logdir=runs", view at http://localhost:6006/')        tb_writer = SummaryWriter()        if os.path.exists("./weights") is False:            os.makedirs("./weights")     3.5、DistributedSamplerDistributedSampler: 给每个rank(gpu)对应的进程分配训练的样本索引 train_sampler = torch.utils.data.distributed.DistributedSampler(train_data_set) val_sampler = torch.utils.data.distributed.DistributedSampler(val_data_set) 
  • [云计算周刊] 人工智能、GPU与云计算的关系和应用
    近年来,人工智能已经渗透不同行业不同领域,随着人工智能算法突飞猛进地发展,越来越多的模型训练需要巨量的算力支撑才能快速有效地实施,算力是未来人工智能应用取得突破的决定性因素,GPU的运用加速了人工智能的计算速度。GPU的特点是有大量的核心和高速内存,擅长并行计算,对海量数据进行快速处理。相较而言,CPU虽然具有很强的通用性来处理各种不同的数据类型,但是计算能力只是CPU很小的一部分。  NVIDIA很早就瞄准GPU在人工智能领域的应用,致力于GPU加速计算的发展。NVIDIA 研究部门曾与斯坦福大学的团队合作,在实验中证明,12 块 NVIDIA GPU 所提供的深度学习性能相当于2000 块 CPU。深度学习作为人工智能的核心,而深度学习是需要训练的,所谓的训练就是在成千上万个变量中寻找最佳值的计算。这需要通过不断的尝试识别,而最终获得的数值并非是人工确定的数字,而是一种常态的公式。通过这种像素级的学习,不断总结规律,计算机就可以实现像人一样思考。因而,更擅长并行计算的高算力GPU,则成了决定深度学习的准确度。  目前深度学习技术应用越来越广,CNN卷积神经网络技术充满了神奇的计算魅力;DL技术广泛应用于:图像处理、人脸识别、自动驾驶、聊天机器人、AI人工智能、机器语言翻译、图片推荐系统、声音处理、音乐作曲、机器写作等领域。现今,日益完善的深度学习技术和AI服务愈加受到市场青睐。与此同时,数据集不断扩大,计算模型和网络也变得越来越复杂,这对于硬件设备也提出了更为严苛的需求。如何利用有限的预算,最大限度升级系统整体的计算性能和数据传输能力成为了最为重要的问题。  因此,如果没有专业的人员对GPU机器进行运维,部署GPU云服务更能成为一个好的解决办法。青椒云GPU云服务器基于异构计算提供强劲浮点计算能力服务,提供端到端的深度学习资源,缩短训练环境部署时间,为客户提供更强大的AI算力支持,加速AI落地应用,而且可以去除采购设备和运维机器的费用,只需下载青椒云客户端,即可享受超强GPU算力,真正实现了开机即用。来源: 小坤哥娱乐说
  • [问题求助] #化鲲为鹏,我有话说# 求关于GPU Turbo的知识
    化鲲为鹏,我有话说华为吓人技术GPU Turbo技术发布了好久,的确的确会给手机性能带来很大的提升,尤其是打游戏时,但是官方给的资料寥寥无几,求大神科普。落款:云南大学
  • [获奖公告] 【华为云•微话题】“如何利用GPU云资源训练自己的TensorFlow模型?”
    微话题 “如何利用GPU云资源训练自己的TensorFlow模型?”希望大家能够畅所欲言。如果大家有其他任何与TensorFlow模型相关的问题,也可以在本帖回复直接咨询云享专家江魁。=====【华为云·微话题】如何利用GPU云资源训练自己的TensorFlow模型? =====人工智能的火热,带来了一波学习TensorFlow深度学习框架的热潮。聊深度学习免不了要用GPU,但目前一块GPU费用较高,对于个人学习者和创业公司来讲的话,按需配置的云GPU服务器是一个不错的选项。华为云提供了按需配置的GPU服务器。云资源购买很方便,但GPU服务器的配置安装往往依赖一些Nvidia开发的组件,其文档晦涩难懂,很容易把新手拒之门外。幸运的是,在这个Docker流行的时代,有一些工作可以用容器化的服务来简化。Nvidia也开发了Nvidia-docker支持容器化。今天我们就来讨论一下如何利用GPU云资源训练自己的TensorFlow模型?期望看到大家精彩的评论:1、你是如何训练自己的TensorFlow模型?2、你在华为云服务器上训练自己的TensorFlow模型有没有碰到什么问题?如何解决的?3、你尝试着在GPU云资源部署你的Nvidia-docker时最大的收获是什么?4、你的TensorFlow训练的模型在用Restful API发布时有没有碰到什么问题?微话题活动:参与本次微话题讨论,有机会获得优质评论奖,赢取华为小天鹅蓝牙音箱。活动时间:2019年7月24日-8月7日参与方式:直接在本帖回复关于以上4个问题中的任意1个或多个问题的理解或评论获奖方式:活动结束后,将由云享专家 江魁 选取出2名优质评论奖,各送出华为小天鹅蓝牙音箱1个。评奖标准:回复话题数量和内容质量。优质评论:云的记忆:1、你是如何训练自己的TensorFlow模型?接触人工智能一年多,报了网课,前段时间第一次在华为提供的Modelarts AI实践营上 训练了 花草识别,猫狗识别 以及一个YOLO3模型。也是通过你们华为云第一次训练自己的第一个TensorFlow模型,算是入门,感谢华为。 2、你在华为云服务器上训练自己的TensorFlow模型有没有碰到什么问题? 记得第二期实践的时候,上传数据集到你们 对象存储的那个桶,通过你们那个 Browers传东西 传到 66%的时间就一直传不上去了,这个东西是个大的bug,需要修复,后面是通过另外一种命令行的方式上传的,后面多次遇到其他的一些大大小小的问题,但是都解决了,后面遇到再反馈  3、你尝试着在GPU云资源部署你的Nvidia-docker时最大的收获是什么? 没有实践过,通过你们Modelarts 学会做深度学习的时候,后面有计划这样去部署。因为感觉更自由。 4、你的TensorFlow训练的模型在用Restful API发布时有没有碰到什么问题? 还没遇到过。 buyi:利用TensorFlow,然后基于 CNN 数字识别的代码,采用简单的卷积神经网络模型,模型为: 输入 - 第一层卷积 - 第一层池化 - 第二层卷积 - 第二层池化 - 第一层全连接 - 第二层全连接。实现1—9的数字识别,根据ModelArts开发步骤,总结下列流程。1. 训练数据集下载上传2. CNN 模型构建3. 创建一个源文件 mnist_model.py123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778from __future__ import absolute_importfrom __future__ import divisionfrom __future__ import print_function  import argparseimport sysimport tempfile  from tensorflow.examples.tutorials.mnist import input_data  import tensorflow as tf  FLAGS = None    def deepnn(x):    with tf.name_scope('reshape'):    x_image = tf.reshape(x, [-1, 28, 28, 1])    #第一层卷积层,卷积核为5*5,生成32个feature maps.  with tf.name_scope('conv1'):    W_conv1 = weight_variable([5, 5, 1, 32])    b_conv1 = bias_variable([32])    h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1) #激活函数采用relu    # 第一层池化层,下采样2.  with tf.name_scope('pool1'):    h_pool1 = max_pool_2x2(h_conv1)    # 第二层卷积层,卷积核为5*5,生成64个feature maps  with tf.name_scope('conv2'):    W_conv2 = weight_variable([5, 5, 32, 64])    b_conv2 = bias_variable([64])    h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2)#激活函数采用relu    # 第二层池化层,下采样2.  with tf.name_scope('pool2'):    h_pool2 = max_pool_2x2(h_conv2)    #第一层全连接层,将7x7x64个feature maps与1024个features全连接  with tf.name_scope('fc1'):    W_fc1 = weight_variable([7 * 7 * 64, 1024])    b_fc1 = bias_variable([1024])      h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*64])    h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)    #dropout层,训练时候随机让某些隐含层节点权重不工作  with tf.name_scope('dropout'):    keep_prob = tf.placeholder(tf.float32)    h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)    # 第二层全连接层,1024个features和10个features全连接  with tf.name_scope('fc2'):    W_fc2 = weight_variable([1024, 10])    b_fc2 = bias_variable([10])      y_conv = tf.matmul(h_fc1_drop, W_fc2) + b_fc2  return y_conv, keep_prob  #卷积def conv2d(x, W):  return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')  #池化def max_pool_2x2(x):  return tf.nn.max_pool(x, ksize=[1, 2, 2, 1],                        strides=[1, 2, 2, 1], padding='SAME')#权重def weight_variable(shape):  initial = tf.truncated_normal(shape, stddev=0.1)  return tf.Variable(initial)  #偏置def bias_variable(shape):  initial = tf.constant(0.1, shape=shape)  return tf.Variable(initial) 训练模型123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596from __future__ import absolute_importfrom __future__ import divisionfrom __future__ import print_function  import argparseimport sysimport tempfile  from tensorflow.examples.tutorials.mnist import input_data  import tensorflow as tf  import mnist_model  FLAGS = None    def main(_):  mnist = input_data.read_data_sets(FLAGS.data_dir, one_hot=True)    #输入变量  x = tf.placeholder(tf.float32, [None, 784])    #输出变量,数字是1-10  y_ = tf.placeholder(tf.float32, [None, 10])    # 构建网络,输入—>第一层卷积—>第一层池化—>第二层卷积—>第二层池化—>第一层全连接—>第二层全连接  y_conv, keep_prob = mnist_model.deepnn(x)    #第一步对网络最后一层的输出做一个softmax,第二步将softmax输出和实际样本做一个交叉熵  #cross_entropy返回的是向量  with tf.name_scope('loss'):    cross_entropy = tf.nn.softmax_cross_entropy_with_logits(labels=y_,                                                            logits=y_conv)    #求cross_entropy向量的平均值得到交叉熵  cross_entropy = tf.reduce_mean(cross_entropy)    #AdamOptimizer是Adam优化算法:一个寻找全局最优点的优化算法,引入二次方梯度校验  with tf.name_scope('adam_optimizer'):    train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)    #在测试集上的精确度  with tf.name_scope('accuracy'):    correct_prediction = tf.equal(tf.argmax(y_conv, 1), tf.argmax(y_, 1))    correct_prediction = tf.cast(correct_prediction, tf.float32)  accuracy = tf.reduce_mean(correct_prediction)    #将神经网络图模型保存本地  graph_location = tempfile.mkdtemp()  print('Saving graph to: %s' % graph_location)  train_writer = tf.summary.FileWriter(graph_location)  train_writer.add_graph(tf.get_default_graph())    #将训练的网络保存下来  saver = tf.train.Saver()  with tf.Session() as sess:    sess.run(tf.global_variables_initializer())    for i in range(5000):      batch = mnist.train.next_batch(50)      if i % 100 == 0:        train_accuracy = accuracy.eval(feed_dict={            x: batch[0], y_: batch[1], keep_prob: 1.0})#输入是字典,表示tensorflow被feed的值        print('step %d, training accuracy %g' % (i, train_accuracy))      train_step.run(feed_dict={x: batch[0], y_: batch[1], keep_prob: 0.5})      test_accuracy = 0    for i in range(200):      batch = mnist.test.next_batch(50)      test_accuracy += accuracy.eval(feed_dict={x: batch[0], y_: batch[1], keep_prob: 1.0}) / 200;      print('test accuracy %g' % test_accuracy)      save_path = saver.save(sess,"mnist_cnn_model.ckpt")  if __name__ == '__main__':  parser = argparse.ArgumentParser()  parser.add_argument('--data_dir', type=str,                      default='./',                      help='Directory for storing input data')  FLAGS, unparsed = parser.parse_known_args()  tf.app.run(main=main, argv=[sys.argv[0]] + unparsed)    for i in range(200):      batch = mnist.test.next_batch(50)      test_accuracy += accuracy.eval(feed_dict={x: batch[0], y_: batch[1], keep_prob: 1.0}) / 200;      print('test accuracy %g' % test_accuracy)      save_path = saver.save(sess,"mnist_cnn_model.ckpt")  if __name__ == '__main__':  parser = argparse.ArgumentParser()  parser.add_argument('--data_dir', type=str,                      default='./',                      help='Directory for storing input data')  FLAGS, unparsed = parser.parse_known_args()  tf.app.run(main=main, argv=[sys.argv[0]] + unparsed) 4. 然后执行5. 实现预测代码创建源文件 predict_mnist_model.py12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061from __future__ import absolute_importfrom __future__ import divisionfrom __future__ import print_function  import argparseimport sysimport tempfile  from tensorflow.examples.tutorials.mnist import input_data  import tensorflow as tf  import mnist_modelfrom PIL import Image, ImageFilter  def load_data(argv):      grayimage = Image.open(argv).convert('L')    width = float(grayimage.size[0])    height = float(grayimage.size[1])    newImage = Image.new('L', (28, 28), (255))      if width > height:        nheight = int(round((20.0/width*height),0))        if (nheigth == 0):            nheigth = 1        img = grayimage.resize((20,nheight), Image.ANTIALIAS).filter(ImageFilter.SHARPEN)        wtop = int(round(((28 - nheight)/2),0))        newImage.paste(img, (4, wtop))    else:        nwidth = int(round((20.0/height*width),0))        if (nwidth == 0):            nwidth = 1        img = grayimage.resize((nwidth,20), Image.ANTIALIAS).filter(ImageFilter.SHARPEN)        wleft = int(round(((28 - nwidth)/2),0))        newImage.paste(img, (wleft, 4))      tv = list(newImage.getdata())    tva = [ (255-x)*1.0/255.0 for x in tv]    return tva  def main(argv):      imvalue = load_data(argv)      x = tf.placeholder(tf.float32, [None, 784])    y_ = tf.placeholder(tf.float32, [None, 10])    y_conv, keep_prob = mnist_model.deepnn(x)      y_predict = tf.nn.softmax(y_conv)    init_op = tf.global_variables_initializer()    saver = tf.train.Saver()    with tf.Session() as sess:        sess.run(init_op)        saver.restore(sess, "mnist_cnn_model.ckpt")        prediction=tf.argmax(y_predict,1)        predint = prediction.eval(feed_dict={x: [imvalue],keep_prob: 1.0}, session=sess)        print (predint[0])  if __name__ == "__main__":main(sys.argv[1])这样就可进行一个简单的数字预测,利用率TensorFlow相关函数和简单神经网络。
  • [技术干货] 【云享专家•微话题】“如何利用GPU云资源训练自己的TensorFlow模型?”
                                                  微话题 “如何利用GPU云资源训练自己的TensorFlow模型?”希望大家能够畅所欲言。如果大家有其他任何与TensorFlow模型相关的问题,也可以在本帖回复直接咨询云享专家江魁。=====【华为云·微话题】如何利用GPU云资源训练自己的TensorFlow模型? =====人工智能的火热,带来了一波学习TensorFlow深度学习框架的热潮。聊深度学习免不了要用GPU,但目前一块GPU费用较高,对于个人学习者和创业公司来讲的话,按需配置的云GPU服务器是一个不错的选项。华为云提供了按需配置的GPU服务器。云资源购买很方便,但GPU服务器的配置安装往往依赖一些Nvidia开发的组件,其文档晦涩难懂,很容易把新手拒之门外。幸运的是,在这个Docker流行的时代,有一些工作可以用容器化的服务来简化。Nvidia也开发了Nvidia-docker支持容器化。今天我们就来讨论一下如何利用GPU云资源训练自己的TensorFlow模型?期望看到大家精彩的评论:1、你是如何训练自己的TensorFlow模型?2、你在华为云服务器上训练自己的TensorFlow模型有没有碰到什么问题?如何解决的?3、你尝试着在GPU云资源部署你的Nvidia-docker时最大的收获是什么?4、你的TensorFlow训练的模型在用Restful API发布时有没有碰到什么问题?微话题活动:参与本次微话题讨论,有机会获得优质评论奖,赢取华为小天鹅蓝牙音箱。活动时间:2019年7月24日-8月7日参与方式:直接在本帖回复关于以上4个问题中的任意1个或多个问题的理解或评论获奖方式:活动结束后,将由云享专家 江魁 选取出2名优质评论奖,各送出华为小天鹅蓝牙音箱1个。评奖标准:回复话题数量和内容质量。
  • [线上活动] 【立即报名 分享赢大礼】华为云专家技术公开课第四期:解码&quot;AI大杀器&quot;
    人工智能的火热,带来了一波学习TensorFlow深度学习框架的热潮。聊深度学习免不了要用GPU,但目前GPU费用较高,对于个人学习者和创业公司来讲的话,按需配置的云GPU服务器是一个不错的选项。华为云提供了按需配置的GPU服务器,云资源购买很方便,但GPU服务器的配置安装往往依赖一些Nvidia开发的组件,如何快速进行部署,可以用容器化的服务来简化,华为云专家技术公开课邀-请到云享专家江魁,对这套开发组件作一次系统介绍。【立即报名】点击报名链接,进行线上预约观看https://developer.huaweicloud.com/signup/da8435fc6e274e93868a1cb37ad2eebd【你分享,我送礼】了解专家课程详情:
  • [热门活动] 华为云GPU计算加速型P2v云服务器于2019年3月28日00:00(北京时间)转商通知
    尊敬的华为云客户:华为云计划于2019/03/28 00:00(北京时间)将GPU计算加速型P2v云服务器正式转商用。商用后,服务会按功能类型、性能规格和使用时长计费,具体价格请届时参考该服务的计费详情页。如果需要继续使用P2v云服务器,请提前确保账户余额充足,华为云在此提醒您,相关资源如果不再使用,请于2019/03/28 00:00(北京时间)前登陆控制台,删除对应资源,避免产生费用。更多关于GPU计算加速型P2v云服务器的产品介绍,请您点击了解。如您在使用过程中有宝贵意见,欢迎您拨打华为云服务热线:4000-955-988与我们联系。感谢您对华为云的支持!https://www.huaweicloud.com/notice/2018/20190320172853803.html
  • [技术干货] 使用创建时的用户名和密码无法SSH方式登录GPU加速云服务器?
    先使用VNC方式远程登录弹性云服务器,并修改配置文件,然后再使用SSH方式登录。 [*]进入弹性云服务器运行页面,单击“远程登录”。 [*]自动跳转至登录页面,登录root用户,输入密码。说明: 密码为创建弹性云服务器时设置的密码。 [*]在“/etc/ssh/”目录下,修改sshd_config文件中3个配置项,修改参数如下图所示。 [*]修改完成后保存退出,执行如下命令,重启SSH服务。[color=color:#F7F7F7]ervice sshd restartservice sshd restartservice sshd restart [*]重启后,重新登录弹性云服务器。 [*]通过以上步骤依然无法登录,请联系技术人员进行处理。
  • [交流分享] GPU图形加速型服务器,专为图形处理而生!
    本帖最后由 哆啦A梦 于 2017-11-30 11:14 编辑还有一个月,2017就结束了!你是否还在为自建GPU物理服务器而烦恼?是否还在为采购软硬件的交付期而忧伤?是否害怕组建的机器计算能力不足以满足业务需求?揪心于每年都要付出的机器维护升级费用!如果我说,华为云有一款已经重磅上线的服务器,几分钟即可开通实例,方便快捷;可以根据计算规模的需求,灵活扩展计算能力;它专业为图形处理而生,无需运营维护;关键是价格还低的很可爱。你,是否期待去见它一面?5858GPU图形加速型云服务器重磅上线!每日上午十点限量秒杀只需领取优惠券即可免免免费试用5859它,专业:内置GM204图形芯片,支持众多专业图形应用程序。可靠:真正数据中心级GPU显卡,提供稳定的、可靠地GPU解决方案基础。极速: 多达10个高效视频编码(HEVC)流,提供更快的视频帧处理和更优的图像保真度。5861适合于航空航天,国防,工业制造,建筑和施工、医疗影像,能源和石油图层、电影,游戏、动画、广告等领域。怎么样, 是不是感觉到心动了,这么完美的图形处理服务器,无论是自己用,还是请朋友用都是完美的选择。快和朋友们一起来抢购吧!58625863活动规则:1、活动时间:2017年10月30日起完成华为云实名认证的华为云注册用户即可参与活动;2、参与限制:0元秒杀套餐每天限量发放,每人限购1台,数量有限,先到先得,7折套餐不限购买台数, 以成功支付为准;3、套餐使用:所有套餐为特价产品,不支持代金券与打折券叠加使用,如退订退款,再次购买相同资源不再享受同等折扣,套餐产品宽限期7天保留期15天;4、续费说明:续费按当期官网目录价为准;5、为保证活动的公平公正,华为云有权对恶意刷活动资源(“恶意”是指为获取资源而异常注册账号等破坏活动公平性的行为),利用资源从事违法违规行为的用户收回套餐使用资格;6、所有参加本活动的用户,均视为认可并同意遵守《华为云用户协议》。
总条数:406 到第
上滑加载中