☰
4096节点鲲鹏CPU集群:Agent高并发场景的算力新底座
2026/10/1 15:36:38 网站建设 项目流程

“你们搞Agent,是不是又在疯抢GPU了?”这是最近被问最多的一句话。我回答说:没有,我们刚把一台用鲲鹏CPU拼起来的“超级计算机”推上线,一共4096个节点,跑的是Agent的完整生产链路,包括模型推理、工具调用、记忆检索、多智能体编排,全部压在CPU集群上。这正好踩中了“CPU重回C位”这个题眼——当大家一窝蜂去挤GPU时,我们用CPU造出来的这台4096节点集群,反而在Agent的高并发场景里打出了性价比和吞吐优势。

这篇文章就把这套方案的完整思路拆开来讲。从“为什么Agent场景会重新拥抱CPU”,到4096节点集群的拓扑设计、CPU亲和性调度、高并发链路改造,再到实际运维中的坑和排查经验,适合三类人看:正在做Agent基础设施的架构师、想把业务从GPU挪到CPU上降本的平台团队,以及单纯想了解大规模CPU集群怎么支撑AI应用的同学。

1. 为什么Agent场景会让CPU重回C位

1.1 先看看Agent到底需要什么样的算力

过去两年,行业里默认一个观点:AI应用离不开GPU。这个结论在大模型训练阶段成立,但在Agent推理场景里,往往被过度套用。Agent的负载构成和纯大模型推理很不一样,我把它拆成了四类:

  • 短请求为主:一次Agent决策往往只调用小模型或中模型,模型参数在1B到14B之间,不是每次都要跑千亿参数。
  • 有状态交互:多轮会话、长期记忆、上下文拼接,需要频繁读写状态,这部分对CPU、内存、IO的需求一点不比模型推理低。
  • 工具调用密集:Agent要反复决定“下一步调什么工具”,伴随JSON解析、参数校验、外部API请求,这是典型的CPU指令密集型负载。
  • 并发路径多而杂:一个复杂任务会拆出多个子任务并行执行,彼此通过消息传递,而不是靠一个巨大的矩阵计算统摄全局。

所以,Agent的真实算力瓶颈往往不在单次GPU计算,而在高并发下的调度、状态同步、工具执行和上下文管理。CUDA再强,也不能帮你省掉一次函数调用、一次序列化、一次网络握手。把这一类负载整体搬到CPU上,逻辑上是成立的。

1.2 鲲鹏这类ARM服务器CPU凭什么接得住

选了鲲鹏,不是情怀,是这几条硬指标综合下来的结果。

第一是核心数。鲲鹏920芯片单颗能做到64核甚至更多,一台2路服务器就是128逻辑核心。对于Agent这种“多任务并发”场景,核心数量直接影响并发能力上限,比单核频率更关键。

第二是内存通道和带宽。Agent运行时会把大量模型权重、上下文状态、工具列表放在内存里,频繁访问。鲲鹏的内存控制器支持多通道DDR4/DDR5,内存带宽比同期的部分x86平台还要宽。带宽够了,高并发下不容易出“内存墙”问题。

第三是功耗和部署密度。同样一张机柜,塞满GPU的功耗可能让机房电源直接报警,而CPU节点的功耗相对平缓,4096个节点可以按照标准机架密度铺开,不需要单独改制冷方案。

第四是生态兼容性。鲲鹏在服务器上跑的是标准Linux内核、标准容器运行时,Kubernetes、Docker、Python/C++运行时都能直接跑,Agent框架不需要为特定架构重写,只需要做编译和指令集适配。

基于这些理由,我们把“Agent算力底座”从GPU方案切换成鲲鹏CPU方案。刚执行完这个决定时,团队内部也有质疑,但等4096节点集群接通后,用实际吞吐数据说话,大家才真信了。

1.3 与传统GPU方案的取舍

不是把GPU说得一无是处。大模型预训练、长文本总结、复杂多步推理的大型模型,该用GPU还得用GPU。但Agent场景有一个特点:大量请求是“短平快”的,模型推理只占整条链路的30%-40%,剩下的时间都在做Agent框架逻辑、工具调用和状态读写。

用GPU处理这剩下的60%时间,等于拿跑车运货,成本高不说,还可能因为GPU显存有限而让请求排队。CPU集群则可以把每个小任务散布到不同核心,任务之间相互隔离,哪怕一个Agent任务因为等待外部API而挂起,也不会阻塞其他任务。

成本方面,单颗GPU的价格是主流CPU服务器的几倍,4096节点的CPU集群在性价比上吊打同等采购预算下能买到的GPU集群。而且CPU节点作为通用算力,白天跑Agent,晚上还能部分复用做数据处理、批量任务,资源利用率更高。

2. 4096节点“超级计算机”的整体架构规划

2.1 节点规格选型和容量粗算

先明确一个概念:这里的“超级计算机”不是天河那种,而是指一个由大量通用计算节点汇聚成的分布式算力池,规模到了4096节点,调度和运维复杂度跟超算已经属于一个层级。

我们最终采用鲲鹏920双路服务器作为计算节点,节点规格如下:

组件配置
CPU2 x 鲲鹏920(单颗64核心)
内存512GB DDR4,32条16GB
系统盘2 x 480GB SATA SSD RAID1
数据盘4 x 3.84TB NVMe SSD
网卡2 x 25GE,支持RoCE
操作系统openEuler 22.03 LTS
容器运行时Docker + containerd

单节点大概128逻辑核。我们在实际压测中,单节点稳定跑一个13B量化模型的Agent推理,吞吐在20-30个并发任务每秒左右,具体数值随上下文长度波动。按4096个节点算,理论并发吞吐峰值能到8万到12万QPS,扣掉调度、网络、存储的损耗,实际可用吞吐在5万到7万QPS之间。

这个量级对绝大多数Agent业务完全够用。设计容量时,我们故意留了冗余:日常生产负载控制在峰值的40%以下,保证突发流量进来时不会把CPU打到100%,留出故障转移的缓冲。

2.2 网络与存储:别让4096节点卡在I/O上

4096个节点最怕的不是CPU不够,而是网络和存储拖后腿。Agent任务之间有频繁的上下文同步、消息分发和记忆检索,如果节点间通信出现拥塞,整个集群的吞吐会被拉低一大截。

网络方案采用leaf-spine两层架构。每个机柜里的40台计算节点接入两台25G leaf交换机,互为冗余;leaf交换机上行通过100G接口接到spine交换机,形成无阻塞网络。节点之间的Agent任务调度消息、心跳、日志,全部走这个平面。RoCE(RDMA over Converged Ethernet)用在存储和Redis访问场景,能显著降低网络延迟。

存储这块没有让每个节点单独存状态,而是采用分布式存储池。Agent的会话状态、记忆快照、模型权重文件都放在集中存储里,计算节点全部无状态化。这样做的好处是,任何一个节点宕机,其上的Agent任务可以被调度器马上迁移到其他节点,不需要搬数据。代价是网络带宽消耗增加,所以我们给存储平面单独拨了100G链路,和业务网络物理隔离。

2.3 控制面与计算面分离的部署拓扑

4096个节点不能全混在一起跑业务,必须区分控制面和计算面。控制面承担集群调度、Agent编排、服务注册发现和监控告警,计算面只跑Agent实例。

控制面我们部署在单独的100个节点上,用Kubernetes管理。API Server、调度器、控制器管理器都是高可用部署,至少保证3副本。之所以单独分出来,是为了防止大规模的Agent业务波动打爆控制面的CPU,出现“忙到连故障自愈都做不了”的情况。

计算面分成若干资源池,每个资源池对应一类Agent业务。比如在线客服Agent池、代码生成Agent池、内部数据分析Agent池。每个池用Kubernetes的Namespace和ResourceQuota隔离,互不干扰。任务分发不直接走Kubernetes API,而是通过消息队列做异步解耦,Kubernetes只负责容器的生命周期管理,任务队列的消费逻辑由Agent worker自己处理。

3. Agent平台在鲲鹏集群上的落地实现

3.1 Agent运行时引擎怎么设计

Agent要跑得稳,先要有一个好的运行时引擎。我们没有直接用开源框架一把梭,而是基于LangGraph的总体思路,自研了一套轻量级Agent编排引擎,核心由三块构成。

第一块是任务状态机。每个Agent请求进来,都会在编排引擎里创建一个状态对象,记录当前走到了哪个阶段、正在等待哪个工具返回、上下文已经拼了多少个token。状态对象不放在内存进程里,而是放进Redis,带TTL过期,保证节点重启后状态不丢。

第二块是工具注册中心。所有工具(包括内部服务、数据库查询、文件系统操作、第三方API)都通过统一的gRPC接口注册进来。引擎收到Agent决策结果后,把“需要调用哪个工具”变成一次标准的RPC请求,不关心工具具体实现。

第三块是执行流水线。每个Agent任务拆成多个stage:接收意图、组装上下文、模型推理、工具选择、工具执行、结果合并、生成回复。每个stage可以在不同的CPU核上并行处理,通过消息队列串联。这样做的好处是:即使某一步因为外部API慢而阻塞,后面的任务也不会跟着排队。

3.2 CPU智能核心调度与亲和性优化

集群层面有Kubernetes调度,节点层面怎么把CPU核心用好,才是真本事。这里我重点讲NUMA亲和性。

鲲鹏服务器是多NUMA节点的结构,每个CPU对应一块本地内存。Agent worker如果被调度到CPU0,但内存却分配到CPU1那边,访问延迟会高出不少。我们使用numactl把Agent worker进程和它的内存绑定到同一个NUMA节点:

numactl --cpunodebind=0 --membind=0 ./agent_worker --config=worker_4201.yaml

每个节点开多组进程,每组绑定一个NUMA节点,进程内部再开线程池处理不同的Agent任务。线程数严格按照物理核数设置,不是无脑多开。我在压测中发现,线程数超过物理核数两倍后,上下文切换成本大幅上升,吞吐反而下降。

Kubernetes层面也在做核心调度。容器配置里明确写CPU资源上限,并且开启static CPU管理策略,让容器可以拿到独占的核心:

resources: limits: cpu: "8" memory: 32Gi

结合Kubernetes的TopologyManager,我们可以保证多容器在节点上分布时,尽量让同类Agent容器落在同一个NUMA域内,减少跨片访问。

3.3 高并发链路:从接入到执行的分级缓冲

“AI Agent怎么扛并发”这个问题,我们给出的答案是四个字:分级缓冲。

入口网关先做第一层控制。网关使用令牌桶限流,每秒允许的请求数按资源池配额计算,超出的请求直接返回429,而不是塞进后续链路。限流参数不是固定的,我们根据实时CPU使用率动态调整,节点CPU超过85%时,自动调低令牌桶速率。

第二层是消息队列。限流通过后的请求进入Kafka主题,每个资源池一个独立主题。Kafka在这里的作用不是单纯堆积消息,而是削峰填谷。业务高峰期的请求先堆在队列里,计算节点按自己的处理能力从队列拉取,不会一下子把每个节点的CPU打满。

第三层是Worker调度。Worker进程消费队列消息时,先做任务级心跳登记,如果任务执行超过预设时间(比如120秒)没有更新心跳,调度器会重新入队并迁移到另一空闲节点执行。这套机制保证了单点故障不会造成任务永久卡死。

3.4 模型推理在CPU上的性能优化

Agent调用的模型不能直接拿原始FP16权重跑,CPU扛不住,也没有必要。我们把权重全部做了INT8量化,部分小模型做了INT4量化。量化后的13B模型参数占用内存约7-8GB,单节点512GB内存可以同时装载几十个模型副本,并且通过共享内存映射,多个Worker访问同一份模型文件,不会重复加载。

推理优化主要做了三件事。第一,算子融合,把Attention层的多个算子合并成一个内核函数,减少数据搬移。第二,KV Cache复用,同会话的连续推理不需要重新计算历史token的KV状态。第三,即时编译(JIT),对一些固定形状的输入,生成优化后的机器码。

实测下来,13B量化模型单次推理延迟在100-200毫秒,对于Agent场景可以接受。如果遇到更复杂的推理请求,我们会把它动态路由到预留的小规模GPU池做混合推理,但大部分日常请求都留在CPU上。这个混合调度的策略,让我们的GPU资源开销降到原来的30%。

4. 性能调优与踩坑实录

4.1 Agent框架本身的CPU开销比模型还大

第一个让我意外的发现是,Agent框架逻辑消耗的CPU往往超过模型推理。尤其在高并发下,Python实现的JSON序列化、工具参数校验、状态存储读写成了一片热点。

我们做了三处优化。一是把Agent决策链路上的高频函数从Python改为Rust编写,通过PyO3做成扩展模块,比如工具调用的参数组装和解析。二是把上下文拼装改成零拷贝方式,减少字符串重复拼接。三是避免在单线程内做同步IO,所有Redis读写都走异步客户端,防止因等待IO而浪费CPU核心。

改完之后,每个Agent请求的平均纯CPU消耗下降了一半。所以别一上来就盯着模型推理优化,先看看你框架代码里有没有重复创建对象、有没有BERT级别的低效Python调用,CPU的浪费往往藏在这些地方。

4.2 内存带宽和NUMA才是真瓶颈

节点并发加大后,最先报警的不是CPU使用率,而是内存带宽。鲲鹏平台的CPU核数高,理论上算力不弱,但Agent Worker要频繁读写上下文、模型权重、Redis缓存,任何一个进程大量跨NUMA访问,都会抢占内存控制器带宽。

排查时用perf stat查看内存带宽和cache miss指标,发现某些节点的L3缓存命中率不足80%,大量请求落到DDR内存上,导致个别核心的指令延迟飙升。

解决办法是把模型权重和Agent上下文数据按NUMA节点分区。比如节点上有两个NUMA域,就把模型切分成两份,分别加载到各自域的内存里,本域的Worker只访问本域的模型副本。同时用cgroup隔离内存带宽,限制高吞吐业务池不要跑到其他NUMA域去抢资源。

4.3 几个印象深刻的故障排查

4096节点的规模下,什么奇怪问题都可能遇到。整理两个印象最深的案例分享。

第一个是二进制指令集不兼容。当时一个Agent服务从x86迁移到鲲鹏,编译时用了流水线优化选项,结果在部分节点上启动直接报“cpu does not support”相关的非法指令错误。原因是集群里存在不同步进的鲲鹏芯片,老步进芯片不支持新指令集。这提醒我们交叉编译时必须指定通用的CPU架构基线,不能为单台机器的微架构做特殊优化后再全量分发。

第二个是高优先级任务抢占导致CPU steal飙升。我们混合部署了在线Agent和离线批量任务,离线任务虽然配了较低的Kubernetes请求值,但偶尔还是会抢占CPU资源,造成在线Agent请求P99延迟从200毫秒飙到1秒。后面直接给在线Agent池挪到独享节点,并给离线任务加了严格的CPU限流,问题才算根治。

4.4 Agent安全边界怎么守

Agent要执行工具,安全边界就变得尤其关键。我们所有工具调用都走白名单机制,Agent只能调用注册过且经过审核的API,不能直接拼接Shell命令访问容器内部文件系统。

每个Agent Worker容器使用独立的Linux命名空间和只读根文件系统,对外网络访问通过代理网关统一管控,内部服务之间使用服务网格做双向TLS认证。对于外部传入的会话内容,我们做了提示注入检测,一旦发现内容里夹带类似“忽略之前指令”的恶意请求,直接识别并阻断该轮Agent决策。

安全这层不能省,尤其是4096节点的大集群,一旦一个Agent实例失陷,横向移动起来破坏力是巨大的。宁可多花点性能开销做隔离,也不要冒险图省事。

5. 常见问题速查与经验沉淀

5.1 问题排查速查表

现象可能原因处理方式
Agent任务执行超时但无日志Worker阻塞在外部API调用检查连接池大小,为工具调用单独配置超时熔断
节点CPU use不高但吞吐上不去内存带宽或NUMA访问瓶颈用numactl做绑定,按NUMA域拆分模型和状态数据
部分节点启动任务即崩溃指令集不兼容,二进制编译优化过度统一编译基线,改成兼容级别指令集后重新发布
在线业务P99延迟忽高忽低离线任务抢占CPU资源在线任务和离线任务分池部署,加上严格的CPU限流
Redis访问延迟高跨网络访问存储平面造成拥塞开启RoCE,业务流量和存储流量走独立网络平面

5.2 我的几点实操心得

4096节点集群从规划到上线,我最大的感触是:规模上去以后,稳定的关键不是某个组件多先进,而是每个环节都预留了退路。

比如所有Agent Worker都是无状态的,状态放Redis;所有任务都走消息队列,不直接绑在某个节点上;所有容器都是快速启停的,节点坏了就换一台。这些听起来很基础,但真正4096个节点同时运行时,每一项都能救命。

另一点是关于CPU战略的选择。GPU很宝贵,也确实强,但Agent的很多并发负载用CPU来完成更经济。我们目前GPU池只保留给大模型分析和复杂推理,CPU集群承载90%以上的Agent任务。这不是倒退,而是让合适的算力去做合适的事。

5.3 下一步还能这么玩

这套集群目前在稳定运行,但我的规划并没有停。下一步想做两件事:一是把调度器升级成支持异构混部,让CPU节点、GPU节点、NPU节点在同一个资源池里按任务类型动态分配;二是把Agent状态存储从Redis改成更高吞吐的云原生数据库,进一步降低状态读写对CPU的消耗。

如果你也在思考自己的Agent业务到底该用什么算力底座,建议先做一个详细的负载画像,把模型推理、工具调用、状态读写三类耗时拆开统计,再决定要不要押注CPU路线。至少在我们这里,4096节点鲲鹏集群用实际吞吐证明了一件事:Agent的下一轮竞争,CPU不但不会缺席,还会重新占据C位。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询