MindSpore-2.4版本中的一些新特性
技术背景
在前面的一篇博客中我们介绍了MindSpore-2.4-gpu的安装和其中可能出现的一些问题。这里我们在安装完成之后,可以尝试使用一些MindSpore新版本的特性。那么在安装之后,如果是使用VSCode作为IDE,可以使用ctrl+shift+P快捷键,然后搜索python:sele将Python解释器切换到我们所需要的最新MindSpore环境下。
设备管理和资源监测
在mindspore-2.4版本中增加了mindspore.hal接口,可以用于管理设备、监测设备以及执行流的处理等等。例如,常用的获取设备的数量:
import mindspore as ms
ms.set_context(device_target="GPU")
device_target = ms.context.get_context("device_target")
print(ms.hal.device_count(device_target))
# 2
这个输出表明我们的环境下有两个GPU卡。也可以打印这两块显卡的名称:
import mindspore as ms
ms.set_context(device_target="GPU")
device_target = ms.context.get_context("device_target")
print(ms.hal.get_device_name(0, device_target))
print(ms.hal.get_device_name(1, device_target))
# Quadro RTX 4000
# Quadro RTX 4000
以及设备的可用状态:
import mindspore as ms
ms.set_context(device_target="GPU")
device_target = ms.context.get_context("device_target")
print(ms.hal.is_available(device_target))
# True
查询设备是否被初始化:
import mindspore as ms
ms.set_context(device_target="GPU")
device_target = ms.context.get_context("device_target")
print(ms.hal.is_initialized(device_target))
A = ms.Tensor([0.], ms.float32)
A2 = (A+A).asnumpy()
print(ms.hal.is_initialized(device_target))
# False
# True
这也说明,只有在计算的过程中,MindSpore才会将Tensor的数据传输到计算后端。除了设备管理之外,新版本的MindSpore还支持了一些内存监测的功能,对于性能管理非常的实用:
import mindspore as ms
import numpy as np
ms.set_context(device_target="GPU")
A = ms.Tensor(np.random.random(1000), ms.float32)
A2 = (A+A).asnumpy()
print(ms.hal.max_memory_allocated())
# 8192
这里输出的占用最大显存的Tensor的大小。需要说明的是,这里不能直接按照浮点数占用空间来进行计算,应该说MindSpore在构建图的过程中会产生一些额外的数据结构,这些数据结构也会占用一定的显存,但是显存增长的趋势是准确的。除了单个的打印,还可以整个的输出一个summary:
import mindspore as ms
import numpy as np
ms.set_context(device_target="GPU")
A = ms.Tensor(np.random.random(1000), ms.float32)
A2 = (A+A).asnumpy()
print(ms.hal.memory_summary())
输出的结果为:
|=============================================|
| Memory summary |
|=============================================|
| Metric | Data |
|---------------------------------------------|
| Reserved memory | 1024 MB |
|---------------------------------------------|
| Allocated memory | 4096 B |
|---------------------------------------------|
| Idle memory | 1023 MB |
|---------------------------------------------|
| Eager free memory | 0 B |
|---------------------------------------------|
| Max reserved memory | 1024 MB |
|---------------------------------------------|
| Max allocated memory | 8192 B |
|=============================================|
ForiLoop
其实简单来说就是一个内置的for循环的操作,类似于Jax中的fori_loop:
import mindspore as ms
import numpy as np
from mindspore import ops
ms.set_context(device_target="GPU")
@ms.jit
def f(_, x):
return x + x
A = ms.Tensor(np.ones(10), ms.float32)
N = 3
AN = ops.ForiLoop()(0, N, f, A).asnumpy()
print (AN)
# [8. 8. 8. 8. 8. 8. 8. 8. 8. 8.]
有了这个新的for循环体,我们可以对整个循环体做端到端自动微分:
import mindspore as ms
import numpy as np
from mindspore import ops, grad
ms.set_context(device_target="GPU", mode=ms.GRAPH_MODE)
@ms.jit
def f(_, x):
return x + x
@ms.jit
def s(x, N):
return ops.ForiLoop()(0, N, f, x)
A = ms.Tensor(np.ones(10), ms.float32)
N = 3
AN = grad(s, grad_position=(0, ))(A, N).asnumpy()
print (AN)
# [8. 8. 8. 8. 8. 8. 8. 8. 8. 8.]
流计算
首先我们来看这样一个例子:
import mindspore as ms
import numpy as np
np.random.seed(0)
from mindspore import numpy as msnp
ms.set_context(device_target="GPU", mode=ms.GRAPH_MODE)
@ms.jit
def U(x, mu=1.0, k=1.0):
return msnp.sum(0.5 * k * (x-mu) ** 2)
x = ms.Tensor(np.ones(1000000000), ms.float32)
energy = U(x)
print (energy)
在本地环境下执行就会报错:
Traceback (most recent call last):
File "/home/dechin/projects/gitee/dechin/tests/test_ms.py", line 13, in <module>
energy = U(x)
File "/home/dechin/anaconda3/envs/mindspore-master/lib/python3.9/site-packages/mindspore/common/api.py", line 960, in staging_specialize
out = _MindsporeFunctionExecutor(func, hash_obj, dyn_args, process_obj, jit_config)(*args, **kwargs)
File "/home/dechin/anaconda3/envs/mindspore-master/lib/python3.9/site-packages/mindspore/common/api.py", line 188, in wrapper
results = fn(*arg, **kwargs)
File "/home/dechin/anaconda3/envs/mindspore-master/lib/python3.9/site-packages/mindspore/common/api.py", line 588, in __call__
output = self._graph_executor(tuple(new_inputs), phase)
RuntimeError:
----------------------------------------------------
- Memory not enough:
----------------------------------------------------
Device(id:0) memory isn't enough and alloc failed, kernel name: 0_Default/Sub-op0, alloc size: 4000000000B.
----------------------------------------------------
- C++ Call Stack: (For framework developers)
----------------------------------------------------
mindspore/ccsrc/runtime/graph_scheduler/graph_scheduler.cc:1066 Run
说明出现了内存不足的情况。通常情况下,可能需要手动做一个拆分,然后使用循环体遍历:
import time
import mindspore as ms
import numpy as np
from mindspore import numpy as msnp
ms.set_context(device_target="GPU", mode=ms.GRAPH_MODE)
@ms.jit
def U(x, mu=1.0, k=1.0):
return msnp.sum(0.5 * k * (x-mu) ** 2)
def f(x, N=1000, size=1000000):
ene = 0.
start_time = time.time()
for i in range(N):
x_tensor = ms.Tensor(x[i*size:(i+1)*size], ms.float32)
ene += U(x_tensor)
end_time = time.time()
print ("The calculation time cost is: {:.3f} s".format(end_time - start_time))
return ene.asnumpy()
x = np.ones(1000000000)
energy = f(x)
print (energy)
# The calculation time cost is: 11.732 s
# 0.0
这里至少没有报内存错误了,因为每次只有在计算的时候我们才把相应的部分拷贝到显存中。接下来使用流计算,也就是边拷贝边计算的功能:
def f_stream(x, N=1000, size=1000000):
ene = 0.
s1 = ms.hal.Stream()
s2 = ms.hal.Stream()
start_time = time.time()
for i in range(N):
if i % 2 == 0:
with ms.hal.StreamCtx(s1):
x_tensor = ms.Tensor(x[i*size:(i+1)*size], ms.float32)
ene += U(x_tensor)
else:
with ms.hal.StreamCtx(s2):
x_tensor = ms.Tensor(x[i*size:(i+1)*size], ms.float32)
ene += U(x_tensor)
ms.hal.synchronize()
end_time = time.time()
print ("The calculation with stream time cost is: {:.3f} s".format(end_time - start_time))
return ene.asnumpy()
因为要考虑到程序编译对性能带来的影响,所以这里使用与不使用Stream的对比需要分开执行。经过多次测试之后,不使用Stream的运行时长大约为:
The calculation time cost is: 10.925 s
41666410.0
而使用Stream的运行时长大约为:
The calculation with stream time cost is: 9.929 s
41666410.0
就直观而言,Stream计算在MindSpore中有可能带来一定的加速效果,但其实这种加速效果相比于直接写CUDA Stream带来的效果增益其实要弱一些,可能跟编译的逻辑有关系。但至少现在有了Stream这样的一个工具可以在MindSpore中直接调用,就可以跟很多同类型的框架同步竞争了。
总结概要
接上一篇对于MindSpore-2.4-gpu版本的安装介绍,本文主要介绍一些MindSpore-2.4版本中的新特性,例如使用hal对设备和流进行管理,进而支持Stream流计算。另外还有类似于Jax中的fori_loop方法,MindSpore最新版本中也支持了ForiLoop循环体,使得循环的执行更加高效,也是端到端自动微分的强大利器之一。
版权声明
本文首发链接为:https://www.cnblogs.com/dechinphy/p/ms24.html
作者ID:DechinPhy
更多原著文章:https://www.cnblogs.com/dechinphy/
请博主喝咖啡:https://www.cnblogs.com/dechinphy/gallery/image/379634.html
MindSpore-2.4版本中的一些新特性的更多相关文章
- cocos3.2版本中的一些新特性
1.设置屏幕分辨率的大小,需要手动添加: 2.去掉了所有CC开头的命名: 3.所有的单例(以前是采用shared开头方法),全部改为getInstance(); 4.cocos3.x以上的版本支持C+ ...
- MVC中的其他新特性
MVC中的其他新特性 (GlobalImport全局导入功能) 默认新建立的MVC程序中,在Views目录下,新增加了一个_GlobalImport.cshtml文件和_ViewStart.cshtm ...
- xmake v2.1.5版本正式发布,大量新特性更新
此版本带来了大量新特性更新,具体详见:xmake v2.1.5版本新特性介绍. 更多使用说明,请阅读:文档手册. 项目源码:Github, Gitee. 新特性 #83: 添加 add_csnippe ...
- Xcode中StoryBoard Reference 新特性的使用
html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,bi ...
- 浅析Oracle 12c中Data Guard新特性
浅析Oracle 12c中Data Guard新特性 写在前面 无论是做Oracle运维的小伙伴还是老伙伴,想必对Oracle数据库的数据级灾备核心技术—Data Guard是再熟悉不过了!这项从 ...
- ES6系列之项目中常用的新特性
ES6系列之项目中常用的新特性 ES6常用特性 平时项目开发中灵活运用ES6+语法可以让开发者减少很多开发时间,提高工作效率.ES6版本提供了很多新的特性,接下来我列举项目中常用的ES6+的特性: l ...
- Jdk5.0中出现的新特性
掌握jdk5.0中出现的新特性1.泛型(Generics)2.增强的"for"循环(Enhanced For loop)3.自动装箱/自动拆箱(Autoboxing/unboxin ...
- C#6.0 中的那些新特性
C#6.0 中的那些新特性 前言 VS2015在自己机器上确实是装好了,费了老劲了,想来体验一下跨平台的快感,结果被微软狠狠的来了一棒子了,装好了还是没什么用,应该还需要装Xarmain插件,配置一些 ...
- iOS中的项目新特性页面的处理
一般项目中都会出现新特性页面,比如第一次使用应用的时候,或者在应用设置里查看新特性的时候会出现. 这里,选择新建一个专门处理项目新特性的控制器,来完成功能. 首先是 NewFeaturesViewCo ...
- [译] OpenStack Kilo 版本中 Neutron 的新变化
OpenStack Kilo 版本,OpenStack 这个开源项目的第11个版本,已经于2015年4月正式发布了.现在是个合适的时间来看看这个版本中Neutron到底发生了哪些变化了,以及引入了哪些 ...
随机推荐
- 在 Mac 上使用 X11
有时我们需要在服务器上运行一个 GUI 程序,然而我们是通过 SSH 连接到服务器的,看不到图形界面,怎么办呢?我们可以通过 X11 将 GUI 程序的界面转发到本地. 在 Mac 上使用 X11 需 ...
- csdn 下载券恶心之处
今天在csdn碰到一个恶心事,啥事呢?下载券.详细的说,就是人家码友把下载积分都设置成0了,让大家自行下载.结果,却不行,非得搞个下载券,得去做任务,给它的广告爹爹们点点任务才能获取下载券的code. ...
- C语言linux系统fork函数
References: c语言fork函数 linux中fork()函数详解 一.fork函数简介 作用 在linux下,C语言创建进程用fork函数.fork就是从父进程拷贝一个新的进程出来,子进程 ...
- Goby漏洞发布 | CVE-2024-38856 Apache OFbiz /ProgramExport 命令执行漏洞【已复现】
漏洞名称:Apache OFbiz /ProgramExport 命令执行漏洞(CVE-2024-38856) English Name:Apache OFbiz /ProgramExport Com ...
- 【合合TextIn】OCR身份证 / 银行卡识别功能适配鸿蒙系统
一.鸿蒙系统与信创国产化的背景 自鸿蒙系统推出以来,其不仅成为了华为在软件领域的重要里程碑,更是国产操作系统的一面旗帜,也是国产移动平台几乎唯一的选择,标志着中国在构建独立自主的软件生态体系上迈 ...
- 深入理解ConcurrentHashMap
HashMap为什么线程不安全 put的不安全 由于多线程对HashMap进行put操作,调用了HashMap的putVal(),具体原因: 假设两个线程A.B都在进行put操作,并且hash函数计算 ...
- SQL注入演示
SQL注入演示 创建一个简易的登录系统/** tb_user 用户表 * 用户登录系统(需在数据库中创建tb_user表 ) */ @Test public void testUserLogin() ...
- MVC模式与三层架构
MVC 模式 三层架构 MVC 模式 与 三层架构 的关系
- Windows远程设置''不可复制''的权限
起因: 有一个技术部门的同事需要远程其他同学的电脑进行操作,但是不允许他复制目标电脑上的文件,避免造成资料外泄 解决办法: 组策略编辑器中,设置 计算机配置 -> 管理模板 -> wind ...
- 离线安装Redis
redis 直接去官网下载tar包就可以 主要是gcc 环境的安装包不太好找,我下载的还缺少 make 如果服务器比较干净,还得预装一下lrzsz-0.12.20.tar.gz 上传下载文件,unzi ...