使用 Python接入 OpenAI API,token计算和completions其他参数含义
前言
回顾上上篇文章写到如何实现最简单的OpenAI对话请求示例:
from openai import OpenAI
from dotenv import load_dotenv, find_dotenv
_ = load_dotenv(find_dotenv())
client = OpenAI()
response = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Who won the world series in 2020?"},
{"role": "assistant", "content": "The Los Angeles Dodgers won the World Series in 2020."},
{"role": "user", "content": "Where was it played?"}
]
)
print(response) # 打印的是一个对象
print(response.choices[0].message.content) # 打印的是一个具体的回复的内容
今天来探究一下token计算和completions接口其他的参数详细含义
token
根据上面的例子返回的内容为
ChatCompletion(id='chatcmpl-9IcMQtYPGYI0cOQCTENdbvO0M2yFx', choices=[Choice(finish_reason='stop', index=0, logprobs=None, message=ChatCompletionMessage(content='The 2020 World Series was played in Globe Life Field in Arlington, Texas.', role='assistant', function_call=None, tool_calls=None))], created=1714224390, model='gpt-3.5-turbo-0125', object='chat.completion', system_fingerprint='fp_3b956da36b', usage=CompletionUsage(completion_tokens=17, prompt_tokens=53, total_tokens=70))
The 2020 World Series was played in Globe Life Field in Arlington, Texas.
只有接口返回时候才知道输入使用了53个token,输出使用了17个token,看起来一个token表示一个或者多个字符,究竟如何计算参考OpenAI 官方文档:
platform.openai.com/docs/guides…
官方示例:"ChatGPT is great!"
这个句话被拆解成6个token: ["Chat", "G", "PT", " is", " great", "!"]
.
实际的计算要利用到一个第三方包:tiktoken
文档ChatGPT 利用了三个编码器对文本进行了编码:
编码名称 | OpenAI 模型名称 |
---|---|
cl100k_base | gpt-4 , gpt-3.5-turbo , text-embedding-ada-002 , text-embedding-3-small , text-embedding-3-large |
p50k_base | Codex models, text-davinci-002, text-davinci-003 |
r50k_base (or gpt2) | GPT-3 models like davinci |
看起来目前主流的ChatPGT模型就是用 `cl100k_base`编码来获取文本占用的token,接下来用代码实际计算token。
先安装这个包
pip install --upgrade tiktoken
import tiktoken
encoding = tiktoken.get_encoding("cl100k_base")
# 或者
# encoding = tiktoken.encoding_for_model("gpt-3.5-turbo")
def get_token_data(words):
resource_data = encoding.encode(words)
len_data = len(resource_data)
print("%s 编码后内容:%s"%(words, resource_data))
print("%s 编码后token个数:%s"%(words,len_data))
return len_data
words_1 = '请说王子请睡觉'
words_2 = 'tiktoken is great!'
get_token_data(words_1)
get_token_data(words_2)
打印内容:
请说王子请睡觉 编码后内容:[15225, 37687, 29207, 233, 45829, 15225, 84949, 94, 19658, 231]
请说王子请睡觉 编码后token个数:10
tiktoken is great! 编码后内容:[83, 1609, 5963, 374, 2294, 0]
tiktoken is great! 编码后token个数:6
这样是不是更清楚token的消耗计算了呢?
其他参数
参考OpenAI 官方文档:
platform.openai.com/docs/api-re…
一共用20个参数:
messages,model,frequency_penalty,logit_bias,logprobs,top_logprobs,max_tokens,n,presence_penalty,response_format,seed,stop,stream,temperature,top_p,tools,tool_choice,user,function_call,functions
除去必需两个参数messages,model,其他的stream**,**function_call,functions,tool_choice,tools,response_format前面两天了解过不做介绍,其他参数分为两个部分,一部分为控制参数:
-
frequency_penalty(数字或null,默认0):惩罚概率,控制模型重复生成相同文本的倾向。值越高,重复的可能性越小。
-
logit_bias(字典):调整模型输出文本的概率分布。它本质上是一个 映射表,用于 调整特定词语 在生成文本中的出现 可能性。
-
max_tokens:参数用于控制模型生成文本的最大长度。它以令牌(tokens)为单位进行衡量,通常用于控制回复长度和计算资源。
-
n(整数,默认值:1):指示模型应生成多少个不同的文本版本。
-
presence_penalty(数字或者null,默认0):类似于
frequency_penalty
,但会惩罚生成的文本中重复的 n-gram(词序列)。 -
seed(整数):一个随机种子值。使用相同的种子值会始终生成相同的文本序列。
-
stop(字符串数组):一个字符串数组,充当终止条件。如果模型在输出中遇到任何这些字符串,它将停止生成文本。
-
temperature(0到2之间,默认值:1.0):控制生成文本的创造性。值越高,文本越具创意和出人意料,但可能与给定提示的相关性较低。值越低,文本越保守和可预测。
-
top_p(浮点数,0.0-1.0,默认值:1.0):通俗地说,
top_p
参数就像一个筛选器,用于控制 OpenAI 模型生成文本时的"冒险程度",0 表示最保守,1 表示最冒险。 -
user 模型微调相关,用户关联数据相关
另一部分为高级参数(用作调试)
-
logprobs(整数,或者null,默认null):当设置为
true
时,模型会提供每个生成词的概率值 (logprob
)。 -
top_logprobs(整数,或者null,默认null):控制与每个词一起返回的概率数量(对于下一个 N 个词)。例如,
top_logprobs=2
会在每个生成词之后返回下一个两个词的概率。
top_logprobs
和 logprobs
是OpenAI API 新增的参数可以帮助我们理解和调试大模型的输出结果,减轻幻觉问题,提高输出的确定性和可靠性。
其中比较重要的参数有temperature,top_p,在很多第三方工具都有见到这两个参数,现在测试一下
代码如下:
from openai import OpenAI
from dotenv import load_dotenv, find_dotenv
_ = load_dotenv(find_dotenv())
client = OpenAI()
response = client.chat.completions.create(
model="gpt-3.5-turbo",
temperature=0,
top_p=1,
messages=[
{"role": "system", "content": "你是一个人工智能助手,你帮助用户回答问题。"},
{"role": "user", "content": "你是谁"},
]
)
print(response.choices[0].message.content)
# 统一询问大多都是统一回复
# 我是一个人工智能助手,可以帮助您回答问题和提供信息。有什么可以帮到您的吗?
# 我是一个人工智能助手,可以帮助您回答问题和提供信息。有什么可以帮到您的吗?
以上代码可以是文本回复最没有创造性,接下来做下调整
temperature=2,
top_p=0,
我是一个人工智能助手,设计来帮助您回答问题和提供信息。怎么可以帮到您呢?
我是一个人工智能助手,可以提供帮助回答你的问题。有什么可以帮到你的吗?
您好!我是这个平台提供的信息辅助工具。有任何问题不妨问我,我会尽全力帮助您回答问题。
我是一个人工智能助手,可以帮助您回答问题和提供信息。有什么可以帮助您的吗
所以结论就是 :如果需要回答编程,数学,物理问题严谨的对话就需要把temperature数值设置高一些,如果是艺术,创意内容对话可以把temperature设置高一点。
最后
如果觉得内容不错,欢迎点个关注,分享和在看,你的支持是我更新的动力。
转载自:https://juejin.cn/post/7362119848661811263