mindspore迁移过程中遇到的问题
经过排查,发现点云数据处理部分使用了transpose等操作,但在操作后没有对内存进行连续性处理,导致数据在内存中不是连续存储的。在数据处理完成后,使用make_contiguous()方法确保数据在内存中是连续存储的。进行维度变换时,如果数据在内存中不是连续存储的,可能会导致一些问题。函数进行张量堆叠操作时,当导出ONNX模型并转换为OM模型时,会遇到动态batch的问题,导致模型无法正常部署。
问题一:
【问题描述】
在将MindSpore点云模型模型迁移到昇腾平台并使用ACL进行推理时,发现推理结果与预期不一致。经过排查,发现点云数据处理部分使用了transpose等操作,但在操作后没有对内存进行连续性处理,导致数据在内存中不是连续存储的。
【根本原因】
在MindSpore中,使用ops.Transpose()进行维度变换时,如果数据在内存中不是连续存储的,可能会导致一些问题。 transpose操作本质上是对张量进行维度重排,这种操作会改变张量的内存布局。具体来说:
ops.Transpose()不会实际移动数据在内存中的位置,而是通过修改张量的stride信息来实现维度变换- 这种变换会导致数据在内存中的存储顺序与逻辑顺序不一致,形成非连续存储
- 需要注意的是,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的问题,导致模型无法正常部署。
【根本原因】
ops.stack()函数会在新维度上堆叠张量,这会在ONNX模型中引入动态维度- 当使用ATC转换为OM模型时,昇腾平台对动态batch的支持有限,导致转换失败
ops.stack()操作会改变张量的维度结构,使得模型在推理时无法确定batch size
【解决方案】
使用ops.cat()函数替代ops.stack()函数,因为ops.cat()是在现有维度上进行拼接,不会引入新的维度,从而避免动态batch的问题。
附:
1、性能下降:
数据方面:磁盘IO,之前通过nfs挂载的方式,如果数据量大会,越往后性能越差出现训不动,建议使用本地存储,或者使用对象存储,比如minio。
算子层面:不同的算子底层实现不一样,方向传播会导致性能下降。
损失函数:损失函数选择不一样,导致收敛速度不一样,比如交叉熵损失函数,和mse损失函数。
鲲鹏昇腾开发者社区是面向全社会开放的“联接全球计算开发者,聚合华为+生态”的社区,内容涵盖鲲鹏、昇腾资源,帮助开发者快速获取所需的知识、经验、软件、工具、算力,支撑开发者易学、好用、成功,成为核心开发者。
更多推荐

所有评论(0)