데이터셋 1개일 때 심볼릭 링크 생성하지 않게 수정
This commit is contained in:
@@ -176,6 +176,8 @@ public class ModelTrainMngDto {
|
|||||||
|
|
||||||
private String requestPath;
|
private String requestPath;
|
||||||
private String responsePath;
|
private String responsePath;
|
||||||
|
private String tmpFileStatus;
|
||||||
|
private ZonedDateTime tmpFileEndDttm;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
|
|||||||
@@ -305,7 +305,19 @@ public class ModelTrainMngService {
|
|||||||
modelTrainMngCoreService.saveModelConfig(modelId, req.getModelConfig());
|
modelTrainMngCoreService.saveModelConfig(modelId, req.getModelConfig());
|
||||||
|
|
||||||
// 데이터셋 임시파일 생성
|
// 데이터셋 임시파일 생성
|
||||||
trainJobService.createTmpFile(modelUuid);
|
List<Long> datasetList = null;
|
||||||
|
if (req.getTrainingDataset() != null) {
|
||||||
|
datasetList = req.getTrainingDataset().getDatasetList();
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isSingleDataset = datasetList != null && datasetList.size() == 1;
|
||||||
|
|
||||||
|
// 데이터셋 1개만 선택한 경우는 symbolic link 미생성 해도 됨 -> train 호출 시 그냥 데이터셋 request 경로로 호출
|
||||||
|
if (isSingleDataset) {
|
||||||
|
trainJobService.updateRequestPath(modelUuid, datasetList);
|
||||||
|
} else {
|
||||||
|
trainJobService.createTmpFile(modelUuid);
|
||||||
|
}
|
||||||
return modelUuid;
|
return modelUuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -180,6 +180,9 @@ public class ModelTrainMngCoreService {
|
|||||||
if (req.getRequestPath() != null && !req.getRequestPath().isEmpty()) {
|
if (req.getRequestPath() != null && !req.getRequestPath().isEmpty()) {
|
||||||
entity.setRequestPath(req.getRequestPath());
|
entity.setRequestPath(req.getRequestPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
entity.setTmpFileStatus(req.getTmpFileStatus());
|
||||||
|
entity.setTmpFileEndDttm(req.getTmpFileEndDttm());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -673,4 +676,36 @@ public class ModelTrainMngCoreService {
|
|||||||
public List<ModelTrainLinkDto> findDatasetTestPath(Long modelId) {
|
public List<ModelTrainLinkDto> findDatasetTestPath(Long modelId) {
|
||||||
return modelDatasetMapRepository.findDatasetTestPath(modelId);
|
return modelDatasetMapRepository.findDatasetTestPath(modelId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void updateTrainRequestPath(Long modelId, String datasetUid) {
|
||||||
|
ModelMasterEntity entity =
|
||||||
|
modelMngRepository
|
||||||
|
.findById(modelId)
|
||||||
|
.orElseThrow(() -> new CustomApiException("NOT_FOUND_DATA", HttpStatus.NOT_FOUND));
|
||||||
|
|
||||||
|
// 임시폴더 UID업데이트
|
||||||
|
entity.setRequestPath(datasetUid);
|
||||||
|
entity.setReqTmpYn(false); // false 인 것은 train, test 실행 시 docker 명령어에 request 폴더를 바라보게 할 예정
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateTmpFileStatusStart(Long modelId) {
|
||||||
|
ModelMasterEntity entity =
|
||||||
|
modelMngRepository
|
||||||
|
.findById(modelId)
|
||||||
|
.orElseThrow(() -> new CustomApiException("NOT_FOUND_DATA", HttpStatus.NOT_FOUND));
|
||||||
|
|
||||||
|
entity.setReqTmpYn(true);
|
||||||
|
entity.setTmpFileStatus("IN_PROGRESS");
|
||||||
|
entity.setTmpFileStartDttm(ZonedDateTime.now());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateTmpFileStatusFail(Long modelId, String message) {
|
||||||
|
ModelMasterEntity entity =
|
||||||
|
modelMngRepository
|
||||||
|
.findById(modelId)
|
||||||
|
.orElseThrow(() -> new CustomApiException("NOT_FOUND_DATA", HttpStatus.NOT_FOUND));
|
||||||
|
|
||||||
|
entity.setTmpFileStatus("FAIL");
|
||||||
|
entity.setTmpFileErrMessage(message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -121,6 +121,21 @@ public class ModelMasterEntity {
|
|||||||
@Column(name = "packing_end_dttm")
|
@Column(name = "packing_end_dttm")
|
||||||
private ZonedDateTime packingEndDttm;
|
private ZonedDateTime packingEndDttm;
|
||||||
|
|
||||||
|
@Column(name = "req_tmp_yn")
|
||||||
|
private Boolean reqTmpYn;
|
||||||
|
|
||||||
|
@Column(name = "tmp_file_status")
|
||||||
|
private String tmpFileStatus;
|
||||||
|
|
||||||
|
@Column(name = "tmp_file_start_dttm")
|
||||||
|
private ZonedDateTime tmpFileStartDttm;
|
||||||
|
|
||||||
|
@Column(name = "tmp_file_end_dttm")
|
||||||
|
private ZonedDateTime tmpFileEndDttm;
|
||||||
|
|
||||||
|
@Column(name = "tmp_file_err_message", columnDefinition = "TEXT")
|
||||||
|
private String tmpFileErrMessage;
|
||||||
|
|
||||||
public ModelTrainMngDto.Basic toDto() {
|
public ModelTrainMngDto.Basic toDto() {
|
||||||
return new ModelTrainMngDto.Basic(
|
return new ModelTrainMngDto.Basic(
|
||||||
this.id,
|
this.id,
|
||||||
|
|||||||
@@ -189,7 +189,8 @@ public class ModelMngRepositoryImpl implements ModelMngRepositoryCustom {
|
|||||||
modelHyperParamEntity.hueDelta,
|
modelHyperParamEntity.hueDelta,
|
||||||
Expressions.nullExpression(Integer.class),
|
Expressions.nullExpression(Integer.class),
|
||||||
Expressions.nullExpression(String.class),
|
Expressions.nullExpression(String.class),
|
||||||
modelHyperParamEntity.uuid))
|
modelHyperParamEntity.uuid,
|
||||||
|
modelMasterEntity.reqTmpYn))
|
||||||
.from(modelMasterEntity)
|
.from(modelMasterEntity)
|
||||||
.leftJoin(modelHyperParamEntity)
|
.leftJoin(modelHyperParamEntity)
|
||||||
.on(modelHyperParamEntity.id.eq(modelMasterEntity.hyperParamId))
|
.on(modelHyperParamEntity.id.eq(modelMasterEntity.hyperParamId))
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ public class EvalRunRequest {
|
|||||||
private Integer timeoutSeconds;
|
private Integer timeoutSeconds;
|
||||||
private String datasetFolder;
|
private String datasetFolder;
|
||||||
private String outputFolder;
|
private String outputFolder;
|
||||||
|
private Boolean reqTmpYn;
|
||||||
|
|
||||||
public String getOutputFolder() {
|
public String getOutputFolder() {
|
||||||
return this.outputFolder.toString();
|
return this.outputFolder.toString();
|
||||||
|
|||||||
@@ -84,6 +84,8 @@ public class TrainRunRequest {
|
|||||||
|
|
||||||
private UUID uuid;
|
private UUID uuid;
|
||||||
|
|
||||||
|
private Boolean reqTmpYn; // tmp 심볼릭 링크를 쓰는지 아닌지 여부
|
||||||
|
|
||||||
public String getOutputFolder() {
|
public String getOutputFolder() {
|
||||||
return String.valueOf(this.outputFolder);
|
return String.valueOf(this.outputFolder);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -271,7 +271,11 @@ public class DockerTrainService {
|
|||||||
c.add("-v");
|
c.add("-v");
|
||||||
c.add(basePath + ":" + basePath); // 심볼릭 링크와 연결되는 실제 파일 경로도 마운트를 해줘야 함
|
c.add(basePath + ":" + basePath); // 심볼릭 링크와 연결되는 실제 파일 경로도 마운트를 해줘야 함
|
||||||
c.add("-v");
|
c.add("-v");
|
||||||
c.add(symbolicDir + ":/data"); // 요청할경로
|
if (req.getReqTmpYn()) {
|
||||||
|
c.add(symbolicDir + ":/data"); // 요청할경로 : tmp 심볼릭 사용하는 것이니 symbolicDir로 호출
|
||||||
|
} else {
|
||||||
|
c.add(requestDir + ":/data"); // 요청할경로 : tmp 심볼릭 사용하지 않으니 request로 호출
|
||||||
|
}
|
||||||
c.add("-v");
|
c.add("-v");
|
||||||
c.add(responseDir + ":/checkpoints"); // 저장될경로
|
c.add(responseDir + ":/checkpoints"); // 저장될경로
|
||||||
|
|
||||||
@@ -472,8 +476,13 @@ public class DockerTrainService {
|
|||||||
|
|
||||||
c.add("-v");
|
c.add("-v");
|
||||||
c.add(basePath + ":" + basePath); // 심볼릭 링크와 연결되는 실제 파일 경로도 마운트를 해줘야 함
|
c.add(basePath + ":" + basePath); // 심볼릭 링크와 연결되는 실제 파일 경로도 마운트를 해줘야 함
|
||||||
|
|
||||||
c.add("-v");
|
c.add("-v");
|
||||||
c.add(basePath + "/tmp:/data");
|
if (req.getReqTmpYn()) {
|
||||||
|
c.add(symbolicDir + ":/data"); // tmp 사용하는 모델은 심볼릭 링크
|
||||||
|
} else {
|
||||||
|
c.add(requestDir + ":/data"); // tmp 사용하지 않는 모델은 request 경로
|
||||||
|
}
|
||||||
|
|
||||||
c.add("-v");
|
c.add("-v");
|
||||||
c.add(responseDir + ":/checkpoints");
|
c.add(responseDir + ":/checkpoints");
|
||||||
|
|||||||
@@ -269,7 +269,7 @@ public class ModelTestMetricsJobService {
|
|||||||
zipFiles(zipFileList, individualZipPath);
|
zipFiles(zipFileList, individualZipPath);
|
||||||
|
|
||||||
log.info(
|
log.info(
|
||||||
"✅ 개별 ZIP 생성 완료: fileName={}, pthFile={}, size={} bytes",
|
"개별 ZIP 생성 완료: fileName={}, pthFile={}, size={} bytes",
|
||||||
individualZipName,
|
individualZipName,
|
||||||
pthFileName,
|
pthFileName,
|
||||||
Files.size(individualZipPath));
|
Files.size(individualZipPath));
|
||||||
|
|||||||
@@ -204,6 +204,18 @@ public class TrainJobService {
|
|||||||
return jobId;
|
return jobId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 데이터셋 1개일 때, 파일 경로 업데이트
|
||||||
|
*
|
||||||
|
* @param modelUuid
|
||||||
|
* @param datasetList
|
||||||
|
*/
|
||||||
|
public void updateRequestPath(UUID modelUuid, List<Long> datasetList) {
|
||||||
|
Long modelId = modelTrainMngCoreService.findModelIdByUuid(modelUuid);
|
||||||
|
List<String> datasetUid = modelTrainMngCoreService.findDatasetUid(datasetList);
|
||||||
|
modelTrainMngCoreService.updateTrainRequestPath(modelId, datasetUid.getFirst());
|
||||||
|
}
|
||||||
|
|
||||||
private enum ResumeMode {
|
private enum ResumeMode {
|
||||||
NONE, // 새로 시작
|
NONE, // 새로 시작
|
||||||
REQUIRE // 이어하기
|
REQUIRE // 이어하기
|
||||||
@@ -274,6 +286,9 @@ public class TrainJobService {
|
|||||||
List<String> uids = modelTrainMngCoreService.findDatasetUid(datasetIds);
|
List<String> uids = modelTrainMngCoreService.findDatasetUid(datasetIds);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// 1. 시작 상태 업데이트
|
||||||
|
modelTrainMngCoreService.updateTmpFileStatusStart(modelId);
|
||||||
|
|
||||||
// 데이터셋 심볼링크 생성
|
// 데이터셋 심볼링크 생성
|
||||||
// String pathUid = tmpDatasetService.buildTmpDatasetSymlink(raw, uids);
|
// String pathUid = tmpDatasetService.buildTmpDatasetSymlink(raw, uids);
|
||||||
// train path 모델 클래스별 조회
|
// train path 모델 클래스별 조회
|
||||||
@@ -298,6 +313,8 @@ public class TrainJobService {
|
|||||||
|
|
||||||
ModelTrainMngDto.UpdateReq updateReq = new ModelTrainMngDto.UpdateReq();
|
ModelTrainMngDto.UpdateReq updateReq = new ModelTrainMngDto.UpdateReq();
|
||||||
updateReq.setRequestPath(raw);
|
updateReq.setRequestPath(raw);
|
||||||
|
updateReq.setTmpFileStatus("COMPLETE");
|
||||||
|
updateReq.setTmpFileEndDttm(ZonedDateTime.now());
|
||||||
|
|
||||||
// 학습모델을 수정한다.
|
// 학습모델을 수정한다.
|
||||||
modelTrainMngCoreService.updateModelMaster(modelId, updateReq);
|
modelTrainMngCoreService.updateModelMaster(modelId, updateReq);
|
||||||
@@ -311,6 +328,9 @@ public class TrainJobService {
|
|||||||
(uids == null ? null : uids.size()),
|
(uids == null ? null : uids.size()),
|
||||||
e);
|
e);
|
||||||
|
|
||||||
|
// 3. 실패 처리
|
||||||
|
modelTrainMngCoreService.updateTmpFileStatusFail(modelId, e.getMessage());
|
||||||
|
|
||||||
// 런타임 예외로 래핑하되, 메시지에 핵심 정보 포함
|
// 런타임 예외로 래핑하되, 메시지에 핵심 정보 포함
|
||||||
throw new CustomApiException(
|
throw new CustomApiException(
|
||||||
"INTERNAL_SERVER_ERROR", HttpStatus.INTERNAL_SERVER_ERROR, "임시 데이터셋 생성에 실패했습니다.");
|
"INTERNAL_SERVER_ERROR", HttpStatus.INTERNAL_SERVER_ERROR, "임시 데이터셋 생성에 실패했습니다.");
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ public class TrainJobWorker {
|
|||||||
evalReq.setTimeoutSeconds(null);
|
evalReq.setTimeoutSeconds(null);
|
||||||
evalReq.setDatasetFolder(datasetFolder);
|
evalReq.setDatasetFolder(datasetFolder);
|
||||||
evalReq.setOutputFolder(outputFolder);
|
evalReq.setOutputFolder(outputFolder);
|
||||||
|
evalReq.setReqTmpYn((Boolean) params.get("reqTmpYn"));
|
||||||
log.info("[JOB] selected test epoch={}", epoch);
|
log.info("[JOB] selected test epoch={}", epoch);
|
||||||
|
|
||||||
// 도커 실행 후 로그 수집
|
// 도커 실행 후 로그 수집
|
||||||
|
|||||||
Reference in New Issue
Block a user