[{"data":1,"prerenderedAt":263},["ShallowReactive",2],{"content-query-koTqPrQwNy":3},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"date":10,"cover":11,"type":12,"category":13,"body":14,"_type":257,"_id":258,"_source":259,"_file":260,"_stem":261,"_extension":262},"/technology-blogs/zh/3711","zh",false,"","源码精读之Mindspore如何实现Python侧和C++侧之间的链接","MindSpore 的 Python 侧是其主要用户接口，提供了高层 API，便于快速构建和训练深度学习模型。","2025-04-27","https://obs-mindspore-file.obs.cn-north-4.myhuaweicloud.com/file/2025/04/30/fbc4bac9512045a6885ae77b13980f72.png","technology-blogs","实践",{"type":15,"children":16,"toc":245},"root",[17,25,31,36,41,59,64,69,79,84,89,97,102,111,120,128,133,138,148,153,161,166,174,179,187,192,207,212,227,232,240],{"type":18,"tag":19,"props":20,"children":22},"element","h1",{"id":21},"源码精读之mindspore如何实现python侧和c侧之间的链接",[23],{"type":24,"value":8},"text",{"type":18,"tag":26,"props":27,"children":28},"p",{},[29],{"type":24,"value":30},"MindSpore 的 Python 侧是其主要用户接口，提供了高层 API，便于快速构建和训练深度学习模型。Python 侧注重开发效率和灵活性，支持动态图（PyNative 模式）和静态图（Graph 模式）两种执行模式，适合算法工程师和数据科学家进行快速原型设计和实验。Python 的语法简洁，支持自动内存管理和动态类型，开发速度快，且提供了丰富的预定义模块和工具（如 `mindspore.nn`、`mindspore.ops`），便于快速实现模型定义、训练和推理任务。此外，Python 侧还支持数据预处理、可视化工具（如 MindSpore Insight）和模型仓库（如 MindSpore Hub），社区生态丰富且支持广泛。",{"type":18,"tag":26,"props":32,"children":33},{},[34],{"type":24,"value":35},"MindSpore 的 C++ 侧更偏向底层，主要用于高性能计算、算子开发、硬件适配和框架扩展。C++ 侧强调性能和底层控制，适合框架开发者和硬件工程师进行深度优化和自定义算子开发。C++ 是编译型语言，执行效率高，能够直接操作硬件资源（如 GPU、NPU），适合对性能要求极高的场景，如嵌入式设备和边缘计算。C++ 侧需要手动管理内存和数据类型，开发效率较低，但提供了对计算图、算子和硬件资源的直接控制能力，适合开发高性能推理引擎和底层优化模块。C++ 侧的生态相对局限，工具链较少，但对性能优化和硬件适配的支持更强。",{"type":18,"tag":26,"props":37,"children":38},{},[39],{"type":24,"value":40},"下面从参数保存加载过程中，简单看下Mindspore如何实现Python侧和C++侧之间的链接。",{"type":18,"tag":42,"props":43,"children":45},"h3",{"id":44},"_01-save_checkpoint整体流程",[46,52,54],{"type":18,"tag":47,"props":48,"children":49},"strong",{},[50],{"type":24,"value":51},"# 01",{"type":24,"value":53}," ",{"type":18,"tag":47,"props":55,"children":56},{},[57],{"type":24,"value":58},"save_checkpoint整体流程",{"type":18,"tag":26,"props":60,"children":61},{},[62],{"type":24,"value":63},"保存checkpoint过程中，有以下几个流程：",{"type":18,"tag":26,"props":65,"children":66},{},[67],{"type":24,"value":68},"1、从nn.cell中过滤出来保存的parameter：",{"type":18,"tag":70,"props":71,"children":73},"pre",{"code":72},"\nsave_obj = _convert_save_obj_to_param_list(save_obj, integrated_save, append_dict, choice_func)\n",[74],{"type":18,"tag":75,"props":76,"children":77},"code",{"__ignoreMap":7},[78],{"type":24,"value":72},{"type":18,"tag":26,"props":80,"children":81},{},[82],{"type":24,"value":83},"2、对parameter进行一系列处理，提取参数名，shape，dtype等重要信息。处理后的结果存储在data_list的字典中。",{"type":18,"tag":26,"props":85,"children":86},{},[87],{"type":24,"value":88},"3、将逐个parameter写入文件中。",{"type":18,"tag":70,"props":90,"children":92},{"code":91},"def _write_parameter_bytes_data(name, value, f, enc_key, plain_data, crc_num=0, crc_check=False, ckpt_total_io_time=0):\n    \"\"\"Write parameter bytes data into protobuf file.\"\"\"\n    bytes_value = value[2].get_bytes()\n    chunk_size = 1024 * SLICE_SIZE\n    ...\n",[93],{"type":18,"tag":75,"props":94,"children":95},{"__ignoreMap":7},[96],{"type":24,"value":91},{"type":18,"tag":26,"props":98,"children":99},{},[100],{"type":24,"value":101},"这里的tensor.get_bytes()函数，用来获取tensor的bytes值。",{"type":18,"tag":42,"props":103,"children":105},{"id":104},"_02",[106],{"type":18,"tag":47,"props":107,"children":108},{},[109],{"type":24,"value":110},"# 02",{"type":18,"tag":42,"props":112,"children":114},{"id":113},"tensorget_bytes函数",[115],{"type":18,"tag":47,"props":116,"children":117},{},[118],{"type":24,"value":119},"Tensor.get_bytes函数",{"type":18,"tag":26,"props":121,"children":122},{},[123],{"type":18,"tag":47,"props":124,"children":125},{},[126],{"type":24,"value":127},"1、pybind11简单介绍",{"type":18,"tag":26,"props":129,"children":130},{},[131],{"type":24,"value":132},"pybind11 是一个轻量级的 C++ 库，用于将 C++ 代码暴露给 Python，从而实现 C++ 和 Python 之间的无缝互操作。它的目标是简化 C++ 代码与 Python 的绑定过程，同时保持高性能和低开销。",{"type":18,"tag":26,"props":134,"children":135},{},[136],{"type":24,"value":137},"MindSpore使用pybind11连接Python侧的接口和C++侧的接口，兼顾Python的简单便捷和C++的高性能。",{"type":18,"tag":26,"props":139,"children":140},{},[141,143],{"type":24,"value":142},"**2、**",{"type":18,"tag":47,"props":144,"children":145},{},[146],{"type":24,"value":147},"具体实现",{"type":18,"tag":26,"props":149,"children":150},{},[151],{"type":24,"value":152},"1、Python侧接口定义在mindspore/python/mindspore/common/tensor.py：tensor.py实现了大部分常用的张量操作。",{"type":18,"tag":70,"props":154,"children":156},{"code":155},"\ndef get_bytes(self):\n        r\"\"\"\n        Get raw data of tensor with type of bytes.\n\n                Supported Platforms:\n            ``CPU`` ``GPU`` ``Ascend``\n        \n        Returns:\n            Bytes of tensor.\n        \n        Examples:\n            >>> import mindspore as ms\n            >>> from mindspore import Tensor\n            >>> x = ms.Tensor([1, 2, 3], ms.int16)\n            >>> print(x.get_bytes())\n            b'\\x01\\x00\\x02\\x00\\x03\\x00'\n        \"\"\"\n        return TensorPy_.get_bytes(self)\n",[157],{"type":18,"tag":75,"props":158,"children":159},{"__ignoreMap":7},[160],{"type":24,"value":155},{"type":18,"tag":26,"props":162,"children":163},{},[164],{"type":24,"value":165},"2、C++侧接口定义在mindspore/ccsrc/utils/tensor_py.cc。tenosor_py.cc文件下实现了tensor的C++侧的接口。",{"type":18,"tag":70,"props":167,"children":169},{"code":168},"py::bytes TensorPybind::GetBytes(const Tensor &tensor) {\n  py::gil_scoped_acquire acquire;\n  if (tensor.get_copy_done_flag()) {\n    const_cast(tensor).set_copy_done_flag(false);\n    return py::bytes(static_cast(tensor.data_c()), tensor.Size());\n  }\n  tensor.data_sync();\n  return py::bytes(static_cast(tensor.data_c()), tensor.Size());\n}\npy::bytes TensorPyImpl::GetBytes(const TensorPyPtr &tensorpy) {\n  auto tensor = tensorpy->GetTensor();\n  return TensorPybind::GetBytes(*tensor);\n}\n",[170],{"type":18,"tag":75,"props":171,"children":172},{"__ignoreMap":7},[173],{"type":24,"value":168},{"type":18,"tag":26,"props":175,"children":176},{},[177],{"type":24,"value":178},"3、pybind绑定Python侧和C++侧。mindspore/ccsrc/pybind_api/tensor_py_reg.cc。",{"type":18,"tag":70,"props":180,"children":182},{"code":181},"void RegTensorPyFunction(py::class_> *tensor_class) {\n  ...\n  tensor_class->def(\"get_bytes\", TensorPyImpl::GetBytes, R\"mydelimiter(\n                             Get raw data of tensor with type of bytes.\n                             \n                             Returns:\n                                 Bytes of tensor.\n                            \n                             Examples:\n                                 >>> import mindspore as ms\n                                 >>> from mindspore import Tensor\n                                 >>> x = ms.Tensor([1, 2, 3], ms.int16)\n                                 >>> print(x.get_bytes())\n                                 b'\\x01\\x00\\x02\\x00\\x03\\x00'\n                             )mydelimiter\");\n  ...\n}\n",[183],{"type":18,"tag":75,"props":184,"children":185},{"__ignoreMap":7},[186],{"type":24,"value":181},{"type":18,"tag":26,"props":188,"children":189},{},[190],{"type":24,"value":191},"如果自定义实现方法的话，需要编译MindSpore源码后才能使用自定义的功能。",{"type":18,"tag":42,"props":193,"children":195},{"id":194},"_03-tensor_convert_bytes_to_tensor函数",[196,201,202],{"type":18,"tag":47,"props":197,"children":198},{},[199],{"type":24,"value":200},"# 03",{"type":24,"value":53},{"type":18,"tag":47,"props":203,"children":204},{},[205],{"type":24,"value":206},"Tensor_.convert_bytes_to_tensor函数",{"type":18,"tag":26,"props":208,"children":209},{},[210],{"type":24,"value":211},"同理在加载ckpt时，用到了类似实现的方法Tensor_.convert_bytes_to_tensor。读者可以自己看看源码，理解下pybind11如何连接的MindSpore的C++和Python层。",{"type":18,"tag":42,"props":213,"children":215},{"id":214},"_04-总结",[216,221,222],{"type":18,"tag":47,"props":217,"children":218},{},[219],{"type":24,"value":220},"# 04",{"type":24,"value":53},{"type":18,"tag":47,"props":223,"children":224},{},[225],{"type":24,"value":226},"总结",{"type":18,"tag":26,"props":228,"children":229},{},[230],{"type":24,"value":231},"在MindSpore中习惯将Python侧的tensor称为Tensor, C++侧的tensor称为Tensor_。",{"type":18,"tag":70,"props":233,"children":235},{"code":234},"from mindspore.common.tensor import Tensor\nfrom mindspore._c_expression import TensorPy as Tensor_\n",[236],{"type":18,"tag":75,"props":237,"children":238},{"__ignoreMap":7},[239],{"type":24,"value":234},{"type":18,"tag":26,"props":241,"children":242},{},[243],{"type":24,"value":244},"总结来说，Python 侧适合快速开发和实验，而 C++ 侧适合高性能计算和底层优化，两者相辅相成，共同支撑 MindSpore 的全场景 AI 计算能力。",{"title":7,"searchDepth":246,"depth":246,"links":247},4,[248,251,252,253,255],{"id":44,"depth":249,"text":250},3,"# 01 save_checkpoint整体流程",{"id":104,"depth":249,"text":110},{"id":113,"depth":249,"text":119},{"id":194,"depth":249,"text":254},"# 03 Tensor_.convert_bytes_to_tensor函数",{"id":214,"depth":249,"text":256},"# 04 总结","markdown","content:technology-blogs:zh:3711.md","content","technology-blogs/zh/3711.md","technology-blogs/zh/3711","md",1776506133628]