Skip to content

Repository files navigation

高性能计算与分析型智能体

Python SQLite LLM offline checks pytest HPC

轻量的 Agent-style 性能分析系统:把真实 ARCHER2 上的 PETSc benchmark 数据导入 SQLite,用一组确定性分析工具 + 中文规则路由做可评测的 baseline,再接入 LLM function calling,与规则基线做可量化的对比。

HPC CSV
-> SQLite benchmark memory
-> analysis tools (best_config / metrics / compare_modes / scaling_report)
-> router: Chinese rule-based baseline (CLI default) + LLM function calling (P2, eval-scored)
-> Markdown report / structured trace / HTTP API / lexical retrieval (P3)
30 问中文评测集 规则 router 83.3% vs LLM router 100% —— 同一评测集、同一打分 harness
system prompt 消融 同一模型去掉 system prompt:100% → 63.3%
测试 229 passed,全程离线,不需要 API key(LLM 部分走 FakeLLM 注入)——CI 每次 push 在无 key 环境下重跑

快速开始

python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
python -m pytest                      # 229 passed

以下输出为真实终端输出:

python -m hpc_agent import-csv examples/sample.csv
# Imported 36 rows into data/benchmarks.sqlite

python -m hpc_agent ask "100万规模下最快配置是什么?"
# unknowns=1000000 的最快配置:ranks=128, threads=1, total_cores=128,耗时 3.866 秒(迭代 10000 次)。

python -m hpc_agent ask "对比一下100万规模下mpi和hybrid模式"
# unknowns=1000000 的模式对比:mpi_like 最快 ranks=128, threads=1,耗时 3.866 秒;
# hybrid_like 最快 ranks=64, threads=2,耗时 4.369 秒。mpi_like 更快,hybrid_like 的耗时是它的 1.13 倍。

python -m hpc_agent report --unknowns 1000000 --output reports/scaling_1000000.md
# Wrote report to reports/scaling_1000000.md

python -m hpc_agent ask "100万规模下最快配置是什么?" --trace trace.jsonl
# 同样的答案,另外把 5 条事件写进 trace.jsonl:
# ask_start -> route_result -> tool_call -> tool_result -> answer(同一 trace_id)

生成的报告见 reports/scaling_1000000.md

同一套能力也可以走 HTTP(P3):

uvicorn hpc_agent.api:app --port 8000
curl -s -X POST localhost:8000/ask -H 'Content-Type: application/json' \
     -d '{"question": "100万规模下最快配置是什么?"}'
# {
#   "answer": "unknowns=1000000 的最快配置:ranks=128, threads=1, total_cores=128,耗时 3.866 秒(迭代 10000 次)。",
#   "trace_id": "e15242fe277d4ec7b593fba0a0e3982c",
#   "events": null
# }

"trace": true 会把同一条 trace 的 5 个事件放进 events 字段返回(服务端不落盘);交互式文档在 http://localhost:8000/docs

--rag <目录> 会先对该目录下的 .md 笔记做检索,命中的片段作为额外上下文交给 LLM(下面的检索本身完全离线,不需要 key):

python -c "
from hpc_agent.rag import load_notes, retrieve
chunks = load_notes('examples/notes')
for c, s in retrieve('hybrid 模式为什么比纯 MPI 慢', chunks):
    print(f'{s:5.2f}  {c.source}  {c.text.splitlines()[0][:40]}')
"
# 12.02  hybrid-vs-pure-mpi.md  # 混合模式为什么常常跑不过纯 MPI
#  3.51  hybrid-vs-pure-mpi.md  第三类是线程绑定。没有正确设置绑定策略时,线程可能被调度到跨 socket 的核
#  2.81  hybrid-vs-pure-mpi.md  第二类是内存局部性。纯 MPI 每个进程有独立的地址空间,数据天然按进程切分;混
python -m hpc_agent ask "hybrid 模式为什么会变慢" --router llm --rag examples/notes

问"量子计算"这类语料里没有的话题,检索返回空列表、不注入任何上下文——没找到就是没找到

这一项只声称做了什么,不声称它提升了准确率。 现有 30 问评测的期望值是 tool call(intent + unknowns),而检索片段影响的是解释性内容,两者不在同一个评价维度上;要证明 RAG 有用,需要另建一套针对解释质量的评测,目前没有。

P1 只依赖标准库 + pytest;P2 引入 openai SDK(兼容各 OpenAI-compatible 服务商)。API key 走环境变量、永不入库pytest 全程不需要 key,只有评测脚本的 --router llm 会调用真实 API。

文档导航

你想知道 看这里
项目到哪一步、怎么配环境、怎么复现 demo 本文件
做什么、边界在哪、完成标准是什么 SPEC.md
代码的流转路径、修改某个文件的波及范围、某个函数的作用 WORKFLOW.md
两个 router 的逐题错因、消融实验、结论与局限 evals/eval_report_p2.md

功能特性

能力 说明 设计要点
CSV 导入 import-csv 把 benchmark 运行记录导入 SQLite,带 schema 与三个索引 malformed 行显式报错,不静默跳过
分析工具 best_config(某规模最快配置)、compare_modes(MPI 式 vs hybrid 式,含 time ratio) 纯函数,返回带 found 标志的 dict;查无数据时显式失败,不做推测
扩展性指标 speedup / parallel_efficiency / scaling_summary,以单核为 baseline 缺少单核 baseline 时整体放弃,不以近似值替代
中文规则路由 ask 接受中文问题:关键词分类 + 规模解析("100万"/"一百万" → 1000000) 确定性、离线、零成本;128核 这类核数不会被误读成规模
LLM function calling llm_route 走任意 OpenAI-compatible API 做工具选择 输出与规则 router 完全同形状 {"intent", "unknowns"}——这是两者能共用一套评测和一个 --router 开关的前提
防御式解析 模型不调工具 / 幻觉工具名 / 坏 JSON 参数 一律收敛到显式 unknown,不伪装成路由决策
评测 harness evals/questions.jsonl 30 问 5 类题型(正常/追问/拒答/数字陷阱/对抗题) 期望值是 tool call(intent + unknowns)而非答案文本;两者均正确才计为正确
Markdown 报告 report 生成单一规模的扩展性报告(最快配置/扩展性表/模式对比/规则化解读) 字节级确定——同一数据库逐字节一致,git diff 只反映真实变化
HTTP 接口 uvicorn hpc_agent.api:app 暴露 POST /ask,请求体 question / router / trace/docs 自动生成交互式文档 只做协议转换,业务逻辑零重复;校验写进类型(非法 router → 422);缺 key 映射为 503(服务端未就绪)而非 500
结构化 tracing ask --trace t.jsonl 产出可回放的 JSON-lines 事件流,同一 trace_id 贯穿 脱敏收在单一收口点:绝对路径降级为文件名、疑似密钥字段一律 [redacted],由扫描测试强制保证
词法检索(最小 RAG) ask --rag <目录> 对本地 .md 笔记做 IDF 加权词重叠检索,命中的片段作为独立一条 system message 进入 LLM 上下文 刻意不用向量检索:零新依赖、离线、可逐条解释命中理由(能指着 idf 分数说话)。检索不到就返回空、不注入,不退而求其次给"最像的一条"。不传 --rag 时 messages 与评测时逐字节相同,由测试锁死

代码链路

hpc_agent/
├── db.py         # 连接、schema、底层查询(全项目唯一数据出入口)
├── importer.py   # CSV -> SQLite
├── metrics.py    # speedup / parallel efficiency / scaling_summary
├── tools.py      # best_config / compare_modes
├── router.py     # 中文规则路由 + ask 编排 + router 选择
├── llm_schema.py # function calling 的 tool schemas + tool call -> intent 映射
├── llm_router.py # LLM router:调 API、防御式解析,输出与规则 router 同形状
├── llm_config.py # 环境变量配置(OPENAI_API_KEY / BASE_URL / MODEL)
├── tracing.py    # trace id + JSONL 事件流 + 脱敏(横切,不依赖任何业务模块)
├── rag.py        # 本地笔记的词法检索(IDF 加权词重叠,纯标准库,无向量库)
├── report.py     # Markdown 扩展性报告(组合上述工具)
├── cli.py        # import-csv / ask / report 子命令
└── api.py        # FastAPI 薄封装:POST /ask(与 cli.py 平级,互不依赖)
tests/            # pytest 验收测试(工具合同 + 端到端,LLM 部分走 FakeLLM 离线)
evals/            # 30 问中文评测集 + 打分 harness + 评测报告与逐题结果
examples/         # 脱敏 CSV fixture 与检索用的 HPC 笔记语料
reports/          # 生成的 Markdown 报告

依赖只向下,无循环。虚线是懒加载——跑规则 router 时 llm_router.py 根本不会被导入,openai SDK 也不会,这是 pytest 无 key 全绿的根因。

graph TD
    CLI["cli.py 进程边界"] --> ROUTER["router.py 规则路由 + ask 编排"]
    API["api.py HTTP 边界"] --> ROUTER
    API --> TR
    CLI --> REP["report.py"]
    CLI --> IMP["importer.py"]
    CLI --> TR["tracing.py 横切"]
    CLI --> RAG["rag.py 词法检索"]
    ROUTER --> TOOLS["tools.py 确定性工具"]
    ROUTER --> TR
    ROUTER -.懒加载.-> LLMR["llm_router.py"]
    REP --> TOOLS
    REP --> MET["metrics.py"]
    LLMR --> LS["llm_schema.py"]
    LLMR --> LC["llm_config.py"]
    TOOLS --> DB["db.py 唯一数据出入口"]
    MET --> DB
    IMP --> DB
Loading

一次提问的主线:cli.py 解析参数并建 Tracer → router.ask() 埋点、select_router() 返回一个 callable(规则 router 是 route 本身,LLM router 是绑好 client 的闭包)→ 两者输出同形状的 {"intent", "unknowns"} → 经 traced() 包装调用 tools.py → 回到 ask() 渲染中文。换 router 只改路由决策,不改答案格式,这是回归测试锁死的。

完整时序图、每个文件的上下游与改动影响面、全部公开函数的一行速查,见 WORKFLOW.md

评测(P2):规则 router vs LLM router

同一份 30 问评测集、同一个打分 harness,对两种 router 各出一个准确率:

Router 准确率 说明
规则 router 83.3% (25/30) 离线、零成本、确定性;丢分集中在对抗题(别名、歧义句、中文复合数词)
LLM router(含 system prompt) 100% (30/30) qwen3.7-plus · temperature 0 · 2026-07-23 · 单次运行

评测集故意包含规则 router 已知会错的题rule_wrong 类),用来量化 LLM 的增量价值;错题逐条归因、system prompt 消融(63.3% → 100%)和结论见评测报告,逐题结果在 evals/results/

python -m evals.run_eval --router rule    # 离线,无需 key
export OPENAI_API_KEY=...                 # 任意 OpenAI-compatible 服务商;见 hpc_agent/llm_config.py
python -m evals.run_eval --router llm     # 真实 API,会产生费用

如何解读:规则 router 的结果字节级可复现;LLM 的结果是带元数据(model / date / temperature)的测量记录,temperature=0 也不保证逐次一致——"可评测"承诺的是打分流程可重跑,而非每个分数可复现。样本量 30、单模型、单次运行,是这组数字的已知局限。

Roadmap

阶段 内容 状态
P1 核心分析工具 + 中文规则 router + CLI ask / report + 评测集种子 已完成
P2 LLM function calling(OpenAI-compatible API)+ 30 问评测集,与规则 baseline 对比准确率 已完成
P3 FastAPI 薄封装 + 最小 RAG + TraceID 结构化日志 已完成(三项均已落地)
P4 完整 demo(GIF、示例报告)与文档打磨 未开始

后续方向(不在当前范围):Redis 缓存、Docker、MCP;以及复用本项目 benchmarking 方法论的 LLM 推理 benchmark(llama.cpp / vLLM)。约束与完成标准详见 SPEC.md

运行环境与数据来源

ARCHER2 是什么

ARCHER2 是英国国家超算服务,部署于爱丁堡大学 EPCC,HPE Cray EX 架构,每个计算节点 128 核(双路 AMD EPYC 7742)。它是作者课业中使用的计算环境——本项目的数据来自在其上运行 PETSc 求解器 scaling 实验的真实导出,不是构造的样例。

读这个仓库不需要了解 ARCHER2,也不需要任何超算访问权限。 数据一旦落成 CSV 并导入 SQLite,本项目的全部功能(分析工具、路由、报告、评测)都在本地离线运行。ARCHER2 只解释这些数字从哪来,不构成运行门槛。

几个会反复出现的术语:

术语 含义
unknowns 问题规模,即待求解方程组的未知数个数(本项目中 = 网格 m × n
ranks / threads MPI 进程数 / 每进程线程数;total_cores = ranks × threads
mpi_like / hybrid_like threads == 1 / threads > 1 推断的保守标签,只描述进程与线程的配比形态,不能证明运行时真的启用了 OpenMP
speedup / efficiency 相对单核 baseline 的加速比与并行效率

数据

数据来自 ARCHER2 上 PETSc scaling_grid 基准的真实运行导出(覆盖 5 个 2D 问题规模,1000000 ~ 40960000 unknowns)。完整数据集不入库;仓库内提供脱敏 fixture examples/sample.csv:单节点、1000000 unknowns(1000 × 1000)、total_cores 从 1 到 128 的 36 条运行记录。所有公开样例和报告均已去除集群绝对路径。

测试策略

python -m pytest                            # 全量
python -m pytest tests/test_router.py -x    # 单文件快速反馈

测试即验收合同:工具层用精确断言钉结构(dict 逐键比对),渲染层用要素断言留文案自由度。LLM 相关单元测试全部通过注入 FakeLLM 客户端离线运行——pytest 在无网络、无 key 的环境下也全绿。

About

Agent-style performance analysis on real PETSc/ARCHER2 benchmark data: SQLite benchmark memory + deterministic tools, with a rule-based router and an LLM function-calling router scored on the same 30-question eval set.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages