深度学习人工智能机器学习分布式训练【免费下载链接】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/mx/mxnet点击查看免费下载MXNet 的mxnet.ndarray.sparse模块为深度学习中的稀疏数据推荐系统特征、图数据邻接矩阵、稀疏梯度等提供了两种原生存储格式CSRCompressed Sparse Row压缩稀疏行与 Row Sparse行稀疏。本文以该模块的官方 API 文档docs/python_docs/python/api/legacy/ndarray/sparse/index.rst为主线结合模块源码 python/mxnet/ndarray/sparse.py 与算子实现、单元测试系统讲解两种稀疏格式的数据布局、五种构造方式、基本运算与限制以及它们在 GPU 稀疏算子如 embedding、sparse dot中的应用场景。读完本文你将掌握在 MXNet 中创建、转换、运算和导出稀疏张量的完整实战能力并能理解其底层存储结构与格式校验机制。一、什么是稀疏 NDArray两种存储格式与适用场景MXNet 中的 NDArray 默认使用稠密dense存储即default存储类型。当数据中包含大量零值例如高维稀疏特征、大规模 embedding 表、邻接矩阵时稠密存储会浪费大量内存与计算资源。mxnet.ndarray.sparse提供了两种稀疏存储类型由stype标识存储类型类名维度限制数据结构典型场景csrCSRNDArray仅 2D 矩阵dataindicesindptr稀疏矩阵乘法、推荐系统、图数据row_sparseRowSparseNDArray至少 2 维dataindices稀疏梯度、稀疏 embedding 查询存储类型 ID 在 python/mxnet/ndarray/ndarray.py 中定义_STORAGE_TYPE_STR_TO_ID、_STORAGE_TYPE_CSR、_STORAGE_TYPE_ROW_SPARSE而每种存储类型对应的辅助aux数据数组类型在 sparse.py 中由_STORAGE_AUX_TYPES映射_STORAGE_AUX_TYPES { row_sparse: [np.int64], # 一个 aux 数组indicesint64 类型 csr: [np.int64, np.int64] # 两个 aux 数组indptr 与 indices均为 int64 }也就是说所有稀疏索引数组统一使用int64存储并且_new_alloc_handle在分配底层句柄时会强制校验 aux 类型必须为 int64见 sparse.py。当 MXNet 开启 int64 维度支持_int64_enabled时走MXNDArrayCreateSparseEx64路径否则走MXNDArrayCreateSparseEx路径。1.1 CSRNDArray压缩稀疏行格式CSRNDArray表示一个二维稀疏矩阵由三个一维数组构成见 sparse.py 的类文档data按行主序存储所有非零元素的值indptr长度为num_rows 1的行偏移数组第i行的列索引区间为indices[indptr[i]:indptr[i1]]对应值区间为data[indptr[i]:indptr[i1]]indices每个非零元素的列索引。格式约束同一行的列索引必须升序排列且同一行内不允许出现重复列。类文档中的经典示例 a mx.nd.array([[0, 1, 0], [2, 0, 0], [0, 0, 0], [0, 0, 3]]) a a.tostype(csr) a.data.asnumpy() array([ 1., 2., 3.], dtypefloat32) a.indices.asnumpy() array([1, 0, 2]) a.indptr.asnumpy() array([0, 1, 2, 2, 3])对照原始矩阵第 0 行非零元素为(列1, 值1)第 1 行为(列0, 值2)第 2 行为空indptr[2]indptr[3]2第 3 行为(列2, 值3)。1.2 RowSparseNDArray行稀疏格式RowSparseNDArray表示一个至少 2 维的 NDArray其中只有少数整行切片非零见 sparse.py 的类文档data形状为[D0, D1, ..., Dn]的 NDArray存放非零行切片indices形状为[D0]的一维 int64 NDArray存放非零行切片的行索引必须升序排列。其与稠密数组的对应关系为dense[rsp.indices[i], :, :, :, ...] rsp.data[i, :, :, :, ...]即除indices命中的行外其余行全部为零。 dense mx.nd.array([[1, 2, 3], [0, 0, 0], [4, 0, 5], [0, 0, 0], [0, 0, 0]]) rsp dense.tostype(row_sparse) rsp.indices.asnumpy() array([0, 2], dtypeint64) rsp.data.asnumpy() array([[ 1., 2., 3.], [ 4., 0., 5.]], dtypefloat32)RowSparseNDArray尤其适合表示形状[LARGE0, D1, ..., Dn]LARGE0 D0且大部分行切片为零的大数组其主要用途是定义具有稀疏梯度的算子如稀疏点积 sparse dot、稀疏 embedding的梯度表示——这是模型训练中节省内存的关键机制。二、稀疏数组的构造五种实例化方式模块提供了两个核心构造函数csr_matrix与row_sparse_array二者都支持从多种输入形态构造稀疏数组。2.1csr_matrix构造 CSRNDArraycsr_matrix(arg1, shapeNone, ctxNone, dtypeNone)的完整签名见 sparse.py支持五种输入形态形态一csr_matrix(D)从稠密二维数组构造。D可以是任意数组接口对象、嵌套序列等ctx默认为当前默认设备dtype默认为D.dtype若D是 NDArray 或 numpy.ndarray否则默认float32。实现上会先把D转为稠密 NDArray必要时做as_in_context跨设备拷贝再调用tostype(csr)。形态二csr_matrix(S)从稀疏矩阵构造。S可以是CSRNDArray或scipy.sparse.csr.csr_matrixdtype默认取S.dtype。注意若传入RowSparseNDArray会抛出ValueError。从 scipy 稀疏矩阵构造时模块会先规范化sorted_indices()排序、sum_duplicates()合并重复项见 sparse.py以保证满足 CSR 格式约束。形态三csr_matrix((M, N))构造空矩阵。M为行数、N为列数得到全零CSRNDArray默认dtype为float32。实现上等价于empty(csr, (M, N), ...)而empty内部会落到zeros见 sparse.py。形态四csr_matrix((data, indices, indptr))按 CSR 定义构造。三个数组分别对应非零值、列索引、行偏移shape默认根据indices与indptr推断(len(indptr)-1, max(indices)1)。构造内部_csr_matrix_from_definitionsparse.py会校验data/indptr/indices均为一维、indptr非空且shape为 2 维然后通过MXNDArraySyncCopyFromNDArray分别把三块数据写入 data索引-1与两个 aux 通道索引0/1。形态五csr_matrix((data, (row, col)))按 COO 坐标格式构造。row[i]/col[i]为第i个元素的坐标data[i]为其值未列出的元素视为零。实现上借助 scipy先构造scipy.sparse.coo_matrix再tocsr()因此要求环境已安装 scipy否则抛ImportError。文档中的综合示例 a mx.nd.sparse.csr_matrix(([1, 2, 3], [1, 0, 2], [0, 1, 2, 2, 3]), shape(4, 3)) a.asnumpy() array([[ 0., 1., 0.], [ 2., 0., 0.], [ 0., 0., 0.], [ 0., 0., 3.]], dtypefloat32)2.2row_sparse_array构造 RowSparseNDArrayrow_sparse_array(arg1, shapeNone, ctxNone, dtypeNone)的完整签名见 sparse.py支持四种输入形态row_sparse_array(D)从稠密数组构造默认 dtype 取D.dtype否则float32row_sparse_array(S)从RowSparseNDArray拷贝构造传入CSRNDArray会抛ValueErrorrow_sparse_array((D0, D1, ..., Dn))构造空的行稀疏数组注意当元组长度恰好为 2 且两个元素都是整数时如(3, 3)被解释为形状而非(data, indices)row_sparse_array((data, indices))按定义构造indices存放非零行切片的行索引升序shape默认推断为(max(indices)1,) data.shape[1:]。文档示例 a mx.nd.sparse.row_sparse_array(([[1, 2], [3, 4]], [1, 4]), shape(6, 2)) a.asnumpy() array([[ 0., 0.], [ 1., 2.], [ 0., 0.], [ 0., 0.], [ 3., 4.], [ 0., 0.]], dtypefloat32)2.3 其他构造辅助函数zeros(stype, shape, ctxNone, dtypeNone)创建指定存储类型的全零稀疏数组stype取row_sparse或csr未知存储类型抛ValueErrorstypedefault时退化为普通稠密zerossparse.py。empty(stype, shape, ctxNone, dtypeNone)名义上不初始化但对稀疏格式而言实际落到zeros。array(source_array, ctxNone, dtypeNone)从RowSparseNDArray/CSRNDArray/scipy.sparse.csr_matrix创建稀疏数组。对 NDArray 输入会断言stype ! default稠密数组应使用tostype转换若同时需要跨 dtype 与跨 ctx 拷贝会先建空数组赋值再as_in_contextsparse.py。三、稀疏数组的基本操作与索引语义3.1 类级别通用能力BaseSparseNDArrayBaseSparseNDArraysparse.py是所有稀疏 NDArray 的基类提供asnumpy()返回稠密numpy.ndarray内部先tostype(default)再取值astype(dtype, copyTrue)类型转换。copyFalse且 dtype 相同时直接返回自身否则通过新建同 stype 零数组 copyto实现注释说明op.cast不支持稀疏 stypecopyto(other)拷贝到目标 NDArray/稀疏数组或设备Device上下文check_format(full_checkTrue)格式合法性校验底层调用MXNDArraySyncCheckFormat。full_checkTrue时是 O(N) 的严格检查False时是 O(1) 的基础检查_data()/_aux_data(i)深拷贝获取数据数组与第i个 aux 数组阻塞式勿在性能关键路径使用。明确的限制继承自NDArray接口但稀疏不支持的操作reshape、_at[idx]整数索引、_slice非连续切片会抛出NotSupportedForSparseNDArraysize属性因语义歧义被禁用NotImplementedError原地运算__iadd__等默认NotImplementedError。__repr__只显示形状与设备而不显示数据内容避免大数组刷屏CSRNDArray 1x2 cpu(0)3.2 CSRNDArray 的索引与赋值读取__getitem__sparse.py支持整数索引a[i]含负索引a[-1]等价于最后一行内部转为op.slice(begini, endi1)连续切片a[start:stop]仅限轴 0a[:]返回自身不支持step切片与多维元组索引分别抛ValueError。 a mx.nd.sparse.csr_matrix((data, indices, indptr), shape(3, 3)) a[1:2].asnumpy() array([[ 0., 0., 3.]], dtypefloat32) a[-1].asnumpy() array([[ 4., 5., 6.]], dtypefloat32)写入__setitem__sparse.py仅支持整切片x[:] value且要求数组可写。value可以是同 stype 稀疏数组、稠密 NDArray直接copytonumpy 数组会先转成临时 NDArray 再拷贝并发出效率不高的RuntimeWarning标量赋值不支持。data/indices/indptr属性为只读setter 抛NotImplementedError保证格式一致性。asscipy()将CSRNDArray转为scipy.sparse.csr_matrix要求已安装 scipy便于与科学计算生态互操作。3.3 RowSparseNDArray 的索引与赋值__getitem__仅支持x[:]返回自身整数索引与带 start/stop/step 的切片均未实现__setitem__同样仅支持x[:] value与 CSR 不同支持标量赋值_internal._set_value填充整个数组见 sparse.pyretain()便捷方法等价于mx.nd.sparse.retain对应算子sparse_retain实现于 src/operator/tensor/sparse_retain.cc可从稀疏数组中按索引挑出子集。四、稀疏数组的四则运算与广播语义模块导出四个模块级函数add/subtract/multiply/divide对应运算符 - * /类内通过__add__等转发。它们的统一语义为形状相同时走逐元素算子elemwise形状不同时走广播算子broadcast具体由_ufunc_helper分派见 sparse.py 的add实现。以add(lhs, rhs)为例def add(lhs, rhs): if isinstance(lhs, NDArray) and isinstance(rhs, NDArray) and lhs.shape rhs.shape: return _ufunc_helper(lhs, rhs, op.elemwise_add, operator.add, _internal._plus_scalar, None) return _ufunc_helper(lhs, rhs, op.broadcast_add, operator.add, _internal._plus_scalar, None)广播规则两数组对应维度大小相等或其一为 1 时即可广播到公共形状。multiply/divide的文档示例同时展示了稀疏 × 稠密列向量(2,3) × (2,1)与稀疏 × 稠密行向量(2,3) × (3,)/(1,3)的广播行为。运算结果统一返回 NDArray稀疏运算结果类型由算子 stype 推断逻辑决定见下文存储回退。单元测试 tests/python/unittest/test_sparse_ndarray.py 覆盖了逐元素加减乘除test_sparse_nd_binary、标量运算test_sparse_nd_binary_scalar_op、原地运算 -test_sparse_nd_binary_iopiadd通过先算后 copyto实现、广播test_sparse_nd_broadcast以及astypetest_sparse_nd_astype、test_sparse_nd_astype_copy等行为可作为验证参考。五、存储类型转换与稀疏算子生态5.1tostype存储格式互转CSRNDArray.tostype(stype)sparse.py支持default转稠密row_sparse不被支持会抛ValueErrorRowSparseNDArray.tostype(stype)sparse.py支持defaultcsr不被支持。两者都通过op.cast_storage算子实现。该算子的 CPU/GPU 实现位于 src/operator/tensor/cast_storage.cc、cast_storage-inl.h 与 cast_storage-inl.cuh从源码结构看它按输入/输出 stype 的组合default↔csr、default↔row_sparse分别走不同的转换内核。5.2 稀疏存储回退Storage Fallback并非所有算子都支持稀疏 stype。当稀疏输入进入不支持的算子时MXNet 会自动回退到稠密存储test_sparse_nd_storage_fallback测试验证了这一行为。因此稀疏格式主要用于内存优化场景实际计算可能仍需稠密化。5.3 稀疏生态算子源码佐证围绕row_sparse存储MXNet 原生实现了面向稀疏梯度的算子族例如sparse_retainsparse_retain-inl.h、sparse_retain.cc、sparse_dot以及sparse embeddingcontrib下的稀疏 embedding 算子如SparseEmbedding。RowSparseNDArray类文档明确说明它主要用于具有稀疏梯度的操作如稀疏点积与稀疏 embedding的梯度表示这类算子在反向传播时直接产出row_sparse梯度避免为全零行分配内存。六、与 SciPy 生态互操作及测试验证MXNet → SciPyCSRNDArray.asscipy()返回scipy.sparse.csr_matrix示例见 sparse.pySciPy → MXNetcsr_matrix(scipy_csr)与array(scipy_csr)均可后者会先规范化排序 去重再构造持久化test_sparse_nd_save_load验证了稀疏 NDArray 的save/load序列化test_sparse_ndarray_load_csr_npz_scipy表明可从 scipy 的.npz文件加载 CSR 数据pickletest_sparse_nd_pickle验证稀疏数组可被pickle序列化两类均实现了__reduce__格式校验test_sparse_nd_unsupported覆盖了各类不支持操作的异常行为。完整测试清单见 tests/python/unittest/test_sparse_ndarray.py 与 tests/python/unittest/test_sparse_operator.py。七、实战建议与限制总结选型二维稀疏矩阵特征交叉、邻接矩阵用csr大 embedding 表 / 稀疏梯度行切片粒度用row_sparse。两者都要求索引升序且无重复CSR 还要求同行列索引不重复构造后可用check_format(True)做严格校验。构造优先用csr_matrix/row_sparse_array的多种形态直接构造或对稠密数组调用tostype与 scipy 互操作时注意先规范化。运算边界稀疏数组仅支持基于 - * /的逐元素/广播四则运算reshape、整数索引、多维索引、非[:]切片赋值均不支持csr与row_sparse之间不能直接互转需先转稠密。内存视角data/indices/indptr属性返回的是深拷贝频繁访问有拷贝开销不宜放入性能关键循环_data()/_aux_data(i)为阻塞式拷贝仅供调试。dtype 规则索引数组统一为int64数据 dtype 未指定时从输入继承NDArray/numpy/scipy否则默认float32。赞分享深度学习人工智能机器学习分布式训练【免费下载链接】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/mx/mxnet点击查看免费下载相关推荐MXNet 稀疏符号 API 详解mxnet.symbol.sparse 模块、稀疏存储格式与稀疏算子MXNet 稀疏符号 API 详解mxnet.symbol.sparse 模块、稀疏存储格式与稀疏算子 MXNet 官方文档中的 symbol.sparse人工智能深度学习机器学习Apache MXNet 稀疏 NDArray 完全指南CSR 与 RowSparse 存储格式的 API 精讲与源码剖析Apache MXNet 稀疏 NDArray 完全指南CSR 与 RowSparse 存储格式的 API 精讲与源码剖析 Apache MXNet 在 mx人工智能深度学习机器学习CuPy GPU 稀疏矩阵与稀疏数组完全指南cupyx.scipy.sparse 用法、索引 dtype 与底层 cuSPARSE 实现CuPy GPU 稀疏矩阵与稀疏数组完全指南cupyx.scipy.sparse 用法、索引 dtype 与底层 cuSPARSE 实现 CuPy 在 cup科学计算高性能计算上一篇Semantic-UI-React错误处理策略提升应用健壮性下一篇Rector 快速升级 PHP 8.4一条 withPhpSets() 完成自动化改造创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考 SEO 优化官网定制响应式建站教育培训建站