如何使用tiktoken计算文本中的标记数

在现代自然语言处理中,标记是一种重要的概念,因为它们是语言模型处理文本的基本单元。本教程将向您展示如何使用OpenAI开源的快速分词工具tiktoken来计算文本中的标记数。通过了解文本中有多少标记,您可以:

  1. 判断文本是否太长以至于超出模型处理的限制。
  2. 了解使用OpenAI API调用的成本,因为计费是按标记计算的。

1. 引言故事

假设您是一名程序员,正在为自己的聊天应用项目编写代码。您已经集成了一个强大的自然语言处理模型,但现在需要确定用户输入的文本有多少标记,以便确保不会超出模型的限制。在解决这个问题之前,您曾不止一次被意想不到的文本长度问题困扰。一天,您在互联网上发现了一个名为tiktoken的开源工具,它能够快速准确地计算文本中的标记数。这似乎是您解决问题的完美工具,因此您决定深入了解它并开始使用它来解决您的标记计数问题。

2. 安装tiktoken

首先,您需要安装tiktoken工具。您可以使用pip来安装它:

pip install --upgrade tiktoken

安装完成后,您就可以开始使用tiktoken来计算文本中的标记数了。

3. 导入tiktoken

在您的Python项目中,首先导入tiktoken库:

import tiktoken

4. 加载编码

接下来,您需要加载一个编码,以告诉tiktoken如何将文本转换为标记。不同的模型使用不同的编码。在本示例中,我们使用了“cl100k_base”编码,它适用于一些OpenAI模型,包括gpt-4和gpt-3.5-turbo。您可以这样加载编码:

encoding = tiktoken.get_encoding("cl100k_base")

5. 使用编码.encode()方法将文本转换为标记

现在,您可以使用编码对象的.encode()方法将文本转换为标记。该方法将文本字符串转换为标记的整数列表。例如,如果我们有文本字符串"tiktoken is great!",您可以这样做:

tokens = encoding.encode("tiktoken is great!")

这将返回一个整数列表,代表文本中的标记。在这个示例中,返回的标记列表为[83, 1609, 5963, 374, 2294, 0]

要计算文本中的标记数,只需查看标记列表的长度:

num_tokens = len(tokens)

这将给您文本中的标记数,本例中为6个标记。

6. 使用编码.decode()方法将标记转换回文本

如果您需要将标记转换回文本,可以使用编码对象的.decode()方法。例如,如果我们有标记列表[83, 1609, 5963, 374, 2294, 0],您可以这样做:

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

这将返回文本字符串"tiktoken is great!"。

请注意,虽然.decode()方法可以应用于单个标记,但对于不在utf-8边界上的标记,它可能会导致信息丢失。对于单个标记,.decode_single_token_bytes()方法可以安全地将单个整数标记转换为其表示的字节。

7. 比较不同编码

不同编码在分割单词、分组空格和处理非英文字符方面有所不同。使用上述方法,我们可以比较不同编码在几个示例字符串上的效果。以下是一个比较不同编码的函数示例:

def compare_encodings(example_string: str) -> None:
    """打印三种字符串编码的比较结果。"""
    # 打印示例字符串
    print(f'\n示例字符串: "{example_string}"')
    # 对于每个编码,打印标记数、标记整数和标记字节
    for encoding_name in ["r50k_base", "p50k_base", "cl100k_base"]:
        encoding = tiktoken.get_encoding(encoding_name)
        token_integers = encoding.encode(example_string)
        num_tokens = len(token_integers)
        token_bytes = [encoding.decode_single_token_bytes(token) for token in token_integers]
        print()
        print(f"{encoding_name}: {num_tokens} 个标记")
        print(f"标记整数: {token_integers}")
        print(f"标记字节: {token_bytes}")

compare_encodings("antidisestablishmentarianism")

8. 为聊天完成API调用计算标记数

对于像gpt-3.5-turbo和gpt-4这样的ChatGPT模型,它们使用标记方式与较早的完成模型相同,但由于它们基于消息格式,因此更难计算消息将使用多少标记。

以下是一个用于计算传递给gpt-3.5-turbo或gpt-4的消息标记数的示例函数。请注意,从消息中计算标记的方式可能会因模型而异。考虑到下面的函数中计算的标记数量是一个估计值,而不是一个永恒的保证。

def num_tokens_from_messages(messages, model="gpt-3.5-turbo-0613"):
    """返回消息列表使用的标记数。"""
    try:
        encoding

 = tiktoken.get_encoding(model)
    except Exception as e:
        print(f"获取编码时发生错误:{e}")
        return None

    total_tokens = 0
    for message in messages:
        tokens = encoding.encode(message["content"])
        num_tokens = len(tokens)
        # 添加额外的标记以表示用户或系统角色
        if message["role"] == "system":
            num_tokens += 1
        else:
            num_tokens += 2  # 一个用于角色,一个用于分隔符
        total_tokens += num_tokens

    return total_tokens

# 示例消息列表
messages = [
    {"role": "system", "content": "You are a helpful assistant."},
    {"role": "user", "content": "Tell me a joke."},
    {"role": "assistant", "content": "Why did the chicken cross the road?"},
    {"role": "user", "content": "I don't know, why did the chicken cross the road?"}
]

total_tokens = num_tokens_from_messages(messages, model="gpt-3.5-turbo-0613")
print(f"消息列表中的总标记数:{total_tokens}")

这个函数可以帮助您估算给定消息列表的标记数,以便控制文本长度和计费。请注意,不同模型的标记数限制可能会有所不同,因此在实际使用中请谨慎估算。

声明:本站所有文章,如无特殊说明或标注,均为本站(王大神)原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

给TA打赏
共{{data.count}}人
人已打赏
指数词

如何使用PHP获取本机IPv4和IPv6地址

2023-10-14 12:27:32

指数词

如何使用ChatGPT模型格式化输入

2023-10-14 12:31:23

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索