Commit b0f73831 authored by linpeiqin's avatar linpeiqin

新增部署功能

parent 91ecb374
package com.yice.webadmin.app.controller;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.page.PageMethod;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.yice.common.core.annotation.MyRequestBody;
......@@ -10,16 +12,28 @@ import com.yice.common.core.util.MyModelUtil;
import com.yice.common.core.util.MyPageUtil;
import com.yice.common.log.annotation.OperationLog;
import com.yice.common.log.model.constant.SysOperationLogType;
import com.yice.webadmin.app.config.LlmModelConfig;
import com.yice.webadmin.app.config.OtherConfig;
import com.yice.webadmin.app.config.PythonConfig;
import com.yice.webadmin.app.dto.ModelDeployDto;
import com.yice.webadmin.app.model.ModelDeploy;
import com.yice.webadmin.app.model.ModelManage;
import com.yice.webadmin.app.model.ModelVersion;
import com.yice.webadmin.app.service.ModelDeployService;
import com.yice.webadmin.app.service.ModelManageService;
import com.yice.webadmin.app.service.ModelVersionService;
import com.yice.webadmin.app.service.ProxyPythonService;
import com.yice.webadmin.app.vo.ModelDeployVo;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.jws.WebParam;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
* 模型部署操作控制器类。
......@@ -35,6 +49,18 @@ public class ModelDeployController {
@Autowired
private ModelDeployService modelDeployService;
@Autowired
private ProxyPythonService proxyPythonService;
@Autowired
private OtherConfig otherConfig;
@Autowired
private LlmModelConfig llmModelConfig;
@Autowired
private PythonConfig pythonConfig;
@Autowired
private ModelVersionService modelVersionService;
@Autowired
private ModelManageService modelManageService;
/**
* 新增模型部署数据。
......@@ -56,10 +82,74 @@ public class ModelDeployController {
if (!callResult.isSuccess()) {
return ResponseResult.errorFrom(callResult);
}
modelDeploy = modelDeployService.saveNew(modelDeploy);
List<ModelDeploy> modelDeployList = this.modelDeployService.getModelDeployList(modelDeploy, "");
for (ModelDeploy modelDeploy1 : modelDeployList) {
if (modelDeploy1.getVersionId() == modelDeploy.getVersionId()) {
return ResponseResult.error(ErrorCodeEnum.DUPLICATED_UNIQUE_KEY, "同一个模型只能部署一次!");
}
}
ModelVersion modelVersion = this.modelVersionService.getById(modelDeploy.getVersionId());
ModelManage modelManage = modelManageService.getById(modelVersion.getModelId());
modelDeploy.setDeployStatus(3);
modelDeploy.setModelId(modelVersion.getModelId());
modelDeploy.setVersionName(modelVersion.getVersionName());
modelDeploy.setModelVersion(modelVersion.getModelVersion());
modelDeploy.setModelName(modelManage.getModelName());
modelDeployService.saveNew(modelDeploy);
return ResponseResult.success(modelDeploy.getDeployId());
}
/**
* 部署指定LLM模型。
*
* @return 应答结果对象,包含查询结果集。
*/
@PostMapping("/deploy")
public ResponseResult<String> deploy(@MyRequestBody ModelDeployDto modelDeployDto, @MyRequestBody String type) {
ModelDeploy modelDeploy = modelDeployService.getById(modelDeployDto.getDeployId());
modelDeploy.setDeployStatus(0);
modelDeployService.updateById(modelDeploy);
ResponseResult<String> responseResult = this.doReloadOrStart(modelDeploy, type);
if (responseResult.isSuccess()) {
modelDeploy.setDeployStatus(1);
modelDeployService.updateById(modelDeploy);
return ResponseResult.success(responseResult.getData());
}
modelDeploy.setDeployStatus(-1);
modelDeployService.updateById(modelDeploy);
return responseResult;
}
private ResponseResult<String> doReloadOrStart(ModelDeploy modelDeploy, String type) {
String gps_ids = JSON.parseArray(modelDeploy.getResourceInfo()).stream()
.map(obj -> ((JSONObject) obj).getString("gpu_id"))
.collect(Collectors.joining(","));
ModelVersion modelVersion = this.modelVersionService.getById(modelDeploy.getVersionId());
String requestBody = "{\n" +
" \"new_model_name\": \"" + modelDeploy.getVersionName() + "\",\n" +
" \"new_model_path\": \"" + modelVersion.getModelUrl() + "\",\n" +
" \"startup_param\": {\n" +
" \"gpu_ids\": \"" + gps_ids + "\"\n" +
" },\n" +
" \"controller_address\": \"" + pythonConfig.getControllerAddress() + "\"\n" +
"}";
try {
String apiName = type.equals("start") ? llmModelConfig.getStart() : llmModelConfig.getReload();
String result = proxyPythonService.predictPost(llmModelConfig.getLlmModelInterface() + apiName, requestBody);
JSONObject jo = JSON.parseObject(result);
Integer code = jo.getIntValue("code");
String msg = jo.getString("msg");
String data = jo.getString("data");
if (code != null && code == 200) {
return ResponseResult.success(data);
} else {
return ResponseResult.create(ErrorCodeEnum.SERVER_INTERNAL_ERROR, msg, data);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* 更新模型部署数据。
*
......@@ -106,6 +196,35 @@ public class ModelDeployController {
return this.doDelete(deployId);
}
/**
* 列出所有可用模型部署列表。
*
* @return 应答结果对象,包含查询结果集。
*/
@PostMapping("/canUseList")
public ResponseResult<MyPageData<ModelDeployVo>> canUseList() {
ModelDeploy modelDeployFilter = new ModelDeploy();
modelDeployFilter.setDeployStatus(1);
List<ModelDeploy> modelDeployList =
modelDeployService.getModelDeployListWithRelation(modelDeployFilter, "deploy_id");
ResponseResult<String> responseResult = this.listRunningModels();
String data = responseResult.getData();
String[] modelNames = stringToArray(data);
List<ModelDeploy> modelDeploys = new ArrayList<ModelDeploy>();
for (ModelDeploy modelDeploy : modelDeployList) {
boolean isEx = false;
for (int i = 0; i < modelNames.length; i++) {
if (modelDeploy.getVersionName().equals(modelNames[i])) {
isEx = true;
}
}
if (isEx) {
modelDeploy.setDeployStatus(1);
modelDeploys.add(modelDeploy);
}
}
return ResponseResult.success(MyPageUtil.makeResponseData(modelDeploys, ModelDeploy.INSTANCE));
}
/**
* 列出符合过滤条件的模型部署列表。
*
......@@ -126,9 +245,124 @@ public class ModelDeployController {
String orderBy = MyOrderParam.buildOrderBy(orderParam, ModelDeploy.class);
List<ModelDeploy> modelDeployList =
modelDeployService.getModelDeployListWithRelation(modelDeployFilter, orderBy);
ResponseResult<String> responseResult = this.listRunningModels();
if (!responseResult.isSuccess()) {
modelDeployList.forEach(modelDeploy -> {
modelDeploy.setDeployStatus(2);
});
return ResponseResult.success(MyPageUtil.makeResponseData(modelDeployList, ModelDeploy.INSTANCE));
}
String data = responseResult.getData();
System.out.println(data);
String[] modelNames = stringToArray(data);
for (ModelDeploy modelDeploy : modelDeployList) {
boolean isEx = false;
for (int i = 0; i < modelNames.length; i++) {
if (modelDeploy.getVersionName().equals(modelNames[i])) {
isEx = true;
}
}
if (!isEx) {
if (modelDeploy.getDeployStatus() != 3)
modelDeploy.setDeployStatus(2);
} else {
modelDeploy.setDeployStatus(1);
}
}
return ResponseResult.success(MyPageUtil.makeResponseData(modelDeployList, ModelDeploy.INSTANCE));
}
private String[] stringToArray(String strArray) {
strArray = strArray.replaceAll("\\[|\\]|\"", "");
return strArray.split(",\\s*"); // 正则表达式也考虑了逗号后的空格
}
private ResponseResult<String> listRunningModels() {
String requestBody = "{\n" +
" \"controller_address\": \"" + pythonConfig.getControllerAddress() + "\",\n" +
" \"placeholder\": \"string\"\n" +
"}";
try {
String result = proxyPythonService.predictPost(llmModelConfig.getLlmModelInterface() + llmModelConfig.getListRunningModels(), requestBody);
JSONObject jo = JSON.parseObject(result);
Integer code = jo.getIntValue("code");
String msg = jo.getString("msg");
String data = jo.getString("data");
if (code != null && code == 200) {
return ResponseResult.success(data);
} else {
return ResponseResult.create(ErrorCodeEnum.SERVER_INTERNAL_ERROR, msg, data);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* 获取GPU信息。
*
* @return 应答结果对象,包含查询结果集。
*/
@PostMapping("/getGpuInfo")
public ResponseResult<String> getGpuInfo() {
try {
String result = proxyPythonService.predictPost(otherConfig.getOtherInterface() + otherConfig.getGetGpuInfo(), "");
JSONObject jo = JSON.parseObject(result);
Integer code = jo.getIntValue("code");
String msg = jo.getString("msg");
String data = jo.getString("data");
if (code != null && code == 200) {
return ResponseResult.success(data);
} else {
return ResponseResult.create(ErrorCodeEnum.SERVER_INTERNAL_ERROR, msg, data);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* 停止指定LLM模型。
*
* @return 应答结果对象,包含查询结果集。
*/
@PostMapping("/stop")
public ResponseResult<String> stop(@MyRequestBody ModelDeployDto modelDeployDto) {
ModelDeploy modelDeploy = modelDeployService.getById(modelDeployDto.getDeployId());
ResponseResult<String> responseResult = this.doStop(modelDeploy);
if (responseResult.isSuccess()) {
modelDeploy.setDeployStatus(3);
modelDeployService.updateById(modelDeploy);
return ResponseResult.success(responseResult.getData());
}
return responseResult;
}
private ResponseResult<String> doStop(ModelDeploy modelDeploy) {
String errorMessage = MyCommonUtil.getModelValidationError(modelDeploy, true);
if (errorMessage != null) {
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
}
String requestBody = "{\n" +
" \"model_name\": \"" + modelDeploy.getVersionName() + "\",\n" +
" \"controller_address\": \"" + pythonConfig.getControllerAddress() + "\"\n" +
"}";
try {
String result = proxyPythonService.predictPost(llmModelConfig.getLlmModelInterface() + llmModelConfig.getStop(), requestBody);
JSONObject jo = JSON.parseObject(result);
Integer code = jo.getIntValue("code");
String msg = jo.getString("msg");
String data = jo.getString("data");
if (code != null && code == 200) {
return ResponseResult.success(data);
} else {
return ResponseResult.create(ErrorCodeEnum.SERVER_INTERNAL_ERROR, msg, data);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* 查看指定模型部署对象详情。
*
......@@ -158,6 +392,7 @@ public class ModelDeployController {
errorMessage = "数据操作失败,删除的对象不存在,请刷新后重试!";
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
}
this.doStop(originalModelDeploy);
return ResponseResult.success();
}
}
......@@ -4,6 +4,7 @@
<resultMap id="BaseResultMap" type="com.yice.webadmin.app.model.ModelDeploy">
<id column="deploy_id" jdbcType="BIGINT" property="deployId"/>
<result column="model_id" jdbcType="BIGINT" property="modelId"/>
<result column="model_name" jdbcType="VARCHAR" property="modelName"/>
<result column="version_id" jdbcType="BIGINT" property="versionId"/>
<result column="version_name" jdbcType="VARCHAR" property="versionName"/>
<result column="deploy_status" jdbcType="TINYINT" property="deployStatus"/>
......@@ -15,12 +16,15 @@
<result column="service_id" jdbcType="BIGINT" property="serviceId"/>
<result column="service_name" jdbcType="VARCHAR" property="serviceName"/>
<result column="service_version" jdbcType="TINYINT" property="serviceVersion"/>
<result column="resource_info" jdbcType="VARCHAR" property="resourceInfo"/>
<result column="service_remark" jdbcType="VARCHAR" property="serviceRemark"/>
</resultMap>
<insert id="insertList">
INSERT INTO lmp_model_deploy
(deploy_id,
model_id,
model_name,
version_id,
version_name,
deploy_status,
......@@ -31,11 +35,14 @@
model_version,
service_id,
service_name,
service_version)
service_version,
resource_info,
service_remark)
VALUES
<foreach collection="list" index="index" item="item" separator=",">
(#{item.deployId},
#{item.modelId},
#{item.modelName},
#{item.versionId},
#{item.versionName},
#{item.deployStatus},
......@@ -46,7 +53,9 @@
#{item.modelVersion},
#{item.serviceId},
#{item.serviceName},
#{item.serviceVersion})
#{item.serviceVersion},
#{item.resourceInfo},
#{item.serviceRemark})
</foreach>
</insert>
......
......@@ -30,6 +30,12 @@ public class ModelDeployDto {
@ApiModelProperty(value = "模型ID")
private Long modelId;
/**
* 模型名称。
*/
@ApiModelProperty(value = "模型名称")
private String modelName;
/**
* 版本ID。
*/
......@@ -71,4 +77,22 @@ public class ModelDeployDto {
*/
@ApiModelProperty(value = "服务版本")
private Integer serviceVersion;
/**
* 资源信息。
*/
@ApiModelProperty(value = "资源信息")
private String resourceInfo;
/**
* 服务描述。
*/
@ApiModelProperty(value = "服务描述")
private String serviceRemark;
/**
* 资源id。
*/
@ApiModelProperty(value = "资源id")
private String gpuIds;
}
......@@ -32,6 +32,10 @@ public class ModelDeploy extends BaseModel {
*/
private Long modelId;
/**
* 模型名称。
*/
private String modelName;
/**
* 版本ID。
*/
......@@ -67,6 +71,16 @@ public class ModelDeploy extends BaseModel {
*/
private Integer serviceVersion;
/**
* 资源信息。
*/
private String resourceInfo;
/**
* 服务描述。
*/
private String serviceRemark;
@Mapper
public interface ModelDeployModelMapper extends BaseModelMapper<ModelDeployVo, ModelDeploy> {
}
......
......@@ -28,7 +28,11 @@ public class ModelDeployVo extends BaseVo {
*/
@ApiModelProperty(value = "模型ID")
private Long modelId;
/**
* 模型名称。
*/
@ApiModelProperty(value = "模型名称")
private String modelName;
/**
* 版本ID。
*/
......@@ -70,4 +74,15 @@ public class ModelDeployVo extends BaseVo {
*/
@ApiModelProperty(value = "服务版本")
private Integer serviceVersion;
/**
* 资源信息。
*/
@ApiModelProperty(value = "资源信息")
private String resourceInfo;
/**
* 服务描述。
*/
@ApiModelProperty(value = "服务描述")
private String serviceRemark;
}
......@@ -78,10 +78,25 @@ python:
#python websocket 服务地址
pythonWebsocketUri: ws://192.168.0.36:7860/queue/join
#输出控制地址
controllerAddress: http://192.168.0.36:20001
controllerAddress: http://127.0.0.1:20001
#对话基础路径
chatAddress: http://192.168.0.36:7861/
chatAddress: http://192.168.0.36:8000/
llm-model:
#模型管理基础路径
llmModelInterface: http://192.168.0.36:7861/llm_model/
#模型停止
stop: stop
#模型模型部署
reload: reload
#模型部署
start: start
#列出当前已加载模型
listRunningModels: list_running_models
other:
#其他管理接口
otherInterface: http://192.168.0.36:7861/other/
#获取gpu信息
getGpuInfo: get_gpu_info
knowledge:
#知识库通用接口地址
knowledgeInterface: http://192.168.0.36:7861/knowledge_base/
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment