feat/training_260202 #8
@@ -10,13 +10,21 @@ import lombok.Getter;
|
|||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public enum TrainStatusType implements EnumType {
|
public enum TrainStatusType implements EnumType {
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
READY("READY", "대기"),
|
READY("대기"),
|
||||||
ING("ING", "진행중"),
|
IN_PROGRESS("진행중"),
|
||||||
COMPLETED("COMPLETED", "완료"),
|
COMPLETED("완료"),
|
||||||
STOPPED("STOPPED", "중단됨"),
|
STOPPED("중단됨"),
|
||||||
ERROR("ERROR", "오류");
|
ERROR("오류");
|
||||||
// @formatter:on
|
|
||||||
|
|
||||||
private final String id;
|
private final String desc;
|
||||||
private final String text;
|
|
||||||
|
@Override
|
||||||
|
public String getId() {
|
||||||
|
return name();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getText() {
|
||||||
|
return desc;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ public class HyperParamDto {
|
|||||||
public static class Basic {
|
public static class Basic {
|
||||||
|
|
||||||
private UUID uuid;
|
private UUID uuid;
|
||||||
|
private String hyperVer;
|
||||||
|
@JsonFormatDttm private ZonedDateTime createdDttm;
|
||||||
|
|
||||||
// -------------------------
|
// -------------------------
|
||||||
// Important
|
// Important
|
||||||
|
|||||||
@@ -12,15 +12,12 @@ import io.swagger.v3.oas.annotations.media.Schema;
|
|||||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
||||||
import io.swagger.v3.oas.annotations.responses.ApiResponses;
|
import io.swagger.v3.oas.annotations.responses.ApiResponses;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import jakarta.validation.Valid;
|
import java.util.UUID;
|
||||||
import java.util.List;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
@@ -33,7 +30,7 @@ public class ModelMngApiController {
|
|||||||
private final ModelMngService modelMngService;
|
private final ModelMngService modelMngService;
|
||||||
private final ModelTrainService modelTrainService;
|
private final ModelTrainService modelTrainService;
|
||||||
|
|
||||||
@Operation(summary = "학습 모델 목록 조회", description = "학습 모델 목록을 조회합니다")
|
@Operation(summary = "모델관리 목록 조회", description = "모델관리 목록 조회 API")
|
||||||
@ApiResponses(
|
@ApiResponses(
|
||||||
value = {
|
value = {
|
||||||
@ApiResponse(
|
@ApiResponse(
|
||||||
@@ -46,186 +43,206 @@ public class ModelMngApiController {
|
|||||||
@ApiResponse(responseCode = "400", description = "잘못된 검색 조건", content = @Content),
|
@ApiResponse(responseCode = "400", description = "잘못된 검색 조건", content = @Content),
|
||||||
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
|
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
|
||||||
})
|
})
|
||||||
@GetMapping
|
@GetMapping("/list")
|
||||||
public ApiResponseDto<Page<Basic>> findByModels(
|
public ApiResponseDto<Page<Basic>> findByModelList(
|
||||||
@Parameter(description = "상태 코드") @RequestParam(required = false) String status,
|
@Parameter(
|
||||||
|
description = "상태코드",
|
||||||
|
example = "IN_PROGRESS",
|
||||||
|
schema = @Schema(allowableValues = {"", "IN_PROGRESS", "COMPLETED"}))
|
||||||
|
@RequestParam(required = false)
|
||||||
|
String status,
|
||||||
@Parameter(description = "페이지 번호") @RequestParam(defaultValue = "0") int page,
|
@Parameter(description = "페이지 번호") @RequestParam(defaultValue = "0") int page,
|
||||||
@Parameter(description = "페이지 크기") @RequestParam(defaultValue = "20") int size) {
|
@Parameter(description = "페이지 크기") @RequestParam(defaultValue = "20") int size) {
|
||||||
ModelMngDto.SearchReq searchReq = new ModelMngDto.SearchReq(status, page, size);
|
ModelMngDto.SearchReq searchReq = new ModelMngDto.SearchReq(status, page, size);
|
||||||
return ApiResponseDto.ok(modelMngService.findByModels(searchReq));
|
return ApiResponseDto.ok(modelMngService.getModelList(searchReq));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "학습 모델 상세 조회", description = "학습 모델의 상세 정보를 UUID로 조회합니다")
|
@Operation(summary = "학습 모델 삭제", description = "학습 모델 삭제 API")
|
||||||
@ApiResponses(
|
|
||||||
value = {
|
|
||||||
@ApiResponse(
|
|
||||||
responseCode = "200",
|
|
||||||
description = "조회 성공",
|
|
||||||
content =
|
|
||||||
@Content(
|
|
||||||
mediaType = "application/json",
|
|
||||||
schema = @Schema(implementation = ModelMngDto.Detail.class))),
|
|
||||||
@ApiResponse(responseCode = "404", description = "모델을 찾을 수 없음", content = @Content),
|
|
||||||
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
|
|
||||||
})
|
|
||||||
@GetMapping("/{uuid}")
|
|
||||||
public ApiResponseDto<ModelMngDto.Detail> getModelDetail(
|
|
||||||
@Parameter(description = "모델 UUID", example = "b7e99739-6736-45f9-a224-8161ecddf287")
|
|
||||||
@PathVariable
|
|
||||||
String uuid) {
|
|
||||||
return ApiResponseDto.ok(modelMngService.getModelDetailByUuid(uuid));
|
|
||||||
}
|
|
||||||
|
|
||||||
// ==================== 학습 모델학습관리 API (5종) ====================
|
|
||||||
|
|
||||||
@Operation(summary = "학습 모델 통합 조회", description = "학습 관리 화면에서 학습 이력 리스트와 현재 상태를 조회합니다")
|
|
||||||
@ApiResponses(
|
|
||||||
value = {
|
|
||||||
@ApiResponse(
|
|
||||||
responseCode = "200",
|
|
||||||
description = "조회 성공",
|
|
||||||
content =
|
|
||||||
@Content(
|
|
||||||
mediaType = "application/json",
|
|
||||||
schema = @Schema(implementation = List.class))),
|
|
||||||
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
|
|
||||||
})
|
|
||||||
@GetMapping("/train")
|
|
||||||
public ApiResponseDto<List<ModelMngDto.TrainListRes>> getTrainModelList() {
|
|
||||||
return ApiResponseDto.ok(modelTrainService.getTrainModelList());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Operation(summary = "학습 설정 통합 조회", description = "학습 실행 팝업 구성에 필요한 모든 데이터를 한 번에 반환합니다")
|
|
||||||
@ApiResponses(
|
|
||||||
value = {
|
|
||||||
@ApiResponse(
|
|
||||||
responseCode = "200",
|
|
||||||
description = "조회 성공",
|
|
||||||
content =
|
|
||||||
@Content(
|
|
||||||
mediaType = "application/json",
|
|
||||||
schema = @Schema(implementation = ModelMngDto.FormConfigRes.class))),
|
|
||||||
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
|
|
||||||
})
|
|
||||||
@GetMapping("/train/form-config")
|
|
||||||
public ApiResponseDto<ModelMngDto.FormConfigRes> getFormConfig() {
|
|
||||||
return ApiResponseDto.ok(modelTrainService.getFormConfig());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Operation(summary = "학습 시작", description = "모든 설정(Step 1~3)을 마치고 최종적으로 학습 프로세스를 시작합니다")
|
|
||||||
@ApiResponses(
|
|
||||||
value = {
|
|
||||||
@ApiResponse(
|
|
||||||
responseCode = "200",
|
|
||||||
description = "학습 시작 성공",
|
|
||||||
content =
|
|
||||||
@Content(
|
|
||||||
mediaType = "application/json",
|
|
||||||
schema = @Schema(implementation = ModelMngDto.TrainStartRes.class))),
|
|
||||||
@ApiResponse(responseCode = "400", description = "잘못된 요청", content = @Content),
|
|
||||||
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
|
|
||||||
})
|
|
||||||
@PostMapping("/train")
|
|
||||||
public ApiResponseDto<ModelMngDto.TrainStartRes> startTraining(
|
|
||||||
@Valid @RequestBody ModelMngDto.TrainStartReq trainReq) {
|
|
||||||
return ApiResponseDto.ok(modelTrainService.startTraining(trainReq));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Operation(summary = "학습 모델 삭제", description = "목록에서 특정 학습 모델을 삭제합니다")
|
|
||||||
@ApiResponses(
|
@ApiResponses(
|
||||||
value = {
|
value = {
|
||||||
@ApiResponse(responseCode = "200", description = "삭제 성공", content = @Content),
|
@ApiResponse(responseCode = "200", description = "삭제 성공", content = @Content),
|
||||||
@ApiResponse(responseCode = "400", description = "진행 중인 모델은 삭제 불가", content = @Content),
|
@ApiResponse(responseCode = "409", description = "HPs_0001 삭제 불가", content = @Content)
|
||||||
@ApiResponse(responseCode = "404", description = "모델을 찾을 수 없음", content = @Content),
|
|
||||||
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
|
|
||||||
})
|
})
|
||||||
@DeleteMapping("/train/{uuid}")
|
@DeleteMapping("/{uuid}")
|
||||||
public ApiResponseDto<Void> deleteTrainModel(
|
public ApiResponseDto<Void> deleteModelTrain(
|
||||||
@Parameter(description = "모델 UUID") @PathVariable String uuid) {
|
@Parameter(description = "학습 모델 uuid", example = "f2b02229-90f2-45f5-92ea-c56cf1c29f79")
|
||||||
modelTrainService.deleteTrainModel(uuid);
|
@PathVariable
|
||||||
|
UUID uuid) {
|
||||||
|
modelMngService.deleteModelTrain(uuid);
|
||||||
return ApiResponseDto.ok(null);
|
return ApiResponseDto.ok(null);
|
||||||
}
|
}
|
||||||
|
//
|
||||||
// ==================== Resume Training (학습 재시작) ====================
|
// @Operation(summary = "학습 모델 상세 조회", description = "학습 모델의 상세 정보를 UUID로 조회합니다")
|
||||||
|
// @ApiResponses(
|
||||||
@Operation(summary = "학습 재시작 정보 조회", description = "중단된 학습의 재시작 가능 여부와 Checkpoint 정보를 조회합니다")
|
// value = {
|
||||||
@ApiResponses(
|
// @ApiResponse(
|
||||||
value = {
|
// responseCode = "200",
|
||||||
@ApiResponse(
|
// description = "조회 성공",
|
||||||
responseCode = "200",
|
// content =
|
||||||
description = "조회 성공",
|
// @Content(
|
||||||
content =
|
// mediaType = "application/json",
|
||||||
@Content(
|
// schema = @Schema(implementation = ModelMngDto.Detail.class))),
|
||||||
mediaType = "application/json",
|
// @ApiResponse(responseCode = "404", description = "모델을 찾을 수 없음", content = @Content),
|
||||||
schema = @Schema(implementation = ModelMngDto.ResumeInfo.class))),
|
// @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
|
||||||
@ApiResponse(responseCode = "404", description = "모델을 찾을 수 없음", content = @Content),
|
// })
|
||||||
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
|
// @GetMapping("/{uuid}")
|
||||||
})
|
// public ApiResponseDto<ModelMngDto.Detail> getModelDetail(
|
||||||
@GetMapping("/train/{uuid}/resume-info")
|
// @Parameter(description = "모델 UUID", example = "b7e99739-6736-45f9-a224-8161ecddf287")
|
||||||
public ApiResponseDto<ModelMngDto.ResumeInfo> getResumeInfo(
|
// @PathVariable
|
||||||
@Parameter(description = "모델 UUID") @PathVariable String uuid) {
|
// String uuid) {
|
||||||
return ApiResponseDto.ok(modelTrainService.getResumeInfo(uuid));
|
// return ApiResponseDto.ok(modelMngService.getModelDetailByUuid(uuid));
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Operation(summary = "학습 재시작", description = "중단된 지점(Checkpoint)부터 학습을 재개합니다")
|
// // ==================== 학습 모델학습관리 API (5종) ====================
|
||||||
@ApiResponses(
|
//
|
||||||
value = {
|
// @Operation(summary = "학습 모델 통합 조회", description = "학습 관리 화면에서 학습 이력 리스트와 현재 상태를 조회합니다")
|
||||||
@ApiResponse(
|
// @ApiResponses(
|
||||||
responseCode = "200",
|
// value = {
|
||||||
description = "재시작 성공",
|
// @ApiResponse(
|
||||||
content =
|
// responseCode = "200",
|
||||||
@Content(
|
// description = "조회 성공",
|
||||||
mediaType = "application/json",
|
// content =
|
||||||
schema = @Schema(implementation = ModelMngDto.ResumeResponse.class))),
|
// @Content(
|
||||||
@ApiResponse(responseCode = "400", description = "재시작 불가능한 상태", content = @Content),
|
// mediaType = "application/json",
|
||||||
@ApiResponse(responseCode = "404", description = "모델을 찾을 수 없음", content = @Content),
|
// schema = @Schema(implementation = List.class))),
|
||||||
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
|
// @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
|
||||||
})
|
// })
|
||||||
@PostMapping("/train/{uuid}/resume")
|
// @GetMapping("/train")
|
||||||
public ApiResponseDto<ModelMngDto.ResumeResponse> resumeTraining(
|
// public ApiResponseDto<List<ModelMngDto.TrainListRes>> getTrainModelList() {
|
||||||
@Parameter(description = "모델 UUID") @PathVariable String uuid,
|
// return ApiResponseDto.ok(modelTrainService.getTrainModelList());
|
||||||
@Valid @RequestBody ModelMngDto.ResumeRequest resumeReq) {
|
// }
|
||||||
return ApiResponseDto.ok(modelTrainService.resumeTraining(uuid, resumeReq));
|
//
|
||||||
}
|
// @Operation(summary = "학습 설정 통합 조회", description = "학습 실행 팝업 구성에 필요한 모든 데이터를 한 번에 반환합니다")
|
||||||
|
// @ApiResponses(
|
||||||
// ==================== Best Epoch Setting (Best Epoch 설정) ====================
|
// value = {
|
||||||
|
// @ApiResponse(
|
||||||
@Operation(summary = "Best Epoch 설정", description = "사용자가 직접 Best Epoch를 선택하여 설정합니다")
|
// responseCode = "200",
|
||||||
@ApiResponses(
|
// description = "조회 성공",
|
||||||
value = {
|
// content =
|
||||||
@ApiResponse(
|
// @Content(
|
||||||
responseCode = "200",
|
// mediaType = "application/json",
|
||||||
description = "설정 성공",
|
// schema = @Schema(implementation = ModelMngDto.FormConfigRes.class))),
|
||||||
content =
|
// @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
|
||||||
@Content(
|
// })
|
||||||
mediaType = "application/json",
|
// @GetMapping("/train/form-config")
|
||||||
schema = @Schema(implementation = ModelMngDto.BestEpochResponse.class))),
|
// public ApiResponseDto<ModelMngDto.FormConfigRes> getFormConfig() {
|
||||||
@ApiResponse(responseCode = "404", description = "모델을 찾을 수 없음", content = @Content),
|
// return ApiResponseDto.ok(modelTrainService.getFormConfig());
|
||||||
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
|
// }
|
||||||
})
|
//
|
||||||
@PostMapping("/train/{uuid}/best-epoch")
|
// @Operation(summary = "학습 시작", description = "모든 설정(Step 1~3)을 마치고 최종적으로 학습 프로세스를 시작합니다")
|
||||||
public ApiResponseDto<ModelMngDto.BestEpochResponse> setBestEpoch(
|
// @ApiResponses(
|
||||||
@Parameter(description = "모델 UUID") @PathVariable String uuid,
|
// value = {
|
||||||
@Valid @RequestBody ModelMngDto.BestEpochRequest bestEpochReq) {
|
// @ApiResponse(
|
||||||
return ApiResponseDto.ok(modelTrainService.setBestEpoch(uuid, bestEpochReq));
|
// responseCode = "200",
|
||||||
}
|
// description = "학습 시작 성공",
|
||||||
|
// content =
|
||||||
@Operation(summary = "Epoch별 성능 지표 조회", description = "학습된 모델의 Epoch별 성능 지표를 조회합니다")
|
// @Content(
|
||||||
@ApiResponses(
|
// mediaType = "application/json",
|
||||||
value = {
|
// schema = @Schema(implementation = ModelMngDto.TrainStartRes.class))),
|
||||||
@ApiResponse(
|
// @ApiResponse(responseCode = "400", description = "잘못된 요청", content = @Content),
|
||||||
responseCode = "200",
|
// @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
|
||||||
description = "조회 성공",
|
// })
|
||||||
content =
|
// @PostMapping("/train")
|
||||||
@Content(
|
// public ApiResponseDto<ModelMngDto.TrainStartRes> startTraining(
|
||||||
mediaType = "application/json",
|
// @Valid @RequestBody ModelMngDto.TrainStartReq trainReq) {
|
||||||
schema = @Schema(implementation = List.class))),
|
// return ApiResponseDto.ok(modelTrainService.startTraining(trainReq));
|
||||||
@ApiResponse(responseCode = "404", description = "모델을 찾을 수 없음", content = @Content),
|
// }
|
||||||
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
|
//
|
||||||
})
|
// @Operation(summary = "학습 모델 삭제", description = "목록에서 특정 학습 모델을 삭제합니다")
|
||||||
@GetMapping("/train/{uuid}/epoch-metrics")
|
// @ApiResponses(
|
||||||
public ApiResponseDto<List<ModelMngDto.EpochMetric>> getEpochMetrics(
|
// value = {
|
||||||
@Parameter(description = "모델 UUID") @PathVariable String uuid) {
|
// @ApiResponse(responseCode = "200", description = "삭제 성공", content = @Content),
|
||||||
return ApiResponseDto.ok(modelTrainService.getEpochMetrics(uuid));
|
// @ApiResponse(responseCode = "400", description = "진행 중인 모델은 삭제 불가", content = @Content),
|
||||||
}
|
// @ApiResponse(responseCode = "404", description = "모델을 찾을 수 없음", content = @Content),
|
||||||
|
// @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
|
||||||
|
// })
|
||||||
|
// @DeleteMapping("/train/{uuid}")
|
||||||
|
// public ApiResponseDto<Void> deleteTrainModel(
|
||||||
|
// @Parameter(description = "모델 UUID") @PathVariable String uuid) {
|
||||||
|
// modelTrainService.deleteTrainModel(uuid);
|
||||||
|
// return ApiResponseDto.ok(null);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // ==================== Resume Training (학습 재시작) ====================
|
||||||
|
//
|
||||||
|
// @Operation(summary = "학습 재시작 정보 조회", description = "중단된 학습의 재시작 가능 여부와 Checkpoint 정보를 조회합니다")
|
||||||
|
// @ApiResponses(
|
||||||
|
// value = {
|
||||||
|
// @ApiResponse(
|
||||||
|
// responseCode = "200",
|
||||||
|
// description = "조회 성공",
|
||||||
|
// content =
|
||||||
|
// @Content(
|
||||||
|
// mediaType = "application/json",
|
||||||
|
// schema = @Schema(implementation = ModelMngDto.ResumeInfo.class))),
|
||||||
|
// @ApiResponse(responseCode = "404", description = "모델을 찾을 수 없음", content = @Content),
|
||||||
|
// @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
|
||||||
|
// })
|
||||||
|
// @GetMapping("/train/{uuid}/resume-info")
|
||||||
|
// public ApiResponseDto<ModelMngDto.ResumeInfo> getResumeInfo(
|
||||||
|
// @Parameter(description = "모델 UUID") @PathVariable String uuid) {
|
||||||
|
// return ApiResponseDto.ok(modelTrainService.getResumeInfo(uuid));
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Operation(summary = "학습 재시작", description = "중단된 지점(Checkpoint)부터 학습을 재개합니다")
|
||||||
|
// @ApiResponses(
|
||||||
|
// value = {
|
||||||
|
// @ApiResponse(
|
||||||
|
// responseCode = "200",
|
||||||
|
// description = "재시작 성공",
|
||||||
|
// content =
|
||||||
|
// @Content(
|
||||||
|
// mediaType = "application/json",
|
||||||
|
// schema = @Schema(implementation = ModelMngDto.ResumeResponse.class))),
|
||||||
|
// @ApiResponse(responseCode = "400", description = "재시작 불가능한 상태", content = @Content),
|
||||||
|
// @ApiResponse(responseCode = "404", description = "모델을 찾을 수 없음", content = @Content),
|
||||||
|
// @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
|
||||||
|
// })
|
||||||
|
// @PostMapping("/train/{uuid}/resume")
|
||||||
|
// public ApiResponseDto<ModelMngDto.ResumeResponse> resumeTraining(
|
||||||
|
// @Parameter(description = "모델 UUID") @PathVariable String uuid,
|
||||||
|
// @Valid @RequestBody ModelMngDto.ResumeRequest resumeReq) {
|
||||||
|
// return ApiResponseDto.ok(modelTrainService.resumeTraining(uuid, resumeReq));
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // ==================== Best Epoch Setting (Best Epoch 설정) ====================
|
||||||
|
//
|
||||||
|
// @Operation(summary = "Best Epoch 설정", description = "사용자가 직접 Best Epoch를 선택하여 설정합니다")
|
||||||
|
// @ApiResponses(
|
||||||
|
// value = {
|
||||||
|
// @ApiResponse(
|
||||||
|
// responseCode = "200",
|
||||||
|
// description = "설정 성공",
|
||||||
|
// content =
|
||||||
|
// @Content(
|
||||||
|
// mediaType = "application/json",
|
||||||
|
// schema = @Schema(implementation = ModelMngDto.BestEpochResponse.class))),
|
||||||
|
// @ApiResponse(responseCode = "404", description = "모델을 찾을 수 없음", content = @Content),
|
||||||
|
// @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
|
||||||
|
// })
|
||||||
|
// @PostMapping("/train/{uuid}/best-epoch")
|
||||||
|
// public ApiResponseDto<ModelMngDto.BestEpochResponse> setBestEpoch(
|
||||||
|
// @Parameter(description = "모델 UUID") @PathVariable String uuid,
|
||||||
|
// @Valid @RequestBody ModelMngDto.BestEpochRequest bestEpochReq) {
|
||||||
|
// return ApiResponseDto.ok(modelTrainService.setBestEpoch(uuid, bestEpochReq));
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Operation(summary = "Epoch별 성능 지표 조회", description = "학습된 모델의 Epoch별 성능 지표를 조회합니다")
|
||||||
|
// @ApiResponses(
|
||||||
|
// value = {
|
||||||
|
// @ApiResponse(
|
||||||
|
// responseCode = "200",
|
||||||
|
// description = "조회 성공",
|
||||||
|
// content =
|
||||||
|
// @Content(
|
||||||
|
// mediaType = "application/json",
|
||||||
|
// schema = @Schema(implementation = List.class))),
|
||||||
|
// @ApiResponse(responseCode = "404", description = "모델을 찾을 수 없음", content = @Content),
|
||||||
|
// @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
|
||||||
|
// })
|
||||||
|
// @GetMapping("/train/{uuid}/epoch-metrics")
|
||||||
|
// public ApiResponseDto<List<ModelMngDto.EpochMetric>> getEpochMetrics(
|
||||||
|
// @Parameter(description = "모델 UUID") @PathVariable String uuid) {
|
||||||
|
// return ApiResponseDto.ok(modelTrainService.getEpochMetrics(uuid));
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ public class ModelMngDto {
|
|||||||
private String step1Status;
|
private String step1Status;
|
||||||
private String step2Status;
|
private String step2Status;
|
||||||
private String transferStatus;
|
private String transferStatus;
|
||||||
|
private String statusCd;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Schema(name = "searchReq", description = "모델 관리 목록조회 파라미터")
|
@Schema(name = "searchReq", description = "모델 관리 목록조회 파라미터")
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import com.kamco.cd.training.model.dto.ModelMngDto;
|
|||||||
import com.kamco.cd.training.model.dto.ModelMngDto.Basic;
|
import com.kamco.cd.training.model.dto.ModelMngDto.Basic;
|
||||||
import com.kamco.cd.training.model.dto.ModelMngDto.SearchReq;
|
import com.kamco.cd.training.model.dto.ModelMngDto.SearchReq;
|
||||||
import com.kamco.cd.training.postgres.core.ModelMngCoreService;
|
import com.kamco.cd.training.postgres.core.ModelMngCoreService;
|
||||||
|
import java.util.UUID;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
@@ -24,10 +25,12 @@ public class ModelMngService {
|
|||||||
* @param searchReq 검색 조건
|
* @param searchReq 검색 조건
|
||||||
* @return 페이징 처리된 모델 목록
|
* @return 페이징 처리된 모델 목록
|
||||||
*/
|
*/
|
||||||
public Page<Basic> findByModels(SearchReq searchReq) {
|
public Page<Basic> getModelList(SearchReq searchReq) {
|
||||||
return modelMngCoreService.findByModels(searchReq);
|
return modelMngCoreService.findByModelList(searchReq);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void deleteModelTrain(UUID uuid) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 모델 상세 조회
|
* 모델 상세 조회
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ public class HyperParamCoreService {
|
|||||||
throw new CustomApiException("CONFLICT", HttpStatus.CONFLICT, "HPs_0001 버전은 삭제할수 없습니다.");
|
throw new CustomApiException("CONFLICT", HttpStatus.CONFLICT, "HPs_0001 버전은 삭제할수 없습니다.");
|
||||||
}
|
}
|
||||||
|
|
||||||
entity.setDelYn("Y");
|
entity.setDelYn(true);
|
||||||
entity.setUpdatedUid(userUtil.getId());
|
entity.setUpdatedUid(userUtil.getId());
|
||||||
entity.setUpdatedDttm(ZonedDateTime.now());
|
entity.setUpdatedDttm(ZonedDateTime.now());
|
||||||
}
|
}
|
||||||
@@ -132,6 +132,8 @@ public class HyperParamCoreService {
|
|||||||
public HyperParamDto.Basic getInitHyperParam() {
|
public HyperParamDto.Basic getInitHyperParam() {
|
||||||
ModelHyperParamEntity entity = new ModelHyperParamEntity();
|
ModelHyperParamEntity entity = new ModelHyperParamEntity();
|
||||||
entity.setUuid(null);
|
entity.setUuid(null);
|
||||||
|
entity.setHyperVer(null);
|
||||||
|
entity.setCreatedDttm(null);
|
||||||
return entity.toDto();
|
return entity.toDto();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.kamco.cd.training.postgres.core;
|
package com.kamco.cd.training.postgres.core;
|
||||||
|
|
||||||
import com.kamco.cd.training.common.exception.BadRequestException;
|
import com.kamco.cd.training.common.exception.BadRequestException;
|
||||||
|
import com.kamco.cd.training.common.exception.CustomApiException;
|
||||||
import com.kamco.cd.training.common.exception.NotFoundException;
|
import com.kamco.cd.training.common.exception.NotFoundException;
|
||||||
import com.kamco.cd.training.model.dto.ModelMngDto;
|
import com.kamco.cd.training.model.dto.ModelMngDto;
|
||||||
import com.kamco.cd.training.model.dto.ModelMngDto.Basic;
|
import com.kamco.cd.training.model.dto.ModelMngDto.Basic;
|
||||||
@@ -10,8 +11,10 @@ import com.kamco.cd.training.postgres.repository.model.ModelDatasetMappRepositor
|
|||||||
import com.kamco.cd.training.postgres.repository.model.ModelMngRepository;
|
import com.kamco.cd.training.postgres.repository.model.ModelMngRepository;
|
||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@@ -26,11 +29,19 @@ public class ModelMngCoreService {
|
|||||||
* @param searchReq 검색 조건
|
* @param searchReq 검색 조건
|
||||||
* @return 페이징 처리된 모델 목록
|
* @return 페이징 처리된 모델 목록
|
||||||
*/
|
*/
|
||||||
public Page<Basic> findByModels(ModelMngDto.SearchReq searchReq) {
|
public Page<Basic> findByModelList(ModelMngDto.SearchReq searchReq) {
|
||||||
Page<ModelTrainMasterEntity> entityPage = modelMngRepository.findByModels(searchReq);
|
Page<ModelTrainMasterEntity> entityPage = modelMngRepository.findByModels(searchReq);
|
||||||
return entityPage.map(ModelTrainMasterEntity::toDto);
|
return entityPage.map(ModelTrainMasterEntity::toDto);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void deleteModel(UUID uuid) {
|
||||||
|
ModelTrainMasterEntity entity =
|
||||||
|
modelMngRepository
|
||||||
|
.findByUuid(uuid)
|
||||||
|
.orElseThrow(() -> new CustomApiException("NOT_FOUND_DATA", HttpStatus.NOT_FOUND));
|
||||||
|
// entity.setDelYn();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 모델 상세 조회
|
* 모델 상세 조회
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -280,9 +280,9 @@ public class ModelHyperParamEntity {
|
|||||||
private String memo;
|
private String memo;
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@ColumnDefault("'N'")
|
@ColumnDefault("false")
|
||||||
@Column(name = "del_yn", nullable = false, length = 1)
|
@Column(name = "del_yn", nullable = false, length = 1)
|
||||||
private String delYn = "N";
|
private Boolean delYn = false;
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@ColumnDefault("CURRENT_TIMESTAMP")
|
@ColumnDefault("CURRENT_TIMESTAMP")
|
||||||
@@ -319,7 +319,8 @@ public class ModelHyperParamEntity {
|
|||||||
public HyperParamDto.Basic toDto() {
|
public HyperParamDto.Basic toDto() {
|
||||||
return new HyperParamDto.Basic(
|
return new HyperParamDto.Basic(
|
||||||
this.uuid,
|
this.uuid,
|
||||||
|
this.hyperVer,
|
||||||
|
this.createdDttm,
|
||||||
// -------------------------
|
// -------------------------
|
||||||
// Important
|
// Important
|
||||||
// -------------------------
|
// -------------------------
|
||||||
|
|||||||
@@ -186,6 +186,7 @@ public class ModelTrainMasterEntity {
|
|||||||
this.step2Duration,
|
this.step2Duration,
|
||||||
this.step1Status,
|
this.step1Status,
|
||||||
this.step2Status,
|
this.step2Status,
|
||||||
this.transferStatus);
|
this.transferStatus,
|
||||||
|
this.statusCd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ public class HyperParamRepositoryImpl implements HyperParamRepositoryCustom {
|
|||||||
queryFactory
|
queryFactory
|
||||||
.select(modelHyperParamEntity)
|
.select(modelHyperParamEntity)
|
||||||
.from(modelHyperParamEntity)
|
.from(modelHyperParamEntity)
|
||||||
.where(modelHyperParamEntity.delYn.eq("N"))
|
.where(modelHyperParamEntity.delYn.isFalse())
|
||||||
.orderBy(modelHyperParamEntity.hyperVer.desc())
|
.orderBy(modelHyperParamEntity.hyperVer.desc())
|
||||||
.limit(1)
|
.limit(1)
|
||||||
.fetchOne());
|
.fetchOne());
|
||||||
@@ -47,7 +47,7 @@ public class HyperParamRepositoryImpl implements HyperParamRepositoryCustom {
|
|||||||
queryFactory
|
queryFactory
|
||||||
.select(modelHyperParamEntity)
|
.select(modelHyperParamEntity)
|
||||||
.from(modelHyperParamEntity)
|
.from(modelHyperParamEntity)
|
||||||
.where(modelHyperParamEntity.delYn.eq("N").and(modelHyperParamEntity.uuid.eq(uuid)))
|
.where(modelHyperParamEntity.delYn.isFalse().and(modelHyperParamEntity.uuid.eq(uuid)))
|
||||||
.fetchOne());
|
.fetchOne());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,7 +56,7 @@ public class HyperParamRepositoryImpl implements HyperParamRepositoryCustom {
|
|||||||
Pageable pageable = req.toPageable();
|
Pageable pageable = req.toPageable();
|
||||||
|
|
||||||
BooleanBuilder builder = new BooleanBuilder();
|
BooleanBuilder builder = new BooleanBuilder();
|
||||||
builder.and(modelHyperParamEntity.delYn.eq("N"));
|
builder.and(modelHyperParamEntity.delYn.isFalse());
|
||||||
|
|
||||||
if (req.getHyperVer() != null && !req.getHyperVer().isEmpty()) {
|
if (req.getHyperVer() != null && !req.getHyperVer().isEmpty()) {
|
||||||
// 버전
|
// 버전
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ package com.kamco.cd.training.postgres.repository.model;
|
|||||||
|
|
||||||
import com.kamco.cd.training.model.dto.ModelMngDto;
|
import com.kamco.cd.training.model.dto.ModelMngDto;
|
||||||
import com.kamco.cd.training.postgres.entity.ModelTrainMasterEntity;
|
import com.kamco.cd.training.postgres.entity.ModelTrainMasterEntity;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.UUID;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
|
|
||||||
public interface ModelMngRepositoryCustom {
|
public interface ModelMngRepositoryCustom {
|
||||||
@@ -13,4 +15,6 @@ public interface ModelMngRepositoryCustom {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
Page<ModelTrainMasterEntity> findByModels(ModelMngDto.SearchReq searchReq);
|
Page<ModelTrainMasterEntity> findByModels(ModelMngDto.SearchReq searchReq);
|
||||||
|
|
||||||
|
Optional<ModelTrainMasterEntity> findByUuid(UUID uuid);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
package com.kamco.cd.training.postgres.repository.model;
|
package com.kamco.cd.training.postgres.repository.model;
|
||||||
|
|
||||||
|
import static com.kamco.cd.training.postgres.entity.QModelTrainMasterEntity.modelTrainMasterEntity;
|
||||||
|
|
||||||
import com.kamco.cd.training.model.dto.ModelMngDto;
|
import com.kamco.cd.training.model.dto.ModelMngDto;
|
||||||
import com.kamco.cd.training.postgres.entity.ModelTrainMasterEntity;
|
import com.kamco.cd.training.postgres.entity.ModelTrainMasterEntity;
|
||||||
import com.kamco.cd.training.postgres.entity.QModelTrainMasterEntity;
|
|
||||||
import com.querydsl.core.BooleanBuilder;
|
import com.querydsl.core.BooleanBuilder;
|
||||||
import com.querydsl.jpa.impl.JPAQueryFactory;
|
import com.querydsl.jpa.impl.JPAQueryFactory;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.UUID;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.PageImpl;
|
import org.springframework.data.domain.PageImpl;
|
||||||
@@ -18,43 +20,57 @@ import org.springframework.stereotype.Repository;
|
|||||||
public class ModelMngRepositoryImpl implements ModelMngRepositoryCustom {
|
public class ModelMngRepositoryImpl implements ModelMngRepositoryCustom {
|
||||||
|
|
||||||
private final JPAQueryFactory queryFactory;
|
private final JPAQueryFactory queryFactory;
|
||||||
private final QModelTrainMasterEntity modelMng = QModelTrainMasterEntity.modelTrainMasterEntity;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 모델 목록 조회
|
* 모델 목록 조회
|
||||||
*
|
*
|
||||||
* @param searchReq
|
* @param req
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Page<ModelTrainMasterEntity> findByModels(ModelMngDto.SearchReq searchReq) {
|
public Page<ModelTrainMasterEntity> findByModels(ModelMngDto.SearchReq req) {
|
||||||
Pageable pageable = searchReq.toPageable();
|
Pageable pageable = req.toPageable();
|
||||||
BooleanBuilder builder = new BooleanBuilder();
|
BooleanBuilder builder = new BooleanBuilder();
|
||||||
//
|
|
||||||
// if (StringUtils.isNotBlank(searchReq.getStatus())) {
|
|
||||||
// builder.and(modelMng.statusCd.eq(searchReq.getStatus()));
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Entity 직접 조회 (Projections 사용 지양)
|
if (req.getStatus() != null && !req.getStatus().isEmpty()) {
|
||||||
|
builder.and(modelTrainMasterEntity.statusCd.eq(req.getStatus()));
|
||||||
|
}
|
||||||
|
|
||||||
List<ModelTrainMasterEntity> content =
|
List<ModelTrainMasterEntity> content =
|
||||||
queryFactory
|
queryFactory
|
||||||
.selectFrom(modelMng)
|
.selectFrom(modelTrainMasterEntity)
|
||||||
.where(builder.and(modelMng.delYn.isFalse()))
|
.where(builder)
|
||||||
.offset(pageable.getOffset())
|
.offset(pageable.getOffset())
|
||||||
.limit(pageable.getPageSize())
|
.limit(pageable.getPageSize())
|
||||||
.orderBy(modelMng.createdDttm.desc())
|
.orderBy(modelTrainMasterEntity.createdDttm.desc())
|
||||||
.fetch();
|
.fetch();
|
||||||
|
|
||||||
// Count 쿼리 별도 실행 (null safe handling)
|
// Count 쿼리 별도 실행 (null safe handling)
|
||||||
long total =
|
Long total =
|
||||||
Optional.ofNullable(
|
|
||||||
queryFactory
|
queryFactory
|
||||||
.select(modelMng.count())
|
.select(modelTrainMasterEntity.count())
|
||||||
.from(modelMng)
|
.from(modelTrainMasterEntity)
|
||||||
.where(builder.and(modelMng.delYn.isFalse()))
|
.where(builder)
|
||||||
.fetchOne())
|
.fetchOne();
|
||||||
.orElse(0L);
|
|
||||||
|
|
||||||
return new PageImpl<>(content, pageable, total);
|
long totalCount = (total != null) ? total : 0L;
|
||||||
|
|
||||||
|
return new PageImpl<>(content, pageable, totalCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 모델 조회
|
||||||
|
*
|
||||||
|
* @param uuid
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Optional<ModelTrainMasterEntity> findByUuid(UUID uuid) {
|
||||||
|
return Optional.ofNullable(
|
||||||
|
queryFactory
|
||||||
|
.select(modelTrainMasterEntity)
|
||||||
|
.from(modelTrainMasterEntity)
|
||||||
|
.where(modelTrainMasterEntity.uuid.eq(uuid))
|
||||||
|
.fetchOne());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user