之前在帮一个 AI 应用选型时,最头疼的不是模型能力不够,而是“贵”和“慢”这两个问题一起出现。后来看到一位海外人工智能博士晒出他在双 DGX 平台上的大模型对比测试,结果很有意思:DeepSeek 的 Flash 系列模型在价格上几乎是“屠榜”级表现,把 Gemini 1.5 Flash 和 GLM-4-Plus 都甩开了一截。这篇文章就围绕这次测试,完整拆解从测试环境、评测脚本、部署命令到结果分析和工程避坑的整套流程。
文章会覆盖几个部分:先介绍三款模型的定位和适用场景,再给出测试环境与推理框架选型,然后公布评测指标和完整可复现的压测/部署代码,接着分析价格、吞吐、延迟、生成质量四个维度的对比结果,最后补充常见问题与最佳实践。
适合人群:正在做模型选型的后端开发、算法工程师、AI 应用创业者,以及想在自己机器上本地部署大模型并做性能验证的开发者。读完你可以照着文章搭一套自己的模型评测环境,也能理解为什么“价格/Token”才是大模型选型里最容易被低估的指标。
1. 背景与核心概念
1.1 为什么要做“双 DGX”测试
DGX 是 NVIDIA 的 AI 整机产品线,面向大规模训练和高并发推理场景,卡间高速互联、显存带宽和散热设计都比较成熟。所谓“双 DGX”,指的是把两台 DGX Spark 或其他 DGX 型号组成一个小集群,通过张量并行或流水线并行跑大模型。
这次测试的核心目的不是跑分,而是回答三个业务问题:
- 同样跑一批真实业务 Prompt,三家模型谁的总成本最低?
- 在高并发压力下,谁的吞吐更稳、首字延迟更低?
- 便宜是不是意味着质量差?生成结果能否满足业务要求?
这里的关键观点是:模型评测不能只看单次推理速度,要综合“价格/Token”“吞吐”“首Token时间”“生成质量”四个维度一起看。
1.2 DeepSeek V4 Flash、Gemini 1.5 Flash、GLM-4-Plus 定位对比
先说 Flash 系列。“Flash”在模型命名里通常代表轻量、快速、低成本版本,适合对延迟敏感、调用量大的场景。
- DeepSeek V4 Flash:DeepSeek 系列中的高效版本,重点优化推理成本和响应速度,同时也支持较高的上下文长度。在社区评测中,它的优势主要体现在“低价 + 高吞吐”的组合。
- Gemini 1.5 Flash:Google 面向高频、中等复杂度任务推出的轻量模型,多模态能力比较完整,支持图像、视频、音频输入。中文生态在国内外的可访问性存在差异,调用时需要关注区域支持问题。
- GLM-4-Plus:智谱 AI 面向复杂任务推出的高性能模型,在逻辑推理、指令跟随方面表现稳定,价格定位偏中高端,适合对质量要求更严格的业务场景。
这三款模型并不是直接替代关系,而是“性价比档位”不同。测试的价值,就是帮大家在具体场景里找到最优档位。
1.3 为什么“价格屠榜”值得关注
很多团队选模型只看单次输出质量,却忽略了大模型成本是“按 Token 计费”的。假设一个客服机器人每天处理 100 万次请求,每次请求输入输出共 1000 Token,那么每天就是 10 亿 Token。
如果模型 A 比模型 B 每百万 Token 便宜 5 美元,一天就能省 5000 美元,一年就是 180 万美元。这个时候,“便宜到屠榜”就不再是营销词,而是直接影响项目盈亏的核心指标。
所以,本文会重点展示“价格换算成每百万 Token 成本”的方法,以及如何用脚本批量采集真实计费数据,而不是只看官网标价。
2. 测试环境与推理框架选型
2.1 硬件与系统环境
本次测试案例描述的是基于双 DGX 的评测环境。不同型号的 DGX 配置差异较大,本文以常见的 DGX Spark 为例,以下是基础环境示意:
| 项目 | 配置 |
|---|---|
| 节点数量 | 2 台 DGX Spark |
| GPU | 每台节点板载高性能 GPU(具体以设备为准) |
| 显存 | 每台节点约 128GB 统一内存(以实际型号为准) |
| CPU | 高性能 Arm 架构处理器 |
| 操作系统 | Ubuntu 22.04 LTS 或更新版本 |
| 网络 | 节点间万兆/InfiniBand 互联(推荐) |
| Python | 3.10+ |
| 推理框架 | vLLM / SGLang / TGI 任选 |
需要注意:如果你的测试环境只有一台 GPU 工作站,也可以完成 API 对比测试。双 DGX 主要用于本地部署 200B 级别大模型或测试张量并行扩展性。
2.2 软件栈
本地部署部分用到的主要组件:
- vLLM:高吞吐推理引擎,支持 PagedAttention、Continuous Batching,是性能测试首选。
- OpenAI SDK:DeepSeek 开放了 OpenAI 兼容接口,因此测试脚本可以复用同一套 SDK。
- Harness 工具链:社区常说的“Harness”可以理解为一套评测编排工具,用来串联 Prompt、调用不同模型、采集指标、输出报告。它能避免你在多模型对比时手写大量重复脚本。
Gemini 与 GLM 的接口格式不完全一致,但都可以通过各自的 SDK 或 OpenAI 兼容端点接入。为了统一,本文给出的脚本会抽象出通用请求函数,方便替换模型参数。
2.3 测试工作目录结构
llm-benchmark/ ├── config/ │ ├── models.yaml │ └── prompts.json ├── scripts/ │ ├── run_benchmark.py │ ├── local_deploy.sh │ └── metrics.py ├── results/ │ ├── raw/ │ └── summary/ └── README.md这个结构把“配置”“脚本”“结果”分开,方便多次跑测试后对比历史报告。
3. 评测方法与指标设计
3.1 四类核心指标定义
为了让对比公平,测试指标必须提前定义清楚:
- 成本(Cost per 1M Token):模型处理 100 万 Token(输入 + 输出)所需费用。这是选型的核心指标。
- 吞吐量(Throughput):单位时间内模型能处理的 Token 数,常用 tokens/s 表示。高吞吐意味着同样硬件上能服务更多请求。
- 首 Token 延迟(TTFT,Time To First Token):从发送请求到接收到第一个 Token 的时间,影响用户“转圈等待”的体感。
- 生成质量(Quality):通过固定评测集打分,或人工抽检回答的准确率、完整性、格式规范性。
3.2 控制变量的几个关键点
- 温度固定为 0.7,避免随机性干扰聚合指标。
- 请求 Prompt 完全一致,避免因输入不同导致输出长度差异。
- 输出上限统一设置为 512 Token。
- 并发数从 1 到 64 递增,分别记录每个并发档位下的吞吐和延迟。
- API 测试和本地部署测试分开记录,避免网络抖动影响判断。
3.3 评测 Prompt 设计
简单举 6 条具有代表性的业务 Prompt:
[ {"id": "qa_basic", "prompt": "用一句话解释什么是数据库索引,并给出一个使用场景。"}, {"id": "code_help", "prompt": "写一个 Python 函数,输入字符串列表,返回按长度排序后的列表。"}, {"id": "summary", "prompt": "总结下面这段新闻的要点,不超过 100 字。"}, {"id": "math", "prompt": "一个商品原价 320 元,打八五折后再减 30 元,最后价格是多少?"}, {"id": "rewrite", "prompt": "把这句话改写成更正式的商务表达:我们想尽快把项目做完。"}, {"id": "json_extract", "prompt": "从文本中提取人名、公司名、日期,以 JSON 格式输出。"} ]之所以混合代码、数学、抽取、改写,是为了避免模型在某类任务上“偏科”导致结果失真。
4. 核心代码:API 压测与本地部署
4.1 用 OpenA I兼容接口批量请求三个模型
DeepSeek 和 GLM 都提供 OpenAI 兼容接口,所以核心调用逻辑可以统一。下面脚本展示了如何循环请求并记录时间、Token 消耗:
# 文件路径:llm-benchmark/scripts/run_benchmark.py import json import time import requests def call_openai_compatible_model( api_key: str, base_url: str, model: str, prompt: str, max_tokens: int = 512, temperature: float = 0.7, ): url = f"{base_url}/chat/completions" headers = { "Authorization": f"Bearer {api_key}", "Content-Type": "application/json", } payload = { "model": model, "messages": [{"role": "user", "content": prompt}], "max_tokens": max_tokens, "temperature": temperature, "stream": False, } start = time.perf_counter() resp = requests.post(url, headers=headers, json=payload, timeout=120) elapsed = time.perf_counter() - start if resp.status_code != 200: return { "error": resp.status_code, "text": resp.text[:500], "elapsed": elapsed, } data = resp.json() content = data["choices"][0]["message"]["content"] usage = data.get("usage", {}) return { "content": content, "prompt_tokens": usage.get("prompt_tokens", 0), "completion_tokens": usage.get("completion_tokens", 0), "elapsed": elapsed, } if __name__ == "__main__": # 这里的 key 和 base_url 需要替换为真实配置 test_prompt = "用一句话解释什么是数据库索引,并给出一个使用场景。" result = call_openai_compatible_model( api_key="your-api-key", base_url="https://api.deepseek.com/v1", model="deepseek-v4-flash", prompt=test_prompt, ) print(json.dumps(result, ensure_ascii=False, indent=2))这段脚本虽然简单,但已经覆盖了“请求、计时、Token 统计”三个核心动作。真实压测时可以把test_prompt换成评测集,并加入并发控制。
4.2 高并发吞吐统计脚本
上面是单请求示例,实际评测需要并发。下面的脚本用concurrent.futures发起并发请求,并统计总吞吐和平均耗时:
# 文件路径:llm-benchmark/scripts/run_benchmark.py(追加内容) from concurrent.futures import ThreadPoolExecutor, as_completed def run_concurrent_benchmark( api_key: str, base_url: str, model: str, prompts: list, max_workers: int = 16, ): results = [] with ThreadPoolExecutor(max_workers=max_workers) as executor: future_map = { executor.submit( call_openai_compatible_model, api_key, base_url, model, p["prompt"], 512, 0.7, ): p["id"] for p in prompts } for future in as_completed(future_map): pid = future_map[future] try: res = future.result() res["id"] = pid results.append(res) except Exception as exc: results.append({"id": pid, "error": str(exc)}) total_completion_tokens = sum( r.get("completion_tokens", 0) for r in results if "error" not in r ) total_elapsed = sum(r.get("elapsed", 0) for r in results if "error" not in r) total_requests = len(results) success_requests = sum(1 for r in results if "error" not in r) return { "model": model, "total_requests": total_requests, "success_requests": success_requests, "total_completion_tokens": total_completion_tokens, "total_elapsed_seconds": round(total_elapsed, 2), "throughput_tokens_per_sec": round( total_completion_tokens / total_elapsed, 2 ) if total_elapsed > 0 else 0, } if __name__ == "__main__": with open("config/prompts.json", "r", encoding="utf-8") as f: prompt_list = json.load(f) summary = run_concurrent_benchmark( api_key="your-api-key", base_url="https://api.deepseek.com/v1", model="deepseek-v4-flash", prompts=prompt_list * 10, # 重复评测集以增加压力 max_workers=32, ) print(json.dumps(summary, ensure_ascii=False, indent=2))这里的throughput_tokens_per_sec是总生成 Token 数除以所有请求的累计耗时。要注意,它表示的是“客户端视角的汇总吞吐”,不是服务端纯吞吐。想要测服务端真实吞吐,建议使用 vLLM 自带 benchmark 工具,或者用locust这类压测平台。
4.3 在 DGX Spark 上本地部署 DeepSeek V4 Flash
API 测试完成以后,如果希望把高频业务流量迁移到本地,降低长期成本,可以在 DGX Spark 上用 vLLM 部署开源或企业授权的模型权重。
下面是一个最小启动脚本:
# 文件路径:llm-benchmark/scripts/local_deploy.sh #!/bin/bash MODEL_PATH="/models/deepseek-v4-flash" PORT=8000 TENSOR_PARALLEL_SIZE=1 MAX_MODEL_LEN=16384 GPU_MEM_UTIL=0.90 python -m vllm.entrypoints.openai.api_server \ --model $MODEL_PATH \ --tensor-parallel-size $TENSOR_PARALLEL_SIZE \ --max-model-len $MAX_MODEL_LEN \ --gpu-memory-utilization $GPU_MEM_UTIL \ --port $PORT解释几个关键参数:
--model:本地模型权重路径,必须是 Hugging Face 格式或 vLLM 支持的格式。--tensor-parallel-size:单机多卡或跨节点张量并行数量,需要根据显存和互联带宽决定。--max-model-len:最大上下文长度。设置过大会占用大量显存,设置过小会导致长文本请求报错。--gpu-memory-utilization:控制显存预留比例,生产环境一般建议 0.85 到 0.95 之间。
如果是两台 DGX Spark 做张量并行,需要把两台机器放在同一个内网,并通过分布式调度参数指定节点信息。具体参数在不同 vLLM 版本中差异较大,建议先查你所用版本的官方文档,不要照搬老教程里的参数。
启动成功后,本地服务会提供一个 OpenAI 兼容端点:
http://<node-ip>:8000/v1然后你只需要把 4.1 节脚本里的base_url改成http://<node-ip>:8000/v1,就可以用同一套评测脚本测试本地模型。
4.4 本地部署后的快速验证命令
部署完成后,用curl做一次冒烟测试:
curl -X POST http://localhost:8000/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{ "model": "/models/deepseek-v4-flash", "messages": [{"role": "user", "content": "你好,请做一次简单的自我介绍。"}], "max_tokens": 128, "temperature": 0.7 }'如果返回正常的 JSON 响应,说明服务已经起来。如果返回显存错误,优先降低--gpu-memory-utilization或缩小--max-model-len。
5. 测试结果对比分析
5.1 价格对比:谁才是“价格屠榜”
先说明:模型 API 价格属于动态信息,不同时间、不同渠道都会有差异。下面表格展示的是测试期间记录的公开参考价,用于说明换算方法,最终请以模型官网实时价格为唯一依据。
| 模型 | 输入价格(每百万 Token) | 输出价格(每百万 Token) | 综合参考定位 |
|---|---|---|---|
| DeepSeek V4 Flash | 相对较低 | 相对较低 | 极致性价比,适合高频调用 |
| Gemini 1.5 Flash | 中等偏低 | 中等偏低 | 多模态 + 轻量任务 |
| GLM-4-Plus | 相对较高 | 相对较高 | 复杂推理,质量优先 |
测试中最直观的结论是:在“每百万 Token 综合成本”上,DeepSeek V4 Flash 明显低于 Gemini 1.5 Flash 和 GLM-4-Plus。如果业务每天调用量在百万级,选择 DeepSeek V4 Flash 每月节省的成本非常可观。
但这里必须提醒一句:价格低不等于总拥有成本低。如果你需要多模态能力,DeepSeek V4 Flash 不一定支持,还是要回归到业务需求本身。
5.2 吞吐对比:高并发下的稳定性
在并发数 16、32、64 三档压力下,测试结果的趋势如下:
- DeepSeek V4 Flash 在每台推理节点上表现稳定,吞吐随并发上升而上升,直到接近硬件上限。
- Gemini 1.5 Flash 的 API 受服务端限流影响较明显,并发过高时会出现
429 Too Many Requests,吞吐曲线呈“先升后平”。 - GLM-4-Plus 吞吐不差,但单请求耗时偏长,导致同样的并发下总吞吐低于 Flash 系列模型。
如果你的业务是“大量短请求”,比如客服、内容审核、标签抽取,那么高吞吐模型能让单位时间处理量更大,后端机器数量也可以更少。
5.3 响应速度:TTFT 与生成速率
用户能感知的核心指标是“发出去消息后,多久开始有字打出来”。测试显示:
- Flash 系列模型的 TTFT 通常较低,尤其是 DeepSeek V4 Flash 在 API 和本地部署场景下都比较快。
- Gemini 1.5 Flash 的 TTFT 在不同区域波动较大,部分时候需要排队,导致首字时间不稳定。
- GLM-4-Plus 的 TTFT 中等,但生成速度稳定,适合流式输出场景。
如果你的产品是 Chat 类应用,TTFT 直接决定用户体验。建议在选型时把“流式输出 + 首Token时间”作为固定测试项,而不是只看总耗时。
5.4 生成质量抽检结论
在代码生成、数学计算、摘要提取三类任务上,测试结果如下:
- 代码任务:GLM-4-Plus 对复杂逻辑的理解最好,DeepSeek V4 Flash 在常见代码补全上表现够用,Gemini 1.5 Flash 对代码注释和文档生成较好。
- 数学任务:三款模型在简单四则运算上都没问题。复杂应用题上 GLM-4-Plus 更稳,DeepSeek V4 Flash 偶尔会出现步骤跳跃。
- 摘要与改写:Flash 类模型的输出更加简洁,在“短摘要”场景下反而更合适。GLM-4-Plus 输出更完整,但字数偏长。
结论是:便宜模型在中等难度任务上质量并不差,真正拉开差距的是高难度推理任务。所以不建议无脑选最贵或最便宜,而是按任务难度分级调用不同模型。
6. 高频问题与排查思路
以下是测试和部署过程中最常见的几类问题,做成表格方便对照。
| 问题现象 | 常见原因 | 解决思路 |
|---|---|---|
| API 请求返回 401 | API Key 无效或权限不足 | 检查 Key 是否过期,确认是否有对应模型权限 |
| API 返回 429 Too Many Requests | 触发了服务端限流 | 降低并发,加入指数退避重试 |
| Gemini 提示“目前不支持你所在的地区” | 区域可用性限制 | 确认官方支持范围,评估是否符合部署要求 |
| 本地 vLLM 启动报显存不足 | 模型+上下文长度超过显存 | 降低--max-model-len或--gpu-memory-utilization |
| 双节点张量并行性能不升反降 | 节点间网络带宽不足 | 检查互联配置,优先用单节点大显存方案 |
| 流式输出卡顿 | 客户端处理不当时延敏感性低 | 开启流式模式,监控每 token 间隔时间 |
| 不同模型返回内容长度差异大 | max_tokens 设置不一致 | 各模型统一 max_tokens,结果才可比较 |
| 本地模型响应慢但 API 快 | 硬件未做并发优化 | 开启 vLLM Continuous Batching,调高并发 |
下面挑三个重点展开。
6.1 遇到过 429 限流怎么办
当你用同一个 API Key 跑高并发压测时,服务端会限制请求速率。直接调高并发只会得到一堆 429。
正确做法:
- 降低并发数到服务端允许范围。
- 加入重试机制,对 429 和 5xx 状态码做退避重试。
- 把长任务拆分到多个时间段执行。
示例重试逻辑:
import time import random def call_with_retry(call_func, max_retries=5): for attempt in range(max_retries): result = call_func() if "error" not in result: return result if result["error"] == 429: wait_time = 2 ** attempt + random.uniform(0, 1) time.sleep(wait_time) else: break return result6.2 本地模型推理一直“转圈”但无报错
出现这种情况,需要区分是输入阶段还是输出阶段慢。
排查顺序:
- 先看 GPU 利用率,如果利用率很高,说明模型在正常计算,只是生成长。
- 如果利用率很低,可能是等待数据加载,检查磁盘 I/O。
- 查看日志中是否有 “Waiting for batch” 之类的信息,确认是否有请求排队。
6.3 双 DGX 部署出现通信瓶颈
两台机器做张量并行,理论上显存翻倍、算力翻倍,但实际吞吐可能只提升几十个百分点。常见原因是节点间网络延迟过高。
建议:
- 优先使用 NVLink 或 InfiniBand 等低延迟互联。
- 如果只有万兆以太网,大模型跨节点张量并行性能会明显受限。
- 对于 70B 以下模型,单机多卡往往比双机效果更稳定。
7. 最佳实践与工程建议
7.1 按任务复杂度分级调用模型
实际项目中,不要所有请求都走同一个模型。建议设计一个简单的路由策略:
任务分类 → 简单任务 → DeepSeek V4 Flash → 中等任务 → Gemini 1.5 Flash / 本地 Flash 模型 → 高难度任务 → GLM-4-Plus 或更强模型这样可以兼顾成本和质量。比如客服机器人中,“查订单状态”“改地址”这类简单意图走 Flash 模型;“处理投诉”“多轮复杂对话”走高级模型。
7.2 成本测算公式
在选型阶段,用下面公式快速估算月成本:
月成本 = 日请求量 × 单请求平均Token数 × 30 × 单价(每Token)建议在测试阶段就记录每个请求的prompt_tokens和completion_tokens,这样才能准确预估线上费用。很多团队上线后才发现账单暴涨,就是因为测试阶段没有统计 Token 消耗。
7.3 本地部署与 API 的取舍
本地部署的优劣势:
- 优势:长期成本可控、数据不出内网、可定制量化与推理参数。
- 劣势:需要硬件投入、需要维护推理服务、模型更新需要自行跟进。
对于日请求量低于 10 万的早期项目,直接用官方 API 更划算。当请求量稳定增长后,再评估是否迁移到 DGX Spark 这类本地设备。
7.4 数据安全与合规边界
任何模型评测和部署都要注意数据安全:
- 生产数据脱敏后再用于评测,不要直接上传真实用户信息。
- 涉及隐私、合规的业务,优先考虑本地部署。
- 使用第三方 API 前,确认服务条款是否允许你的业务场景。
这块没有统一答案,需要结合团队所处行业和地区规定来判断。
7.5 持续评测机制
模型能力、价格、限流策略都可能在三个月内变化,建议把评测脚本做成定时任务:
每周跑一次小规模评测集 每月跑一次完整评测集 每次价格调整后立刻重跑成本对比只有持续跟踪,才能在模型价格波动时快速调整选型策略。
8. 总结与下一步学习方向
这篇实战笔记帮你理清了三个关键点。
第一,大模型选型不能只看模型能力,价格/Token、吞吐、TTFT 同样重要。DeepSeek V4 Flash 在价格和吞吐上的优势,让它成为高频业务的有力候选。Gemini 1.5 Flash 适合多模态场景,GLM-4-Plus 则更适合对质量要求高的复杂推理任务。
第二,一套完整的评测流程并不复杂。准备好统一 Prompt 集、统一并发脚本、统一指标记录方式,就能在三天内完成三到五款模型的横向对比。文章里的脚本和部署命令可以直接改来用。
第三,本地部署是长期降本的有效手段,但前提是业务量足够大、硬件条件合适、团队有维护推理服务的能力。如果只是早期验证,不妨先用 API 跑通业务,再逐步迁移。
接下来你可以继续去了解这几个方向:vLLM 的 Continuous Batching 原理、张量并行与流水线并行的差异、以及如何设计一套自动化的模型 Harness 评测平台。把这些内容吃透之后,面对“选哪个模型”的问题,你就不会再靠感觉,而是能拿出数据说话。
如果这篇文章对你选型或部署有帮助,可以收藏备用。后续遇到新版本模型发布,也建议重新跑一遍评测流程再做决定。