LLM 速度测试台

大模型推理性能基准测试工具,用于测量不同上下文长度下的 预填充速度(prefill首字延迟(TTFT解码吞吐(decode,并以网页 + Excel 形式输出结果。

  • 访问地址: http://<IP>:16097/
  • 技术栈: Python 3 + Flask + SQLite(纯 REST,无额外依赖)
  • 版本: v2.3.0

功能特性

🔌 大模型接口配置

  • 支持 OpenAI 兼容OpenAI / DeepSeek / 火山方舟 / 任意兼容网关)、AnthropicClaudeGoogle 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

快速开始

环境要求

  • Python 3.10+(推荐使用 openclaw conda 环境)
  • 依赖见 requirements.txt

安装

pip install -r requirements.txt
# 或使用 conda 环境
/home/hz1/miniconda3/envs/openclaw/bin/pip install -r requirements.txt

启动

./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

启动测试请求示例

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/模型名。
  • 无 openpyxlpip 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可自定义并发档,整批吞吐聚合+按并发分组)+ 多测试结果对比(历史勾选→对比表/柱状图/并发折线图))
S
Description
No description provided
Readme
264 KiB
0 Stars 1 Watchers 0 Forks
Languages
Python 50.1%
JavaScript 33.1%
CSS 8.6%
HTML 7.6%
Shell 0.6%