[经验分享]使用mindspore算子替换numpy的数组更新操作

例如以下代码, 有两个numpy数组x1和x2, 现在需要更新x1的第0行前512个数据, 只需要一行代码更新对应位置的数据即可, 但是在mindspore中tensor不能这样操作, 需要另外的方案解决. 这里提供一种使用concat算子的解决方案.

import numpy as np
x1 = np.ones((10, 1024), dtype=np.float32)
x2 = np.zeros((10, 1024), dtype=np.float32)
for i in range(10):
    for j in range(1024):
            x2[i][j] = j
x1[0, :512] = x2[0,:512]

假如mindspore中tensor使用类是numpy数组的做法, 生成的mindir模型转ms模型会报如下警告:

\[WARNING\] LITE(267874,7eca2d6c3f40,converter_lite):2025-11-19-02:46:11.089.637 \[mindspore/lite/tools/optimizer/graph/infershape_pass.cc:180\] Run\] exist op cannot support infer shape.
\[WARNING\] LITE(267874,7eca2d6c3f40,converter_lite):2025-11-19-02:46:11.089.701 \[mindspore/lite/src/common/ops/ops_utils.h:50\] GetPrimitiveCreator\] Unsupported primitive type in Create: TensorCopySlices
\[WARNING\] LITE(267874,7eca2d6c3f40,converter_lite):2025-11-19-02:46:11.089.707 \[mindspore/lite/src/common/ops/anf_utils.cc:38\] GetPrimitiveT\] can not find MSOpsRegistry for op: TensorCopySlices
\[WARNING\] LITE(267874,7eca2d6c3f40,converter_lite):2025-11-19-02:46:11.089.714 \[mindspore/lite/tools/optimizer/graph/infershape_pass.cc:180\] Run\] exist op cannot support infer shape.

代码:

import mindspore as ms
from mindspore import Tensor, nn, ops
class Test(nn.Cell):
    def __init__(self, num):
        super().__init__()
        self.num = num

    def construct(self, x1, x2):
        x1[0, :512] = x2[0,:512]
        return x1
x1 = np.ones((10, 1024), dtype=np.float32)
x2 = np.zeros((10, 1024), dtype=np.float32)
for i in range(10):
    for j in range(1024):
            x2[i][j] = j
x1_tensor = Tensor(x1, dtype=ms.float32)
x2_tensor = Tensor(x2, dtype=ms.float32)
net = Test(512)
ms.export(net, x1_tensor, x2_tensor, file_name='test', file_format='MINDIR')

生成的模型长如下, 不知道这个ms模型在lite端是否能够部署:


使用concat算子代替的方法代码如下, 通过切片后再拼接成新的tensor.

import mindspore as ms
from mindspore import Tensor, nn, ops
class Test(nn.Cell):
    def __init__(self, num):
        super().__init__()
        self.num = num

    def construct(self, x1, x2):
        # 通过切片和拼接替换部分数据
        # 取出x1第0行后512个元素
        remaining_part = x1[0:1, self.num:]
        # 取出x2第0行前512个元素并调整形状
        replaced_part = x2[0:1, :self.num]
        # 在列方向拼接
        new_first_row = ops.concat((replaced_part, remaining_part), axis=1)  # 形状: (1, 1024)
        # 在行方向拼接
        x1 = ops.concat((new_first_row, x1[1:]), axis=0)  # 形状: (10, 1024)
        return x1
x1 = np.ones((10, 1024), dtype=np.float32)
x2 = np.zeros((10, 1024), dtype=np.float32)
for i in range(10):
    for j in range(1024):
            x2[i][j] = j
x1_tensor = Tensor(x1, dtype=ms.float32)
x2_tensor = Tensor(x2, dtype=ms.float32)
net = Test(512)
ms.export(net, x1_tensor, x2_tensor, file_name='test', file_format='MINDIR')

生成的mindir转成ms模型不会报警告, 在mindspore lite端是可以正常部署的, 模型如下:

2 个赞

欢迎分享更多MindSpore/MindSpore Lite使用技巧以及模型转换教程