OpenAI API - Text generation models 的概念与使用(二)

目录

4.Managing tokens

        计算 Chat API 调用中的令牌数

        如何在不进行API调用的情况下查看文本字符串中的令牌数

5. Parameter details

        频率惩罚和出现惩罚

        深入了解

令牌对数概率

示例代码

示例代码:获取令牌的对数概率

6. Completions API Legacy

总结


 

4.Managing tokens

        令牌(token) & 汉字:

        令牌(token)并不是直接等同于汉字或单词。在中文和其他语言中,一个令牌的长度可以有所不同。令牌可以是一个汉字、一个英文单词的一部分,或者是一个短语的一部分。OpenAI的模型使用了一种称为Byte Pair Encoding (BPE) 的分词算法,将文本分解成令牌。

在中文中,一个汉字通常被编码为一个令牌,但这并不总是如此。例如,一些常见的短语或组合可能会被编码为一个单独的令牌。总的来说,一个令牌可以包含一个汉字、一个英文单词的一部分,甚至是一个标点符号。

举个例子:

  • 英文句子:"ChatGPT is great!" 被分成 ["Chat", "G", "PT", " is", " great", "!"] 六个令牌。
  • 中文句子:"今天天气很好。" 可能被分成 ["今天", "天气", "很", "好", "。"] 五个令牌。

_____________________________________________________________________________

        管理令牌:

语言模型通过读取和写入称为令牌的文本块来处理文本。在英语中,一个令牌可以短至一个字符或长至一个单词(例如,"a" 或 "apple"),在某些语言中,令牌甚至可以短于一个字符或长于一个单词。

例如,字符串 "ChatGPT is great!" 被编码为六个令牌:["Chat", "G", "PT", " is", " great", "!"]

API调用中的令牌总数会影响以下几点:

  1. API调用的费用:因为你需要为每个令牌付费。
  2. API调用的时长:因为写入更多的令牌需要更多的时间。
  3. API调用是否成功:因为令牌总数必须低于模型的最大限制(对于gpt-3.5-turbo,最大限制为4097个令牌)。

输入和输出令牌都计入这些数量。例如,如果你的API调用在消息输入中使用了10个令牌,并且你在消息输出中收到了20个令牌,那么你将被计费30个令牌。不过需要注意的是,对于某些模型,输入和输出令牌的价格可能不同(详细信息请参见定价页面)。

要查看API调用使用了多少令牌,可以检查API响应中的usage字段,例如response['usage']['total_tokens']

像gpt-3.5-turbo和gpt-4-turbo-preview这样的聊天模型以与完成API中可用的模型相同的方式使用令牌,但由于其基于消息的格式化,计算对话中将使用多少令牌会更加困难。

        计算 Chat API 调用中的令牌数

        下面是一个示例函数,用于计算传递给 gpt-3.5-turbo-0613 的消息的令牌数。

        消息转换为令牌的确切方式可能因模型而异。因此,当未来发布新的模型版本时,该函数返回的答案可能只是近似值。

import tiktoken

def num_tokens_from_messages(messages, model="gpt-3.5-turbo-0613"):
    """返回消息列表使用的令牌数。"""
    try:
        encoding = tiktoken.encoding_for_model(model)
    except KeyError:
        encoding = tiktoken.get_encoding("cl100k_base")
    if model == "gpt-3.5-turbo-0613":  # 注意:未来的模型可能会有所不同
        num_tokens = 0
        for message in messages:
            num_tokens += 4  # 每条消息遵循 <im_start>{role/name}\n{content}<im_end>\n
            for key, value in message.items():
                num_tokens += len(encoding.encode(value))
                if key == "name":  # 如果有名称,角色将被省略
                    num_tokens += -1  # 角色始终是必需的,并且始终为1个令牌
        num_tokens += 2  # 每个回复都以 <im_start>assistant 开头
        return num_tokens
    else:
        raise NotImplementedError(f"num_tokens_from_messages() 目前未实现模型 {model}。")

# 创建一个消息列表并传递给上面定义的函数以查看令牌计数,这应与API使用参数返回的值相匹配:

messages = [
    {"role": "system", "content": "You are a helpful, pattern-following assistant that translates corporate jargon into plain English."},
    {"role": "system", "name":"example_user", "content": "New synergies will help drive top-line growth."},
    {"role": "system", "name": "example_assistant", "content": "Things working well together will increase revenue."},
    {"role": "system", "name":"example_user", "content": "Let's circle back when we have more bandwidth to touch base on opportunities for increased leverage."},
    {"role": "system", "name": "example_assistant", "content": "Let's talk later when we're less busy about how to do better."},
    {"role": "user", "content": "This late pivot means we don't have time to boil the ocean for the client deliverable."},
]

model = "gpt-3.5-turbo-0613"

print(f"{num_tokens_from_messages(messages, model)} prompt tokens counted.")
# 应显示大约126个 total_tokens

# 为确认我们上述函数生成的数字与API返回的相同,创建一个新的Chat Completion:

from openai import OpenAI
client = OpenAI()

response = client.chat.completions.create(
    model=model,
    messages=messages,
    temperature=0,
)

print(f'{response.usage["prompt_tokens"]} prompt tokens used.')

在这个例子中,函数num_tokens_from_messages用于计算传递给Chat Completion API的消息列表中使用的令牌数。通过比较函数输出的令牌数与API返回的令牌数,你可以确认计算是否正确。

        如何在不进行API调用的情况下查看文本字符串中的令牌数

        使用OpenAI的tiktoken Python库可以在不进行API调用的情况下查看文本字符串中的令牌数。可以在OpenAI Cookbook 的指南中找到示例代码,了解如何使用tiktoken计算令牌。

每条传递给API的消息都会消耗内容、角色和其他字段中的令牌数,再加上用于后台格式化的几个额外令牌。这可能会在未来略有变化。

如果对话的令牌数超过了模型的最大限制(例如,gpt-3.5-turbo超过4097个令牌或gpt-4o超过128k个令牌),你将不得不截断、删除或以其他方式缩减文本,直到其适合为止。请注意,如果消息从消息输入中移除,模型将失去对此消息的所有了解。

请注意,非常长的对话更有可能收到不完整的回复。例如,一个长达4090个令牌的对话,其回复将在仅有6个令牌后被截断(对于gpt-3.5-turbo)。

5. Parameter details
        频率惩罚和出现惩罚

        在Chat Completions API和Legacy Completions API中,频率惩罚(frequency penalty)和出现惩罚(presence penalty)可用于减少采样重复令牌序列的可能性。

        深入了解

        惩罚机制的幕后工作

        它们通过添加性贡献直接修改logits(未归一化的对数概率)。

       

        (对于上图博主是通过CHATGPT进行的说明解释,如果感兴趣的同学可以继续深入研究

可以看到,出现惩罚是对所有至少被采样一次的令牌的单次加法贡献,而频率惩罚是与某个特定令牌已被采样次数成比例的贡献。

如果目标只是稍微减少重复采样,合理的惩罚系数值在0.1到1左右。如果目标是强烈抑制重复,可以将系数增加到2,但这可能会显著降低样本质量。负值可以用来增加重复的可能性。

令牌对数概率

当在Chat Completions API和Legacy Completions API中请求logprobs参数时,它会提供每个输出令牌的对数概率,以及在每个令牌位置上最可能的几个令牌及其对数概率。这在某些情况下非常有用,可以评估模型对其输出的置信度,或者检查模型可能给出的替代响应。

示例代码

以下是一个示例代码,展示如何在API调用中使用频率惩罚和出现惩罚参数:

from openai import OpenAI
client = OpenAI()

response = client.chat.completions.create(
  model="gpt-3.5-turbo",
  messages=[
    {"role": "system", "content": "You are a helpful assistant."},
    {"role": "user", "content": "Tell me something interesting about space."}
  ],
  frequency_penalty=0.5,
  presence_penalty=0.5,
  temperature=0.7
)

print(response.choices[0].message.content)

在这个例子中,frequency_penaltypresence_penalty都被设置为0.5,这可以帮助减少响应中重复令牌的可能性。

示例代码:获取令牌的对数概率
response = client.chat.completions.create(
  model="gpt-3.5-turbo",
  messages=[
    {"role": "system", "content": "You are a helpful assistant."},
    {"role": "user", "content": "What are the benefits of exercise?"}
  ],
  logprobs=5  # 请求输出每个令牌的前5个最可能的令牌及其对数概率
)

for choice in response.choices:
    for token, logprob in zip(choice.logprobs['tokens'], choice.logprobs['token_logprobs']):
        print(f"Token: {token}, Log probability: {logprob}")

在这个例子中,logprobs参数被设置为5,这将返回每个位置上前5个最可能的令牌及其对数概率。通过查看这些信息,可以评估模型的输出置信度和可能的替代响应。

6. Completions API Legacy

这是指旧版的文本完成API,可能已经有了新的替代版本,大家感兴趣可以移步官网

Completions API (Legacy

总结

        文本生成模型提供了强大的功能,用于生成高质量的文本输出。通过了解和正确使用消息格式、令牌管理、惩罚机制、确定性输出和JSON模式等功能,可以更有效地利用这些模型来满足不同的应用需求,感谢大家,我们下期再见!

  • 28
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值