使用 tiktoken 计算 token 数量

什么是tiktoken

iktoken是OpenAI开发的一种BPE分词器。

给定一段文本字符串(例如,"tiktoken is great!")和一种编码方式(例如,"cl100k_base"),分词器可以将文本字符串切分成一系列的token(例如,["t", "ik", "token", " is", " great", "!"])。

tiktoken解决了什么问题

将文本字符串切分成token非常有用,因为GPT模型看到的文本就是以token的形式呈现的。

知道一段文本字符串中有多少个token可以告诉你(a)这个字符串是否对于文本模型来说太长了而无法处理,以及(b)一个OpenAI API调用的费用是多少(因为使用量是按照token计价的)。

编码方式

编码方式规定了如何将文本转换成token。不同的模型使用不同的编码方式。

tiktoken支持OpenAI模型使用的三种编码方式:

编码名称 OpenAI模型
cl100k_base gpt-4, gpt-3.5-turbo, text-embedding-ada-002
p50k_base Codex模型, text-davinci-002, text-davinci-003
r50k_base (或 gpt2) davinci 这样的GPT-3模型

如何获取模型的编码方式

你可以使用 tiktoken.encoding_for_model() 获取一个模型的编码方式,

如下所示:

python 复制代码
encoding = tiktoken.encoding_for_model('gpt-3.5-turbo')

注意,p50k_baser50k_base 有很大的重叠,对于非代码应用,它们通常会产生相同的token。

在英语中,token的长度通常在一个字符到一个单词之间变化(例如,"t"" great"),尽管在某些语言中,token可以比一个字符短或比一个单词长。空格通常与单词的开头一起分组(例如," is" 而不是 "is "" "+"is")。你可以快速在 OpenAI分词器 检查一段字符串如何被分词。

安装 tiktoken

css 复制代码
pip install --upgrade tiktoken

示例-编码 encode 将字符串转换成token ID

ini 复制代码
import tiktoken

# 第一次运行时,它将需要互联网连接进行下载。后续运行不需要互联网连接。
encoding = tiktoken.get_encoding("cl100k_base")


# 使用`tiktoken.encoding_for_model()`函数可以自动加载给定模型名称的正确编码。
# encoding = tiktoken.encoding_for_model("gpt-3.5-turbo")

# 实际进行编码
# 通过计算`.encode()`返回的列表的长度来统计token数量。
encoding.encode("tiktoken is great!")

# The `.encode()` method converts a text string into a list of token integers.

输出 83, 1609, 5963, 374, 2294, 0 返回token ID 这边用了6个token

示例-解码 encode 将token ID 还原成 字符串

ini 复制代码
import tiktoken

# 第一次运行时,它将需要互联网连接进行下载。后续运行不需要互联网连接。
encoding = tiktoken.get_encoding("cl100k_base")


print(encoding.decode([83, 1609, 5963, 374, 2294, 0]))

输出 tiktoken is great!

对比不同的编码方式

不同的编码方式在分割单词、处理空格和非英文字符方面存在差异。通过上述方法,我们可以比较几个示例字符串在不同的编码方式下的表现。

统计completions API调用时的token数

ChatGPT模型,如gpt-3.5-turbo和gpt-4,与旧的完成模型一样使用token,但由于其基于消息的格式,很难准确计算对话中将使用多少个token。

python 复制代码
# 定义函数 num_tokens_from_messages,该函数返回由一组消息所使用的token数。
def num_tokens_from_messages(messages, model="gpt-3.5-turbo"):
    """Return the number of tokens used by a list of messages."""
    # 尝试获取模型的编码
    try:
        encoding = tiktoken.encoding_for_model(model)
    except KeyError:
        # 如果模型没有找到,使用 cl100k_base 编码并给出警告
        print("Warning: model not found. Using cl100k_base encoding.")
        encoding = tiktoken.get_encoding("cl100k_base")

    num_tokens = 0
    # 计算每条消息的token数
    for message in messages:
        num_tokens += tokens_per_message
        for key, value in message.items():
            num_tokens += len(encoding.encode(value))
            if key == "name":
                num_tokens += tokens_per_name
    num_tokens += 3  # 每条回复都以助手为首
    return num_tokens
相关推荐
葫芦和十三1 小时前
图解 MongoDB 05|文档模型设计:内嵌 vs 引用,反范式不是免费午餐
后端·mongodb·agent
不能放弃治疗5 小时前
单 Agent 实现模式
后端
IT_陈寒7 小时前
Redis内存爆了,原来我漏掉了这个致命配置
前端·人工智能·后端
fliter8 小时前
最后一块拼图:用 bitvec 构造 IPv4 包,真正做出自己的 Ping
后端
fliter9 小时前
用 Rust 解析并生成 ICMP 包:checksum、nom 与 cookie-factory
后端
蝎子莱莱爱打怪9 小时前
XZLL-IM干货系列 03|消息 ID 设计:一个 UUID 搞不定的事,我用两个 ID 解决了
后端·面试·开源
fliter9 小时前
从 panic 到 Result:用 Rust 重新整理一个 ping 项目的错误处理
后端
森蓝情丶9 小时前
我给 AI 搭了个法庭:一个前端仔的 LangGraph 实战全记录
前端·后端
JensCS猿9 小时前
从 Spring Boot 回看 SSM 框架:手动挡与自动挡的驾驶哲学
后端
爱勇宝9 小时前
干了近 8 年,一夜之间被裁:AI 时代,程序员最该害怕的不是 AI
前端·后端·程序员