# ⚡ LLM 速度测试台 大模型推理性能基准测试工具,用于测量不同上下文长度下的 **预填充速度(prefill)**、**首字延迟(TTFT)** 与 **解码吞吐(decode)**,并以网页 + Excel 形式输出结果。 - **访问地址:** `http://:16097/` - **技术栈:** Python 3 + Flask + SQLite(纯 REST,无额外依赖) - **版本:** v2.3.0 --- ## 功能特性 ### 🔌 大模型接口配置 - 支持 **OpenAI 兼容**(OpenAI / DeepSeek / 火山方舟 / 任意兼容网关)、**Anthropic(Claude)**、**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** - **文件下载 Excel(xlsx)**:历史记录「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://: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/` | 单个配置 / 更新(局部)/ 删除 | | POST | `/api/configs/test` | 测试连接 | | GET/POST | `/api/tests?limit=n` | 测试历史 / 启动测试(异步) | | GET | `/api/tests/` | 测试详情(含 runs / logs / summary / 按长度分组) | | GET | `/api/tests//logs?after=` | 增量日志(前端轮询用) | | POST | `/api/tests//cancel` | 停止测试 | | DELETE | `/api/tests/` | 删除测试 | | GET | `/api/tests//export.xlsx` | 导出 Excel 报告(汇总/采样明细/日志三 Sheet) | | GET | `/api/tests//export.json` | 导出完整测试 JSON | | GET | `/api/tests//chart` | 用 data-chart-tool 生成折线图 PNG(预填充左轴虚线 / 解码右轴实线,X=上下文长度) | | GET | `/api/tests//chart-data` | 画图数据(CSV + 图表请求配置,供一键复制) | | GET | `/api/tests//concurrency-chart` | 并发对比折线图 PNG(X=并发数,预填充左轴虚线 / 解码右轴实线) | | GET | `/api/tests//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可自定义并发档,整批吞吐聚合+按并发分组)+ 多测试结果对比(历史勾选→对比表/柱状图/并发折线图))