Files
hz4th_coder 35ac2a8e40 v2.3.0 多并发测试 + 多测试结果对比
- 并发数配置:默认单流(1),预设2/4并发档,支持丝滑添加任意自定义并发数(≥1),
  多档勾选时同一测试分别跑各并发档并并排对比
- 并发执行:每采样同时发起N个并行流(ThreadPoolExecutor),整批吞吐聚合
  (多流prompt/output之和/批首字/批耗时),并记录每流明细streams;
  并发=1 与旧版单流行为一致;每流独立随机前缀避免共享缓存
- 汇总:新增 by_concurrency(按并发分组,含单流均解码) + by_length_concurrency(长度x并发网格) + concurrency_levels
- 详情页:新增「按并发数汇总」表 + 并发对比折线图(X=并发数,预填充左虚线/解码右实线, /concurrency-chart)
- 多测试对比:历史表格勾选(可全选)多个测试 -> /api/compare 返回对比表+柱状图CSV+并发折线图CSV,
  前端弹窗展示指标对比表 + 柱状图(预填充空心/解码实心) + 解码随并发折线图,画图CSV可复制/PNG可下载
- 通用图表代理 POST /api/chart(转发 data-chart-tool 请求体返回 PNG)
- 历史列表增加「并发」列与勾选列;Excel 导出增加并发数列表/按并发分组/采样并发列
- 文档:README/API.md 同步更新
2026-09-01 19:33:41 +08:00

181 lines
10 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ⚡ LLM 速度测试台
大模型推理性能基准测试工具,用于测量不同上下文长度下的 **预填充速度(prefill**、**首字延迟(TTFT** 与 **解码吞吐(decode**,并以网页 + Excel 形式输出结果。
- **访问地址:** `http://<IP>:16097/`
- **技术栈:** Python 3 + Flask + SQLite(纯 REST,无额外依赖)
- **版本:** v2.3.0
---
## 功能特性
### 🔌 大模型接口配置
- 支持 **OpenAI 兼容**OpenAI / DeepSeek / 火山方舟 / 任意兼容网关)、**AnthropicClaude**、**Google Gemini** 三类提供商
- 配置项:配置名称、Base URL(留空自动使用官方默认)、API Key(可显示/隐藏)、模型名称、温度
- 配置可**保存/加载/删除**,方便多模型对比
### 🚀 速度测试配置
- **测试名称(主题)**:可为每次测试命名,用于标注测试内容/主题,展示在历史列表、详情弹窗与导出报表中
- **多上下文长度测试**:默认为 `512 / 2048 / 4096 / 8192 / 16384 / 32768 / 65536 / 131072` tokens,可通过标签点击启用/禁用,并支持手动添加任意自定义长度(≥16)
- **解码输出长度(max tokens**:默认为 `128`,可手动自定义
- **每个长度×并发采样次数**:默认为 `2`,可手动自定义
- **多并发测试**:默认为**单流**(并发 1);支持预设 **2 / 4** 并发档,并可“丝滑”添加任意自定义并发数(如 8、16、3…,≥1)。勾选多个并发档时,同一测试会分别跑各并发档,**把多个并发下的测试结果放在一起对比**:
- 并发采样时同时发起 N 个并行流,**整批吞吐**(聚合 prompt/output token / 批首字 / 批耗时)作为该采样指标,并记录每流明细
- 汇总按并发数分组 + 长度×并发全网格;详情页「按并发数汇总」表 + **并发对比折线图**(X=并发数,预填充左轴虚线 / 解码右轴实线)直观展示吞吐随并发的变化
- **测试前预热(空转)**:默认开启,先发一次不计速度的空转请求(按并发数预热),避免冷启动/首请求偏慢污染真实采样数据
- **避免缓存**:默认开启,为每次采样追加随机前缀(每个并发流独立前缀),测量真实预填充性能
### 📊 指标与结果
- 实时指标卡:首字延迟、预填充速度、解码速度、上文/输出 tokens、总耗时
- **整体统计(平均/最小/最大)**:详情弹窗与 Excel 汇总展示首字延迟、预填充速度、解码速度、总耗时的平均/最小/最大
- **推理型模型兼容**:支持 Qwen3 / DeepSeek 等思维链模型(`reasoning_content` / `thinking` / `thought`),思维过程计入输出,不会误报“未收到输出”
- **采样失败不中断**:单次采样失败会记录并继续,不会让整个测试半途终止;全部失败才标记 error
- 实时控制台日志:校准、预热、每次采样明细全程可追溯
- **每次完整测试**支持:
- **网页点击查看**:历史记录「查看」按钮弹出详情(整体统计 + 按上下文长度分组 + 每次采样明细 + 完整日志)
- **📈 折线图(data-chart-tool)**:详情弹窗内点击「生成/刷新折线图」,调用 data-chart-tool 的 `/api/chart` 画**双Y轴折线图**——左轴=预填充速度(虚线),右轴=解码速度(实线),X 轴为上下文长度;并提供**画图 CSV 数据一键复制 / 下载 PNG**
- **文件下载 Excelxlsx)**:历史记录「Excel」按钮或详情弹窗「导出 Excel」,包含 汇总 / 采样明细 / 日志 三个 Sheet
- **文件下载 JSON**:详情弹窗「导出 JSON」
- 测试历史留存(含测试名称),可随时刷新、查看、导出、删除
- **⚖️ 多测试结果对比**:测试历史表格勾选多个测试(可全选),点「⚖️ 对比所选」弹出对比面板:
- **指标对比表**:时间 / 名称 / 模型 / 并发档 / 采样 / 首字 / 预填充 / 解码 / 单流均解码 / 输出 / 总耗时 并排展示(点击测试名可跳详情)
- **柱状图**:各测试预填充(空心柱)vs 解码(实心柱)速度对比
- **折线图**:解码速度随并发数的变化(各测试一条线,取共同并发档);画图 CSV 可一键复制、PNG 可下载
### 🔌 开放 API
- 页面所有功能均通过 REST API 提供,前端只是可视化客户端
- **API 文档见 [API.md](API.md)**
---
## 快速开始
### 环境要求
- Python 3.10+(推荐使用 openclaw conda 环境)
- 依赖见 `requirements.txt`
### 安装
```bash
pip install -r requirements.txt
# 或使用 conda 环境
/home/hz1/miniconda3/envs/openclaw/bin/pip install -r requirements.txt
```
### 启动
```bash
./start.sh # 启动(默认端口 16097
./start.sh stop # 停止
./start.sh restart # 重启
```
启动成功后访问 `http://<IP>:16097/`
---
## 使用说明
1. **配置接口**:选择提供商 → 填写配置名称 / Base URL(可留空)/ API Key / 模型名称 → 点「保存」可留存,或直接点「🔍 测试连接」验证连通性
2. **配置测试参数**:勾选要测试的上下文长度(默认 5 档),设置解码输出长度、每个组合采样次数与**并发数**(默认单流,可加 2/4/自定义并发档,多档自动并排对比),按需开关预热/避免缓存
3. **开始测试**:点「▶ 开始测试」,右侧实时展示指标与日志;可随时「■ 停止」
4. **查看与导出**:测试完成后,在「测试历史」中点「查看」看完整详情,点「Excel」或详情内「导出 Excel」下载 xlsx 报告
### 指标含义
| 指标 | 含义 |
|------|------|
| 首字延迟 TTFT (ms) | 从请求发出到收到第一个 token 的时间(含预填充);并发时=整批任一流最早首字 |
| 预填充速度 (tok/s) | prompt tokens / 首字延迟,衡量上文处理吞吐;并发时=多流 prompt 之和 / 批首字,即**整批吞吐** |
| 解码速度 (tok/s) | 输出 tokens / 解码阶段耗时,衡量逐 token 生成吞吐;并发时=多流输出之和 / 批解码耗时(**整批吞吐**) |
| 单流均解码 (tok/s) | 并发整批解码吞吐 ÷ 并发数,衡量单流平均生成速率 |
| 上下文/输出 tokens | 实际发送的提示词 token 数与模型返回的 token 数(并发时为多流之和) |
---
## API
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | `/api/health` | 健康检查 |
| GET/POST | `/api/configs` | 配置列表 / 新增配置 |
| GET/PUT/DELETE | `/api/configs/<id>` | 单个配置 / 更新(局部)/ 删除 |
| POST | `/api/configs/test` | 测试连接 |
| GET/POST | `/api/tests?limit=n` | 测试历史 / 启动测试(异步) |
| GET | `/api/tests/<id>` | 测试详情(含 runs / logs / summary / 按长度分组) |
| GET | `/api/tests/<id>/logs?after=<id>` | 增量日志(前端轮询用) |
| POST | `/api/tests/<id>/cancel` | 停止测试 |
| DELETE | `/api/tests/<id>` | 删除测试 |
| GET | `/api/tests/<id>/export.xlsx` | 导出 Excel 报告(汇总/采样明细/日志三 Sheet) |
| GET | `/api/tests/<id>/export.json` | 导出完整测试 JSON |
| GET | `/api/tests/<id>/chart` | 用 data-chart-tool 生成折线图 PNG(预填充左轴虚线 / 解码右轴实线,X=上下文长度) |
| GET | `/api/tests/<id>/chart-data` | 画图数据(CSV + 图表请求配置,供一键复制) |
| GET | `/api/tests/<id>/concurrency-chart` | 并发对比折线图 PNG(X=并发数,预填充左轴虚线 / 解码右轴实线) |
| GET | `/api/tests/<id>/concurrency-chart-data` | 并发对比画图数据(CSV + 图表请求配置) |
| POST | `/api/chart` | 通用图表代理:转发任意 data-chart-tool 请求体,返回 PNG(多测试对比用) |
| POST | `/api/compare` | 多测试对比:`{ids:[...]}` → 对比表 + 柱状图CSV + 并发折线图CSV |
> 完整字段说明、响应示例与 curl 示例见 **API.md**。
### 启动测试请求示例
```json
POST /api/tests
{
"config": {
"provider": "openai",
"name": "DeepSeek-V4",
"base_url": "https://api.deepseek.com/v1",
"api_key": "sk-xxx",
"model": "deepseek-chat",
"temperature": 0.7
},
"gen": {
"context_lengths": [512, 2048, 4096, 8192, 16384, 32768, 65536, 131072],
"max_tokens": 128,
"samples": 2,
"concurrency_levels": [1, 2, 4],
"warmup": true,
"avoid_cache": true
}
}
```
---
## 项目结构
```
llm-speed-tester/
├── app.py # Flask 主应用(路由 + Excel 导出)
├── config.py # 全局配置(端口/超时/路径)
├── database.py # SQLite 存储(配置/测试/采样/日志)
├── tester.py # 测试执行器(校准 → 预热 → 多长度采样 → 汇总)
├── llm_providers.py # 提供商适配器(OpenAI / Anthropic / Gemini
├── requirements.txt
├── start.sh # 启动/停止脚本
├── static/ # 前端(index.html / js/app.js / css/style.css
├── data/ # SQLite 数据库(llm_speed_tester.db
└── logs/ # 运行日志 + PID
```
### 测试执行流程
1. **校准**:发送一个短探测请求,估算 `token/字符` 比例
2. **逐上下文长度**:对每个选中的长度构造对应 token 量的基准提示词
3. **预热(空转,不计速度)**:每个长度先发一次请求,规避冷启动偏差
4. **采样**:每个长度按采样次数重复请求,记录每次指标
5. **汇总**:按长度分组 + 整体平均,写入测试记录
---
## 常见问题
- **连接测试提示“未收到任何输出内容”**:多为推理型模型(Qwen3/DeepSeek 思维链)或只返回 usage 的网关。已兼容 `reasoning_content` 等思维字段,连接成功即视为通过;若仍出现,请检查 API Key/Base URL/模型名。
- **无 openpyxl**`pip install openpyxl`(已加入 requirements.txt
- **老版本数据库**:程序启动时自动迁移,为 `test_runs` 表补充 `context_length` 列,无需手动处理
- **慢模型/长上文超时**:连接超时 60s、两次数据包间隔 300s(`config.STREAM_READ_TIMEOUT` 可调);推理型模型思考阶段停顿不计超时,超长文(131072)生成慢属正常,请耐心等待
---
## Git
- **仓库:** `hz4th_coder/llm-speed-tester`
- **版本:** v2.3.0(多并发测试(默认单流,预设2/4可自定义并发档,整批吞吐聚合+按并发分组)+ 多测试结果对比(历史勾选→对比表/柱状图/并发折线图))