首页 > 编程语言 >【开源免费】ChatGPT-Java版SDK重磅更新至1.0.10版,支持Tokens计算,快来一键接入。

【开源免费】ChatGPT-Java版SDK重磅更新至1.0.10版,支持Tokens计算,快来一键接入。

时间:2023-04-07 18:33:07浏览次数:58  
标签:tokens 10 Java log messages Tokens info chatgpt com

简介

ChatGPT Java版SDK开源地址:https://github.com/Grt1228/chatgpt-java ,目前收获将近1000个star。

有bug欢迎朋友们指出,互相学习,所有咨询全部免费。

最新版:1.0.10

<dependency>
    <groupId>com.unfbx</groupId>
    <artifactId>chatgpt-java</artifactId>
    <version>1.0.10</version>
</dependency>

整合web示例,支持流式返回:

开发思路可以参考:https://github.com/Grt1228/chatgpt-steam-output

流式输出实现方式 小程序 安卓 ios H5
SSE参考:OpenAISSEEventSourceListener 不支持 支持 支持 支持
WebSocket参考:OpenAIWebSocketEventSourceListener 支持 支持 支持 支持

更新日志


最新版支持tokens计算

tokens计算说明

openai 的tokens计算规则适合模型先关的,不同的模型计算方法是不一样的。大致的表格如下:

关于流式返回

流式返回的数据,返回行数-2=返回tokens

[DONE]这一行不参与tokens计算,没有content属性的不参与token计算。
所以tokens数量是4,["Ser","end","ip","ity"],总返回行数6 - 无效行数2 = 4个tokens


[OkHttp 省略 INFO com.unfbx.chatgpt.*****istener - OpenAI建立sse连接...
[OkHttp 省略 INFO com.unfbx.chatgpt.*****istener - OpenAI返回数据:{"choices":[{"delta":{"role":"assistant"},"index":0,"finish_reason":null}]}
[OkHttp 省略 INFO com.unfbx.chatgpt.*****istener - OpenAI返回数据:{"choices":[{"delta":{"content":"Ser"},"index":0,"finish_reason":null}]}
[OkHttp 省略 INFO com.unfbx.chatgpt.*****istener - OpenAI返回数据:{"choices":[{"delta":{"content":"end"},"index":0,"finish_reason":null}]}
[OkHttp 省略 INFO com.unfbx.chatgpt.*****istener - OpenAI返回数据:{"choices":[{"delta":{"content":"ip"},"index":0,"finish_reason":null}]}
[OkHttp 省略 INFO com.unfbx.chatgpt.*****istener - OpenAI返回数据:{"choices":[{"delta":{"content":"ity"},"index":0,"finish_reason":null}]}
[OkHttp 省略 INFO com.unfbx.chatgpt.*****istener - OpenAI返回数据:{"choices":[{"delta":{},"index":0,"finish_reason":"stop"}]}
[OkHttp 省略 INFO com.unfbx.chatgpt.*****istener - OpenAI返回数据:[DONE]
[OkHttp 省略 INFO com.unfbx.chatgpt.*****istener - OpenAI返回数据结束了
[OkHttp 省略 INFO com.unfbx.chatgpt.*****istener - OpenAI关闭sse连接...

tokens计算使用示例

完整使用示例请参考:TikTokensTest

结合chat模型使用示例:
完整示例参考:OpenAiClientTest

    public void chatTokensTest() {
        //聊天模型:gpt-3.5
        List<Message> messages = new ArrayList<>(2);
        messages.add(Message.builder().role(Message.Role.USER).content("关注微信公众号:程序员的黑洞。").build());
        messages.add(Message.builder().role(Message.Role.USER).content("获取最新版本更新通知。").build());
        ChatCompletion chatCompletion = ChatCompletion.builder().messages(messages).build();
        ChatCompletionResponse chatCompletionResponse = v2.chatCompletion(chatCompletion);
        //获取请求的tokens数量
        long tokens = chatCompletion.tokens();
        //这种方式也可以
//        long tokens = TikTokensUtil.tokens(chatCompletion.getModel(),messages);
        log.info("Message集合文本:【{}】", messages, tokens);
        log.info("本地计算的请求的tokens数{}", tokens);
        log.info("本地计算的返回的tokens数{}", TikTokensUtil.tokens(chatCompletion.getModel(),chatCompletionResponse.getChoices().get(0).getMessage().getContent()));
        log.info("---------------------------------------------------");
        log.info("Open AI 官方计算的总的tokens数{}", chatCompletionResponse.getUsage().getTotalTokens());
        log.info("Open AI 官方计算的请求的tokens数{}", chatCompletionResponse.getUsage().getPromptTokens());
        log.info("Open AI 官方计算的返回的tokens数{}", chatCompletionResponse.getUsage().getCompletionTokens());
    }

单独使用示例:

public class TikTokensTest {
    String text;
    List<Message> messages;

    @Before
    public void prepareData() {
        text = "关注微信公众号:程序员的黑洞。进入chatgpt-java交流群获取最新版本更新通知。";
        messages = new ArrayList<>(2);
        messages.add(Message.builder().role(Message.Role.USER).content("关注微信公众号:程序员的黑洞。").build());
        messages.add(Message.builder().role(Message.Role.USER).content("进入chatgpt-java交流群获取最新版本更新通知。").build());
    }
    /**
     * gpt-3.5和gpt4.0聊天模型接口计算推荐这种方法
     */
    @Test
    public void chatCompletionTokensTest() {
        
        ChatCompletion completion = ChatCompletion.builder().messages(messages).build();
        long tokens = completion.tokens();
        log.info("Message集合文本:【{}】", messages, tokens);
        log.info("总tokens数{}", tokens);
    }

    /**
     * Completion 接口计算推荐使用这种方法
     */
    @Test
    public void completionTokensTest() {
        Completion completion = Completion.builder().prompt(text).build();
        long tokens = completion.tokens();
        log.info("单句文本:【{}】", text);
        log.info("总tokens数{}", tokens);
    }

    /**
     * 通过模型模型名称计算
     */
    @Test
    public void byModelNameTest() {
        String modelName = ChatCompletion.Model.GPT_4.getName();
//        String modelName = ChatCompletion.Model.GPT_3_5_TURBO.getName();
        List<Integer> encode = TikTokensUtil.encode(modelName, text);
        log.info(encode.toString());
        long tokens = TikTokensUtil.tokens(modelName, text);
        log.info("单句文本:【{}】", text);
        log.info("总tokens数{}", tokens);
        log.info("--------------------------------------------------------------");
        tokens = TikTokensUtil.tokens(modelName, messages);
        log.info("Message集合文本:【{}】", messages, tokens);
        log.info("总tokens数{}", tokens);
    }

    /**
     * 通过Encoding计算
     */
    @Test
    public void byEncodingTest() {
        EncodingRegistry registry = Encodings.newDefaultEncodingRegistry();
        Encoding enc = registry.getEncoding(EncodingType.P50K_BASE);
        List<Integer> encode = TikTokensUtil.encode(enc, text);
        log.info(encode.toString());
        long tokens = TikTokensUtil.tokens(enc, text);
        log.info("单句文本:【{}】", text);
        log.info("总tokens数{}", tokens);
    }

    /**
     * 通过EncodingType计算
     */
    @Test
    public void byEncodingTypeTest() {
        List<Integer> encode = TikTokensUtil.encode(EncodingType.CL100K_BASE, text);
        log.info(encode.toString());
        long tokens = TikTokensUtil.tokens(EncodingType.CL100K_BASE, text);
        log.info("单句文本:【{}】", text);
        log.info("总tokens数{}", tokens);
    }

}

站在巨人的肩膀

感谢大佬:knuddelsgmbhjtokkit 的开源计算算法。

标签:tokens,10,Java,log,messages,Tokens,info,chatgpt,com
From: https://www.cnblogs.com/coder-heidong/p/17297090.html

相关文章

  • salesforce学习笔记(3-1)- JavaScript Promise(LWC)
    在JS代码中,Promise到底有什么作用?首先,我们知道的是,Javascript是单线程的,什么意思呢?就是说JS在同一时间只能做一个操作,代码的执行是一行一行进行的:  这种执行方式带来的问题就是在我们打开某个画面的时候,画面可能会卡住转圈、加载中状态很久,用户体验感很差。Promise可用于......
  • Jenkins Maven Java项目
     [root@localhost~]#catx2.sh#!/bin/bashrm-rfjavawebappname=$1pid=`ps-ef|grep$appname|grep'java-jar'|awk'{printf$2}'`echo$pidif[-z$pid];thenecho"$appnamenotstarted"else......
  • 从功能到年薪30W+的测试开发工程师,分享我这10年的职业规划路线
     求职?择业?跳槽?职业规划?作为一名初出茅庐的软件测试员,职业发展的道路的确蜿蜒曲折,面对一次次的岗位竞争,挑战一道道的面试关卡,一边带着疑惑,一边又要做出选择,只能无奈的感叹:比你优秀的人比你还努力,你有什么资格不去奋斗……那软件测试员,你究竟该如何规划下一份工作?路该怎么走......
  • Java | 一分钟掌握异步编程 | 5 - CompletableFuture异步
     作者:Mars酱 声明:本文章由Mars酱编写,部分内容来源于网络,如有疑问请联系本人。 转载:欢迎转载,转载前先请联系我!前言继续讲,前面讲了Future实现异步,优点缺点也都有,这里讲使用CompletableFuture机制,目前为止,应该说JDK原生提供的异步方式的最优方案就是CompletableFuture了,已知的开源......
  • 如何在Java中做基准测试?JMH使用初体验
    大家好,我是王有志,欢迎和我聊技术,聊漂泊在外的生活。快来加入我们的Java提桶跑路群:共同富裕的Java人。最近公司在搞新项目,由于是实验性质,且不会直接面对客户的项目,这次的技术选型非常激进,如,直接使用了Java17。作为公司里练习两年半的个人练习生,我自然也是深度的参与到了技术选型的......
  • 实战-JAVA应用程序CPU占用率飙升,定位线程的堆栈信息
    分以下几个步奏:(1)使用命令top-p<pid>,显示你的java进程的cpu情况,pid是你的java进程号,比如14203。(使用jps可以获取到java的进程id或者top直接查看)(2)按H,获取每个线程的CPU情况。(shirt+H)(3)找到内存和cpu占用最高的线程tid,比如14204。(4)转为十六进制得到377C,此为线程id的十六进......
  • 什么是 Java 字节码?采用字节码的好处是什么?
    在Java中,JVM可以理解的代码就叫做字节码(即扩展名为.class的文件),它不面向任何特定的处理器,只面向虚拟机。Java语言通过字节码的方式,在一定程度上解决了传统解释型语言执行效率低的问题,同时又保留了解释型语言可移植的特点。所以,Java程序运行时相对来说还是高效的(不过,和C++......
  • Java 判断是否是数字 正则表达式
    privatestaticbooleanisInteger(Stringstr){//可以包含小数Patternpattern=Pattern.compile("^[0-9]+(.[0-9]+)?$");//只包含两位小数Patternpattern=Pattern.compile("^(([1-9]{1}\\d*)|([0]{1}))(\\.(\\d){0,2})?$");......
  • javascript把本地sql数据库表转换为对象
    在做项目的时候,需要读取本地数据库,并且在页面上显示出来,原始数据读取出来的原始数据如下:varr=sqliteDB.exec(document.getElementById('txtSQL').value); console.info(r);  使用系统的转换方式console.log('Hereisarow:'+JSON.stringify(r));  可以看到其......
  • 【Java 并发】【九】【AQS】【七】Semaphore信号量底层机制原理
    1 前言接下来我们来看看Semaphore,也是基于之前讲解的AQS来实现的,建立在AQS体系之上的一个并发工具类。2  Semaphore是什么Semaphore,它是一个信号量,主要作用是用来控制并发中同一个时刻执行的线程数量,可以用来做限流器,或者流程控制器。在创建的时候会指定好它有多少个信号量......