feat(llm): 更新基座模型状态并优化相关功能
- 在 BaseModelController 中添加刷新基座模型状态的接口 - 在 BaseModelService 中新增相关方法以支持模型状态更新 - 在 BaseModelTaskService 中实现定时任务以同步远程模型状态 - 更新 BaseModelDO 和相关 VO 类以适应新的模型状态逻辑- 在 LLMBackendProperties 中添加 baseModelStatus 属性以配置模型状态接口 URL
This commit is contained in:
parent
9523d0c077
commit
ebe7fced35
@ -1,5 +1,6 @@
|
||||
package cn.iocoder.yudao.module.llm.controller.admin.basemodel;
|
||||
|
||||
import cn.iocoder.yudao.module.llm.service.basemodel.BaseModelTaskService;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import javax.annotation.Resource;
|
||||
@ -38,6 +39,8 @@ public class BaseModelController {
|
||||
|
||||
@Resource
|
||||
private BaseModelService baseModelService;
|
||||
@Resource
|
||||
private BaseModelTaskService baseModelTaskService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建基座模型")
|
||||
@ -58,7 +61,7 @@ public class BaseModelController {
|
||||
@Operation(summary = "启动")
|
||||
// @PreAuthorize("@ss.hasPermission('llm:base-model:update')")
|
||||
public CommonResult<Boolean> active(@Valid @RequestBody BaseModelSaveReqVO updateReqVO) {
|
||||
updateReqVO.setIsActive(true);
|
||||
updateReqVO.setIsActive(1);
|
||||
baseModelService.updateBaseModel(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
@ -71,6 +74,14 @@ public class BaseModelController {
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/getCount")
|
||||
@Operation(summary = "刷新基座模型状态")
|
||||
public CommonResult<PageResult<BaseModelRespVO>> getCount(@Valid BaseModelPageReqVO pageReqVO) {
|
||||
baseModelTaskService.updateTheBaseModelState();
|
||||
PageResult<BaseModelDO> pageResult = baseModelService.getBaseModelPage(pageReqVO);
|
||||
return success(BeanUtils.toBean(pageResult, BaseModelRespVO.class));
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除基座模型")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
|
@ -28,7 +28,7 @@ public class BaseModelPageReqVO extends PageParam {
|
||||
private String modelType;
|
||||
|
||||
@Schema(description = "是否启动")
|
||||
private Boolean isActive;
|
||||
private Integer isActive;
|
||||
|
||||
@Schema(description = "是否微调")
|
||||
private Boolean isFinetuned;
|
||||
|
@ -34,7 +34,7 @@ public class BaseModelRespVO {
|
||||
|
||||
@Schema(description = "是否启动", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@ExcelProperty("是否启动")
|
||||
private Boolean isActive;
|
||||
private Integer isActive;
|
||||
|
||||
@Schema(description = "是否微调", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@ExcelProperty("是否微调")
|
||||
|
@ -30,7 +30,7 @@ public class BaseModelSaveReqVO {
|
||||
|
||||
@Schema(description = "是否启动", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "是否启动不能为空")
|
||||
private Boolean isActive;
|
||||
private Integer isActive;
|
||||
|
||||
@Schema(description = "是否微调", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "是否微调不能为空")
|
||||
@ -58,4 +58,6 @@ public class BaseModelSaveReqVO {
|
||||
private Long gpuId;
|
||||
|
||||
private String gpuName;
|
||||
|
||||
private String aigcModelName;
|
||||
}
|
||||
|
@ -45,8 +45,9 @@ public class BaseModelDO extends BaseDO {
|
||||
private String modelType;
|
||||
/**
|
||||
* 是否启动
|
||||
* 字典base_model_status
|
||||
*/
|
||||
private Boolean isActive;
|
||||
private Integer isActive;
|
||||
/**
|
||||
* 是否微调
|
||||
*/
|
||||
|
@ -112,6 +112,8 @@ public class LLMBackendProperties {
|
||||
private String autoEvaluation;
|
||||
private String textToImage;
|
||||
|
||||
private String baseModelStatus;
|
||||
|
||||
/**
|
||||
* 知识库向量嵌入
|
||||
*/
|
||||
|
@ -70,4 +70,10 @@ public interface BaseModelService {
|
||||
* @param updateReqVO 更新信息
|
||||
*/
|
||||
void unActive (@Valid BaseModelSaveReqVO updateReqVO);
|
||||
|
||||
void updetatebyId(BaseModelDO localModel);
|
||||
|
||||
List<BaseModelDO> getAllModels();
|
||||
|
||||
void updetatebyIds(List<BaseModelDO> differentModels);
|
||||
}
|
||||
|
@ -153,10 +153,26 @@ public class BaseModelServiceImpl implements BaseModelService {
|
||||
// 校验使用
|
||||
validateModelUse(updateReqVO.getId());
|
||||
|
||||
updateReqVO.setIsActive(false);
|
||||
updateReqVO.setIsActive(0);
|
||||
updateBaseModel(updateReqVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updetatebyId(BaseModelDO localModel) {
|
||||
baseModelMapper.updateById(localModel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BaseModelDO> getAllModels() {
|
||||
List<BaseModelDO> baseModelDOS = baseModelMapper.selectList();
|
||||
return baseModelDOS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updetatebyIds(List<BaseModelDO> differentModels) {
|
||||
baseModelMapper.updateBatch(differentModels);
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验模型使用情况
|
||||
*
|
||||
|
@ -1,11 +1,15 @@
|
||||
package cn.iocoder.yudao.module.llm.service.basemodel;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.iocoder.yudao.framework.common.util.http.HttpUtils;
|
||||
import cn.iocoder.yudao.module.llm.controller.admin.basemodel.vo.BaseModelSaveReqVO;
|
||||
import cn.iocoder.yudao.module.llm.dal.dataobject.basemodel.BaseModelDO;
|
||||
import cn.iocoder.yudao.module.llm.dal.dataobject.servername.ServerNameDO;
|
||||
import cn.iocoder.yudao.module.llm.dal.mysql.servername.ServerNameMapper;
|
||||
import cn.iocoder.yudao.module.llm.framework.backend.config.LLMBackendProperties;
|
||||
import cn.iocoder.yudao.module.llm.handler.AigcCustomDateTimeDeserializer;
|
||||
import cn.iocoder.yudao.module.llm.service.basemodel.vo.ModelListRes;
|
||||
import cn.iocoder.yudao.module.llm.service.basemodel.vo.PedestalModelVo;
|
||||
import cn.iocoder.yudao.module.llm.service.http.FineTuningTaskHttpService;
|
||||
import cn.iocoder.yudao.module.llm.service.http.TrainHttpService;
|
||||
import cn.iocoder.yudao.module.llm.service.http.vo.AigcModelDeploySaveReq;
|
||||
@ -34,22 +38,20 @@ import java.util.stream.Collectors;
|
||||
@Slf4j
|
||||
public class BaseModelTaskService {
|
||||
|
||||
private static final String DEFAULT_MODEL_URL_SUFFIX = "/v1/chat/completions";
|
||||
@Resource
|
||||
TrainHttpService trainHttpService;
|
||||
|
||||
@Resource
|
||||
BaseModelService baseModelService;
|
||||
|
||||
@Resource
|
||||
ServerNameMapper serverNameMapper;
|
||||
|
||||
@Resource
|
||||
private FineTuningTaskHttpService fineTuningTaskHttpService;
|
||||
|
||||
private static final String DEFAULT_MODEL_URL_SUFFIX = "/v1/chat/completions";
|
||||
@Resource
|
||||
private LLMBackendProperties llmBackendProperties;
|
||||
|
||||
// 减少维护 先注释掉
|
||||
@Scheduled(cron ="0 0/1 * * * ?")
|
||||
@Scheduled(cron = "0 0/1 * * * ?")
|
||||
public void synchronous() throws JsonProcessingException {
|
||||
try {
|
||||
log.info("开始同步基础模型信息...");
|
||||
@ -87,7 +89,8 @@ public class BaseModelTaskService {
|
||||
SimpleModule module = new SimpleModule();
|
||||
module.addDeserializer(LocalDateTime.class, new AigcCustomDateTimeDeserializer());
|
||||
mapper.registerModule(module);
|
||||
List<AigcModelDeployVO> aigcModelDeploys = mapper.readValue(res, new TypeReference<List<AigcModelDeployVO>>() {});
|
||||
List<AigcModelDeployVO> aigcModelDeploys = mapper.readValue(res, new TypeReference<List<AigcModelDeployVO>>() {
|
||||
});
|
||||
log.debug("模型部署信息解析完成。记录数量: {}", aigcModelDeploys.size());
|
||||
|
||||
if (!aigcModelDeploys.isEmpty()) {
|
||||
@ -135,11 +138,11 @@ public class BaseModelTaskService {
|
||||
}
|
||||
|
||||
|
||||
// @Scheduled(cron ="0 0/1 * * * ?")
|
||||
// @Scheduled(cron ="0 0/1 * * * ?")
|
||||
public void updateBaseModel() {
|
||||
Log.info("定时任务启动");
|
||||
String resStr = trainHttpService.modelsList("");
|
||||
Log.info("获取aicg模型列表返回数据内容{}",resStr);
|
||||
Log.info("获取aicg模型列表返回数据内容{}", resStr);
|
||||
JSONObject jsonObject = JSONObject.parseObject(resStr);
|
||||
JSONObject data = jsonObject.getJSONObject("data");
|
||||
JSONArray list = data.getJSONArray("list");
|
||||
@ -148,43 +151,112 @@ public class BaseModelTaskService {
|
||||
for (ModelListRes modelListRe : modelListRes) {
|
||||
Long id = modelListRe.getId();
|
||||
BaseModelDO byAigcId = baseModelService.getByAigcId(id);
|
||||
if(byAigcId == null){
|
||||
if (byAigcId == null) {
|
||||
BaseModelSaveReqVO baseModelSaveReqVO = new BaseModelSaveReqVO();
|
||||
baseModelSaveReqVO.setAigcId(id);
|
||||
baseModelSaveReqVO.setModelName(modelListRe.getModelName());
|
||||
baseModelSaveReqVO.setModelType(modelListRe.getModelType());
|
||||
baseModelSaveReqVO.setMaxContextLength(modelListRe.getMaxTokens());
|
||||
baseModelSaveReqVO.setIsActive(modelListRe.getEnabled());
|
||||
baseModelSaveReqVO.setIsActive(1);
|
||||
baseModelSaveReqVO.setIsFinetuned(modelListRe.getIsFineTuning());
|
||||
baseModelSaveReqVO.setNotes(modelListRe.getRemark());
|
||||
baseModelSaveReqVO.setParameterCount(1);
|
||||
baseModelService.createBaseModel(baseModelSaveReqVO);
|
||||
}else{
|
||||
BaseModelSaveReqVO baseModelSaveReqVO = new BaseModelSaveReqVO();
|
||||
baseModelSaveReqVO.setId(byAigcId.getId());
|
||||
baseModelSaveReqVO.setParameterCount(1);
|
||||
baseModelSaveReqVO.setModelName(modelListRe.getModelName());
|
||||
baseModelSaveReqVO.setModelType(modelListRe.getModelType());
|
||||
baseModelSaveReqVO.setMaxContextLength(modelListRe.getMaxTokens());
|
||||
baseModelSaveReqVO.setIsActive(modelListRe.getEnabled());
|
||||
baseModelSaveReqVO.setIsFinetuned(modelListRe.getIsFineTuning());
|
||||
baseModelSaveReqVO.setNotes(modelListRe.getRemark());
|
||||
baseModelService.updateBaseModel(baseModelSaveReqVO);
|
||||
} else {
|
||||
BaseModelSaveReqVO baseModelSaveReqVO = new BaseModelSaveReqVO();
|
||||
baseModelSaveReqVO.setId(byAigcId.getId());
|
||||
baseModelSaveReqVO.setParameterCount(1);
|
||||
baseModelSaveReqVO.setModelName(modelListRe.getModelName());
|
||||
baseModelSaveReqVO.setModelType(modelListRe.getModelType());
|
||||
baseModelSaveReqVO.setMaxContextLength(modelListRe.getMaxTokens());
|
||||
baseModelSaveReqVO.setIsActive(1);
|
||||
baseModelSaveReqVO.setIsFinetuned(modelListRe.getIsFineTuning());
|
||||
baseModelSaveReqVO.setNotes(modelListRe.getRemark());
|
||||
baseModelService.updateBaseModel(baseModelSaveReqVO);
|
||||
}
|
||||
}
|
||||
|
||||
List<BaseModelDO> baseModelList = baseModelService.getBaseModelList();
|
||||
|
||||
List<Long> ids = modelListRes.stream().map(ModelListRes::getId).collect(Collectors.toList());
|
||||
List<Long> ids = modelListRes.stream().map(ModelListRes::getId).collect(Collectors.toList());
|
||||
|
||||
for (BaseModelDO baseModelDO : baseModelList) {
|
||||
if(baseModelDO.getAigcId() == null){
|
||||
if (baseModelDO.getAigcId() == null) {
|
||||
continue;
|
||||
}
|
||||
if(!ids.contains(baseModelDO.getAigcId())){
|
||||
if (!ids.contains(baseModelDO.getAigcId())) {
|
||||
baseModelService.deleteBaseModel(baseModelDO.getId());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Scheduled(cron = "0 0/5 * * * ?")
|
||||
public void updateTheBaseModelState() {
|
||||
try {
|
||||
// 获取所有基础模型列表
|
||||
List<BaseModelDO> baseModelList = baseModelService.getAllModels();
|
||||
log.info("获取到 {} 个基础模型", baseModelList.size());
|
||||
|
||||
// 调用接口获取远程模型状态
|
||||
String resStr = HttpUtils.post(llmBackendProperties.getBaseModelStatus(), null, "");
|
||||
log.info("获取aicg模型列表返回数据内容: {}", resStr);
|
||||
|
||||
JSONArray objects = JSONArray.parseArray(resStr);
|
||||
String s = JSON.toJSONString(objects);
|
||||
List<PedestalModelVo> modelListRes = JSONObject.parseArray(s, PedestalModelVo.class);
|
||||
List<String> remoteModelNames = modelListRes.stream()
|
||||
.map(PedestalModelVo::getDeploymentName)
|
||||
.collect(Collectors.toList());
|
||||
List<BaseModelDO> differentModels = baseModelList.stream()
|
||||
.filter(baseModel -> !remoteModelNames.contains(baseModel.getModelName())&& baseModel.getIsActive()==1)
|
||||
.collect(Collectors.toList());
|
||||
for (BaseModelDO baseModel : differentModels){
|
||||
baseModel.setIsActive(2);
|
||||
}
|
||||
baseModelService.updetatebyIds(differentModels);
|
||||
for (PedestalModelVo pedestalModelVo : modelListRes) {
|
||||
// JSONObject jsonObject = (JSONObject) object;
|
||||
// String string = JSON.toJSONString(jsonObject);
|
||||
// PedestalModelVo pedestalModelVo = JSON.parseObject(string, PedestalModelVo.class);
|
||||
|
||||
// 查找本地模型
|
||||
List<BaseModelDO> localModels = baseModelList.stream()
|
||||
.filter(baseModel -> pedestalModelVo.getDeploymentName().equals(baseModel.getModelName()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (localModels != null && localModels.size() > 0) {
|
||||
BaseModelDO localModel = localModels.get(0);
|
||||
// 如果状态不是 "running",更新本地状态
|
||||
if (!"running".equals(pedestalModelVo.getStatus())) {
|
||||
log.info("更新模型状态,模型名称: {}, 状态: {}", pedestalModelVo.getDeploymentName(), pedestalModelVo.getStatus());
|
||||
localModel.setIsActive(2);
|
||||
baseModelService.updetatebyId(localModel);
|
||||
} else {
|
||||
String string1 = pedestalModelVo.getHost() + "/v1/chat/completions";
|
||||
if (!string1.equals(localModel.getChatUrl())) {
|
||||
localModel.setIsActive(1);
|
||||
localModel.setChatUrl(string1);
|
||||
baseModelService.updetatebyId(localModel);
|
||||
}
|
||||
log.debug("模型 {} 状态为 running,无需更新", pedestalModelVo.getDeploymentName());
|
||||
}
|
||||
} else {
|
||||
//新增基座模型
|
||||
if ("running".equals(pedestalModelVo.getStatus())){
|
||||
BaseModelSaveReqVO baseModelSaveReqVO = new BaseModelSaveReqVO();
|
||||
baseModelSaveReqVO.setModelName(pedestalModelVo.getDeploymentName());
|
||||
baseModelSaveReqVO.setIsActive(1);
|
||||
baseModelSaveReqVO.setAigcModelName(pedestalModelVo.getDeploymentName());
|
||||
baseModelSaveReqVO.setChatUrl(pedestalModelVo.getHost() + "/v1/chat/completions");
|
||||
baseModelService.createBaseModel(baseModelSaveReqVO);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("更新基础模型状态时发生异常: {}", e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,93 @@
|
||||
package cn.iocoder.yudao.module.llm.service.basemodel.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
|
||||
@Data
|
||||
public class PedestalModelVo {
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
public String createdAt;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
public String updatedAt;
|
||||
|
||||
/**
|
||||
* 模型ID
|
||||
*/
|
||||
public int modelId;
|
||||
|
||||
/**
|
||||
* 模型状态
|
||||
*/
|
||||
public String status;
|
||||
|
||||
/**
|
||||
* 推理类型
|
||||
*/
|
||||
public String inferredType;
|
||||
|
||||
/**
|
||||
* GPU数量
|
||||
*/
|
||||
public int gpu;
|
||||
|
||||
/**
|
||||
* 量化类型
|
||||
*/
|
||||
public String quantization;
|
||||
|
||||
/**
|
||||
* 部署名称
|
||||
*/
|
||||
public String deploymentName;
|
||||
|
||||
/**
|
||||
* 端口号
|
||||
*/
|
||||
public String port;
|
||||
|
||||
/**
|
||||
* ID
|
||||
*/
|
||||
public int id;
|
||||
|
||||
/**
|
||||
* 删除时间
|
||||
*/
|
||||
public String deletedAt;
|
||||
|
||||
/**
|
||||
* 模型路径
|
||||
*/
|
||||
public String modelPath;
|
||||
|
||||
/**
|
||||
* 副本数量
|
||||
*/
|
||||
public int replicas;
|
||||
|
||||
/**
|
||||
* 标签
|
||||
*/
|
||||
public String label;
|
||||
|
||||
/**
|
||||
* CPU数量
|
||||
*/
|
||||
public int cpu;
|
||||
|
||||
/**
|
||||
* VLLM数量
|
||||
*/
|
||||
public int vllm;
|
||||
|
||||
/**
|
||||
* 主机地址
|
||||
*/
|
||||
public String host;
|
||||
}
|
@ -328,6 +328,8 @@ llm:
|
||||
check_file_list: /llm/finetuning/checkpoints?model_name=
|
||||
# 模型调优停止 POST
|
||||
stop_finetuning: /llm/finetuning/stop
|
||||
# 基座模型状态 POST
|
||||
base_model_status: http://36.103.199.248:5123/llm/deploy/list
|
||||
|
||||
#################### 30000: 大模型对话相关API。 ###################
|
||||
#### 大模型对话
|
||||
|
Loading…
x
Reference in New Issue
Block a user