【大模型】Token计算方式与DeepSeek输出速率测试

概述

现在大模型厂家很多,每家的API价格都是以tokens作为计费单位。第一次见时,不免产生疑问:tokens究竟是啥?为什么国产化之后都没有翻译成中文,看着很怪。本文将围绕token,对输入token进行统计分析,并对本地部署的DeepSeek大模型token的输出速度进行相关测试。

1. token的定义

有人早就提出了“在中文 NLP 等论文中,应该如何翻译 token 这个词?”[1]这个问题,实际上,并不是国内厂商偷懒懒得翻译,实在是没有标准翻译方法。因为在“互联网”应用中,往往把“token”直译作令牌,因为其往往用于身份验证代表某个用户、设备或会话的授权信息。

在NLP领域,再对token进行直译,似乎与其实际语义存在较大偏差。token实际是语言模型处理文本的基础单元,比较相近的语义是词元、词符等。但标准不明,莫衷一是,索性直接不翻译。

对于token的划分,实际上也没有统一的做法,不同的语言模型可能会使用不同的 Token 化方法[2] :

  • 基于字符的 Token:将文本分割成单个字符,例如 “Hello” 被分割成 [“H”, “e”, “l”, “l”, “o”]。

  • 基于单词的 Token:将文本分割成单词,例如 “Hello, world” 被分割成 [“Hello”, “world”]。

  • 基于子词的 Token:将单词分割成更小的子词单元,例如 “unhappy” 被分割成 [“un”, “happy”]。这种方法在处理词缀和词根时非常有效。

  • 混合 Token:一些模型会结合多种 Token 化方法,以更好地处理语言的复杂性。

2. token离线计算

DeepSeek API 文档[3] 提供了一个token计算方式,用的是LlamaTokenizerFast的分词器,共包含三个文件:

  • deepseek_tokenizer.py:分词器使用示例
  • tokenizer_config.json:分词器配置信息
  • tokenizer.json:包含词汇表和分词规则

我稍微修改了一下 deepseek_tokenizer.py,使其输出更为清晰,内容如下:

import transformers

chat_tokenizer_dir = "./"

tokenizer = transformers.AutoTokenizer.from_pretrained( 
        chat_tokenizer_dir, trust_remote_code=True
        )

text = "Hello,world!"
result = tokenizer.encode(text)
print(f"编码结果: {result}")

# 解码回文本
decoded = tokenizer.decode(result)
print(f"解码结果: {decoded}")

# 查看每个ID对应的标记
tokens = tokenizer.convert_ids_to_tokens(result)
print(f"标记列表: {tokens}")

# 详细展示每个标记及其ID
for token_id, token in zip(result, tokens):
    print(f"ID: {token_id}, 标记: {token}")

输出结果如下:

编码结果: [19923, 14, 29616, 3]
解码结果: Hello,world!
标记列表: ['Hello', ',', 'world', '!']
ID: 19923, 标记: Hello
ID: 14, 标记: ,
ID: 29616, 标记: world
ID: 3, 标记: !

可以看到,它将"Hello,world!"分解成了4个tokens。

3. 本地大模型输出速率测试

如果用ollama在本地部署大模型,可以通过eval_count参数直接获取到具体输出的tokens数量。我写了一个测试tokens输出速率的脚本,内容如下:

import requests
import time

# ollama 的 API 地址
OLLAMA_API_URL = "http://localhost:11434/api/generate"

# 请求参数
payload = {
    "model": "deepseek-r1:32b",  # 替换为你的模型名称
    "prompt": "目标检测的具体含义是什么?",  # 替换为你的输入文本
    "stream": False,  # 设置为 False,一次性返回完整结果
    "max_tokens": 100  # 设置生成的最大 token 数量
}

# 打印 model 和 prompt 信息
print(f"使用的模型: {payload['model']}")
print(f"输入的问题: {payload['prompt']}")

# 记录开始时间
start_time = time.time()
print(f"开始时间: {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(start_time))}")

# 发送请求
response = requests.post(OLLAMA_API_URL, json=payload)

# 记录结束时间
end_time = time.time()
print(f"结束时间: {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(end_time))}")

# 解析响应
if response.status_code == 200:
    result = response.json()
    # print(result)
    generated_text = result.get("response", "")
    generated_tokens = result.get("eval_count", 0)  # 获取生成的 token 数量
    elapsed_time = end_time - start_time

    # 计算每秒生成的 token 数量
    tokens_per_second = generated_tokens / elapsed_time

    print(f"模型回答: {generated_text}")
    print(f"生成时间: {elapsed_time:.2f}秒")
    print(f"生成 token 数量: {generated_tokens}")
    print(f"每秒生成 token 数量: {tokens_per_second:.2f}")
else:
    print(f"请求失败,状态码: {response.status_code}")
    print(f"错误信息: {response.text}")

下面是我在四卡4090 D服务器上进行的实验效果:

模型名称模型精度部署方式实际显存占用生成tokens/秒
deepseek-r1:32b4单卡部署20GB33.76
deepseek-r1:32b4双卡部署20GB32.98
deepseek-r1:32b4四卡部署20GB32.65
deepseek-r1:70b4双卡部署44GB17.68
deepseek-r1:70b4四卡部署44GB17.46
deepseek-r1:70b8四卡部署74GB11.54
qwen2.5:72b(非推理模型)4四卡部署49GB17.25

从实测数据中,可以得到以下三个结论:

  1. 多卡部署时,生成速度会受到PCIE带宽限制影响,但实际测算影响较低
  2. 同一参数量模型,使用更高精度推理,速度会大大降低
  3. 模型是否包含推理过程,对生成速率无明显影响,因为对于推理模型来说,推理过程就是输出的一部分

下面是一张主流大模型平台输出tokens速率的对比图,大部分模型的输出速率在20-40这个区间,因此,输出速率在这个范围左右,基本可以保证流畅的用户体验。

在这里插入图片描述

4. 节省tokens小提示

在写这篇文章时,特意看了下各大模型的API收费标准,输入tokens和输出tokens实际上是单独计费的。我的上一篇文章【大模型】如何正确评估DeepSeek-R1各版本所需推理显存?KV Cache原理和显存计算解析提到过,对于多轮对话,目前主流框架/应用都会把历史记录继续输入到大模型中。

因此,如果利用API进行部署,下一个问题和之前的问题没什么关联,可以新开一个对话,避免API用量被过度消耗。

参考

[1] 在中文 NLP 等论文中,应该如何翻译 token 这个词?:https://www.zhihu.com/question/39279003
[2] 大模型中的token:https://blog.csdn.net/xixingzhe2/article/details/145797529
[3] DeepSeek API 文档:https://api-docs.deepseek.com/zh-cn/quick_start/token_usage

<think>好的,我现在需要给用户介绍一下GNU工具。首先,我得回忆一下GNU项目的基本信息。GNU是Richard Stallman在1983年发起的,目标是创建一个完全自由的操作系统。用户可能想知道GNU工具具体包括哪些,以及它们的作用。 接下来,我应该考虑GNU工具的核心组成部分。GNU工具链里的编译器(GCC)、调试器(GDB)、构建工具(make)这些都是基础。还有像核心工具(coreutils),里面包含ls、cp、grep这些常用命令。需要分别解释每个工具的作用,但不要太过深入细节,保持整体介绍。 然后,用户可能想知道GNU工具和Linux的关系。这里要区分清楚,GNU提供了很多工具,而Linux是内核,两者结合成了GNU/Linux系统。这一点很重要,避免用户混淆。 另外,GNU工具的特点,比如自由软件、可移植性、模块化设计,这些也是需要提到的重点。用户可能关心为什么选择GNU工具,这些特点能给出答案。 还需要考虑用户的实际应用场景。比如开发软件时,GCC编译代码,GDB调试,make管理构建过程。系统管理中使用coreutils和shellutils进行文件操作和脚本编写。这些例子能帮助用户理解工具的实际用途。 最后,要确保按照系统级指令的要求,使用正确的中文,结构清晰,分点说明。检查是否有行内公式需要用$...$,不过GNU工具介绍可能数学内容不多,但如果有提到版本号或其他可能需要强调的地方,注意格式。不过根据用户的问题,可能不需要数学表达式,但还是要留意。比如如果有版本号如GCC 11.2,可能不需要特别处理,但如果有涉及参数或代码,可能需要用行内代码格式,但用户没有特别要求这个,所以保持中文描述即可。 现在整理结构:简介、核心工具、工具链、Linux关系、特点、应用场景、总结。每个部分简明扼要,用例子说明。确保语言口语化,避免技术术语过多,但必要的术语需要解释清楚。 可能还需要检查是否有错误,比如GNU工具是否包含某些特定工具,或者历史背景是否正确。例如,GNU Hurd内核未完成,所以采用Linux内核,这点需要准确描述。 最后,确保符合用户的中文回答要求,结构清晰,分点列出,帮助用户逐步了解GNU工具。避免使用Markdown格式,用自然的分段和编号。</think>GNU工具是由**GNU项目**(GNU’s Not Unix)开发的一系列自由软件工具,广泛应用于软件开发、系统管理和日常操作中。以下是逐步介绍: --- ### 1. **GNU项目背景** - **目标**:由Richard Stallman于1983年发起,旨在创建一个完全自由(开源)且兼容Unix的操作系统。 - **现状**:虽然GNU未完成自己的内核(Hurd仍在开发中),但其工具集Linux内核结合,形成了广泛使用的**GNU/Linux操作系统**。 --- ### 2. **GNU工具的核心组成** #### (1) **GNU核心工具(Coreutils)** - **功能**:提供基础命令行工具,如文件操作、文本处理等。 - **常见工具**: - `ls`(列出目录内容)、`cp`(复制文件)、`mv`(移动文件) - `grep`(文本搜索)、`sed`(流编辑器)、`awk`(文本分析工具) #### (2) **GNU编译工具链(GNU Toolchain)** - **GCC(GNU Compiler Collection)**: - 支持C、C++、Fortran等语言的编译器。 - 示例:`gcc -o program program.c` - **GDB(GNU Debugger)**: - 调试程序,支持断点、变量检查等功能。 - **Make**: - 自动化构建工具,通过`Makefile`定义编译规则。 #### (3) **其他重要工具** - **Bash(Bourne-Again SHell)**:默认的Unix shell,支持脚本编程。 - **GNU Binutils**:包含链接器(`ld`)、汇编器(`as`)等二进制工具。 - **GRUB(Grand Unified Bootloader)**:多系统引导程序。 --- ### 3. **GNU工具的特点** - **自由开源**:遵循GPL协议,允许自由使用、修改和分发。 - **可移植性**:支持多种操作系统(如Linux、BSD、Windows via Cygwin)。 - **模块化设计**:工具之间松散耦合,可灵活组合(例如管道操作`|`)。 --- ### 4. **GNU工具的应用场景** - **软件开发**: - 用`GCC`编译代码,`GDB`调试,`Make`管理项目。 - **系统管理**: - 通过`coreutils`管理文件,`cron`定时任务,`grep`日志分析。 - **脚本自动化**: - 结合`Bash`和`sed/awk`编写脚本处理数据。 --- ### 5. **GNULinux的关系** - **互补性**:GNU提供用户空间工具,Linux提供内核,共同构成完整的操作系统。 - **常见误解**:许多人称系统为“Linux”,但严格来说应为“GNU/Linux”。 --- ### 6. **总结** GNU工具是自由软件生态的基石,其稳定性、灵活性和开放性使其成为开发者、运维人员的首选。无论是编写代码、调试程序,还是管理系统,GNU工具链都能提供高效支持。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zstar-_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值