ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

使用 R 语言操作 MXNet NDArray:CPU/GPU 上的向量化张量计算与自动并行

使用 R 语言操作 MXNet NDArray:CPU/GPU 上的向量化张量计算与自动并行 人工智能深度学习机器学习【免费下载链接】mxnetLightweight, Portable, Flexible Distributed/Mobile Deep Learning with Dynamic, Mutation-aware Dataflow Dep Scheduler; for Python, R, Julia, Scala, Go, Javascript and more项目地址https://gitcode.com/gh_mirrors/mxne/mxnet点击查看免费下载NDArray是 MXNet 中面向矩阵与张量计算的基础向量化运算单元。本文基于 MXNet 官方 R 教程 ndarray.md 展开系统讲解在 R 中创建、初始化、运算、跨设备复制以及序列化NDArray的完整方法并深入剖析其底层惰性求值 依赖感知调度引擎实现自动并行化的原理。读完本文你将能在 R 会话中熟练完成 CPU/GPU 上的张量运算并理解 MXNet 引擎Engine如何在多设备场景下自动解析依赖、并行执行算子。NDArray 是什么NDArrayN-Dimensional Array是 MXNet 中的基本向量化运算单元负责矩阵和张量Tensor计算。它的使用体验与 R 语言原生的多维数组array非常接近——可以像操作普通 R 数组一样做加减乘除、切片等常规运算但在此基础上额外提供两个关键特性多设备支持Multiple devices所有运算都可以运行在多种设备上包括 CPU 与 GPU自动并行化Automatic parallelization所有运算彼此之间都会被引擎自动并行执行。这两个特性由 MXNet 底层的执行引擎统一保障R 前端通过 C API 将算子派发到引擎由引擎负责设备调度与依赖解析详见 engine.h 中Push/PushAsync/PushSync等接口。这意味着使用 R 编写的深度学习代码可以在几乎不修改的情况下从单机 CPU 平滑迁移到 GPU 乃至多卡环境。创建与初始化 NDArray在 CPU 或 GPU 上创建使用require(mxnet)加载 R 包后即可通过mx.nd.zeros在指定设备上创建全零张量require(mxnet)输出## Loading required package: mxnet ## Loading required package: methodsa - mx.nd.zeros(c(2, 3)) # 在 cpu 上创建 2×3 矩阵 b - mx.nd.zeros(c(2, 3), mx.cpu()) # 显式指定 cpu创建 2×3 矩阵 # c - mx.nd.zeros(c(2, 3), mx.gpu(0)) # 在 gpu 0 上创建 2×3 矩阵需要 CUDA 环境几点说明不传设备参数时默认在 CPU 上创建mx.cpu()与mx.gpu()是 R 包提供的设备上下文构造函数对 CUDA 使能的设备GPU 的 device id 从0开始编号因此mx.gpu(0)表示第一块 GPU设备上下文Context信息会随 NDArray 一起被记录与序列化见 ndarray.cc 中Context ctx this-ctx(); ctx.Save(strm);的保存逻辑。多种初始化方式除了全零矩阵R 包还提供了多种初始化入口a - mx.nd.ones(c(4, 4)) # 全 1 矩阵4×4 b - mx.rnorm(c(4, 5)) # 标准正态随机数4×5 c - mx.nd.array(1:5) # 从 R 向量 1:5 构造 NDArraymx.nd.ones全 1 张量常用于初始化偏置或掩码mx.rnorm按标准正态分布采样用于权重随机初始化mx.nd.array将 R 向量 / 矩阵 / 数组直接包装为 NDArray是 R 数据进入 MXNet 计算图最常见的入口。查看 NDArray 内容要查看 NDArray 中的数值可以使用as.array将其转换为 R 原生的数组对象a - mx.nd.ones(c(2, 3)) b - as.array(a) class(b)输出## [1] matrixb输出## [,1] [,2] [,3] ## [1,] 1 1 1 ## [2,] 1 1 1as.array是一个同步点synchronization point它会把 NDArray 中尚未完成的计算强制拉取到 CPU 并阻塞等待结果因此输出的b是标准的 Rmatrix可以继续用 R 的一切原生工具处理。执行基本运算逐元素运算Element-wise OperationsNDArray 支持与 R 数组一致的逐元素运算符重载*、/、、-都会逐元素作用于整个张量a - mx.nd.ones(c(2, 4)) * 2 b - mx.nd.ones(c(2, 4)) / 8 as.array(a)输出## [,1] [,2] [,3] [,4] ## [1,] 2 2 2 2 ## [2,] 2 2 2 2as.array(b)输出## [,1] [,2] [,3] [,4] ## [1,] 0.125 0.125 0.125 0.125 ## [2,] 0.125 0.125 0.125 0.125c - a b as.array(c)输出## [,1] [,2] [,3] [,4] ## [1,] 2.125 2.125 2.125 2.125 ## [2,] 2.125 2.125 2.125 2.125d - c / a - 5 as.array(d)输出## [,1] [,2] [,3] [,4] ## [1,] -3.9375 -3.9375 -3.9375 -3.9375 ## [2,] -3.9375 -3.9375 -3.9375 -3.9375可以看到c / a - 5这样的复合表达式可以一气呵成地作用在张量上这正是向量化运算的威力无需手写循环一个表达式即完成对整个矩阵的变换。跨设备复制如果两个 NDArray 位于不同设备上必须先把它们显式移动到同一设备才能参与同一表达式运算。例如a - mx.nd.ones(c(2, 3)) * 2 b - mx.nd.ones(c(2, 3), mx.gpu()) / 8 c - mx.nd.copyto(a, mx.gpu()) * b as.array(c)这里a在 CPU 上、b在 GPU 上直接a * b会失败先用mx.nd.copyto(a, mx.gpu())把a复制到 GPU再与b相乘。底层对应的正是 ndarray.cc 中的CopyFromTo系列实现——它按cpu-cpu、cpu-gpu、gpu-cpu、gpu-gpu四条路径分别派发见CopyFromToImplcpu, gpu、CopyFromToImplgpu, cpu等重载并通过WaitToWrite/WaitToRead保证复制前后的读写依赖正确性。跨设备复制本身也是由引擎异步执行的算子因此可以和其它计算重叠这也是自动并行化的重要组成。加载与保存序列化保存到本地磁盘可以使用mx.nd.save将一个 NDArray 列表保存到磁盘a - mx.nd.ones(c(2, 3)) mx.nd.save(list(a), temp.ndarray)重新加载加载同样简单mx.nd.load返回一个列表通过[[1]]取出第一个元素a - mx.nd.load(temp.ndarray) as.array(a[[1]])输出## [,1] [,2] [,3] ## [1,] 1 1 1 ## [2,] 1 1 1分布式文件系统保存/加载天然支持分布式文件系统只需把路径换成对应的 URI 前缀mx.nd.save(list(a), s3://mybucket/mydata.bin) # 保存到 Amazon S3 mx.nd.save(list(a), hdfs///users/myname/mydata.bin) # 保存到 HDFS这种能力来自 dmlc-core 的流式抽象NDArray::Save与NDArray::Load都基于dmlc::Stream见 ndarray.cc。保存时会先写入魔术数NDARRAY_V2_MAGIC/NDARRAY_V3_MAGIC标记存储格式随后依次序列化存储类型storage type、稀疏存储形状、数据形状、设备上下文与数据本身若张量在 GPU 上还会先拷贝一份 CPU 副本再落盘保证加载端无设备依赖。S3 / HDFS 这类分布式文件系统即由dmlc::Stream的对应实现s3://、hdfs://前缀透明接管R 用户无需感知差异。自动并行化原理惰性求值与依赖感知调度为什么需要自动并行当程序同时使用多种资源多块 CPU、多块 GPU、CPU 与 GPU 之间的内存带宽时自动并行化能显著提升效率。例如先执行a - a 1a 在 CPU 上再执行b - b 1b 在 GPU 上两者互不依赖并行执行自然更快又因为 CPU 与 GPU 之间的数据拷贝本身代价高昂把拷贝与其它计算并行执行能进一步藏掉传输延迟。用肉眼难以判断依赖下面这段代码中哪些操作可以并行、哪些必须串行a - mx.nd.ones(c(2,3)) b - a c - mx.nd.copyto(a, mx.cpu()) a - a 1 b - b * 3 c - c * 3分析依赖关系a - a 1与c - c * 3读写互不干扰可以并行a - a 1与b - b * 3表面上无关但b - a让b与a共享同一份底层存储copy-on-write 语义对a的写入会影响b的读取因此两者必须串行。这类隐藏在共享存储背后的依赖靠肉眼逐行分析极易出错。幸运的是MXNet 会自动解析依赖关系并准确地将无依赖的操作并行执行。这意味着我们可以用假设只有单线程的方式编写程序MXNet 会负责把程序自动派发到多个设备上。底层机制惰性求值Lazy EvaluationMXNet 实现自动并行的核心是惰性求值每个运算都会被派发issue到内部引擎Engine后立即返回。例如执行a - a 1时R 调用会先返回加号算子则被压入引擎队列——调用本身几乎不阻塞这种异步处理方式让我们可以持续向引擎压入更多算子而不会卡在等待计算完成上引擎会确定每个算子的读写依赖找出最优的并行执行方式。引擎层面的接口定义可见 engine.hNewOperator创建算子OprHandlePush/PushAsync/PushSync负责把算子连同执行上下文Context与优先级推入调度队列DeleteOperator在算子完成后回收资源。引擎内部维护算子的读写依赖边据此构造可并行的执行图——这正是教程中自动解析依赖并准确并行在源码层面的落点。何时真正同步实际计算会在我们需要结果的那一刻完成例如执行as.array(a)或mx.nd.save(a, temp.dat)时引擎才会阻塞等待相关算子链全部执行完毕。因此要写出高度并行的代码只需尽量推迟取结果的时间点把结果留在引擎的异步流水线里让尽可能多的算子在后台重叠执行。小结与下一步本文完整覆盖了 R 中NDArray的四大操作主题主题关键 API核心要点创建与初始化mx.nd.zeros/mx.nd.ones/mx.rnorm/mx.nd.array指定设备CPU/GPUGPU id 从 0 开始基本运算运算符重载 - * /逐元素运算跨设备需先mx.nd.copyto加载与保存mx.nd.save/mx.nd.load支持本地、S3、HDFS底层为dmlc::Stream序列化自动并行惰性求值 依赖感知引擎单线程编程假设引擎自动并行派发在掌握 NDArray 之后建议继续学习 MXNet R 包的后续教程构建从张量运算到端到端模型的完整能力Symbol声明式符号编程了解如何用 Symbol 组合计算图、定义网络结构使用预训练模型对真实图片分类将 NDArray Symbol 用于实际推理任务基于 RNN 的字符语言模型完整展示一个序列模型在 R 中的训练流程。相关教程的完整性由仓库测试保障例如 test_sanity_tutorials.py 将r/ndarray.md等 R 教程纳入白名单并校验其格式规范确保本文引用的代码示例与文档结构在仓库中始终可复现。赞分享人工智能深度学习机器学习【免费下载链接】mxnetLightweight, Portable, Flexible Distributed/Mobile Deep Learning with Dynamic, Mutation-aware Dataflow Dep Scheduler; for Python, R, Julia, Scala, Go, Javascript and more项目地址https://gitcode.com/gh_mirrors/mxne/mxnet点击查看免费下载相关推荐CAVA并行计算多线程与向量化计算的协同使用CAVA并行计算多线程与向量化计算的协同使用 引言音频可视化的性能挑战 音频可视化在现代多媒体应用中扮演着重要角色从音乐播放器到专业音频分析工具实时频谱音视频桌面应用使用 FAIRChem UMA 与 quacc 自动计算弹性张量与体模量使用 FAIRChem UMA 与 quacc 自动计算弹性张量与体模量 本文介绍如何基于 FAIR Chemistry 仓库ocp的 UMA 系列机器学习人工智能机器学习深度学习预训练科学计算科研基础模型如何为Baichuan-M1-14B-Base配置MindIE服务从单机到集群的部署策略如何为Baichuan M1 14B Base配置MindIE服务从单机到集群的部署策略 想要高效部署Baichuan M1 14B Base大语言模型吗M上一篇L2P常见问题解答解决AI图像生成中的20个技术难题 下一篇3个关键步骤掌握LuytenJava字节码反编译的终极解决方案创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表