当前位置: 首页 > article >正文

CANN runtime:昇腾NPU 运行时的职责边界

个人主页ujainu文章目录前言为什么需要运行时这一层runtime管什么不管什么Stream并行的基本调度单位Event跨Stream的同步锚点内存池化少一次malloc就少一次卡顿任务队列从计算图到硬件指令的最后一跳在五层架构里占什么位置和上下游仓库怎么协作关键警告runtime最容易踩的两个坑前言一个模型从编译完成到真正在芯片上执行中间隔着一条鸿沟——谁把计算图拆成硬件能认的指令谁管理多路并发不冲突谁保证算完一步再走下一步在昇腾CANN的架构里这个活落在runtime头上。runtime是昇腾NPU的运行时层驻守在编译层和硬件驱动之间负责任务调度与资源管理。没有它ge编译出来的计算图只是一份图纸永远变不成芯片上的电信号。仓库地址https://atomgit.com/cann/runtime为什么需要运行时这一层先看一个反直觉的事实同一个模型ge编译后直接逐算子下发给驱动执行吞吐可能只有优化后的五分之一。差的不是算子本身而是调度——算子之间的等待、内存的反复申请释放、多流之间的冲突全是运行时该管的事。runtime存在的原因可以归结为三点硬件并发需要编排——昇腾NPU有多组计算单元不编排就是单线程串行编排好了多流并行吞吐翻倍内存不能乱来——NPU显存有限无规划的分配会导致碎片化甚至OOM同步不能靠猜——多流之间有依赖关系不同步就出数据竞争调试到怀疑人生runtime管什么不管什么runtime的职责边界需要说清楚否则很容易把它和ge、Driver混为一谈runtime管的Stream的创建、销毁与任务编排Event的记录与跨Stream同步Device显存的池化分配与回收Task队列的异步下发与完成通知多Stream间的资源隔离与共享runtime不管的计算图的算子融合与重排——这是ge的编译期职责硬件寄存器的直接读写——这是Driver的基础层职责算子的具体计算逻辑——这是Ascend C算子开发的事分布式通信的拓扑构建——这是hccl的事runtime只提供Stream承载// runtime管与不管的边界示例// ✅ runtime管创建Stream、分配显存、下发TaskaclrtStream stream;aclrtCreateStream(stream);aclrtMalloc(dev_ptr,size,ACL_MEM_MALLOC_HUGE_FIRST);// ❌ runtime不管算子融合策略、硬件寄存器配置// 这些分别由ge编译期和Driver负责理解这条边界才能在遇到问题时定位到正确的仓库调度异常找runtime算子执行异常找Ascend C算子或Driver编译结果不对找ge。Stream并行的基本调度单位Stream是runtime最核心的抽象。你可以把它理解成一条独立的任务流水线——同一个Stream里的任务严格按顺序执行不同Stream之间的任务可以并行。// 创建两个Stream让数据拷贝和计算重叠aclrtStream stream1,stream2;aclrtCreateStream(stream1);aclrtCreateStream(stream2);// stream1 做数据搬运aclrtMemcpyAsync(dev_a,size,host_a,size,ACL_MEMCPY_HOST_TO_DEVICE,stream1);// stream2 做计算不等stream1aclrtLaunchKernel(kernel1,...,stream2);这段代码的关键不是怎么写而是理解runtime在背后做了什么——两条Stream的任务队列独立维护硬件调度器从不同队列取任务并发执行。一个常见的坑以为创建多个Stream就能自动并行但如果没有Event同步stream2可能在数据还没搬完时就开始计算。Stream的数量不是越多越好。每个Stream在硬件侧对应一组任务队列和上下文资源创建过多会挤占执行资源。实际使用中2-4条Stream通常足以覆盖H2D搬运、D2H回传、计算这三条流水线。# Python AscendCL调用中创建Stream的典型方式importacl# 初始化acl.init()contextacl.rt.create_context(0)# 创建默认Stream和专用Streamdefault_streamacl.rt.create_stream()# 默认计算流h2d_streamacl.rt.create_stream()# 专用搬运流# 异步拷贝使用专用Streamacl.rt.memcpy_async(dev_buf,size,host_buf,size,acl.ACL_MEMCPY_HOST_TO_DEVICE,h2d_stream)Event跨Stream的同步锚点Stream解决了谁跟谁并行的问题Event解决的是谁等谁的问题。Event是一个轻量的同步原语插在Stream的某个位置其他Stream可以等待这个Event完成。// stream1搬完数据后记录一个EventaclrtEvent event;aclrtCreateEvent(event);aclrtRecordEvent(event,stream1);// stream2等待这个Event确保数据就绪aclrtStreamWaitEvent(stream2,event);// 现在stream2的计算可以安全使用dev_a了aclrtLaunchKernel(kernel2,...,stream2);Event的延迟极低——它不是CPU侧的轮询等待而是硬件层面的信号量机制。runtime把Event映射到昇腾NPU的硬件同步原语上开销几乎可以忽略。但别滥用每个Event占用硬件资源同时活跃的Event数量有上限。Event还有一个常见用法是计时。通过在Stream前后各Record一个Event然后计算两个Event之间的耗时可以精确测量某段Device侧执行的时长精度远高于Host侧的时钟// 用Event测量Device侧执行耗时aclrtEvent start,stop;aclrtCreateEvent(start);aclrtCreateEvent(stop);aclrtRecordEvent(start,stream);aclrtLaunchKernel(kernel,...,stream);// 要测量的执行aclrtRecordEvent(stop,stream);aclrtSynchronizeStream(stream);// 等执行完floatelapsed_ms;aclrtEventElapsedTime(elapsed_ms,start,stop);printf(kernel耗时: %.3f ms\n,elapsed_ms);内存池化少一次malloc就少一次卡顿NPU显存的分配和释放是昂贵操作。直接调用驱动的内存接口每次都要走完整的分配路径包括物理页映射和TLB刷新。runtime的做法是池化——预分配一大块显存内部按需切分。// runtime内部大致的内存池逻辑简化示意// 不是真实API只是说明池化思路// 首次分配时向驱动申请大块if(pool_sizerequest_size){aclrtMalloc(pool_base,EXPAND_SIZE,ACL_MEM_MALLOC_HUGE_FIRST);pool_sizeEXPAND_SIZE;}// 从池中切分不走驱动void*ptrpool_alloc(request_size);// 释放时归还池不真正freepool_free(ptr);池化的收益不只是快。连续内存分配意味着更少的内存碎片对于大模型推理这种显存吃紧的场景碎片化往往是OOM的直接原因。runtime的内存池还支持多Stream间的共享避免每个Stream各占一块、互相浪费。runtime的内存池有两种分配策略通过aclrtMalloc的参数选择ACL_MEM_MALLOC_HUGE_FIRST优先分配大页内存减少TLB miss适合大tensorACL_MEM_MALLOC_NORMAL_FIRST优先分配普通页内存适合小tensor和临时缓冲区# Python中的内存分配策略选择importacl# 大tensor用HUGE_FIRSTbig_tensoracl.rt.malloc(1024*1024*512,# 512MBacl.ACL_MEM_MALLOC_HUGE_FIRST)# 小缓冲区用NORMAL_FIRSTsmall_bufacl.rt.malloc(1024*4,# 4KBacl.ACL_MEM_MALLOC_NORMAL_FIRST)# 使用完归还到池不是真正freeacl.rt.free(big_tensor)acl.rt.free(small_buf)任务队列从计算图到硬件指令的最后一跳ge编译完的计算图最终被拆解成一系列Task由runtime下发给驱动。每个Task对应一个硬件可执行的指令包runtime负责把这些Task按Stream编排、按依赖排序、按优先级调度。// runtime内部Task下发的简化流程// 1. 接收ge编译后的Task列表TaskList*tasksge_get_compiled_tasks(graph);// 2. 按Stream分配Taskfor(task in tasks){streamget_stream(task);enqueue(stream,task);// 入队不立即执行}// 3. 触发硬件执行aclrtSynchronizeStream(stream);一个关键特征runtime的任务队列是异步的。调用aclrtLaunchKernel时Task只是入队不会等硬件执行完才返回。这意味着CPU可以继续准备下一个Task实现Host和Device的流水线重叠。但如果你忘了同步就去读结果——恭喜数据可能是半成品。异步队列带来的另一个好处是批处理。多个Task连续入队后runtime会尝试将它们合并成更大的指令包一次性下发给硬件减少Host-Device交互次数。这种攒一批再发的策略在大batch推理时尤为有效# 通过环境变量控制runtime的Task下发行为# 开启Task聚合减少下发次数exportASCEND_LAUNCH_TASK_OPTIMIZE1# 设置Stream优先级数值越小优先级越高exportASCEND_STREAM_PRIORITY0在五层架构里占什么位置runtime处在昇腾CANN五层架构的第4层——昇腾计算执行层同层还有Graph Executor、HCCL、DVPP、AIPP。这一层是干活的层编译层负责把计算图翻译好执行层负责真正把活干完。第3层 ge编译层 → 输出编译后的Task列表 ↓ 第4层 runtime执行层 → Stream编排、内存管理、Task下发 ↓ 第5层 Driver基础层 → 硬件寄存器操作、物理内存映射runtime往上看接收ge编译后的模型和Task往下看通过Driver接口操作硬件横着看HCCL的分布式通信也是在runtime的Stream机制上运行的。runtime与AscendCL的关系需要特别说明。AscendCL是昇腾CANN对外的统一编程接口层runtime的核心能力——Stream、Event、内存管理、Task下发——都通过AscendCL的API暴露给开发者。你在代码里调用的aclrtCreateStream、aclrtMalloc、aclrtLaunchKernel看似是AscendCL的函数底层实现全在runtime里。AscendCL更像一层薄薄的胶水把runtime、hccl、DVPP等子系统的能力统一封装起来给开发者一个一致的调用体验。// AscendCL调用与runtime的对应关系// 开发者视角调AscendCLaclrtCreateStream(stream);// → runtime创建Stream对象aclrtMalloc(ptr,size,flag);// → runtime内存池分配aclrtLaunchKernel(...,stream);// → runtime Task入队// runtime视角接收请求后操作Driver// Stream创建 → 向Driver申请硬件队列资源// 内存分配 → 池化分配或向Driver申请新页// Task入队 → 写入Stream对应队列通知硬件调度器和上下游仓库怎么协作runtime不是孤立存在的它的上下游关系很清晰上游——gege编译完计算图后把优化后的Task列表下沉给runtime执行。ge管怎么算更优runtime管怎么跑更快。ge在编译期做的算子融合、流水线切分、内存复用规划最终都体现为Task列表里的依赖关系和内存地址。runtime拿到这份Task列表后按照依赖顺序和Stream分配策略把Task逐个下发到硬件。下游——Driverruntime通过Driver的HAL接口操作硬件。内存分配、Task下发、硬件状态查询最终都走Driver。runtime不直接碰硬件寄存器。这意味着同一套runtime代码只要Driver适配了不同的芯片型号就能跑在不同的昇腾NPU上——这正是硬件抽象的意义。下游——AscendCLAscendCL是CANN对外的统一编程接口runtime的Stream、Event、内存管理能力都通过AscendCL暴露给开发者。你调用的aclrtCreateStream底层就是runtime在干活。关联——hcclHCCL的集合通信操作AllReduce、AllGather等在runtime的Stream上运行依赖runtime的同步机制保证通信和计算的执行顺序。HCCL不直接操作硬件它把通信Task提交到runtime的Stream上由runtime统一调度。这种设计保证通信和计算可以正确地交叉执行——比如先算两轮再做一次AllReduce再算两轮全程在同一个Stream上下文中有序推进。ge → runtime → Driver ↑ AscendCL对外接口 hccl分布式通信// hccl在runtime Stream上运行的简化示意// hccl的AllReduce本质上是向Stream提交通信TaskhcclResult_trethcclAllReduce(sendbuf,recvbuf,count,hcclFloat,hcclSum,comm,stream// ← 使用runtime的Stream);// 通信Task入队后runtime负责调度执行// 后续计算Task可以依赖这个Stream的顺序保证aclrtLaunchKernel(post_reduce_kernel,...,stream);关键警告runtime最容易踩的两个坑坑一忘了同步就读结果。runtime的接口大多是异步的Launch之后数据还在硬件上跑CPU侧直接读Device内存拿到的是未定义数据。aclrtSynchronizeStream不是可选的是必须的。// 错误示范异步Launch后直接读aclrtLaunchKernel(kernel,...,stream);aclrtMemcpy(host_result,size,dev_result,size,ACL_MEMCPY_DEVICE_TO_HOST);// ❌ 数据可能还没算完// 正确做法先同步再读aclrtLaunchKernel(kernel,...,stream);aclrtSynchronizeStream(stream);// ✅ 等硬件执行完aclrtMemcpy(host_result,size,dev_result,size,ACL_MEMCPY_DEVICE_TO_HOST);坑二Stream之间隐式依赖。两个Stream操作同一块Device内存时runtime不做自动同步。必须手动插Event否则就是数据竞争——而且这种bug是概率性的跑一百次可能只有三次出错排查到崩溃。# 排查Stream同步问题的实用命令# 开启runtime的同步检查日志exportASCEND_LOG_EVENT_ENABLE1# 检测未同步的Device内存访问exportASCEND_MEM_CHECK1# 查看runtime内部Stream和Event状态cat/usr/local/Ascend/ascend-toolkit/latest/runtime/conf/runtime.conf想真正理解runtime最直接的方式是写一个多Stream并行的推理程序手动管理Event和内存池。代码量不大但能把Stream编排、同步等待、内存复用这几个核心概念全部串起来。仓库地址https://atomgit.com/cann/runtime 里面有你需要的头文件和示例。

相关文章:

CANN runtime:昇腾NPU 运行时的职责边界

个人主页:ujainu 文章目录前言为什么需要运行时这一层runtime管什么,不管什么Stream:并行的基本调度单位Event:跨Stream的同步锚点内存池化:少一次malloc就少一次卡顿任务队列:从计算图到硬件指令的最后一跳…...

为内部知识库问答机器人集成taotoken多模型能力的架构设计

🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 为内部知识库问答机器人集成taotoken多模型能力的架构设计 应用场景类,探讨为企业内部知识库构建智能问答机器人时&…...

Windows Cleaner如何5步解决C盘爆红问题?完全指南助你释放宝贵空间

Windows Cleaner如何5步解决C盘爆红问题?完全指南助你释放宝贵空间 【免费下载链接】WindowsCleaner Windows Cleaner——专治C盘爆红及各种不服! 项目地址: https://gitcode.com/gh_mirrors/wi/WindowsCleaner 你是否曾经面对C盘爆红的警告束手无…...

星露谷物语SMAPI模组加载器:从新手到专家的完整使用指南

星露谷物语SMAPI模组加载器:从新手到专家的完整使用指南 【免费下载链接】SMAPI The modding API for Stardew Valley. 项目地址: https://gitcode.com/gh_mirrors/smap/SMAPI 星露谷物语SMAPI模组加载器是官方推荐的模组API,它为玩家和开发者提供…...

基于ESP8266的可穿戴Wi-Fi设备:从硬件设计到ESPHome智能控制

1. 项目概述:一个可穿戴的Wi-Fi智能小玩意最近在捣鼓智能家居和可穿戴电子,总想把手边的小物件变得更“聪明”一点。于是,我设计并制作了一个基于ESP8266的可穿戴Wi-Fi设备。它的核心思路很简单:把一块功能强大的Wi-Fi微控制器&am…...

DeTikZify:基于AI的TikZ图形程序自动生成技术深度解析

DeTikZify:基于AI的TikZ图形程序自动生成技术深度解析 【免费下载链接】DeTikZify Synthesizing Graphics Programs for Scientific Figures and Sketches with TikZ. 项目地址: https://gitcode.com/gh_mirrors/de/DeTikZify DeTikZify是一款革命性的多模态…...

基于ESP8266与RGBDigit的Wi-Fi网络时钟:硬件设计、物联网集成与DIY实践

1. 项目概述:一个能感知环境的网络时钟如果你和我一样,对复古又带点科技感的显示设备没有抵抗力,同时又是个喜欢动手折腾的极客,那么这个项目绝对能让你在工作室或家里多一个既实用又炫酷的玩意儿。我说的就是这款基于RGBDigit数码…...

如何快速掌握ncmdumpGUI:Windows平台网易云音乐NCM文件转换完整教程

如何快速掌握ncmdumpGUI:Windows平台网易云音乐NCM文件转换完整教程 【免费下载链接】ncmdumpGUI C#版本网易云音乐ncm文件格式转换,Windows图形界面版本 项目地址: https://gitcode.com/gh_mirrors/nc/ncmdumpGUI 你是否曾经下载了网易云音乐的…...

Hitboxer:终极SOCD按键重映射解决方案,彻底解决游戏按键冲突问题

Hitboxer:终极SOCD按键重映射解决方案,彻底解决游戏按键冲突问题 【免费下载链接】socd Key remapper for epic gamers 项目地址: https://gitcode.com/gh_mirrors/so/socd 在激烈的游戏对战中,你是否曾因同时按下左右方向键而导致角色…...

告别RaiDrive广告!用开源rclone+Alist,免费把阿里云盘/百度网盘变成电脑本地硬盘

开源方案实战:用rcloneAlist打造无广告的云盘本地化体验 每次打开RaiDrive时弹出的广告窗口是否让您感到困扰?商业软件的收费模式是否让您犹豫不决?今天,我们将彻底解决这些问题。通过开源工具Alist和rclone的组合,您不…...

DSP、FPGA、STM32大对决:谁才是嵌入式开发的“天选之子”?

在嵌入式开发的广阔天地里,DSP、FPGA 和 STM32(作为通用 MCU 的典型代表)可以说是三款绕不开的核心处理器。很多初学者甚至有一定经验的工程师在选择时都会陷入纠结:我的项目到底该选哪一个?为了帮你彻底理清思路&…...

别再只会用--nogpgcheck了!手把手教你安全修复PostgreSQL yum源的GPG密钥问题

企业级PostgreSQL部署:安全解决GPG密钥验证的完整方案 当你在生产环境中部署PostgreSQL时,遇到GPG签名验证错误直接使用--nogpgcheck绕过检查,就像因为门锁打不开就直接把门拆掉一样危险。本文将带你深入理解GPG验证机制,并提供一…...

当B站字幕不再只是弹幕:你的个人学习宝库解锁指南

当B站字幕不再只是弹幕:你的个人学习宝库解锁指南 【免费下载链接】BiliBiliCCSubtitle 一个用于下载B站(哔哩哔哩)CC字幕及转换的工具; 项目地址: https://gitcode.com/gh_mirrors/bi/BiliBiliCCSubtitle 还记得那个深夜吗?你正在B站追着某个技术…...

别只盯着主控芯片!拆解STM32最小系统板:电源、时钟、复位三大支柱电路深度解析

STM32最小系统板设计进阶:电源、时钟与复位电路的工程实践 在嵌入式系统开发中,我们常常将注意力集中在主控芯片的功能实现上,却忽略了支撑系统稳定运行的三大基础电路——电源、时钟和复位。这些看似简单的电路模块,实则是整个系…...

深入解析NxDumpTool:Switch游戏文件系统提取的终极指南 [特殊字符]

深入解析NxDumpTool:Switch游戏文件系统提取的终极指南 🎮 【免费下载链接】nxdumptool Generates XCI/NSP/HFS0/ExeFS/RomFS/Certificate/Ticket dumps from Nintendo Switch gamecards and installed SD/eMMC titles. 项目地址: https://gitcode.com…...

告别Appium!用Python+UIAutomator2搞定Android自动化测试(附完整环境搭建与实战代码)

PythonUIAutomator2:Android自动化测试的高效实践指南 在移动应用测试领域,效率与稳定性始终是工程师们追求的核心目标。传统方案如Appium虽然功能全面,但在执行速度和资源消耗方面往往难以满足高频测试需求。本文将带您探索基于Python和UIA…...

终极Windows风扇控制指南:FanControl让你的电脑安静又高效

终极Windows风扇控制指南:FanControl让你的电脑安静又高效 【免费下载链接】FanControl.Releases This is the release repository for Fan Control, a highly customizable fan controlling software for Windows. 项目地址: https://gitcode.com/GitHub_Trendin…...

告别Selenium?手把手教你用Playwright录制脚本,5分钟搞定Web自动化测试

5分钟极速上手Playwright脚本录制:零代码实现Web自动化测试当产品经理突然丢给你一个刚上线的电商活动页,要求半小时内完成所有核心链路测试时,传统的手写Selenium脚本显然来不及。作为测试工程师,我最近发现微软开源的Playwright…...

终极虚拟显示器解决方案:ParsecVDisplay完整使用指南

终极虚拟显示器解决方案:ParsecVDisplay完整使用指南 【免费下载链接】parsec-vdd ✨ Perfect virtual display for game streaming 项目地址: https://gitcode.com/gh_mirrors/pa/parsec-vdd ParsecVDisplay是一个基于Parsec虚拟显示驱动(VDD)的独立应用程序…...

如何用Nucleus Co-Op让单机游戏变身本地多人分屏神器

如何用Nucleus Co-Op让单机游戏变身本地多人分屏神器 【免费下载链接】nucleuscoop Starts multiple instances of a game for split-screen multiplayer gaming! 项目地址: https://gitcode.com/gh_mirrors/nu/nucleuscoop 还在为想和朋友一起玩游戏却只有一台电脑而烦…...

基于窗口比较器与晶体管逻辑的可编程非线性电压指示器设计

1. 项目概述:打造一个可编程的“移动光点”电压指示器在电子制作和仪器仪表领域,我们经常需要一个直观的电压指示器。经典的LM3914点/条图显示驱动芯片大家都很熟悉,它能把一个模拟电压信号转换成10个LED的点亮状态,形成移动的光点…...

AI专著生成必备工具,轻松撰写20万字专著,质量与效率双保障!

学术专著的写作是一个严谨的过程,其背后需要大量的资料和数据作为基础。搜集和整理这些资料与数据往往是写作过程中最繁琐且耗时的部分。研究人员需要广泛收集国内外的前沿文献,确保所用文献不仅具备权威性,还要与研究主题密切相关。同时&…...

茉莉花插件:如何让中文文献管理效率提升300%

茉莉花插件:如何让中文文献管理效率提升300% 【免费下载链接】jasminum A Zotero add-on to retrive CNKI meta data. 一个简单的Zotero 插件,用于识别中文元数据 项目地址: https://gitcode.com/gh_mirrors/ja/jasminum 还在为中文文献的元数据抓…...

5步完美解决Windows 10 PL2303驱动兼容性问题:完整实施方案指南

5步完美解决Windows 10 PL2303驱动兼容性问题:完整实施方案指南 【免费下载链接】pl2303-win10 Windows 10 driver for end-of-life PL-2303 chipsets. 项目地址: https://gitcode.com/gh_mirrors/pl/pl2303-win10 在Windows 10系统中使用PL2303 USB转串口设…...

3分钟快速上手:bilibili-parse视频解析API终极指南

3分钟快速上手:bilibili-parse视频解析API终极指南 【免费下载链接】bilibili-parse bilibili Video API 项目地址: https://gitcode.com/gh_mirrors/bi/bilibili-parse bilibili-parse是一款高效专业的B站视频解析工具,为开发者和内容创作者提供…...

全方位梳理 OpenClaw 部署与使用干货

OpenClaw 一键安装包|可视化部署,简化环境配置流程 ✨适配系统:Windows10/11 64 位 当前版本:v2.7.5(虾壳云版) ✨核心优势:全程可视化操作,不用命令行、不用手动配置 Python/Node…...

VideoDownloadHelper终极指南:解锁浏览器视频下载的完整解决方案

VideoDownloadHelper终极指南:解锁浏览器视频下载的完整解决方案 【免费下载链接】VideoDownloadHelper Chrome Extension to Help Download Video for Some Video Sites. 项目地址: https://gitcode.com/gh_mirrors/vi/VideoDownloadHelper 还在为无法保存网…...

3步搞定B站缓存视频转换:m4s转MP4的终极解决方案

3步搞定B站缓存视频转换:m4s转MP4的终极解决方案 【免费下载链接】m4s-converter 一个跨平台小工具,将bilibili缓存的m4s格式音视频文件合并成mp4 项目地址: https://gitcode.com/gh_mirrors/m4/m4s-converter 你是否曾经在B站缓存了珍贵的视频&a…...

服务器数据下载安全:实时加密与动态访问控制实战

1. 这不是又一个“加个密码”的方案,而是服务器数据流动的实时安检闸机IP-guard安全网关——这个名字在企业IT运维圈里,常被误读为“桌面端U盘管控工具”或“员工上网行为审计系统”。但真正用过它来守服务器的人,会立刻意识到:它…...

智能体任务分配算法:从启发式到深度强化学习的演进与实践

1. 项目概述:从“谁来做”到“如何做得更好”的智能进化在机器人集群、无人机编队或是自动化仓储系统中,我们常常面临一个看似简单实则复杂的问题:眼前有一堆任务,手头有一群可用的智能体(机器人、无人机、服务器等&am…...