ARTICLE DETAIL

资讯详情

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

HIXL FabricMem 传输模式深度解析:基于 A3 FabricMemory 的 D2RH 高性能数据通路

HIXL FabricMem 传输模式深度解析:基于 A3 FabricMemory 的 D2RH 高性能数据通路 HIXL FabricMem 传输模式深度解析基于 A3 FabricMemory 的 D2RH 高性能数据通路【免费下载链接】hixlHIXLHuawei Xfer Library是一个灵活、高效的昇腾单边通信库面向集群场景提供简单、可靠、高效的点对点数据传输能力。项目地址: https://gitcode.com/cann/hixlFabricMem 是 HIXLHuawei Xfer Library为 Atlas A3 超节点提供的专用传输模式它利用 A3 服务器的 FabricMemory 技术实现超节点内 DRAM 统一编址通过 HCCS 链路完成 NPU 到 DRAMD2RH与 DRAM 到 NPURH2D的高性能传输。本文以 docs/zh/design/FabricMem.md 设计文档为主线结合仓库源码深入讲解其启用方式、编程接口、内部组件架构、并发与锁设计、关键检查点与性能设计帮助读者掌握如何在集群场景中正确启用并高效使用 FabricMem 模式。背景为什么需要 FabricMem 传输模式随着大语言模型LLM推理规模的扩大KV Cache 规模越来越大Mooncake store 等分布式 DRAM 缓存池场景对 NPU 到 DRAMD2RH传输性能提出了更高要求。在此背景下A3 服务器提供的 FabricMemory 技术支持超节点内 DRAM 内存统一编址能够利用 HCCS 链路进行 D2RH/RH2D 传输从而绕开传统模式的瓶颈。其他传输模式的限制与劣势HCCS 传输模式底层调用 HCCL 接口不支持 D2RH 传输。中转模式在 A3 上会占用 HBM 带宽对模型推理影响较大。FabricMem 模式正是为弥补上述空白而设计它绕过 HCCL 与 HBM 中转直接在 NPU 与远端 DRAM 之间建立可编址的数据通路适合 KV Cache 分布式缓存等对 D2RH 带宽敏感的推理场景。需要说明的是根据 HIXL Python 接口文档 中OPTION_ENABLE_USE_FABRIC_MEM的说明该模式仅在 Atlas A3 训练系列/Atlas A3 推理系列服务器上受支持且集群场景下所有节点必须配置相同的值否则会造成行为不一致。使用方式从启用选项到一次完整传输输入要素使用 FabricMem 模式时涉及三类输入配置选项通过OPTION_ENABLE_USE_FABRIC_MEM选项启用 FabricMem 模式值为1表示启用0表示不启用。内存描述注册内存时使用MemDesc结构体包含内存地址addr和长度len。传输操作传输时使用TransferOp枚举READ/WRITE描述方向使用TransferOpDesc描述传输地址源地址、目的地址、长度。完整使用示例// 初始化HIXL引擎启用FabricMem模式 Hixl engine1; std::mapAscendString, AscendString options1; options1[OPTION_ENABLE_USE_FABRIC_MEM] 1; engine1.Initialize(127.0.0.1:26000, options1); // 注册内存 std::vectoruint8_t buffer(size, 0xAA); hixl::MemDesc mem_desc{}; mem_desc.addr reinterpret_castuintptr_t(buffer.data()); mem_desc.len size; MemHandle handle nullptr; engine1.RegisterMem(mem_desc, MEM_HOST, handle); // 建立连接 engine1.Connect(127.0.0.1:26001); // 执行传输 TransferOpDesc desc{src_addr, dst_addr, size}; engine1.TransferSync(127.0.0.1:26001, WRITE, {desc});输出要素使用过程中会获得三类输出内存句柄注册内存时返回MemHandle用于标识已注册的内存区域后续DeregisterMem注销时同样需要该句柄。传输请求异步传输时返回TransferReq用于异步传输状态查询。传输状态查询异步任务状态时返回TransferStatus枚举。端到端编程流程在 FabricMem 模式下一个完整的传输业务通常按以下四步组织1. 内存申请。FabricMem 的 host 内存申请由FabricMemTransferService::MallocMem统一封装底层会完成虚拟地址预留、物理内存申请和映射void *fabric_ptr nullptr; Hixl::MallocMem(MEM_HOST, mem_size, fabric_ptr);传输完成后通过Hixl::FreeMem释放。2. 引擎初始化和内存注册。启用 FabricMem 模式options[OPTION_ENABLE_USE_FABRIC_MEM] 1初始化 Hixl然后注册内存。注册时可选择MEM_HOST或MEM_DEVICE两种内存类型engine.RegisterMem(desc, MEM_HOST, handle); // 或 MEM_DEVICE3. 连接建立和数据交换。调用Connect方法建立连接FabricMemEngine会拉取并导入远端共享句柄详见后文连接建立阶段。4. 数据传输和验证。执行传输并验证结果engine.TransferSync(remote_engine, WRITE, {desc});验证传输结果的方式是读取远程写入的数据并比对。架构总览独立的 FabricMemEngineFabricMem 由独立的FabricMemEngine承载不再侵入HixlEngine、AdxlInnerEngine、ChannelMsgHandler或Channel。EngineFactory在发现OPTION_ENABLE_USE_FABRIC_MEM1时创建FabricMemEngine后续注册、建链、传输、统计和资源清理由 src/hixl/fabric_mem 与 fabric_mem_engine.cc 负责。从源码看EngineFactory::CreateEngine 在解析选项后若parsed_options.EnableFabricMem().value_or(false)为真则直接返回std::make_uniqueFabricMemEngine(...)不会进入 HixlEngine / CommEngine / Adxl 路径印证了设计文档中的引擎路由逻辑。类图与设计文档一致fabric_mem_engine.h 中FabricMemEngine恰好持有FabricMemConfig、FabricMemStatistic、FabricMemLocalMemory、shared_ptrFabricMemTransferService与unique_ptrFabricMemControlServer五个成员且FabricMemLocalMemory被值持有——这正是薄门面设计的体现Engine 不持有连接表或 async record只做编排。组件职责划分FabricMemEngine薄门面编排TransferService/LocalMemory/ControlServer持有FabricMemLocalMemory不持有连接表或 async record。FabricMemTransferService对外传输门面持有FabricMemChannelManager与FabricMemSlotPool负责拷贝编排、async record 的查询/完成含 prof 元数据。FabricMemChannelManager连接生命周期Fetch/Install/Disconnect、请求路由req_2_channel_、出站 keepalive 线程、disconnect 时立即 abort。FabricMemSlotPoolasync slotstream host flag池。FabricMemLocalMemory本地内存注册、Export、share handle 管理。FabricMemRemoteMemory单 channel 导入的远端内存映射由 channel 持有。值得注意的是FabricMemTransferService在源码中是抽象基类fabric_mem_engine.cc 根据enable_aicpu_unfold配置选择两种具体实现enable_aicpu_unfold true时创建FabricMemAicpuTransferServiceAICPU 展开路径一条 channel 绑定一个 slot通过 SDMA 写 RTSQ 队列下发拷贝enable_aicpu_unfold false时创建FabricMemHostTransferServiceHost 展开路径多 slot 并发传输直接使用aclrtMemcpyAsync。核心处理流程从初始化到资源清理时序图FabricMem 模式下的数据传输1. 初始化阶段用户通过OPTION_ENABLE_USE_FABRIC_MEM选项启用 FabricMem 模式。EngineFactory根据该选项创建FabricMemEngine不进入AdxlInnerEngine或HixlEngine。FabricMemEngine解析FabricMemConfig初始化VirtualMemoryManager、FabricMemTransferService、FabricMemControlServer和FabricMemStatistic。从源码看FabricMemEngine::InitializeLocked 的执行顺序为校验支持选项集合kSupportedOptions→ 校验OPTION_BUFFER_POOL必须为禁用态 → 校验EnableFabricMem必须为 1 → 获取 device id 并创建 aclrt context → 应用虚拟内存配置 → 读取 auto_connect →InitFabricMem()。其中InitFabricMem()依次完成应用虚拟内存容量/起始地址配置、初始化VirtualMemoryManager、启动统计周期 dump、启动 ControlServer、初始化 TransferService。关于内存申请FabricMem host 内存申请由FabricMemTransferService::MallocMem统一封装静态方法底层完成虚拟地址预留、物理内存申请和映射传输完成后通过Hixl::FreeMem释放。2. 内存注册阶段用户调用RegisterMem注册内存。FabricMemTransferService通过aclrtMemRetainAllocationHandle获取物理内存句柄。使用aclrtMemExportToShareableHandleV2导出为 Fabric 可共享句柄。将共享句柄信息存储在share_handles_中。H2H 传输模式的特殊性对于 HOST 内存FabricMem 传输需要额外的转换处理。HOST 内存需要先通过aclrtMemRetainAllocationHandle获取物理内存句柄然后使用aclrtMemExportToShareableHandleV2导出为共享句柄最后进行 VMM 映射将物理内存映射到虚拟地址空间。从 fabric_mem_memory.h 可以看到FabricMemLocalMemory内部区分了两类注册自有内存RegisterOwnMem直接导出注册内存为 fabric share handle外部内存RegisterForeignMem对未通过本库申请的 host 内存需要先导入再导出——通过aclrtMemRetainAllocationHandle拿到物理内存句柄后本地映射再作为 segment 导出BuildForeignSegments/AttachForeignPaPage负责构建完整底层分配的映射段因为aclrtMapMem导入的是整块 PA block并支持重叠注册overlap check相邻用户区间可能共享同一个 retained PA。传输过程中TranslateLocalHostOpAddrs会把 host 用户地址解析到其导入后的设备可见映射地址这正是 H2H 模式额外转换处理的落地实现。3. 连接建立阶段本端FabricMemChannelManager通过FabricMemControlClient向对端FabricMemControlServer拉取share_handles_。FabricMemChannelManager通过FabricMemRemoteMemory导入远程内存的共享句柄。使用aclrtMemImportFromShareableHandleV2导入共享句柄映射到虚拟地址空间。建立远端用户地址到本地映射地址的映射关系并登记到channels_连接表。源码层面连接建立由 fabric_mem_channel_manager.h 的FetchAndInstallRemote驱动connect_mutex_串行化 Fetch Install 两步Fetch通过 Control 通道FabricMemControlClient::Fetch拉取远端 share_handles 与 keepalive fd随后CreateAndRegisterRemoteMemory创建FabricMemRemoteMemory并执行Import。导入完成后远端用户 VA 到本地映射 VA 的转换关系保存在new_va_to_old_va_映射与只读的FabricMemRemoteIndexmultimapuintptr_t, VaInfo中供传输阶段做地址翻译。4. 数据传输阶段FabricMemEngine通过FabricMemChannelManager获取 channel 并构建FabricMemTransferContext。FabricMemTransferService进行用户地址和映射地址转换。从 stream pool 获取任务需要的流资源。使用aclrtMemcpyAsync执行内存拷贝操作。同步传输阻塞等待异步传输在每个 copy stream 上追加 host flag D2H轮询 host flag 判定完成不再使用 EventRecord/query event。传输耗时、真实拷贝耗时、总字节数和 op desc 数量记录在FabricMemStatistic中。地址转换是传输前必经的一步fabric_mem_transfer_service.h 中的ResolveTransferAddrs遍历每个TransferOpDesc用TransOpAddr在FabricMemRemoteIndex中查找远端 VA 对应的本地映射地址同时NeedTransLocalAddr判断是否需要转换本端 host 地址。只有源/目的地址都换算成设备可见的映射地址后aclrtMemcpyAsync才能正确执行。在 Host 展开路径enable_aicpu_unfoldfalse下FabricMemHostTransferService 通过submit_gateshared_mutex共享锁允许多个传输在同一 channel 上并行下发拷贝到各自的 slot stream异步传输由IssueAsyncCopyAndRegister登记AsyncRecord并注册请求路由GetTransferStatus查询 stream 状态判定完成。5. 资源清理阶段用户调用DeregisterMem注销内存释放物理内存句柄和共享句柄。连接断开或Finalize时清理远端导入映射、stream、异步资源含 host flag 池和统计通道。Disconnect立即 abort该 channel 在途的 sync/async stream不等待传输完成清空其 async record 与请求路由后销毁 async slot。配置项详解FabricMemConfig 与传输参数FabricMemConfigfabric_mem_config.h承载 FabricMem 模式的核心配置配置字段类型默认值说明enabledboolfalse是否启用 FabricMem 模式由EnableUseFabricMem选项驱动auto_connectboolfalse是否自动建链对应OPTION_AUTO_CONNECThas_capacity_tb/capacity_tbbool / size_tfalse/0是否显式配置 Fabric 虚拟内存容量TBhas_start_address_tb/start_address_tbbool / size_tfalse/0是否显式配置 Fabric 虚拟内存起始地址TB合法范围[0, 1024]task_stream_numsize_t1任务流数量enable_aicpu_unfoldtrue时必须为 1max_stream_numsize_t512最大流数量enable_aicpu_unfoldbooltrue是否启用 AICPU 展开路径max_transfer_count_per_batchuint32_t1920单批最大传输数量范围[1, 1920]关于max_transfer_count_per_batch设计文档与 transfer_config.h 的约束相互印证kDefaultMaxTransferCountPerBatch 1920U两种展开模式Host/AICPU都会执行[1, 1920]的范围校验。两种展开模式下该参数的作用不同enable_aicpu_unfoldtrue时它控制 AICPU 展开的逻辑批次和 Notify 边界不改变固定 2K 的 STARS 队列深度enable_aicpu_unfoldfalse时Host 逐条提交aclrtMemcpyAsync不按该值分批也不在该值边界增加同步。该参数还会向下游传递max_transfer_count_per_batch经 client_handler_config_helper.h 写入transfer_config.max_transfer_count_per_batch并在 direct_client_handler.cc 中对 HCCS 路径执行 kMaxFixedQueueTransferCountPerBatch(1920)的校验。虚拟内存容量与起始地址通过VirtualMemoryManager应用fabric_mem_engine.cc 中的ApplyVirtualMemoryConfig在配置了capacity_tb/start_address_tb时分别调用SetVirtualMemoryCapacity/SetGlobalStartAddress。并发与锁设计正确性保证的核心设计前提与组件职责设计前提不考虑Finalize与对外 API 并发对外 API 入口仅做is_initialized_检查。组件职责与前述架构章节一致FabricMemEngine薄门面FabricMemTransferService传输门面FabricMemChannelManager连接生命周期与请求路由FabricMemSlotPoolslot 池FabricMemLocalMemory本地注册FabricMemRemoteMemory单 channel 远端映射。锁层级组件锁保护对象Enginemutex_Initialize/Finalize 编排LocalMemoryshare_handle_mutex_share_handles_含 overlap 校验ChannelManagerconnect_mutex_Fetch Install 串行化独立网络 I/O 阶段不持channels_mutex_ChannelManagerchannels_mutex_channels_连接表与initialized_ChannelManagerreq_route_mutex_req_2_channel_请求路由表Channelsubmit_gateshared_mutex传输提交与断链互斥提交持共享锁并行下发拷贝断链AbortAndClearChannelRecords持独占锁drain 在途提交后再 abort/unmapabort-before-unmapChannelrecords_mutex单 channel 的disconnecting/async_records/active_sync_slots简短簿记不含拷贝下发SlotPoolpool_mutex_slot 池叶锁RemoteMemorymutex_单 channel 导入映射叶锁ControlServerState::mutexsessions/client_id_to_fd/ 监听与 epoll fd发送一律在锁外从源码可以印证该锁结构fabric_mem_channel_manager.h 中FabricMemChannel持有submit_gatestd::shared_mutex、records_mutexstd::mutex、disconnectingstd::atomicbool、async_records与active_sync_slotsFabricMemChannelManager持有独立的connect_mutex_、channels_mutex_与req_route_mutex_。AICPU 路径还额外使用 channel 上的transfer_mubound_slot做单 channel 串行化。固定加锁顺序channels_mutex_独立持有禁止在其内执行网络 I/O。单 channel 内submit_gate→records_mutex传输提交持submit_gate共享锁仅在登记 record/slot 时短暂持records_mutexAbortAndClearChannelRecords先持submit_gate独占锁再持records_mutex。submit_gate→req_route_mutex_IssueAsyncCopyAndRegister在释放records_mutex之后、仍持submit_gate共享锁时调用AddReqRouteRemoveReqRoute在释放submit_gate之后调用。禁止逆序。connect_mutex_与channels_mutex_分离。pool_mutex_/share_handle_mutex_/ RemoteMemorymutex_为叶锁不与上述锁嵌套。跨组件规则Engine API 不在多个组件间嵌套持锁典型传输路径为 TransferService 经 ChannelManager 取 channel → 持submit_gate共享锁下发拷贝在records_mutex内登记 record/slot异步路径再持submit_gate共享锁下调用AddReqRoute→GetTransferStatus在records_mutex内查询 stream 状态并取出 record仅在锁外做阻塞 synchronize。典型并发场景场景行为多线程 TransferSync 同一 remote拷贝在submit_gate共享锁下并行下发records_mutex仅用于登记active_sync_slots供 disconnect abortTransferAsync GetTransferStatus拷贝在submit_gate共享锁下并行下发async record 由 channelrecords_mutex保护GetTransferStatus在锁内查询 stream 状态并取出 record避免与 disconnect 销毁 stream 竞争仅需reqDisconnect立即 abort、不等待传输完成先设disconnectingtrue持submit_gate独占锁 drain 在途提交在records_mutex内取出并清空 async record、abort sync slot仅 abort锁外销毁 async slot 并清理请求路由keepalive 线程 auto-disconnectkeepalive 线程内聚于 ChannelManager不持 Engine 锁独立 DisconnectRemoveChannel先 abort/清理该 channel 的 async record 与请求路由再清理导入映射、stream、统计通道Heartbeat 机制FabricMemControlClient::SendHeartBeat/ 入站 ADXL 解析均内聚于 fabric_mem_control.h 的fabric_mem_control模块自连 session 与远端 session 统一启用 heartbeat 超时检查。ControlServer的 worker 线程仅在State::mutex内做 session 读取与 map 变更所有发送在锁外完成慢速对端不会拖垮Stop()或 keepalive monitorpending_connections仅由 worker 线程访问Stop()在 join worker 之后再清理 map。CheckClientHeartbeatTimeouts负责回收心跳超时的对端连接配合FabricMemChannelManager::DisconnectDeadRemote完成对端异常下线时的资源清理。关键检查点与兼容性设计检查点列表Engine 路由检查OPTION_ENABLE_USE_FABRIC_MEM1时必须由EngineFactory创建FabricMemEngine。配置合法性检查FabricMemConfig解析EnableUseFabricMem、GlobalResourceConfig、流数量、虚拟地址容量、起始地址和单批最大传输数量。transfer_config.max_transfer_count_per_batch范围为[1, 1920]、默认1920两种展开模式都会执行该范围校验。enable_aicpu_unfoldtrue时它控制 AICPU 展开的逻辑批次和 Notify 边界不改变固定 2K 的 STARS 队列深度enable_aicpu_unfoldfalse时Host 逐条提交aclrtMemcpyAsync不按该值分批也不在该值边界增加同步。内存类型检查在 FabricMem 模式下HOST 内存注册需要额外的本地导入和映射处理。传输参数检查验证传输描述中的地址范围是否在本端已注册或对端已导入的内存范围内。流资源管理检查确保流池中的流资源正确分配和释放避免资源泄漏。异步请求状态检查异步传输时正确跟踪请求状态确保状态查询的准确性。内存映射清理检查连接断开时正确清理FabricMemRemoteMemory中的导入映射关系。并发安全检查多线程环境下对共享数据结构的访问安全。对端异常下线对端异常下线时需要清理相关资源避免资源泄漏。性能关键点流池管理预创建和管理设备流避免频繁创建销毁的开销。FabricMemSlotPool以有界池的形式复用 transfer slot每个 slot 拥有 context、task streams 与 host 完成标志AcquireWithTimeout/AcquireAsync获取、Release归还或销毁abort 其 stream。多流并发支持一次使用多条流并发处理。max_stream_num默认 512控制流池规模Host 路径下同一 channel 的多传输可并行下发。异步操作支持异步传输允许重叠计算和通信。异步完成判定使用 host flag D2H 轮询方式替代了传统 EventRecord/query event 方案。兼容性考虑向后兼容默认不启用 FabricMem 模式enabledfalse保持与传统 ADXL/HCCL 路径的兼容性。统计归属FabricMem 传输统计由FabricMemStatistic维护ADXL 侧StatisticManager只维护 ADXL/HCCL 路径的建链与传输统计。统计模块的源码实现与设计文档完全对应fabric_mem_statistic.h 中FabricMemTransferStatisticInfo按 channel 记录transfer传输耗时与real_copy真实拷贝耗时两类成本统计次数/最大耗时/总耗时外加total_bytes与total_op_desc_countFabricMemStatistic通过RegisterChannel/UpdateCosts/GetSnapshot/Dump维护全量统计并支持StartPeriodicDump周期导出。UpdateCosts的四个统计字段正是设计文档中传输耗时、真实拷贝耗时、总字节数和 op desc 数量的落点。仓库中的验证与配套在仓库中可以找到 FabricMem 相关的一组配套资源便于读者对照源码深入理解设计文档中文版、英文版另有 docs/en/FabricMem.md 简要介绍启用方法。核心实现src/hixl/fabric_memchannel/slot/memory/control/statistic 等与 fabric_mem_engine.cc。引擎路由engine_factory.cc 展示EnableFabricMem分支。单元测试tests/cpp/hixl/fabric_mem 下的fabric_mem_unittest.cc、fabric_mem_config_parser_unittest.cc、fabric_mem_aicpu_unfold_unittest.cc、virtual_memory_manager_unittest.cc、fabric_mem_st.cc等覆盖配置解析、AICPU 展开、虚拟内存管理与系统级场景hixl_options_unittest.cc 覆盖选项解析。使用示例基准测试中comm_benchmark 的 benchmark_config.cpp 在未显式配置时默认注入OPTION_ENABLE_USE_FABRIC_MEM 1kv_benchmark 的 hixl_kv_bench.cpp 同样以该选项初始化引擎可作为实际工程调用的参考。结语FabricMem 传输模式是 HIXL 面向 A3 超节点 D2RH/RH2D 场景的专用数据通路通过独立FabricMemEngine与既有 ADXL/HCCL 路径解耦借助共享句柄导入/导出实现跨节点内存统一编址以 slot 池 多流并发 host flag 轮询异步完成机制保障传输性能并以一套清晰的锁层级与 heartbeat 机制保证并发安全与异常清理。对 LLM 推理场景中的分布式 DRAM 缓存池如 Mooncake store而言理解并正确配置OPTION_ENABLE_USE_FABRIC_MEM、enable_aicpu_unfold与max_transfer_count_per_batch等关键参数是充分发挥该模式价值的前提。【免费下载链接】hixlHIXLHuawei Xfer Library是一个灵活、高效的昇腾单边通信库面向集群场景提供简单、可靠、高效的点对点数据传输能力。项目地址: https://gitcode.com/cann/hixl创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表