当前位置:首页>python>源码精读之MindSpore如何实现Python侧和C++侧之间的链接

源码精读之MindSpore如何实现Python侧和C++侧之间的链接

  • 2026-09-05 02:08:42
源码精读之MindSpore如何实现Python侧和C++侧之间的链接
关注+星标,每天学习Python新技能

来源:网络

MindSpore 的 Python 侧是其主要用户接口,提供了高层 API,便于快速构建和训练深度学习模型。Python 侧注重开发效率和灵活性,支持动态图(PyNative 模式)和静态图(Graph 模式)两种执行模式,适合算法工程师和数据科学家进行快速原型设计和实验。Python 的语法简洁,支持自动内存管理和动态类型,开发速度快,且提供了丰富的预定义模块和工具(如 `mindspore.nn`、`mindspore.ops`),便于快速实现模型定义、训练和推理任务。此外,Python 侧还支持数据预处理、可视化工具(如 MindSpore Insight)和模型仓库(如 MindSpore Hub),社区生态丰富且支持广泛。

MindSpore 的 C++ 侧更偏向底层,主要用于高性能计算、算子开发、硬件适配和框架扩展。C++ 侧强调性能和底层控制,适合框架开发者和硬件工程师进行深度优化和自定义算子开发。C++ 是编译型语言,执行效率高,能够直接操作硬件资源(如 GPU、NPU),适合对性能要求极高的场景,如嵌入式设备和边缘计算。C++ 侧需要手动管理内存和数据类型,开发效率较低,但提供了对计算图、算子和硬件资源的直接控制能力,适合开发高性能推理引擎和底层优化模块。C++ 侧的生态相对局限,工具链较少,但对性能优化和硬件适配的支持更强。 

下面从参数保存加载过程中,简单看下Mindspore如何实现Python侧和C++侧之间的链接。

# 01

save_checkpoint整体流程

保存checkpoint过程中,有以下几个流程:

1、从nn.cell中过滤出来保存的parameter:

save_obj = _convert_save_obj_to_param_list(save_obj, integrated_save, append_dict, choice_func)

2、对parameter进行一系列处理,提取参数名,shape,dtype等重要信息。处理后的结果存储在data_list的字典中。

3、将逐个parameter写入文件中。

def _write_parameter_bytes_data(name, value, f, enc_key, plain_data, crc_num=0, crc_check=False, ckpt_total_io_time=0):    """Write parameter bytes data into protobuf file."""    bytes_value = value[2].get_bytes()    chunk_size = 1024 * SLICE_SIZE    ...

这里的tensor.get_bytes()函数,用来获取tensor的bytes值。

# 02

Tensor.get_bytes函数

1、pybind11简单介绍

pybind11 是一个轻量级的 C++ 库,用于将 C++ 代码暴露给 Python,从而实现 C++ 和 Python 之间的无缝互操作。它的目标是简化 C++ 代码与 Python 的绑定过程,同时保持高性能和低开销。

MindSpore使用pybind11连接Python侧的接口和C++侧的接口,兼顾Python的简单便捷和C++的高性能。

2、具体实现

1、Python侧接口定义在mindspore/python/mindspore/common/tensor.py:tensor.py实现了大部分常用的张量操作。

def get_bytes(self):        r"""        Get raw data of tensor with type of bytes.                Supported Platforms:            ``CPU`` ``GPU`` ``Ascend``        Returns:            Bytes of tensor.        Examples:            >>> import mindspore as ms            >>> from mindspore import Tensor            >>> x = ms.Tensor([1, 2, 3], ms.int16)            >>> print(x.get_bytes())            b'\x01\x00\x02\x00\x03\x00'        """        return TensorPy_.get_bytes(self)

2、C++侧接口定义在mindspore/ccsrc/utils/tensor_py.cc。tenosor_py.cc文件下实现了tensor的C++侧的接口。

py::bytes TensorPybind::GetBytes(const Tensor &tensor){  py::gil_scoped_acquire acquire;  if (tensor.get_copy_done_flag()) {    const_cast<Tensor &>(tensor).set_copy_done_flag(false);    return py::bytes(static_cast<const char *>(tensor.data_c()), tensor.Size());  }  tensor.data_sync();  return py::bytes(static_cast<const char *>(tensor.data_c()), tensor.Size());}py::bytes TensorPyImpl::GetBytes(const TensorPyPtr &tensorpy){  auto tensor = tensorpy->GetTensor();  return TensorPybind::GetBytes(*tensor);}

3、pybind绑定Python侧和C++侧。mindspore/ccsrc/pybind_api/tensor_py_reg.cc。

void RegTensorPyFunction(py::class_<TensorPy, std::shared_ptr<TensorPy>> *tensor_class) {  ...  tensor_class->def("get_bytes", TensorPyImpl::GetBytes, R"mydelimiter(                             Get raw data of tensor with type of bytes.                             Returns:                                 Bytes of tensor.                             Examples:                                 >>> import mindspore as ms                                 >>> from mindspore import Tensor                                 >>> x = ms.Tensor([1, 2, 3], ms.int16)                                 >>> print(x.get_bytes())                                 b'\x01\x00\x02\x00\x03\x00'                             )mydelimiter");  ...}

如果自定义实现方法的话,需要编译MindSpore源码后才能使用自定义的功能。

# 03

Tensor_.convert_bytes_to_tensor函数

同理在加载ckpt时,用到了类似实现的方法Tensor_.convert_bytes_to_tensor。读者可以自己看看源码,理解下pybind11如何连接的MindSpore的C++和Python层。

# 04

总结

在MindSpore中习惯将Python侧的tensor称为Tensor, C++侧的tensor称为Tensor_。

from mindspore.common.tensor import Tensorfrom mindspore._c_expression import TensorPy as Tensor_

总结来说,Python 侧适合快速开发和实验,而 C++ 侧适合高性能计算和底层优化,两者相辅相成,共同支撑 MindSpore 的全场景 AI 计算能力。

长按或扫描下方二维码,免费获取 Python公开课和大佬打包整理的几百G的学习资料,内容包含但不限于Python电子书、教程、项目接单、源码等等

推荐阅读

Python 中的==操作符 和 is关键字

MATLAB 和 Python 两大软件的较量,数学建模到底谁更厉害!

使用uv高效管理Python项目

Python 类不要再写 __init__ 方法了

点击 阅读原文 了解更多

最新文章

随机文章