데이터셋 1개일 때 심볼릭 링크 생성하지 않게 수정
This commit is contained in:
@@ -176,6 +176,8 @@ public class ModelTrainMngDto {
|
||||
|
||||
private String requestPath;
|
||||
private String responsePath;
|
||||
private String tmpFileStatus;
|
||||
private ZonedDateTime tmpFileEndDttm;
|
||||
}
|
||||
|
||||
@Getter
|
||||
|
||||
@@ -305,7 +305,19 @@ public class ModelTrainMngService {
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -180,6 +180,9 @@ public class ModelTrainMngCoreService {
|
||||
if (req.getRequestPath() != null && !req.getRequestPath().isEmpty()) {
|
||||
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) {
|
||||
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")
|
||||
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() {
|
||||
return new ModelTrainMngDto.Basic(
|
||||
this.id,
|
||||
|
||||
@@ -189,7 +189,8 @@ public class ModelMngRepositoryImpl implements ModelMngRepositoryCustom {
|
||||
modelHyperParamEntity.hueDelta,
|
||||
Expressions.nullExpression(Integer.class),
|
||||
Expressions.nullExpression(String.class),
|
||||
modelHyperParamEntity.uuid))
|
||||
modelHyperParamEntity.uuid,
|
||||
modelMasterEntity.reqTmpYn))
|
||||
.from(modelMasterEntity)
|
||||
.leftJoin(modelHyperParamEntity)
|
||||
.on(modelHyperParamEntity.id.eq(modelMasterEntity.hyperParamId))
|
||||
|
||||
@@ -15,6 +15,7 @@ public class EvalRunRequest {
|
||||
private Integer timeoutSeconds;
|
||||
private String datasetFolder;
|
||||
private String outputFolder;
|
||||
private Boolean reqTmpYn;
|
||||
|
||||
public String getOutputFolder() {
|
||||
return this.outputFolder.toString();
|
||||
|
||||
@@ -84,6 +84,8 @@ public class TrainRunRequest {
|
||||
|
||||
private UUID uuid;
|
||||
|
||||
private Boolean reqTmpYn; // tmp 심볼릭 링크를 쓰는지 아닌지 여부
|
||||
|
||||
public String getOutputFolder() {
|
||||
return String.valueOf(this.outputFolder);
|
||||
}
|
||||
|
||||
@@ -271,7 +271,11 @@ public class DockerTrainService {
|
||||
c.add("-v");
|
||||
c.add(basePath + ":" + basePath); // 심볼릭 링크와 연결되는 실제 파일 경로도 마운트를 해줘야 함
|
||||
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(responseDir + ":/checkpoints"); // 저장될경로
|
||||
|
||||
@@ -472,8 +476,13 @@ public class DockerTrainService {
|
||||
|
||||
c.add("-v");
|
||||
c.add(basePath + ":" + basePath); // 심볼릭 링크와 연결되는 실제 파일 경로도 마운트를 해줘야 함
|
||||
|
||||
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(responseDir + ":/checkpoints");
|
||||
|
||||
@@ -269,7 +269,7 @@ public class ModelTestMetricsJobService {
|
||||
zipFiles(zipFileList, individualZipPath);
|
||||
|
||||
log.info(
|
||||
"✅ 개별 ZIP 생성 완료: fileName={}, pthFile={}, size={} bytes",
|
||||
"개별 ZIP 생성 완료: fileName={}, pthFile={}, size={} bytes",
|
||||
individualZipName,
|
||||
pthFileName,
|
||||
Files.size(individualZipPath));
|
||||
|
||||
@@ -204,6 +204,18 @@ public class TrainJobService {
|
||||
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 {
|
||||
NONE, // 새로 시작
|
||||
REQUIRE // 이어하기
|
||||
@@ -274,6 +286,9 @@ public class TrainJobService {
|
||||
List<String> uids = modelTrainMngCoreService.findDatasetUid(datasetIds);
|
||||
|
||||
try {
|
||||
// 1. 시작 상태 업데이트
|
||||
modelTrainMngCoreService.updateTmpFileStatusStart(modelId);
|
||||
|
||||
// 데이터셋 심볼링크 생성
|
||||
// String pathUid = tmpDatasetService.buildTmpDatasetSymlink(raw, uids);
|
||||
// train path 모델 클래스별 조회
|
||||
@@ -298,6 +313,8 @@ public class TrainJobService {
|
||||
|
||||
ModelTrainMngDto.UpdateReq updateReq = new ModelTrainMngDto.UpdateReq();
|
||||
updateReq.setRequestPath(raw);
|
||||
updateReq.setTmpFileStatus("COMPLETE");
|
||||
updateReq.setTmpFileEndDttm(ZonedDateTime.now());
|
||||
|
||||
// 학습모델을 수정한다.
|
||||
modelTrainMngCoreService.updateModelMaster(modelId, updateReq);
|
||||
@@ -311,6 +328,9 @@ public class TrainJobService {
|
||||
(uids == null ? null : uids.size()),
|
||||
e);
|
||||
|
||||
// 3. 실패 처리
|
||||
modelTrainMngCoreService.updateTmpFileStatusFail(modelId, e.getMessage());
|
||||
|
||||
// 런타임 예외로 래핑하되, 메시지에 핵심 정보 포함
|
||||
throw new CustomApiException(
|
||||
"INTERNAL_SERVER_ERROR", HttpStatus.INTERNAL_SERVER_ERROR, "임시 데이터셋 생성에 실패했습니다.");
|
||||
|
||||
@@ -87,6 +87,7 @@ public class TrainJobWorker {
|
||||
evalReq.setTimeoutSeconds(null);
|
||||
evalReq.setDatasetFolder(datasetFolder);
|
||||
evalReq.setOutputFolder(outputFolder);
|
||||
evalReq.setReqTmpYn((Boolean) params.get("reqTmpYn"));
|
||||
log.info("[JOB] selected test epoch={}", epoch);
|
||||
|
||||
// 도커 실행 후 로그 수집
|
||||
|
||||
Reference in New Issue
Block a user