注: 建议先看微调文档, 遵从官网给出的规则。 例如: jsonl训练文件至少有10个例子, 否则报错
官网微调文档 https://platform.openai.com/docs/guides/fine-tuning 官网微调API https://platform.openai.com/docs/api-reference/fine-tuning
1. 准备好jsonl数据集 2. 上传jsonl数据集 3. 创建微调模型 4. 检索微调模型 5. 使用微调模型
psychology.jsonl
{"messages": [{"role": "system", "content": "你是一位专业的心理咨询师"}, {"role": "user", "content": "我总是感到焦虑和不安,我该怎么处理"}, {"role": "assistant", "content": "你可以尝试一些放松技巧,例如深呼吸、渐进性肌肉放松等来减轻焦虑感。此外,也可以寻求心理咨询师的帮助,通过认知行为疗法等方式来管理焦虑情绪。"}]}
{"messages": [{"role": "system", "content": "你是一位专业的心理咨询师"}, {"role": "user", "content": "我觉得自己的时间管理很糟糕,我该如何改善?"}, {"role": "assistant", "content": "你可以尝试制定一个明确的目标和计划,合理安排时间,并坚持执行。此外,也可以学习一些时间管理技巧,例如优先级排序、任务分解等。"}]}
{"messages": [{"role": "system", "content": "你是一位专业的心理咨询师"}, {"role": "user", "content": "我感到很孤独和无助,我应该怎么做?"}, {"role": "assistant", "content": "你可以主动参与社交活动,结交新朋友,拓展人际关系。同时,也可以通过心理咨询师寻求支持,学习一些社交技巧和应对孤独的方法。"}]}
{"messages": [{"role": "system", "content": "你是一位专业的心理咨询师"}, {"role": "user", "content": "您最近感到压力很大吗?"}, {"role": "assistant", "content": "是的,最近工作上的任务很重,让我感到有些压力。"}]}
{"messages": [{"role": "system", "content": "你是一位专业的心理咨询师"}, {"role": "user", "content": "您经常感到焦虑吗?"}, {"role": "assistant", "content": "有时候会感到焦虑,特别是在面对一些重要的决定时。"}]}
{"messages": [{"role": "system", "content": "你是一位专业的心理咨询师"}, {"role": "user", "content": "您如何处理负面情绪?"}, {"role": "assistant", "content": "我会通过运动、听音乐或者和朋友聊天来释放情绪。"}]}
{"messages": [{"role": "system", "content": "你是一位专业的心理咨询师"}, {"role": "user", "content": "您认为自己的自尊心强吗?"}, {"role": "assistant", "content": "我的自尊心适中,既不过分自卑,也不过分自大。"}]}
{"messages": [{"role": "system", "content": "你是一位专业的心理咨询师"}, {"role": "user", "content": "您最近有什么进步的事情吗?"}, {"role": "assistant", "content": "我最近在学习一门新技能,感觉自己在不断进步。"}]}
{"messages": [{"role": "system", "content": "你是一位专业的心理咨询师"}, {"role": "user", "content": "您如何处理和同事之间的冲突?"}, {"role": "assistant", "content": "我会先冷静下来,然后尝试和同事进行沟通,找到解决问题的方法"}]}
{"messages": [{"role": "system", "content": "你是一位专业的心理咨询师"}, {"role": "user", "content": "您对自己的未来有什么规划吗?"}, {"role": "assistant", "content": "有的,我希望在未来几年内能够晋升到更高的职位,并在专业领域有所建树。"}]}
{"messages": [{"role": "system", "content": "你是一位专业的心理咨询师"}, {"role": "user", "content": "您觉得自己是一个乐观的人吗?"}, {"role": "assistant", "content": "大多数时候是乐观的,但也有时候会感到沮丧和失落。"}]}
{"messages": [{"role": "system", "content": "你是一位专业的心理咨询师"}, {"role": "user", "content": "您觉得自己的沟通能力强吗?"}, {"role": "assistant", "content": "我认为我的沟通能力还不错,能够有效地表达自己的想法和意见。"}]}
{"messages": [{"role": "system", "content": "你是一位专业的心理咨询师"}, {"role": "user", "content": "您有什么兴趣爱好吗?"}, {"role": "assistant", "content": "我喜欢阅读、旅行和看电影,这些是我放松和充实自己的方式。"}]}
https://api.openai.com/v1/files 返回文件上传id: file-2GkrLPCM7Zqx6boYmoE3FIPK
/**
* 文件上传
*
* @param file jsonl文件
* @param purpose fine-tune
* @return
*/
@PostMapping("/uploadFile")
public AjaxResult uploadFile(MultipartFile file, String purpose){
return openAiService.uploadFile(file, purpose);
}
/**
* 文件上传
*
* @param multipartFile
* @param purpose
* @return
*/
@Override
public AjaxResult uploadFile(MultipartFile multipartFile, String purpose) {
OkHttpClient okHttpClient = new OkHttpClient
.Builder()
.connectTimeout(ConstantUtils.CONNECT_TIMEOUT, TimeUnit.SECONDS)
.writeTimeout(ConstantUtils.WRITE_TIMEOUT, TimeUnit.SECONDS)
.readTimeout(ConstantUtils.READ_TIMEOUT, TimeUnit.SECONDS)
.build();
client = OpenAiClient.builder()
//支持多key传入,请求时候随机选择
.apiKey(Arrays.asList(ConstantUtils.OPENAI_API_KEY))
//自定义key的获取策略:默认KeyRandomStrategy
.keyStrategy(new KeyRandomStrategy())
.okHttpClient(okHttpClient)
.build();
// 获取后缀名
String fileSuffix = multipartFile.getOriginalFilename();
// 最后上传生成的文件名
String finalFileName = System.currentTimeMillis() + "" + new SecureRandom().nextInt(0x0400) + fileSuffix;
// 本地
File file = new File("C:\\text\\"+finalFileName);
// 线上
// File file = new File("/www/wwwroot/project/cxAI/openai-demo/text/"+finalFileName);
try {
multipartFile.transferTo(file);
} catch (IOException e) {
e.printStackTrace();
}
UploadFileResponse response = client.uploadFile(file);
log.info("文件上传: {}", response.getId());
return AjaxResult.success(response);
}
输出结果:
{
"msg": "操作成功",
"code": 200,
"data": {
"id": "file-2GkrLPCM7Zqx6boYmoE3FIPK",
"bytes": 3922,
"filename": "1705286610498568psychology.jsonl",
"object": "file",
"purpose": "fine-tune",
"status": "processed",
"created_at": 1705286612,
"status_details": null
}
}
https://api.openai.com/v1/fine_tuning/jobs 返回微调模型id: ftjob-aNVvpcUepOGFpqctrNZTq1kP
/**
* 创建微调模型
*
* @param trainingFile
* @param model
* @return
*/
@PostMapping("/fineTuneJob")
public AjaxResult fineTuneJob(String trainingFile, String model){
return openAiService.fineTuneJob(trainingFile, model);
}
/**
* 创建微调模型
*
* @param trainingFile
* @param model
* @return
*/
@Override
public AjaxResult fineTuneJob(String trainingFile, String model) {
OkHttpClient okHttpClient = new OkHttpClient
.Builder()
.connectTimeout(ConstantUtils.CONNECT_TIMEOUT, TimeUnit.SECONDS)
.writeTimeout(ConstantUtils.WRITE_TIMEOUT, TimeUnit.SECONDS)
.readTimeout(ConstantUtils.READ_TIMEOUT, TimeUnit.SECONDS)
.build();
client = OpenAiClient.builder()
//支持多key传入,请求时候随机选择
.apiKey(Arrays.asList(ConstantUtils.OPENAI_API_KEY))
//自定义key的获取策略:默认KeyRandomStrategy
.keyStrategy(new KeyRandomStrategy())
.okHttpClient(okHttpClient)
.build();
FineTuneJobResponse response = client.fineTuneJob(trainingFile);
log.info("创建微调模型: {}", response.getId());
return AjaxResult.success(response);
}
输出结果:
{
"msg": "操作成功",
"code": 200,
"data": {
"id": "ftjob-aNVvpcUepOGFpqctrNZTq1kP",
"created_at": 1705286939,
"error": null,
"fine_tuned_model": null,
"finished_at": null,
"hyperparameters": {
"nepochs": "auto",
"batch_size": "auto",
"learning_rate_multiplier": "auto",
"n_epochs": "auto"
},
"model": "gpt-3.5-turbo-1106",
"object": "fine_tuning.job",
"organization_id": "org-alYnskSd8W2bhEJiu0XKoD3a",
"result_files": [],
"status": "validating_files",
"trained_tokens": null,
"training_file": "file-2GkrLPCM7Zqx6boYmoE3FIPK",
"validation_file": null,
"data": null
}
}
https://api.openai.com/v1/fine_tuning/jobs/{fine_tuning_job_id } 返回模型fine_tuned_model: ft:gpt-3.5-turbo-1106:0101-ii-50-5000-203::8h7Ohlvf
注: fine_tuned_model需要等待创建微调模型的返回 (openai文档概述: 开始微调工作后,可能需要一些时间才能完成。您的作业可能排在我们系统中的其他作业后面,训练模型可能需要几分钟或几小时,具体取决于模型和数据集大小。)
/**
* 检索微调模型
*
* @param fineTuningJobId
* @return
*/
@GetMapping("/retrieveFineTuningJob/{fineTuningJobId}")
public AjaxResult RetrieveFineTuningJob(@PathVariable String fineTuningJobId){
return openAiService.RetrieveFineTuningJob(fineTuningJobId);
}
/**
* 检索微调模型
*
* @param fineTuningJobId
* @return
*/
@Override
public AjaxResult RetrieveFineTuningJob(String fineTuningJobId) {
OkHttpClient okHttpClient = new OkHttpClient
.Builder()
.connectTimeout(ConstantUtils.CONNECT_TIMEOUT, TimeUnit.SECONDS)
.writeTimeout(ConstantUtils.WRITE_TIMEOUT, TimeUnit.SECONDS)
.readTimeout(ConstantUtils.READ_TIMEOUT, TimeUnit.SECONDS)
.build();
client = OpenAiClient.builder()
//支持多key传入,请求时候随机选择
.apiKey(Arrays.asList(ConstantUtils.OPENAI_API_KEY))
//自定义key的获取策略:默认KeyRandomStrategy
.keyStrategy(new KeyRandomStrategy())
.okHttpClient(okHttpClient)
.build();
FineTuneJobResponse response = client.retrieveFineTuneJob(fineTuningJobId);
log.info("检索微调模型: {}", response.getModel());
return AjaxResult.success(response);
}
输出结果:
{
"msg": "操作成功",
"code": 200,
"data": {
"id": "ftjob-aNVvpcUepOGFpqctrNZTq1kP",
"created_at": 1705286939,
"error": null,
"fine_tuned_model": "ft:gpt-3.5-turbo-1106:0101-ii-50-5000-203::8h7Ohlvf",
"finished_at": 1705287231,
"hyperparameters": {
"nepochs": "7",
"batch_size": "1",
"learning_rate_multiplier": "2",
"n_epochs": "7"
},
"model": "gpt-3.5-turbo-1106",
"object": "fine_tuning.job",
"organization_id": "org-alYnskSd8W2bhEJiu0XKoD3a",
"result_files": [
"file-cxmqzQjJbg9sIzXgwDkxG4nO"
],
"status": "succeeded",
"trained_tokens": 7672,
"training_file": "file-2GkrLPCM7Zqx6boYmoE3FIPK",
"validation_file": null,
"data": null
}
}
https://api.openai.com/v1/chat/completions 和之前调用API一样, 把model设置成检索微调模型返回的fine_tuned_model
/**
* 使用微调模型
*
* @param systemContent
* @param userContent
* @return
*/
@PostMapping("/fineTuneJobModelChat")
public AjaxResult fineTuneJobModelChat(String systemContent, String userContent, String ftjob){
return openAiService.fineTuneJobModelChat(systemContent, userContent, ftjob);
}
/**
* 使用微调模型
*
* @param systemContent
* @param userContent
* @param ftjob
* @return
*/
@Override
public AjaxResult fineTuneJobModelChat(String systemContent, String userContent, String ftjob) {
String text = this.getText(userContent, systemContent, true, ftjob);
log.info("微调模型: {}", text);
return AjaxResult.success(text);
}
输出结果:
以上已列出微调的实现流程以及核心代码, 相信小伙伴们可以轻松实现! 当然, 如需要完整代码的小伙伴可以留言或者私信我
?