Agentic AI负载下CPU性能评估方法解析

针对Agentic AI负载,内部测试评估CPU性能。聚焦代理循环端到端表现及多会话扩展性,分析芯片吞吐量。现有方案虽具局限,但旨在为硬件决策提供数据支持,而非取代本地AI评估体系。

过去六个月,代理式人工智能(Agentic AI)在 CPU 性能评估领域引发了广泛关注。针对这一新兴负载,我们开展了一系列内部测试,旨在对存在争议的代理循环进行端到端评估。

并发会话下的CPU吞吐量瓶颈

本文详细阐述了测试方法、原型设计及核心架构,并分享了在构建基准过程中发现的技术细节。尽管测试原型已初步成型,但鉴于该计算领域的快速演进特性,现有方案仍存在局限性。目前的测试重点在于观察代理性能随会话数量增加时的扩展情况,以及各芯片在维持交互的同时所能提供的理想吞吐量。

文末将讨论当前方法的不足之处,以及针对多轮代理流等问题的改进思路。需强调的是,这些测试并非取代现有的本地 AI 评估体系,而是随着硬件特征的明确,为后续决策提供更充分的数据支持。

定义代理 AI 循环

“人工智能代理人”常被通俗地描述为具备法律学位的微型工人,但在性能比较中,我们需要更精确的技术定义。

代理 AI 的核心包含两个部分:函数与工具。通过 LangGraph 等流行框架,LLM 可以访问各类工具,如读写文件、查询数据库或执行代码测试。以下是一个 Python 中的基本示例:

@tool    def run_command(command: str) -> str:        """Run a build or test command in the repository root. Allowed: make [targets], python -m pytest [args]."""        return traced("run_command", {"command": command}, lambda: ws.run_command(command))

上述代码展示了如何在 LangGraph 中定义一个供 LLM 调用的工具。通过 @tool 装饰器,普通 Python 函数被转化为 LLM 可识别的工具接口。-> str 表明参数和返回值均为字符串类型。LLM 读取三重引号内的描述,从而了解如何使用 make 或 pytest 运行命令。在此例中,函数被包裹在一个匿名 lambda 中,并传递给跟踪函数,其目的是展示工具调用的结构。

除了执行命令,编码代理还可利用文件读写、编辑及正则表达式搜索等功能。代理 AI 之所以被称为“循环”,是因为任务通常涉及多次调用同一工具或不同工具。例如,在处理 Python 项目调试任务时,LLM 可能先调用“列出文件”工具评估脚本,接着使用“阅读文件”或“搜索代码”定位故障点。若问题未解决,它将重复这些步骤。这种提示-评估-调用工具-获取信息-重新评估的过程,构成了代理循环。

从并发视角切入

在执行任务列表时,大部分会话时间消耗在 GPU 上,单个代理按顺序执行。(图片来源:Tom's Hardware)

理解基准测试的设计逻辑至关重要。我们在 Nvidia DGX Spark (GB10) 平台上开发测试,该设备配备 128GB 统一内存、Blackwell GPU 以及相对较弱的 Arm Grace CPU。上图展示了 GB10 运行 gemma4-26b-a4b 模型处理代理循环的时间分布。只要能够调用工具,即可使用不同模型重新记录测试数据。

关键在于时间占比而非具体工作内容。每个结果代表代理对模型执行的顺序任务列表,绝大部分时间花在 GPU 推理上。即使是计算密集型的 CPU 任务(如编码代理),仅占计算时间的一小部分。在拥有强大 GPU 且运行足够大模型的情况下,运行单个或少数几个代理对 CPU 而言并非瓶颈。

即使单个查询也会触发多次工具调用,形成代理调用工具、传递响应、再次调用工具的循环。(图片来源:Tom's Hardware)

虽然 CPU 在窗口期内执行的任务种类繁多,但其发生速度极快。

工具调用模式因任务而异。(图片来源:Tom's Hardware)

此外,任务间隔并不均匀。根据代理调用工具的需求,工作负载形状差异巨大。例如,负责扫描和提取 PDF 信息的文件代理,其大部分时间花费在任务初期,随后几乎完全依赖 GPU 推理。

显然,更强的 GPU 能加速推理步骤,但在单个代理循环中,CPU 与 GPU 之间存在严重的不平衡,常见工具往往成为瓶颈。然而,现实场景中多个会话可能在同一系统的沙箱环境中并行运行,资源争夺成为实际问题。

为避免设计造成严重失衡的测试平台,我们引入了并发性概念。通过同时运行各自进程中的任务列表来扫描芯片性能。这涵盖了工具调用、代码执行、编译、网页浏览等多种任务的小幅差异。

基准指标的工作原理

基准测试的整体设计简洁明了:使用 LangGraph 构建的自定义代理执行包含 30 个任务的列表,顺序调用运行 gemma4-26b-a4b 模型的 llama.cpp 服务器。所有代理行为均通过代理服务器进行跟踪。

在实时录制阶段,代理与代理服务器通信,后者将请求转发至 llama.cpp 服务器。同时,代理服务器将每个 LLM 请求及其响应写入主 JSON 文件。工具调用绕过服务器链,单独记录到各自的 JSON 文件中。最后,为每个任务生成正确响应,进行哈希处理并存储。

(图片来源:Tom's Hardware)

全面记录使得我们可以从方程中移除现场模型。代理不再与活体 LLM 交互,而是与回放捕获轨迹的代理服务器运行。虽然请求和工具调用看似实时发生,但响应源自预先录制的轨迹。

从代理请求开始,系统通过会话标签和哈希匹配确保准确性。若不匹配,运行停止并标记无效。代理会话调用所需工具,并与录制生成的 JSON 进行比较,返回记录的结果。这一步骤至关重要。

测试将实时工具调用与记录结果对比,始终返回记录结果以防止测试漂移,即使调用本身正确。真正的工具不匹配会被记录,测试继续但标记为无效。

这种设置便于基准的重构与扩展。我们可以用 Python 编写新角色,或扩展至其他框架。未来也可针对不同模型重新录制。只要通过 OpenAI 兼容端点通信,即可混合匹配测试组件。

测试从单个工作进程开始,逐步扩展至 CPU 最大线程数,每级运行三次重复。每个 worker 进程在 30 个任务列表中运行,新进程从列表下一项开始。由于任务耗时不一,这种偏移会造成不平衡的资源竞争。

实际测量内容

核心指标为每秒会话数(Sessions Per Second)。一个会话指从头到尾完成的单一任务。在低并发水平下,完成速率较低,通常低于 1 次/秒,任务呈顺序完成状态。我们关注的是芯片随会话增加时的分离表现,即 CPU 上代理工作的吞吐量。

扫描得出两个头条数据:峰值吞吐量(记录的最高每秒会话数及对应并发水平)和理想吞吐量(最慢 5% 会话耗时不超过基础并发下单个会话耗时 1.5 倍的临界点)。预计随着会话增加,任务时间延长;超过 1.5 倍阈值后,任务长度显著增加,吞吐量可能下降。

需强调,此并发扫描中无 GPU 延迟影响。GPU 已被完全移除,以最大化 CPU 上的并发工作量。然而,GPU 仍扮演重要角色,结果需在现实背景下解读。

随着更多代理在 CPU 上工作,资源争夺加剧,但平衡易变。若 GPU 马力不足,代理可能排队等待,导致处理器算力未被有效利用。我们的测试并非基于理论推导,因为变量过多,难以产生广泛适用的数字。

不过,可利用实时推断扫描评估系统级性能。在实时运行中,返回给代理的响应仍来自录音以保持等级,但请求由 llama.cpp 服务器记录,并在丢弃前生成相同数量的代币。这解释了正常的推断管道,包括预填充、解码、缓存性能及代理排队情况。

这两个数字都很重要:实时扫描是对整个系统本地 AI 的现实观察,而冷重播则测量了 CPU 在理论上访问所有 GPU 计算时的峰值吞吐量。

初始代理角色设定

我们定义了六个智能体角色。“角色”是基于 LangGraph 构建的 Python 脚本,用于定义智能体能力。工具调用是连接 LangGraph 节点的主脚本中定义的 Python 函数。每个角色依据本地文档中的独立任务列表开展工作。例如,研究角色可通过检索包含约 50,000 篇文章的维基百科语料库回答问题。

Persona

副任务描述

Tools

Analyst

计划师,分析师,作家通过使用 SQL 搜索 DuckDB,回答有关虚假零售公司的问题并撰写报告。列出表,描述表,运行 SQL 查询,从查询中创建图表

Coding

编码员,审查员从问题报告中修复四个小项目 (两个 C,两个 Python) 的一个错误。列表文件,阅读文件,代码搜索,文件编辑,命令执行,测试审查
文件吸入器,抽出器,审计器扫描购买订单,发票和其他会计文件,并将发票与购买订单相匹配。列出文档,从 PDF 中提取文本,从 PDF 中提取表格,Tesseract OCR,基本算术
研究工作规划者,研究人员,作家搜索本地英语维基百科库以回答问题。查询库

Support

分类,研究人员,响应者使用知识库来回答虚构公司的支持门票。搜索知识库,阅读文章

Web

规划器,浏览器代理,编辑器

Find products that meet specified criteria in a headless Chromium session.

Open URL, click web element, enter text, select option, go back, read more of page

上述表格概览了每个角色。除编码者外,其余五个角色均遵循“规划阶段-主代理循环-报告生成”的流程。以分析师为例,规划者将问题拆分为两到四个结构化步骤,分析师并行搜索数据库,写作者将发现转化为回复。

编码者角色略有不同。它处理四个项目,尝试修复类似 GitHub issue 报告中的 bug。编码者定位 bug,运行测试确认修复,然后移交给审查步骤。审查步骤在应用修复前进行评估。

当前测试设置针对单轮任务。代理根据任务需要进行多次 LLM 循环并多次调用工具,但旨在解决无先前上下文的单一任务。例如,客服查询可能需要多次检索知识库,但一旦回答完毕进入下一个查询,即视为独立动作,不带前文上下文。

这并不完全代表真实的代理工作流,后者通常是多轮过程。虽然可以脚本化多轮任务,但这会增加偏差风险和崩溃风险。在本地运行时,复杂交互几轮后很容易超出上下文窗口。虽可行,但目前并非优先事项。

下表提供了每个角色的示例任务:

Persona

Example Task

Source of Truth

Analyst

“How do discounts affect gross margin across categories?”

DuckDB warehouse

Coding

Invoice project – Saturday due dates move to Sunday, not Monday

PyTest, make

Documents

Approve correct invoices from purchase orders based on a price from a list of six documents across four scans.

Faux PDF invoices, purchase orders, and goods received notices with errors planted

Research

“What causes earthquakes and how are they measured?”

50,000-article English Wikipedia corpus

Support

“How long a two-factor code stays valid”

Knowledge base for fictional smart home company

Web

Highest-rated 55L backpack and lightest waterproof boots

Local website for an outdoor gear store

其他任务与示例类似。例如,文件角色始终批准正确的发票,但文档组合和错误类型在不同集合间变化。支持角色始终回答支持问题,但侧重点不同,有的排查错误码,有的询问政策,有的需整合知识库多个区域的信息。

当前方法的局限性

尽管试图涵盖广泛的代理工作负载,当前版本测试仍存在局限。最显著的是,测试和录音仅来自两种系统:配备 128GB DDR5-6000 RDIMMs 的 64 核 Threadripper 测试台,以及 DGX Spark。

随着对其他平台的测试深入,可能需要调整测试、重新运行录音或更换模型,这将导致需要重新收集所有结果。这里的“其他平台”不仅指 Intel 系统,还包括 Mac Studio 集群或 GPU 密集型工作站。CPU 负载完全取决于 GPU 性能、模型、量化级别和服务器设置。

另一局限是 API 性能。测试设计允许轻松连接前沿实验室的任何模型 API。虽然模型在云端运行,除非使用全云沙箱,否则工具本身在本地运行。例如,在预算有限的笔记本电脑上使用 AI 辅助开发工作流时,编译、测试和代理代码仍在本地机器上执行。

虽然计划探索弱主机 PC 配合云 API 的混合模型,但在初始开发阶段未深入探讨。API 使用成本高昂,不希望因调试初始测试套件而浪费代币。

最后是沙箱隔离。当前测试通过 Docker 镜像隔离,相比裸机运行引入的开销可忽略不计 (<2%)。未来需进一步探索本地沙箱化的开销影响。

评论 0

0/500

评论需审核后展示,请文明发言

💬
还没有评论,来说两句

相关阅读