1 Commits
3 changed files with 15 additions and 5 deletions
+4 -3
View File
@@ -4,7 +4,7 @@
- **访问地址:** `http://<IP>:16097/`
- **技术栈:** Python 3 + Flask + SQLite(纯 REST,无额外依赖)
- **版本:** v2.5.0
- **版本:** v2.5.1
---
@@ -30,7 +30,8 @@
### 📊 指标与结果
- 实时指标卡:首字延迟、预填充速度、解码速度、上文/输出 tokens、总耗时
- **整体统计(平均/最小/最大)**:详情弹窗与 Excel 汇总展示首字延迟、预填充速度、解码速度、总耗时的平均/最小/最大
- **推理型模型兼容**:支持 Qwen3 / DeepSeek 等思维链模型(`reasoning_content` / `thinking` / `thought`),思维过程计入输出,不会误报“未收到输出”
- **推理型模型兼容**:支持 Qwen3 / DeepSeek 等思维链模型(`reasoning_content` / `reasoning` / `thinking` / `thought`),思维过程计入输出,不会误报“未收到输出”
- **解码速度防荒谬值**:兼容 vLLM/Qwen3.8-27B 用 `reasoning` 字段流式输出思维链(此前未识别导致 output_chars=0、解码时间≈0、解码速度飙到数百万 tok/s,已修复);另防“幻影 token”——usage 报了输出 token 但流里没收到任何文本时(如推理用满 max_tokens 没正文),解码速度标记为不可测(—)而非荒谬数字
- **采样失败不中断**:单次采样失败会记录并继续,不会让整个测试半途终止;全部失败才标记 error
- 实时控制台日志:校准、预热、每次采样明细全程可追溯
- **每次完整测试**支持:
@@ -178,4 +179,4 @@ llm-speed-tester/
## Git
- **仓库:** `hz4th_coder/llm-speed-tester`
- **版本:** v2.5.0(模型实时获取:接口配置区「📋 查看模型」按钮,Base URL+API Key 下实时拉取模型列表(GET /models),搜索/点击填入,仍支持手动输入
- **版本:** v2.5.1(修复解码速度荒谬值:兼容 vLLM `reasoning` 字段思维链 + 幻影token防护(usage 有 token 但流无正文时解码速度置空)
+7 -2
View File
@@ -63,6 +63,10 @@ def _metrics(start, first_token_at, end, prompt_tokens, output_tokens,
total_ms = (end - start) * 1000
prefill = (prompt_tokens / (ttft_ms / 1000)) if prompt_tokens and ttft_ms > 0 else None
decode = (output_tokens / (decode_ms / 1000)) if output_tokens and decode_ms > 0 else None
# 防“幻影 token”:usage 报了输出 token,但整个流没收到任何文本(如推理全用满 max_tokens
# 或提供商只回 usage 不正文),此时解码时间无意义,不报出数百万的荒谬速度
if output_tokens and decode is not None and not output_chars:
decode = None
return {
"prompt_tokens": int(prompt_tokens or 0),
"output_tokens": int(output_tokens or 0),
@@ -132,8 +136,9 @@ def stream_openai(cfg, prompt, gen, log, should_stop=None):
event_count += 1
if obj.get("choices"):
delta = obj["choices"][0].get("delta") or {}
# 兼容推理型模型:Qwen3/DeepSeek 思维链在 reasoning_content
piece = delta.get("content") or delta.get("reasoning_content") or ""
# 兼容推理型模型思维链DeepSeek reasoning_content,部分 vLLM(Qwen3.8-27B-FP8) 用 reasoningAnthropic/Gemini 分别在各自适配器处理
piece = (delta.get("content") or delta.get("reasoning_content")
or delta.get("reasoning") or "")
if piece:
if first_token_at is None:
first_token_at = time.time()
+4
View File
@@ -200,6 +200,10 @@ class TestRunner(threading.Thread):
total_ms = max((batch_end - batch_start) * 1000.0, 0.1)
prefill = (total_prompt / (ttft_ms / 1000.0)) if total_prompt else None
decode = (total_output / (decode_ms / 1000.0)) if total_output else None
# 防“幻影 token”:所有流都没收到任何流式文本但 usage 报了输出 token(如推理用满 max_tokens),
# 整批解码时间无意义,不报数百万的荒谬解码速度
if total_output and decode is not None and not total_ochars:
decode = None
agg = {
"concurrency": concurrency,