簡介
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);
}
}
站在巨人的肩膀
感謝大佬:knuddelsgmbh 的jtokkit 的開源計算演算法,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/549394.html
標籤:其他
上一篇:Springfox與SpringDoc——swagger如何選擇(SpringDoc入門)
下一篇:WAL模塊主要方法簡述
