问题一:

【问题描述】

在将MindSpore点云模型模型迁移到昇腾平台并使用ACL进行推理时,发现推理结果与预期不一致。经过排查,发现点云数据处理部分使用了transpose等操作,但在操作后没有对内存进行连续性处理,导致数据在内存中不是连续存储的。

【根本原因】

在MindSpore中,使用ops.Transpose()进行维度变换时,如果数据在内存中不是连续存储的,可能会导致一些问题。 transpose操作本质上是对张量进行维度重排,这种操作会改变张量的内存布局。具体来说:

  1. ops.Transpose()不会实际移动数据在内存中的位置,而是通过修改张量的stride信息来实现维度变换
  2. 这种变换会导致数据在内存中的存储顺序与逻辑顺序不一致,形成非连续存储
  3. 需要注意的是,save和print等操作会对数据进行连续化处理,这会导致通过print和save很难定位到非连续存储的问题。

【解决方案】

在数据处理完成后,使用make_contiguous()方法确保数据在内存中是连续存储的。确保数据内存连续性 在数据处理管道中,特别是在使用transpose等维度变换操作后,需要显式确保数据的内存连续性: 具体修改如下:

- 示例代码:

```python
  import mindspore as ms
  import mindspore.ops as ops

  #原始可能有问题的方式
  data = ops.Transpose()(data, (0, 2, 1))  # 转置操作

  # 修正后的方式 - 确保内存连续性
  data = ops.Transpose()(data, (0, 2, 1))
  data = ops.Contiguous()(data)  # 显式确保内存连续



  ```
  - C++中使用Pybind11确保NumPy数组内存连续性的示例:
  ```cpp
  py::array_t<float> BinModelProcessBatch::make_contiguous(py::array_t<float> &input)
  {
      // 获取 numpy 模块
      py::module numpy = py::module::import("numpy");

      // 调用 numpy.ascontiguousarray() 确保内存连续性
      // 该函数会返回一个新的连续存储的数组,如果输入数组已经是连续的,则直接返回输入数组
      // 对于非连续数组,会创建一个新的连续存储的副本
      py::array_t<float> contiguous_array = numpy.attr("ascontiguousarray")(input);

      return contiguous_array;
  }
  ```

问题二:

【问题描述】

在MindSpore中使用ops.stack()函数进行张量堆叠操作时,当导出ONNX模型并转换为OM模型时,会遇到动态batch的问题,导致模型无法正常部署。

【根本原因】

  1. ops.stack()函数会在新维度上堆叠张量,这会在ONNX模型中引入动态维度
  2. 当使用ATC转换为OM模型时,昇腾平台对动态batch的支持有限,导致转换失败
  3. ops.stack()操作会改变张量的维度结构,使得模型在推理时无法确定batch size

【解决方案】

使用ops.cat()函数替代ops.stack()函数,因为ops.cat()是在现有维度上进行拼接,不会引入新的维度,从而避免动态batch的问题。

附:
1、性能下降:
数据方面:磁盘IO,之前通过nfs挂载的方式,如果数据量大会,越往后性能越差出现训不动,建议使用本地存储,或者使用对象存储,比如minio。
算子层面:不同的算子底层实现不一样,方向传播会导致性能下降。
损失函数:损失函数选择不一样,导致收敛速度不一样,比如交叉熵损失函数,和mse损失函数。

Logo

鲲鹏昇腾开发者社区是面向全社会开放的“联接全球计算开发者,聚合华为+生态”的社区,内容涵盖鲲鹏、昇腾资源,帮助开发者快速获取所需的知识、经验、软件、工具、算力,支撑开发者易学、好用、成功,成为核心开发者。

更多推荐