ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

CANN/ge:Session到GeSession迁移指导

CANN/ge:Session到GeSession迁移指导 Session 到 GeSession 迁移指导【免费下载链接】geGEGraph Engine是面向昇腾的图编译器和执行器提供了计算图优化、多流并行、内存复用和模型下沉等技术手段加速模型执行效率减少模型内存占用。 GE 提供对 PyTorch、TensorFlow 前端的友好接入能力并同时支持 onnx、pb 等主流模型格式的解析与编译。项目地址: https://gitcode.com/cann/ge概述本文档旨在指导用户从Session类迁移到新引入的GeSession类。GeSession是对原有Session类的重构和优化主要变化包括移除了与 DataFlow 相关的接口简化了编译和加载流程统一了执行接口的参数类型从ge::Tensor改为gert::Tensor优化了接口命名和参数类型库链接变化项目SessionGeSession库文件libge_runner.solibge_runner_v2.so头文件ge/ge_api.hge/ge_api_v2.h接口对比表Session 接口GeSession 接口迁移说明Session(options)GeSession(options)构造函数基本一致但只提供了ABI兼容的std::mapAscendString, AscendString类型版本~Session()~GeSession()析构函数无变化AddGraph(uint32_t, const Graph)AddGraph(uint32_t, const Graph)接口保持一致AddGraph(uint32_t, const Graph, options)AddGraph(uint32_t, const Graph, options)只提供了ABI兼容的 std::mapAscendString, AscendString 类型版本AddGraphWithCopyAddGraphClone重命名功能相同RemoveGraphRemoveGraph无变化BuildGraphCompileGraph重命名功能相同。GeSession 的 CompileGraph 支持 VariableCompileGraphCompileGraph合并了 BuildGraph 和 CompileGraph 的功能LoadGraphLoadGraph接口基本一致但 GeSession 中会自动检查是否需要先 CompileGraphRunGraphRunGraph重要变化输入输出从ge::Tensor改为gert::TensorRunGraphWithStreamAsyncRunGraphWithStreamAsync重要变化输入输出从ge::Tensor改为gert::TensorCompileGraph 和 LoadGraph 可省略ExecuteGraphWithStreamAsyncRunGraphWithStreamAsyncSession 中的ExecuteGraphWithStreamAsync使用gert::Tensor合并到 GeSession 的RunGraphWithStreamAsyncRunGraphAsyncRunGraphAsync重要变化输入输出从ge::Tensor改为gert::Tensor回调函数签名从RunAsyncCallback改为RunAsyncCallbackV2RegisterCallBackFuncRegisterCallBackFunc回调函数签名变化使用RunCallback类型GetCompiledGraphSummaryGetCompiledGraphSummary无变化SetGraphConstMemoryBaseSetGraphConstMemoryBase无变化UpdateGraphFeatureMemoryBaseUpdateGraphFeatureMemoryBase无变化SetGraphFixedFeatureMemoryBaseSetGraphFixedFeatureMemoryBaseWithType接口名称变化增加了 type 参数UpdateGraphRefreshableFeatureMemoryBaseUpdateGraphRefreshableFeatureMemoryBase无变化RegisterExternalAllocatorRegisterExternalAllocator无变化UnregisterExternalAllocatorUnregisterExternalAllocator无变化IsGraphNeedRebuildIsGraphNeedRebuild无变化GetSessionIdGetSessionId无变化-GetCompiledModel新增接口获取编译后的模型数据FeedDataFlowGraph-已删除迁移到 DataFlow 接口FetchDataFlowGraph-已删除迁移到 DataFlow 接口FeedRawData-已删除迁移到 DataFlow 接口GetVariables-已删除无替代接口ShardGraphsToFile-已删除图分片功能不再提供ShardGraphs-已删除图分片功能不再提供SaveGraphsToPb-已删除保存图到pb文件功能不再提供PaRemapped-已删除虚拟内存重映射功能不再提供初始化接口变化GEInitialize/GEFinalizeSession (ge_api.h)GeSession (ge_api_v2.h)GEInitialize(options)GEInitializeV2(options)GEFinalize()GEFinalizeV2()GEGetErrorMsg()GEGetErrorMsgV3()GEGetWarningMsg()GEGetWarningMsgV3()最大的变化点Tensor 类型ge::Tensor vs gert::Tensor特性ge::Tensorgert::Tensor命名空间gegert数据结构使用std::shared_ptrTensorImpl管理内部实现POD类型Plain Old Data所有数据内联存储内存布局间接访问通过 impl_ 指针扁平化布局支持直接memcpyPlacement支持通过 TensorDesc 设置 Placement支持多种 Placement 类型拷贝行为浅拷贝shared_ptr语义浅拷贝指针共享性能一般高性能适用场景图构建阶段运行时执行构造 gert::Tensor// 方法1: 使用 gert::Tensor 的基本构造需要包含 exe_graph/runtime/tensor.h #include exe_graph/runtime/tensor.h // 创建 host tensor gert::Tensor tensor; // 设置 shape、数据类型等 tensor.SetShape(...); tensor.SetDataType(...); tensor.SetPlacement(gert::TensorPlacement::kOnHost); // 方法2: 从已有数据构造 void* data ...; // 已有数据指针 size_t size ...; // 数据大小 gert::Tensor tensor(data, size, gert::TensorPlacement::kOnHost);Tensor 生命周期说明RunGraph 接口std::vectorgert::Tensor inputs ...; std::vectorgert::Tensor outputs; session-RunGraph(graph_id, inputs, outputs); // inputs 和 outputs 在调用完成后可以安全释放RunGraphWithStreamAsync 接口// GeSession 的 RunGraphWithStreamAsync // 注意可以不先调用 CompileGraph 和 LoadGraph会自动处理 std::vectorgert::Tensor inputs ...; std::vectorgert::Tensor outputs; session-RunGraphWithStreamAsync(graph_id, stream, inputs, outputs); // inputs 和 outputs 在 stream 同步之前不能释放 // 需要调用 aclrtSynchronizeStream(stream) 或其他同步机制RunGraphAsync 接口重要using RunAsyncCallbackV2 std::functionvoid(Status, std::vectorgert::Tensor); std::vectorgert::Tensor inputs ...; session-RunGraphAsync(graph_id, inputs, [](https://gitcode.com/cann/ge/blob/c0d49447b42efb8b9cf0661ccf64449a92418d34/docs/zh/api/graph_engine_api/Status ret, std::vectorgert::Tensor outputs?utm_sourcegitcode_repo_files) { // 处理输出 }); // ⚠️ 重要inputs 不能立即释放 // 必须等到 callback 函数被调用后才能释放 inputs // 因为模型执行的时候会读取inputscallback被调用可保证模型执行完成重要变化点详解1. CompileGraph/LoadGraph 不再必需在 GeSession 中RunGraph、RunGraphAsync和RunGraphWithStreamAsync三个执行接口会自动检查图是否已编译和加载。如果未编译会先自动编译如果未加载会先自动加载。// GeSession 的自动处理机制 GeSession session(options); session.AddGraph(graph_id, graph); // 直接执行无需手动 CompileGraph 和 LoadGraph session.RunGraph(graph_id, inputs, outputs); // 自动编译和加载2. 执行模式互斥GeSession 的三种执行模式RunGraph、RunGraphAsync、RunGraphWithStreamAsync是互斥的不能混用。一旦使用了某种执行模式该图就必须继续使用同一种模式。// 错误示例 session.RunGraph(graph_id, inputs1, outputs1); // 使用 RunGraph 模式 session.RunGraphAsync(graph_id, inputs2, callback); // 错误不能混用gert::Tensor 构造示例数据结构对比ge::Tensor 的内部结构class Tensor { private: std::shared_ptrTensorImpl impl_; // 使用智能指针管理 };使用 shared_ptr 管理 TensorImpl拷贝时共享底层实现数据通过 TensorDesc 描述gert::Tensor 的内部结构class Tensor { private: StorageShape storage_shape_; // Shape信息 StorageFormat storage_format_; // Format信息 TensorVersion version_; // 版本 uint8_t reserved_[3]; // 预留字段 ge::DataType data_type_; // 数据类型 TensorData tensor_data_; // 数据指针和placement uint8_t reserved_field_[40]; // 预留字段 };所有字段直接内联在对象中是标准布局类型std::is_standard_layout构造 gert::Tensor 的方法方法1: 使用 TensorData 构造推荐#include exe_graph/runtime/tensor.h #include acl_rt.h // 构造 Host Tensor void* host_buf nullptr; aclError ret aclrtMallocHost(host_buf, data_len); // 分配Host内存 if (ret ! ACL_ERROR_NONE) { // 处理错误 } // 使用 TensorData 构造 gert::TensorData td(host_buf, nullptr, data_len, gert::kOnHost); gert::Tensor tensor; tensor.SetData(std::move(td)); // 设置数据类型如果需要 // tensor.SetDataType(ge::DT_FLOAT);方法2: 使用构造函数直接创建// 从 shape、format 和 dtype 构造 gert::StorageShape shape {{batch_size, channels, height, width}, {4}}; gert::StorageFormat format {ge::FORMAT_ND, ge::FORMAT_ND, {}}; gert::Tensor tensor(shape, format, ge::DT_FLOAT); // 然后分配内存 void* host_buf nullptr; aclrtMallocHost(host_buf, tensor.GetSize()); gert::TensorData td(host_buf, nullptr, tensor.GetSize(), gert::kOnHost); tensor.SetData(std::move(td));方法3: 构造 Device Tensor// 分配Device内存 void* dev nullptr; aclError ret aclrtMalloc(dev, bytes, ACL_MEM_MALLOC_NORMAL_ONLY); if (ret ! ACL_ERROR_NONE) { // 处理错误 } // 构造 Device Tensor gert::TensorData td(dev, nullptr, bytes, gert::kOnDeviceHbm); gert::Tensor device_tensor; device_tensor.SetData(std::move(td));gert::Tensor 常用方法gert::Tensor tensor; // 获取数据地址 void* addr tensor.GetAddr(); // 获取数据大小字节数 size_t size tensor.GetSize(); // 获取数据类型 ge::DataType dtype tensor.GetDataType(); // 获取元素数量 uint32_t elem_count tensor.GetShapeSize(); // 设置数据 gert::TensorData td(data, nullptr, size, gert::kOnHost); tensor.SetData(std::move(td));完整示例构造输入数据#include exe_graph/runtime/tensor.h #include acl_rt.h ge::Status PrepareInputTensor(std::vectorgert::Tensor inputs, int32_t batch_size) { // 定义输入shape gert::StorageShape shape {{batch_size, 3, 224, 224}, {4}}; gert::StorageFormat format {ge::FORMAT_ND, ge::FORMAT_ND, {}}; // 创建Tensor gert::Tensor tensor(shape, format, ge::DT_FLOAT); // 计算所需内存大小 const uint32_t elem_count tensor.GetShapeSize(); const uint32_t data_size elem_count * sizeof(float); // 分配Host内存 void *host_buf nullptr; aclError ret aclrtMallocHost(host_buf, data_size); if (ret ! ACL_ERROR_NONE) { return ge::FAILED; } // 填充数据 float *data_ptr reinterpret_castfloat*(host_buf); for (uint32_t i 0; i elem_count; i) { data_ptr[i] 1.0f; // 填充示例值 } // 设置Tensor数据 gert::TensorData td(host_buf, nullptr, data_size, gert::kOnHost); tensor.SetData(std::move(td)); inputs.push_back(std::move(tensor)); return ge::SUCCESS; }释放 gert::Tensor 内存// 释放Host Tensor内存 void FreeHostTensor(gert::Tensor tensor) { if (tensor.GetAddr() ! nullptr) { aclrtFreeHost(tensor.GetAddr()); } } // 释放Device Tensor内存 void FreeDeviceTensor(gert::Tensor tensor) { if (tensor.GetAddr() ! nullptr) { aclrtFree(tensor.GetAddr()); } } // 批量释放 void FreeTensorVector(std::vectorgert::Tensor tensors, bool is_device) { for (auto t : tensors) { if (t.GetAddr() ! nullptr) { if (is_device) { aclrtFree(t.GetAddr()); } else { aclrtFreeHost(t.GetAddr()); } } } }编译配置变化Makefile 或 CMakeLists.txt 需要更新# 旧配置 target_link_libraries(your_app libge_runner.so) # 新配置 target_link_libraries(your_app libge_runner_v2.so)注意事项总结头文件变化从ge/ge_api.h改为ge/ge_api_v2.h库文件变化从libge_runner.so改为libge_runner_v2.soTensor 类型变化所有 Run 接口的输入输出从ge::Tensor改为gert::Tensor异步生命周期使用RunGraphAsync时inputs 必须保持有效直到 callback 被调用接口简化不需要手动调用 CompileGraph 和 LoadGraph除非需要显式控制DataFlow 分离Feed/Fetch 接口已删除使用 DataFlow 专用接口执行模式互斥三种 Run 模式不能混用回调函数签名变化从RunAsyncCallback改为RunAsyncCallbackV2【免费下载链接】geGEGraph Engine是面向昇腾的图编译器和执行器提供了计算图优化、多流并行、内存复用和模型下沉等技术手段加速模型执行效率减少模型内存占用。 GE 提供对 PyTorch、TensorFlow 前端的友好接入能力并同时支持 onnx、pb 等主流模型格式的解析与编译。项目地址: https://gitcode.com/cann/ge创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表