GPT3.5 改用 GPT4 价格翻了30倍 如何破局? GPT 对话成本推演

场景介绍

假设你搭建了一个平台,提供 ChatGPT 3.5 的聊天服务。目前已经有一批用户的使用数据,想要测算一下如果更换 GPT 4.0 服务需要多少成本?

方案阐述

如果是全切,最简单粗暴的方案就是根据提供 ChatGPT 3.5 消费的金额乘以一个倍数,这个倍数是 GPT 4 的单格/ChatGPT 3.5 的单价,不过由于输入价和输出价有差异,所以会有一定误差,但不影响全量切换的大致判断。

如果要求更精确一些,就需要根据每一次问答的输入 Token 数和输出 Token 数,分别求和,计算有多少 k Tokens,然后算一个占比,看看各自的消费占比,分别乘以输入和输出的价格倍数。
image.png
以上是直接接官方的情况,但是更多时候,可能是通过第三方服务,第三方的价格不是根据官方定价,会有出入,需要结合第三方价格具体分析。

由于 GPT 4.0 相对高昂的价格,一般需要做限制,比如:限制访问频率、限制整体用量等。
举个例子,限制每分钟不超过 3 次,每 3 小时不超过 50 次;每天 10 次,每月 100次、200 次等。
这时候就需要精确一些的计算,通过指定的算法,测算切换 GPT 4.0 的成本是多少。

本次用于示例计算的单价为:

ModelInputOutput
gpt-4$0.03 / 1K tokens$0.06 / 1K tokens
gpt-3.5-turbo-1106$0.0010 / 1K tokens$0.0020 / 1K tokens

本次拿两个限制做案例开展:

  • 案例1:限制每天 10 次
  • 案例2:限制每分钟不超过 3 次,每 3 小时不超过 50 次

创建测试数据

本次测试借助数据库 MySQL 来实现这些复杂的算法。
首先在本地创建数据库testdb

create database if not exists testdb;

创建表chat_logs,并给四个字段都加上索引,提高查询效率:

create table if not exists testdb.chat_logs(user_id					bigint	comment '用户ID',request_time		bigint	comment '请求时间',prompt_tokens	bigint	comment '提示词的 Tokens,input Tokens',output_tokens	bigint	comment '回答的 Tokens,output Tokens',index userid_idx(user_id),index reqtime_idx(request_time),index prompt_idx(prompt_tokens),index output_idx(output_tokens)
) comment 'GPT对话记录';

插入数据,本次demo 数据量 100 条。

由于数据较长,不便展示,另外上传到资源,可前往免费下载:GPT 对话成本推演-数据demo

插入数据方法

  • 方法1:复制代码,接着上面步骤粘贴代码,回车即可执行
  • 方法2:直接执行文件,假设文件路径为:D:\insert_into_table.sql,则执行命令如下:
SOURCE D:\insert_into_table.sql;

案例1:限制每天 10 次(总量限制)

该逻辑实现比较简单,按天聚合,然后排序计算不超过 10 有多少 Tokens,大于 10 次又有多少 Tokens,然后再分别乘以单价,计算得出限制后的成本。

使用 SQL 实现

查看每天限制 10 次 GPT 4.0,超过部分按 GPT 3.5 计算,需要先将请求的数据按天进行排序,然后计算不超过 10 的部分和大于 10 的分别的 Tokens 分别是多少。

格式化时间,将request_time转为request_date

-- 格式化时间
select user_id,from_unixtime(request_time,'%Y-%m-%d') request_date,request_time,prompt_tokens,output_tokens
from testdb.chat_logs

按天编号

with chat_logs_format as(-- 格式化时间select user_id,from_unixtime(request_time,'%Y-%m-%d') request_date,request_time,prompt_tokens,output_tokensfrom testdb.chat_logs
)
-- 对话排序
select *,row_number()over(partition by user_id,request_date order by request_time) req_sort
from chat_logs_format

分类求 Tokens 数,编号req_sort不超过 10 次的分为GPT4,其他分为GPT3.5

with chat_logs_format as(-- 格式化时间select user_id,from_unixtime(request_time,'%Y-%m-%d') request_date,request_time,prompt_tokens,output_tokensfrom testdb.chat_logs
)
,chat_sort as(-- 对话排序select user_id,request_date,prompt_tokens,output_tokens,row_number()over(partition by user_id,request_date order by request_time) req_sortfrom chat_logs_format
)
-- 分类求 Tokens 数
select if(req_sort<=10,'GPT4','GPT3.5') mark_model,sum(prompt_tokens)/1000 k_prompt_tokens,sum(output_tokens)/1000 k_output_tokens
from chat_sort
group by mark_model

image.png

根据 Tokens 计算成本。

with chat_logs_format as(-- 格式化时间select user_id,from_unixtime(request_time,'%Y-%m-%d') request_date,request_time,prompt_tokens,output_tokensfrom testdb.chat_logs
)
,chat_sort as(-- 对话排序select user_id,request_date,prompt_tokens,output_tokens,row_number()over(partition by user_id,request_date order by request_time) req_sortfrom chat_logs_format
)
,k_tokens as(-- 分类求 Tokens 数select if(req_sort<=10,'GPT4','GPT3.5') mark_model,sum(prompt_tokens)/1000 k_input_tokens,sum(output_tokens)/1000 k_output_tokensfrom chat_sortgroup by mark_model
)
-- gpt-4:input 0.03,output 0.06
-- gpt-3:input 0.0010,output 0.0020
select sum(0.0010*k_input_tokens+0.0020*k_output_tokens) "调整前成本",sum(if(mark_model='GPT4',0.03,0.0010)*k_input_tokens+if(mark_model='GPT4',0.06,0.0020)*k_output_tokens) "调整后成本"
from k_tokens

image.png
调整前后成本相差还是挺大的,调整后成本是调整前的 12.5 倍。实际情况可以拿更多的数据,比如说一周、一个月,进行测算。

使用 Python 实现

使用 Python 实现比 SQL 实现多加了一步:读取数据,并转化为数组。之后的逻辑也是大同小异:时间格式化->记录排序、编号->分类求 Token->计算成本。

读取数据表,使用sql读取数据库数据,并使用 Pandas 转为 DataFrame。

import pandas as pd
from sqlalchemy import create_engine
def get_datas(sql):# 连接数据库# engine = create_engine("mysql+pymysql://用户名:密码@主机地址:端口号/数据库名")connect_info = 'mysql+pymysql://{}:{}@{}:{}/{}?charset=utf8'\.format("root", "123123", "127.1.1.0", "3306","testdb")engine = create_engine(connect_info)# 执行SQL语句prox = engine.execute(sql)df = pd.DataFrame(list(prox),columns=prox.keys())return df
sql = 'select * from testdb.chat_logs'
df = get_datas(sql)

image.png

将时间戳格式化

#将 request_time 转为日期格式
df['request_date'] = pd.to_datetime(df.request_time,unit='s').dt.date

排序编号

df['req_sort'] = df.groupby(['user_id','request_date'])['request_time'].rank(ascending=True,method='first')

分类,编号req_sort不超过 10 次的分为GPT4,其他分为GPT3.5

df['mark_model'] = df.req_sort.apply(lambda x:'GPT4' if x<=10 else 'GPT3.5')

求和,并转化为 k Token 单位

df_1 = df.groupby(['mark_model'])['prompt_tokens','output_tokens'].sum().reset_index()
df_1['k_input_tokens'] = df_1.prompt_tokens/1000
df_1['k_output_tokens'] = df_1.output_tokens/1000
df_1[['mark_model','k_input_tokens','k_output_tokens']]

image.png
计算成本

-- gpt-4input 0.03,output 0.06
-- gpt-3input 0.0010,output 0.0020
input_price_4 = 0.03
input_price_3 = 0.0010
output_price_4 = 0.06
output_price_3 = 0.0020
df_1['调整前成本'] = df_1[['mark_model','k_input_tokens','k_output_tokens']].apply(lambda x:x[1]*input_price_3+x[2]*output_price_3,axis=1)
df_1['调整后成本'] = df_1[['mark_model','k_input_tokens','k_output_tokens']].apply(lambda x:x[1]*input_price_4+x[2]*output_price_4 if x[0]=='GPT4' else x[1]*input_price_3+x[2]*output_price_3,axis=1)
df_1[['调整前成本','调整后成本']].sum()

image.png

案例2:限制每分钟不超过 3 次,每 3 小时不超过 50 次(频率限制)

该逻辑实现比较复杂一些,本质上还是先切分,然后排序再进行统计 Tokens,再计算成本。
不同点在于,前面是按天切分,有天然的便捷方式,直接格式化即可,每天看做一个桶,分桶计算,而 1 分钟和 3 小时需要自行构建相关的计算桶,不能一步到位。

过程算法其实也有多种:
比如说按自然分钟计算,每分钟为一个单位;按自然小时计算,02、35、68、911、1214、1517、1820、2123。
比如说拿一个初始的值做差值计算,然后在这个基础上分割,这个会受到初始值的影响,不过如果把初始值设置为某一天的零时零点零分,可以兼容上面一个算法,本次拿第二种来展开。

PS:实现第一种的方法:1分钟分桶:from_unixtime(request_time,’%Y-%m-%d %H:%i’);3小时分桶(日期+小时):from_unixtime(request_time,’%Y-%m-%d’)、floor(hour(from_unixtime(request_time)/3)

使用 SQL 实现

取最小时间,使用窗口函数来取值。如果是想设置固定的某个值,可以直接新增一个列。

-- 取最小的请求时间,
select user_id,request_time,prompt_tokens,output_tokens,min(request_time)over(partition by user_id) min_time
from chat_logs

求时间差值,使用request_time减去最小值。

-- 取时间差值
select user_id,request_time,prompt_tokens,output_tokens,request_time-min(request_time)over(partition by user_id) minute_diff
from chat_logs

分桶,1 分钟则除以 60 秒,3 小时则除以 60603 秒,然后使用ceil()函数向上取值。

-- 分桶
select user_id,request_time,prompt_tokens,output_tokens,ceil((request_time-min(request_time)over(partition by user_id))/60) minute_bucket,ceil((request_time-min(request_time)over(partition by user_id))/60/60/3) hour_bucket
from chat_logs

排序,根据用户和分桶字段进行分组,然后对request_time升序排序

with 
-- 分桶
cut_bucket as(select user_id,request_time,prompt_tokens,output_tokens,ceil((request_time-min(request_time)over(partition by user_id))/60) minute_bucket,ceil((request_time-min(request_time)over(partition by user_id))/60/60/3) hour_bucketfrom chat_logs
)
-- 排序
select user_id,request_time,prompt_tokens,output_tokens,minute_bucket,hour_bucket,row_number()over(partition by user_id,minute_bucket order by request_time) minute_bucket_sort,row_number()over(partition by user_id,hour_bucket order by request_time) hour_bucket_sort
from cut_bucket

分类求和,将minute_bucket_sort<=3 and hour_bucket_sort<=50分为GPT4,其他的分为GPT3.5,然后聚合求 Tokens。

with
-- 分桶
cut_bucket as(select user_id,request_time,prompt_tokens,output_tokens,ceil((request_time-min(request_time)over(partition by user_id))/60) minute_bucket,ceil((request_time-min(request_time)over(partition by user_id))/60/60/3) hour_bucketfrom chat_logs
)
-- 排序
,bucket_sort as(select user_id,request_time,prompt_tokens,output_tokens,minute_bucket,hour_bucket,row_number()over(partition by user_id,minute_bucket order by request_time) minute_bucket_sort,row_number()over(partition by user_id,hour_bucket order by request_time) hour_bucket_sortfrom cut_bucket
)
-- 分类
,mark_models as(select user_id,request_time,prompt_tokens,output_tokens,minute_bucket,hour_bucket,minute_bucket_sort,hour_bucket_sort,(case when minute_bucket_sort<=3 and hour_bucket_sort<=50 then 'GPT4' else 'GPT3.5' end) mark_modelfrom bucket_sort
)
-- 计算分钟<=3且3小时<=50
select mark_model,sum(prompt_tokens)/1000 k_input_tokens,sum(output_tokens)/1000 k_output_tokens
from mark_models
group by mark_model

image.png
然后再计算成本,完事!
直接计算minute_bucket_sort<=3hour_bucket_sort<=50就可以了?
不不不!这里有坑,先不聚合,查看明细数据看看,如下图第一个红框,它不符合 1 分钟 3 次上限的逻辑,所以被剔除了,标记为 GPT3.5。而第二个框,它不符合 3 小时 50 次上限的逻辑,所以也被剔除了。
不知道你是否意识到了问题,通过肉眼看,第二个框的 3 条记录应该是要被统计到 3 小时 50 次上限的逻辑的,因为前面因为 1 分钟的限制多剔除了 3 条记录。
所以在 3 小时的桶里面排序的时候,需要建立 1 分钟的桶的基础之上,先保证每一条记录都符合 1 分钟的逻辑,再针对这些记录拿 3 小时的逻辑加以限制。
image.png
修改 3 小时的分桶排序逻辑,要建立在 1 分钟的基础上才开始排序。
新增一个步骤,对 1 分钟的桶不超过 3 次的部分和大于 3 次的部分进行分类。然后对 3 小时的分桶排序则建在 1 分钟不超过 3 次的类别上。
代码实现上,将 1 分钟不超过 3 次和大于 3 次的分类(mark_target_record)加入 3 小时的分桶排序的分组(partition by)中,然后限制只取mark_target_record=1部分作为GPT4,参考修改逻辑如下:

with 
-- 分桶
cut_bucket as(select user_id,request_time,prompt_tokens,output_tokens,ceil((request_time-min(request_time)over(partition by user_id))/60) minute_bucket,ceil((request_time-min(request_time)over(partition by user_id))/60/60/3) hour_bucketfrom chat_logs
)
-- 排序
,bucket_sort as(select user_id,request_time,prompt_tokens,output_tokens,minute_bucket,hour_bucket,row_number()over(partition by user_id,minute_bucket order by request_time) minute_bucket_sort,row_number()over(partition by user_id,hour_bucket order by request_time) hour_bucket_sortfrom cut_bucket
)
-- 对分钟的排序数据进行分类
,mark_chatlog as(select user_id,request_time,prompt_tokens,output_tokens,minute_bucket,hour_bucket,minute_bucket_sort,hour_bucket_sort,(case when minute_bucket_sort<=3 then 1 else 0 end) mark_target_recordfrom bucket_sort
)
-- 分钟 <= 3 且 3小时 <= 50 标记为 GPT4
,mark_models as(select user_id,request_time,prompt_tokens,output_tokens,minute_bucket,hour_bucket,minute_bucket_sort,hour_bucket_sort,mark_target_record,(case when mark_target_record=1 and row_number() over(partition by user_id,hour_bucket,mark_target_record order by request_time)<=50 then 'GPT4' else 'GPT3.5' end) mark_modelfrom mark_chatlog
)
select *
from mark_models
order by user_id,request_time

修改为叠加的逻辑之后,效果如下:
image.png

计算 Token 数,根据分好的模型聚合求和即可。

with 
-- 分桶
cut_bucket as(select user_id,request_time,prompt_tokens,output_tokens,ceil((request_time-min(request_time)over(partition by user_id))/60) minute_bucket,ceil((request_time-min(request_time)over(partition by user_id))/60/60/3) hour_bucketfrom chat_logs
)
-- 排序
,bucket_sort as(select user_id,request_time,prompt_tokens,output_tokens,minute_bucket,hour_bucket,row_number()over(partition by user_id,minute_bucket order by request_time) minute_bucket_sort,row_number()over(partition by user_id,hour_bucket order by request_time) hour_bucket_sortfrom cut_bucket
)
-- 对分钟的排序数据进行分类
,mark_chatlog as(select user_id,request_time,prompt_tokens,output_tokens,minute_bucket,hour_bucket,minute_bucket_sort,hour_bucket_sort,(case when minute_bucket_sort<=3 then 1 else 0 end) mark_target_recordfrom bucket_sort
)
-- 分钟 <= 3 且 3小时 <= 50 标记为 GPT4
,mark_models as(select user_id,request_time,prompt_tokens,output_tokens,minute_bucket,hour_bucket,minute_bucket_sort,hour_bucket_sort,mark_target_record,(case when mark_target_record=1 and row_number() over(partition by user_id,hour_bucket,mark_target_record order by request_time)<=50 then 'GPT4' else 'GPT3.5' end) mark_modelfrom mark_chatlog
)
-- 聚合求 Tokens
select mark_model,sum(prompt_tokens)/1000 k_input_tokens,sum(output_tokens)/1000 k_output_tokens
from mark_models
group by mark_model

统计结果如下:
image.png
计算调整前后成本:

with 
-- 分桶
cut_bucket as(select user_id,request_time,prompt_tokens,output_tokens,ceil((request_time-min(request_time)over(partition by user_id))/60) minute_bucket,ceil((request_time-min(request_time)over(partition by user_id))/60/60/3) hour_bucketfrom chat_logs
)
-- 排序
,bucket_sort as(select user_id,request_time,prompt_tokens,output_tokens,minute_bucket,hour_bucket,row_number()over(partition by user_id,minute_bucket order by request_time) minute_bucket_sort,row_number()over(partition by user_id,hour_bucket order by request_time) hour_bucket_sortfrom cut_bucket
)
-- 对分钟的排序数据进行分类
,mark_chatlog as(select user_id,request_time,prompt_tokens,output_tokens,minute_bucket,hour_bucket,minute_bucket_sort,hour_bucket_sort,(case when minute_bucket_sort<=3 then 1 else 0 end) mark_target_recordfrom bucket_sort
)
-- 分钟 <= 3 且 3小时 <= 50 标记为 GPT4
,mark_models as(select user_id,request_time,prompt_tokens,output_tokens,minute_bucket,hour_bucket,minute_bucket_sort,hour_bucket_sort,mark_target_record,(case when mark_target_record=1 and row_number() over(partition by user_id,hour_bucket,mark_target_record order by request_time)<=50 then 'GPT4' else 'GPT3.5' end) mark_modelfrom mark_chatlog
)
-- 聚合求 Tokens
,k_tokens as(select mark_model,sum(prompt_tokens)/1000 k_input_tokens,sum(output_tokens)/1000 k_output_tokensfrom mark_modelsgroup by mark_model
)
-- gpt-4:input 0.03,output 0.06
-- gpt-3:input 0.0010,output 0.0020
select sum(0.0010*k_input_tokens+0.0020*k_output_tokens) "调整前成本",sum(if(mark_model='GPT4',0.03,0.0010)*k_input_tokens+if(mark_model='GPT4',0.06,0.0020)*k_output_tokens) "调整后成本"
from k_tokens

统计结果如下:
image.png
调整前后成本相差 27 倍。

使用 Python 实现

同样,使用 Python 实现比 SQL 实现多加了一步:读取数据,并转化为数组。之后的逻辑也是大同小异:求最小时间->求时间差值->分桶->1分钟排序和分类->3 小时排序和最终分类->分类求 Token->计算成本。

读取数据表,使用sql读取数据库数据,并使用 Pandas 转为 DataFrame。

import pandas as pd
from sqlalchemy import create_engine
def get_datas(sql):# 连接数据库# engine = create_engine("mysql+pymysql://用户名:密码@主机地址:端口号/数据库名")connect_info = 'mysql+pymysql://{}:{}@{}:{}/{}?charset=utf8'\.format("root", "123123", "127.1.1.0", "3306","testdb")engine = create_engine(connect_info)# 执行SQL语句prox = engine.execute(sql)df = pd.DataFrame(list(prox),columns=prox.keys())return df
sql = 'select * from testdb.chat_logs'
df = get_datas(sql)

取最小请求时间,并合并到原来的数据框。

#取每个key的最小请求时间
df_mintime = df.groupby(['user_id'])['request_time'].min().reset_index()
#合并到原DataFrame
df = df.merge(df_mintime,on='user_id',how='left',suffixes=['','_min'])

将请求时间和最小请求时间求差值。

#将请求时间和最小请求时间求差值;  
df['diff_time'] = df.request_time-df.request_time_min

分桶,保持单位一致,即 1 分钟转为 60 秒,3 小时转为 60603 秒。
使用math.ceil()向上取整。

#根据差值进行分桶,两层:1 分钟 和 3 小时,都向上取整数; 
import math
df['minute_bucket'] = df.diff_time.apply(lambda x:math.ceil(x/60))
df['hour_bucket'] = df.diff_time.apply(lambda x:math.ceil(x/60/60/3))

对 1 分钟的桶排序和分类:不超过 3 次的为一类用 1 标识,其他的为另外一类,用 0 表示。

#对 1 分钟的桶和 user_id 分组,按请求时间排序; 
df['minute_bucket_sort'] = df.groupby(['user_id','minute_bucket'])['request_time'].rank(ascending=True,method='first')
#对 1 分钟不超过 3 次和大于 3 次的部分进行分组
df['mark_target_record'] = df.minute_bucket_sort.apply(lambda x:1 if x<=3 else 0)

3 小时的桶排序,根据用户、分桶和 1 分钟的分类进行分组,按请求时间排序。

#3小时的桶排序
df['hour_bucket_sort'] = df.groupby(['user_id','hour_bucket','mark_target_record'])['request_time'].rank(ascending=True,method='first')

最终分类:minute_bucket_sort<=3,且hour_bucket_sort<=50为 GPT4,其他为 GPT3.5。

#最终分类
df['mark_model']  = df[['minute_bucket_sort','hour_bucket_sort']].apply(lambda x:'GPT4' if x[0]<=3 and x[1]<=50 else 'GPT3.5',axis=1)

分类聚合求 Tokens

#按请求日期和模型聚合,统计Tokens 和价格
df_1 = df.groupby(['mark_model'])['prompt_tokens','output_tokens'].sum().reset_index()
df_1['k_input_tokens'] = df_1.prompt_tokens/1000
df_1['k_output_tokens'] = df_1.output_tokens/1000
df_1[['mark_model','k_input_tokens','k_output_tokens']]

结果如下,再除以 1000 就是上面 SQL 的结果。
image.png

求最终调整前后成本

#求调整前后成本
#gpt-4:input 0.03,output 0.06
#gpt-3:input 0.0010,output 0.0020
input_price_4 = 0.03
input_price_3 = 0.0010
output_price_4 = 0.06
output_price_3 = 0.0020
df_1['调整前成本'] = df_1[['mark_model','k_input_tokens','k_output_tokens']].apply(lambda x:x[1]*input_price_3+x[2]*output_price_3,axis=1)
df_1['调整后成本'] = df_1[['mark_model','k_input_tokens','k_output_tokens']].apply(lambda x:x[1]*input_price_4+x[2]*output_price_4 if x[0]=='GPT4' else x[1]*input_price_3+x[2]*output_price_3,axis=1)
df_1[['调整前成本','调整后成本']].sum()

image.png

Python 完整代码:

import pandas as pd
from sqlalchemy import create_engine#连接数据库读取数据,并转为 DataFrame
def get_datas(sql):# 连接数据库# engine = create_engine("mysql+pymysql://用户名:密码@主机地址:端口号/数据库名")connect_info = 'mysql+pymysql://{}:{}@{}:{}/{}?charset=utf8'\.format("root", "123123", "127.1.1.0", "3306","testdb")engine = create_engine(connect_info)# 执行SQL语句prox = engine.execute(sql)data = list()for result in prox:cur = dict()#     print(result)for k, v in result._mapping.items(): # 不用 _mapping 也可以,后续会被弃用而已cur[k] = vdata.append(cur)df = pd.DataFrame(data)return df
sql = 'select * from testdb.chat_logs'
df = get_datas(sql)#取每个key的最小请求时间
df_mintime = df.groupby(['user_id'])['request_time'].min().reset_index()
#合并到原DataFrame
df = df.merge(df_mintime,on='user_id',how='left',suffixes=['','_min'])#将请求时间和最小请求时间求差值;  
df['diff_time'] = df.request_time-df.request_time_min#根据差值进行分桶,两层:1 分钟 和 3 小时,都向上取整数; 
import math
df['minute_bucket'] = df.diff_time.apply(lambda x:math.ceil(x/60))
df['hour_bucket'] = df.diff_time.apply(lambda x:math.ceil(x/60/60/3))#对 1 分钟的桶和 user_id 分组,按请求时间排序; 
df['minute_bucket_sort'] = df.groupby(['user_id','minute_bucket'])['request_time'].rank(ascending=True,method='first')
#对 1 分钟不超过 3 次和大于 3 次的部分进行分组
df['mark_target_record'] = df.minute_bucket_sort.apply(lambda x:1 if x<=3 else 0)
#3小时的桶排序
df['hour_bucket_sort'] = df.groupby(['user_id','hour_bucket','mark_target_record'])['request_time'].rank(ascending=True,method='first')
#最终分类
df['mark_model']  = df[['minute_bucket_sort','hour_bucket_sort']].apply(lambda x:'GPT4' if x[0]<=3 and x[1]<=50 else 'GPT3.5',axis=1)#按请求日期和模型聚合,统计Tokens 和价格
df_1 = df.groupby(['mark_model'])['prompt_tokens','output_tokens'].sum().reset_index()
df_1['k_input_tokens'] = df_1.prompt_tokens/1000
df_1['k_output_tokens'] = df_1.output_tokens/1000
df_1[['mark_model','k_input_tokens','k_output_tokens']]#求调整前后成本
#gpt-4:input 0.03,output 0.06
#gpt-3:input 0.0010,output 0.0020
input_price_4 = 0.03
input_price_3 = 0.0010
output_price_4 = 0.06
output_price_3 = 0.0020
df_1['调整前成本'] = df_1[['mark_model','k_input_tokens','k_output_tokens']].apply(lambda x:x[1]*input_price_3+x[2]*output_price_3,axis=1)
df_1['调整后成本'] = df_1[['mark_model','k_input_tokens','k_output_tokens']].apply(lambda x:x[1]*input_price_4+x[2]*output_price_4 if x[0]=='GPT4' else x[1]*input_price_3+x[2]*output_price_3,axis=1)
df_1[['调整前成本','调整后成本']].sum()

小结

从上面的两个案例来看,成本都是以十倍上涨,不过加了限制,最高也不会超过官方标价的倍数(30 倍)。
但无论如何,成本较之前都是很高的。
如果想要保证用户体验好、可以多用GPT4、成本又不高,那是很难的。
当然,解决办法还是有的:

  • 用户层面:可以搞会员制,要求不高的,用用GPT3.5,要求高的多掏钱买个会员。
  • 供应商层面:降低成本,这个要拼渠道了。

没有完美的,只有合适的,看需求搞事情~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/600507.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据结构:STL:queue stack

目录 1.queue的头文件 2.queue的定义 3.queue的常用函数 3.1 push() 3.2 pop() 3.3 size() 3.4 empty() 3.5 front() 3.6 back() 4.stack的头文件 5.stack的定义 6.stack的常用函数 6.1 push() 6.2 top() 6.3 pop() 6.4 size() 6.6 empty() STLf封装的queue也是…

集合基础知识点

集合基础 1. 集合的由来 当 Java 程序中需要存放数据的时候&#xff0c;通常会定义变量来实现数据的存储&#xff0c;但是&#xff0c;当需要存储大量数据的时候该怎么办呢&#xff1f;这时首先想到的是数组&#xff0c;但是&#xff01;数组只能存放同一类型的数据&#xff…

16 Linux 内核定时器

一、Linux 时间管理和内核定时器简介 1. 内核时间管理简介 Linux 内核中有大量的函数需要时间管理&#xff0c;比如周期性的调度程序、延时程序、定时器等。 硬件定时器提供时钟源&#xff0c;时钟源的频率可以设置&#xff0c;设置好以后就周期性的产生定时中断&#xff0c;系…

连续学习(Continual Learning)或者增量学习的场景中,multiband和replay分别是什么?起到什么作用

multiband和replay是两种不同的训练策略&#xff0c;通常用在处理连续学习或者增量学习的场景中。这些策略旨在解决新知识学习导致旧知识遗忘的问题&#xff0c;即所谓的灾难性遗忘。以下是multiband和replay两种策略的基本区别&#xff1a; Multiband: 定义: multiband通常是…

C语言编译器(C语言编程软件)完全攻略(第十六部分:Dev C++下载地址和安装教程(图解))

介绍常用C语言编译器的安装、配置和使用。 十六、Dev C下载地址和安装教程&#xff08;图解&#xff09; Dev C是一款免费开源的 C/C IDE&#xff0c;内嵌GCC编译器&#xff08;GCC 编译器的 Windows 移植版&#xff09;&#xff0c;是 NOI、NOIP 等比赛的指定工具。Dev C 的…

Spring中的数据校验

文章目录 引言摘要正文基于 ValidationUtils的简单校验基于自定义 Validator的校验Spring内置校验 LocalValidatorFactoryBeanHibernateValidator校验使用HibernateValidator自定义校验规则 总结 引言 我们在日常的软件开发过程中&#xff0c;尤其是WEB开发过程中&#xff0c;…

读算法霸权笔记12_数据科学

1. 公平与公正 1.1. 公平大多数时候只是副产品 1.2. 由贪婪或偏见导致的不公正一直发生在我们身边 1.2.1. 如果承认法律面前人人平等&#xff0c;或者作为选民的大众应该被平等对待&#xff0c;我们就不能允许模型把我们分为不同的群体进行区别对待 1.3. 对于数学模型来说&…

YOLOv5:指定类别进行评估验证

YOLOv5&#xff1a;指定类别进行评估验证 前言前提条件相关介绍实验环境YOLOv5&#xff1a;指定类别进行评估验证代码实现进行验证没有指定的结果指定类别的结果 前言 由于本人水平有限&#xff0c;难免出现错漏&#xff0c;敬请批评改正。更多精彩内容&#xff0c;可点击进入P…

STM32学习笔记二十:WS2812制作像素游戏屏-飞行射击游戏(10)探索游戏平衡

游戏平衡很重要&#xff0c;然而&#xff0c;却往往得不到开发者的重视。或者&#xff0c;没有花时间仔细去做调整。 做过游戏开发的&#xff0c;都听说过一个词叫“数值爆炸”&#xff0c;实际上就是平衡没做好。 怎么样才能算是平衡呢&#xff1f; 玩家投入游戏的有两个&a…

农业银行RPA实践 3大典型案例分析

零接触开放金融服务在疫情之下被越来越多的银行和客户所认同&#xff0c;引起了更广泛的持续关注&#xff0c;各家银行纷纷开展产品服务创新&#xff0c;加速渠道迁移&#xff0c;同时通过远程办公、构建金融生态等方式积极推进零接触开放金融体系建设。 随着商业银行科技力量的…

Ansible的安装及简单使用

## Ansible的安装及简单使用 ## 一.Ubuntu安装Ansible sudo apt update sudo apt install ansible #使用以下命令检查安装是否成功&#xff1a; ansible --version二.配置Ansible #进入配置文件目录 cd /etc/ansible/ ls#文件含义 ansible.cfg #ansible配置文件,默认基本不用…

scratch绘制小正方形 2023年12月中国电子学会图形化编程 少儿编程 scratch编程等级考试四级真题和答案解析

目录 scratch绘制小正方形 一、题目要求 1、准备工作 2、功能实现 二、案例分析

紫光展锐5G扬帆出海 | 欧洲积极拥抱更多5G选择

和我国一样&#xff0c;欧洲不少国家也在2019年进入5G商用元年&#xff1a;英国在2019年5月推出了5G商用服务&#xff0c;该国最大的移动运营商EE(Everything Everywhere)最先商用5G&#xff1b;德国在2019年年中推出5G商用服务&#xff0c;德国电信、沃达丰和 Telefonica是首批…

Hive实战:分科汇总求月考平均分

文章目录 一、实战概述二、提出任务三、完成任务&#xff08;一&#xff09;准备数据1、在虚拟机上创建文本文件2、上传文件到HDFS指定目录 &#xff08;二&#xff09;实现步骤1、启动Hive Metastore服务2、启动Hive客户端3、创建分区的学生成绩表4、按分区加载数据5、查看分区…

nginx rewrite重写URL地址, laravel路由404问题

前言 在开发项目时&#xff0c;我面临一个需求&#xff1a;区分移动端和桌面端访问路径。移动端访问应在路径前加上/m/&#xff0c;而桌面端则不需要。例如&#xff1a; 移动端: 域名/m/路由地址桌面端: 域名/路由地址 这种设计在路由规则上带来了一定的重复&#xff0c;因为…

[C#]使用OpenCvSharp实现二维码图像增强超分辨率

【官方框架地址】 github.com/shimat/opencvsharp 【算法介绍】 借助于opencv自带sr.prototxt和sr.caffemodel实现对二维码图像增强 【效果展示】 【实现部分代码】 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin…

【机器学习】循环神经网络(一)

一、网络结构 RNN 处理输入序列时的信息流。 粗体箭头为各时间点信息流的活跃路径&#xff0c;虚线箭头显示当时不活动的连接。 一个简单RNN例子 RNN 不是一类网络&#xff0c;而是适用于不同问题的拓扑结构的集合。循环网络的一个有趣的方面是&#xff0c;有了足够的层和节点&…

export命令详解

export命令详解 大家好&#xff0c;我是免费搭建查券返利机器人赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;今天&#xff0c;让我们一同深入了解 Linux 和 Unix 系统中的一个强大命令——export&#xff0c;并…

PC+Wap仿土巴兔装修报价器源码 PHP源码

核心功能&#xff1a; 业主自助预算计算&#xff1a;通过简洁的界面&#xff0c;业主可以输入装修需求&#xff0c;系统自动进行预算计算信息自动收集&#xff1a;系统自动收集业主的基本信息&#xff0c;如姓名、联系方式、房屋面积等一键发送报价&#xff1a;业主完成预算计…

GnuTLS recv error (-110): The TLS connection was non-properly terminated.

bug 解决方案&#xff1a;参考 GnuTLS recv error (-110): The TLS connection was non-properly terminated. 解决方案&#xff1a; apt-get install gnutls-bin git config --global http.sslVerify false git config --global http.postBuffer 1048576000参考