From 9956ca7d6367696f540d7fea32fdb25372dcb374 Mon Sep 17 00:00:00 2001 From: teddy Date: Mon, 2 Feb 2026 19:42:48 +0900 Subject: [PATCH 1/2] =?UTF-8?q?=EB=AA=A8=EB=8D=B8=EA=B4=80=EB=A6=AC=20?= =?UTF-8?q?=ED=95=99=EC=8A=B5=20=EC=A1=B0=ED=9A=8C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cd/training/postgres/entity/ModelHyperParamEntity.java | 6 ++++++ .../cd/training/postgres/entity/ModelTrainMasterEntity.java | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/src/main/java/com/kamco/cd/training/postgres/entity/ModelHyperParamEntity.java b/src/main/java/com/kamco/cd/training/postgres/entity/ModelHyperParamEntity.java index cb33384..12965b8 100644 --- a/src/main/java/com/kamco/cd/training/postgres/entity/ModelHyperParamEntity.java +++ b/src/main/java/com/kamco/cd/training/postgres/entity/ModelHyperParamEntity.java @@ -5,10 +5,13 @@ import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; +import jakarta.persistence.OneToMany; import jakarta.persistence.Table; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; import java.time.ZonedDateTime; +import java.util.LinkedHashSet; +import java.util.Set; import java.util.UUID; import lombok.Getter; import lombok.Setter; @@ -217,4 +220,7 @@ public class ModelHyperParamEntity { @Column(name = "cnn_filter_cnt") private Integer cnnFilterCnt; + + @OneToMany(mappedBy = "hyperParamUuid") + private Set tbModelTrainMasters = new LinkedHashSet<>(); } diff --git a/src/main/java/com/kamco/cd/training/postgres/entity/ModelTrainMasterEntity.java b/src/main/java/com/kamco/cd/training/postgres/entity/ModelTrainMasterEntity.java index ff577fe..4305710 100644 --- a/src/main/java/com/kamco/cd/training/postgres/entity/ModelTrainMasterEntity.java +++ b/src/main/java/com/kamco/cd/training/postgres/entity/ModelTrainMasterEntity.java @@ -161,6 +161,10 @@ public class ModelTrainMasterEntity { @Column(name = "status_cd", length = 10) private String statusCd; + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "hyper_param_uuid", referencedColumnName = "uuid") + private ModelHyperParamEntity hyperParamUuid; + public ModelMngDto.Basic toDto() { return new ModelMngDto.Basic( this.id, From e2757d3ca01eba556307f7f6b36359c181810fdb Mon Sep 17 00:00:00 2001 From: teddy Date: Mon, 2 Feb 2026 20:19:30 +0900 Subject: [PATCH 2/2] =?UTF-8?q?=EB=AA=A8=EB=8D=B8=EA=B4=80=EB=A6=AC=20?= =?UTF-8?q?=ED=95=99=EC=8A=B5=20=EC=A1=B0=ED=9A=8C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cd/training/model/dto/ModelMngDto.java | 233 ++++++++---------- .../postgres/core/HyperParamCoreService.java | 6 - .../entity/ModelHyperParamEntity.java | 177 +++++++++---- .../entity/ModelTrainMasterEntity.java | 42 ++-- 4 files changed, 250 insertions(+), 208 deletions(-) diff --git a/src/main/java/com/kamco/cd/training/model/dto/ModelMngDto.java b/src/main/java/com/kamco/cd/training/model/dto/ModelMngDto.java index 0f05ff6..41c8558 100644 --- a/src/main/java/com/kamco/cd/training/model/dto/ModelMngDto.java +++ b/src/main/java/com/kamco/cd/training/model/dto/ModelMngDto.java @@ -5,6 +5,7 @@ import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; +import java.time.LocalDate; import java.time.ZonedDateTime; import java.util.List; import java.util.Map; @@ -307,182 +308,148 @@ public class ModelMngDto { @Setter @NoArgsConstructor @AllArgsConstructor - public static class HyperParamCreateReq { - // baseHyperVer는 필수 아님 (신규 생성 시 H1으로 자동 설정) - @Schema(description = "기준이 되는 하이퍼파라미터 버전", example = "H3") - private String baseHyperVer; + public class HyperParamCreateReq { - @NotBlank(message = "신규 버전명은 필수입니다") - @Schema(description = "새로 생성할 하이퍼파라미터 버전명", example = "V3.99.251221.120518") + @Schema(description = "새로운 하이파라미터 버전", example = "") private String newHyperVer; - // Important - 필수 필드 - @NotBlank(message = "Backbone은 필수입니다") - @Schema(example = "large") - private String backbone; + @Schema(description = "불러온 하이파라미터 버전", example = "") + private String baseHyperVer; - @NotBlank(message = "Input Size는 필수입니다") - @Schema(example = "256,256") - private String inputSize; + @Schema(description = "하이퍼파라미터 PK", example = "1") + private Long hyperParamId; // hyper_param_id - @NotBlank(message = "Crop Size는 필수입니다") - @Schema(example = "256,256") - private String cropSize; + @Schema(description = "하이퍼파라미터 UUID", example = "3fa85f64-5717-4562-b3fc-2c963f66afa6") + private UUID uuid; // uuid (또는 hyper_param_uuid 컬럼이면 이름 맞춰 주세요) - @NotNull(message = "Epoch Count는 필수입니다") - @Schema(example = "200") - private Integer epochCnt; + @Schema(description = "하이퍼파라미터 버전", example = "V3.99.251221.120518") + private String hyperVer; // hyper_ver - @NotNull(message = "Batch Size는 필수입니다") - @Schema(example = "16") - private Integer batchSize; + @Schema(description = "백본 네트워크", example = "large") + private String backbone; // backbone - // Architecture - 필수 필드 - @NotNull(message = "Drop Path Rate는 필수입니다") - @Schema(example = "0.3") - private Double dropPathRate; + @Schema(description = "입력 이미지 크기(H,W)", example = "256,256") + private String inputSize; // input_size - @NotNull(message = "Frozen Stages는 필수입니다") - @Schema(example = "-1") - private Integer frozenStages; + @Schema(description = "크롭 크기(H,W 또는 단일값)", example = "256,256") + private String cropSize; // crop_size - @NotBlank(message = "Neck Policy는 필수입니다") - @Schema(example = "abs_diff") - private String neckPolicy; + @Schema(description = "총 학습 에폭 수", example = "200") + private Integer epochCnt; // epoch_cnt - @NotBlank(message = "Decoder Channels는 필수입니다") - @Schema(example = "512,256,128,64") - private String decoderChannels; + @Schema(description = "배치 크기(Per GPU)", example = "16") + private Integer batchSize; // batch_size - @NotBlank(message = "Class Weight는 필수입니다") - @Schema(example = "1,1") - private String classWeight; + @Schema(description = "Drop Path 비율", example = "0.3") + private Double dropPathRate; // drop_path_rate - // numLayers는 필수 아님 - @Schema(example = "24") - private Integer numLayers; + @Schema(description = "Freeze 단계(-1:None)", example = "-1") + private Integer frozenStages; // frozen_stages - // Optimization - 필수 필드 - @NotNull(message = "Learning Rate는 필수입니다") - @Schema(example = "0.00006") - private Double learningRate; + @Schema(description = "Neck 결합 정책", example = "abs_diff") + private String neckPolicy; // neck_policy - @NotNull(message = "Weight Decay는 필수입니다") - @Schema(example = "0.05") - private Double weightDecay; + @Schema(description = "디코더 채널 구성", example = "512,256,128,64") + private String decoderChannels; // decoder_channels - @NotNull(message = "Layer Decay Rate는 필수입니다") - @Schema(example = "0.9") - private Double layerDecayRate; + @Schema(description = "클래스별 가중치", example = "1,10") + private String classWeight; // class_weight - @NotNull(message = "DDP Find Unused Params는 필수입니다") - @Schema(example = "true") - private Boolean ddpFindUnusedParams; + @Schema(description = "레이어 깊이", example = "24") + private Integer numLayers; // num_layers - @NotNull(message = "Ignore Index는 필수입니다") - @Schema(example = "255") - private Integer ignoreIndex; + @Schema(description = "학습률", example = "0.00006") + private Double learningRate; // learning_rate - // Data - 필수 필드 - @NotNull(message = "Train Num Workers는 필수입니다") - @Schema(example = "16") - private Integer trainNumWorkers; + @Schema(description = "Weight Decay", example = "0.05") + private Double weightDecay; // weight_decay - @NotNull(message = "Val Num Workers는 필수입니다") - @Schema(example = "8") - private Integer valNumWorkers; + @Schema(description = "Layer Decay Rate", example = "0.9") + private Double layerDecayRate; // layer_decay_rate - @NotNull(message = "Test Num Workers는 필수입니다") - @Schema(example = "8") - private Integer testNumWorkers; + @Schema(description = "DDP unused params 탐색 여부", example = "true") + private Boolean ddpFindUnusedParams; // ddp_find_unused_params - @NotNull(message = "Train Shuffle는 필수입니다") - @Schema(example = "true") - private Boolean trainShuffle; + @Schema(description = "Loss 계산 제외 인덱스", example = "255") + private Integer ignoreIndex; // ignore_index - @NotNull(message = "Train Persistent는 필수입니다") - @Schema(example = "true") - private Boolean trainPersistent; + @Schema(description = "Train dataloader workers", example = "16") + private Integer trainNumWorkers; // train_num_workers - @NotNull(message = "Val Persistent는 필수입니다") - @Schema(example = "true") - private Boolean valPersistent; + @Schema(description = "Val dataloader workers", example = "8") + private Integer valNumWorkers; // val_num_workers - // Evaluation - 필수 필드 - @NotBlank(message = "Metrics는 필수입니다") - @Schema(example = "mFscore,mIoU") - private String metrics; + @Schema(description = "Test dataloader workers", example = "8") + private Integer testNumWorkers; // test_num_workers - @NotBlank(message = "Save Best는 필수입니다") - @Schema(example = "changed_fscore") - private String saveBest; + @Schema(description = "Train shuffle 여부", example = "true") + private Boolean trainShuffle; // train_shuffle - @NotBlank(message = "Save Best Rule은 필수입니다") - @Schema(example = "greater") - private String saveBestRule; + @Schema(description = "Train persistent workers 여부", example = "true") + private Boolean trainPersistent; // train_persistent - @NotNull(message = "Val Interval은 필수입니다") - @Schema(example = "10") - private Integer valInterval; + @Schema(description = "Val persistent workers 여부", example = "true") + private Boolean valPersistent; // val_persistent - @NotNull(message = "Log Interval은 필수입니다") - @Schema(example = "400") - private Integer logInterval; + @Schema(description = "평가 지표 목록", example = "mFscore,mIoU") + private String metrics; // metrics - @NotNull(message = "Vis Interval은 필수입니다") - @Schema(example = "1") - private Integer visInterval; + @Schema(description = "Best 모델 선정 기준 지표", example = "changed_fscore") + private String saveBest; // save_best - // Hardware - 필수 아님 (예외 항목) - @Schema(example = "4") - private Integer gpuCnt; + @Schema(description = "Best 모델 선정 규칙", example = "greater") + private String saveBestRule; // save_best_rule - @Schema(example = "0,1,2,3") - private String gpuIds; + @Schema(description = "검증 수행 주기(Epoch)", example = "10") + private Integer valInterval; // val_interval - @Schema(example = "1122") - private Integer masterPort; + @Schema(description = "로그 기록 주기(Iteration)", example = "400") + private Integer logInterval; // log_interval - // Augmentation - 필수 필드 - @NotNull(message = "Rotation Probability는 필수입니다") - @Schema(example = "0.5") - private Double rotProb; + @Schema(description = "시각화 저장 주기(Epoch)", example = "1") + private Integer visInterval; // vis_interval - @NotNull(message = "Flip Probability는 필수입니다") - @Schema(example = "0.5") - private Double flipProb; + @Schema(description = "회전 적용 확률", example = "0.5") + private Double rotProb; // rot_prob - @NotBlank(message = "Rotation Degree는 필수입니다") - @Schema(example = "-20,20") - private String rotDegree; + @Schema(description = "반전 적용 확률", example = "0.5") + private Double flipProb; // flip_prob - @NotNull(message = "Exchange Probability는 필수입니다") - @Schema(example = "0.5") - private Double exchangeProb; + @Schema(description = "회전 각도 범위(Min,Max)", example = "-20,20") + private String rotDegree; // rot_degree - @NotNull(message = "Brightness Delta는 필수입니다") - @Schema(example = "10") - private Integer brightnessDelta; + @Schema(description = "채널 교환 확률", example = "0.5") + private Double exchangeProb; // exchange_prob - @NotBlank(message = "Contrast Range는 필수입니다") - @Schema(example = "0.8,1.2") - private String contrastRange; + @Schema(description = "밝기 변화량", example = "10") + private Integer brightnessDelta; // brightness_delta - @NotBlank(message = "Saturation Range는 필수입니다") - @Schema(example = "0.8,1.2") - private String saturationRange; + @Schema(description = "대비 범위(Min,Max)", example = "0.8,1.2") + private String contrastRange; // contrast_range - @NotNull(message = "Hue Delta는 필수입니다") - @Schema(example = "10") - private Integer hueDelta; + @Schema(description = "채도 범위(Min,Max)", example = "0.8,1.2") + private String saturationRange; // saturation_range - // Legacy - 필수 아님 (예외 항목) - private Double dropoutRatio; - private Integer cnnFilterCnt; + @Schema(description = "색조 변화량", example = "10") + private Integer hueDelta; // hue_delta - // Common - 필수 아님 (예외 항목) - @Schema(example = "안녕하세요 캠코담당자 입니다. 하이퍼파라미터 신규등록합니다") - private String memo; + @Schema(description = "사용 GPU 개수", example = "4") + private Integer gpuCnt; // gpu_cnt + + @Schema(description = "사용 GPU ID 목록", example = "0,1,2,3") + private String gpuIds; // gpu_ids + + @Schema(description = "분산학습 마스터 포트", example = "1122") + private Integer masterPort; // master_port + + @Schema(description = "메모", example = "하이퍼파라미터 신규등록") + private String memo; // memo + + @Schema(description = "삭제 여부(Y/N)", example = "N") + private String delYn; // del_yn + + @Schema(description = "생성 일시") + private LocalDate createdDttm; // created_dttm } @Schema(name = "TrainStartReq", description = "학습 시작 요청") diff --git a/src/main/java/com/kamco/cd/training/postgres/core/HyperParamCoreService.java b/src/main/java/com/kamco/cd/training/postgres/core/HyperParamCoreService.java index e275073..9d8dfeb 100644 --- a/src/main/java/com/kamco/cd/training/postgres/core/HyperParamCoreService.java +++ b/src/main/java/com/kamco/cd/training/postgres/core/HyperParamCoreService.java @@ -245,12 +245,6 @@ public class HyperParamCoreService { entity.setHueDelta( createReq.getHueDelta() != null ? createReq.getHueDelta() : baseEntity.getHueDelta()); - // Legacy - entity.setCnnFilterCnt( - createReq.getCnnFilterCnt() != null - ? createReq.getCnnFilterCnt() - : baseEntity.getCnnFilterCnt()); - // Common entity.setMemo(createReq.getMemo()); entity.setDelYn("N"); diff --git a/src/main/java/com/kamco/cd/training/postgres/entity/ModelHyperParamEntity.java b/src/main/java/com/kamco/cd/training/postgres/entity/ModelHyperParamEntity.java index 12965b8..95c0a8a 100644 --- a/src/main/java/com/kamco/cd/training/postgres/entity/ModelHyperParamEntity.java +++ b/src/main/java/com/kamco/cd/training/postgres/entity/ModelHyperParamEntity.java @@ -1,12 +1,6 @@ package com.kamco.cd.training.postgres.entity; -import jakarta.persistence.Column; -import jakarta.persistence.Entity; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; -import jakarta.persistence.OneToMany; -import jakarta.persistence.Table; +import jakarta.persistence.*; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; import java.time.ZonedDateTime; @@ -16,11 +10,14 @@ import java.util.UUID; import lombok.Getter; import lombok.Setter; import org.hibernate.annotations.ColumnDefault; +import org.hibernate.annotations.UuidGenerator; @Getter @Setter @Entity -@Table(name = "tb_model_hyper_params") +@Table( + name = "tb_model_hyper_params", + indexes = {@Index(name = "idx_hyper_params_hyper_ver", columnList = "hyper_ver")}) public class ModelHyperParamEntity { @Id @@ -29,198 +26,272 @@ public class ModelHyperParamEntity { private Long id; @NotNull - @ColumnDefault("gen_random_uuid()") - @Column(name = "uuid", nullable = false) - private UUID uuid = UUID.randomUUID(); + @UuidGenerator + @Column(name = "uuid", nullable = false, updatable = false) + private UUID uuid; @Size(max = 50) @NotNull @Column(name = "hyper_ver", nullable = false, length = 50) private String hyperVer; + // ------------------------- + // Important (Default 반영) + // ------------------------- + + /** Choices: base, large. Default: large */ @Size(max = 20) @NotNull @Column(name = "backbone", nullable = false, length = 20) - private String backbone; + private String backbone = "large"; + /** Choices: 256,256 or 512,512. Default: 256,256 */ @Size(max = 15) @NotNull @Column(name = "input_size", nullable = false, length = 15) - private String inputSize; + private String inputSize = "256,256"; + /** Range: 128~512. Default: 256,256 (H,W or int) */ @Size(max = 15) @NotNull @Column(name = "crop_size", nullable = false, length = 15) - private String cropSize; + private String cropSize = "256,256"; + /** Range: >=1. Default: 200 */ @NotNull @Column(name = "epoch_cnt", nullable = false) - private Integer epochCnt; + private Integer epochCnt = 200; + /** Range: >=1. Default: 16 (per GPU) */ @NotNull @Column(name = "batch_size", nullable = false) - private Integer batchSize; + private Integer batchSize = 16; + // ------------------------- + // Model Architecture (Default 반영) + // ------------------------- + + /** Range: 0.0~1.0. Default: 0.3 */ @NotNull @Column(name = "drop_path_rate", nullable = false) - private Double dropPathRate; + private Double dropPathRate = 0.3; + /** Default: -1 (none) */ @NotNull @Column(name = "frozen_stages", nullable = false) - private Integer frozenStages; + private Integer frozenStages = -1; + /** Choices: abs_diff, concat, sum, diff. Default: abs_diff */ @Size(max = 20) @NotNull @Column(name = "neck_policy", nullable = false, length = 20) - private String neckPolicy; + private String neckPolicy = "abs_diff"; + /** Default: 512,256,128,64 */ @Size(max = 50) @NotNull @Column(name = "decoder_channels", nullable = false, length = 50) - private String decoderChannels; + private String decoderChannels = "512,256,128,64"; + /** + * Example: 1,1 (large) or 1,10 (base) - 스펙에는 default가 명시가 애매하지만 UI/설명 흐름상 large 기본이므로 1,1로 - 만약 + * base가 기본이면 1,10으로 + */ @Size(max = 50) @NotNull @Column(name = "class_weight", nullable = false, length = 50) - private String classWeight; + private String classWeight = "1,1"; + /** Default: 24(large), 12(base) → backbone=large 기본이므로 24 */ @NotNull @Column(name = "num_layers", nullable = false) - private Integer numLayers; + private Integer numLayers = 24; + // ------------------------- + // Loss & Optimization (Default 반영) + // ------------------------- + + /** Range: >0. Default: 6e-5 */ @NotNull @Column(name = "learning_rate", nullable = false) - private Double learningRate; + private Double learningRate = 6e-5; + /** Range: >=0. Default: 0.05 */ @NotNull @Column(name = "weight_decay", nullable = false) - private Double weightDecay; + private Double weightDecay = 0.05; + /** Range: 0.0~1.0. Default: 0.9 */ @NotNull @Column(name = "layer_decay_rate", nullable = false) - private Double layerDecayRate; + private Double layerDecayRate = 0.9; + /** Default: true */ @NotNull @Column(name = "ddp_find_unused_params", nullable = false) - private Boolean ddpFindUnusedParams = false; + private Boolean ddpFindUnusedParams = true; + /** Default: 255 */ @NotNull @Column(name = "ignore_index", nullable = false) - private Integer ignoreIndex; + private Integer ignoreIndex = 255; + // ------------------------- + // Data (Default 반영) + // ------------------------- + + /** Range: >=0. Default: 16 */ @NotNull @Column(name = "train_num_workers", nullable = false) - private Integer trainNumWorkers; + private Integer trainNumWorkers = 16; + /** Range: >=0. Default: 8 */ @NotNull @Column(name = "val_num_workers", nullable = false) - private Integer valNumWorkers; + private Integer valNumWorkers = 8; + /** Range: >=0. Default: 8 */ @NotNull @Column(name = "test_num_workers", nullable = false) - private Integer testNumWorkers; + private Integer testNumWorkers = 8; + /** Default: true (from config) */ @NotNull @Column(name = "train_shuffle", nullable = false) - private Boolean trainShuffle = false; + private Boolean trainShuffle = true; + /** Default: true */ @NotNull @Column(name = "train_persistent", nullable = false) - private Boolean trainPersistent = false; + private Boolean trainPersistent = true; + /** Default: true */ @NotNull @Column(name = "val_persistent", nullable = false) - private Boolean valPersistent = false; + private Boolean valPersistent = true; + // ------------------------- + // Evaluation (Default 반영) + // ------------------------- + + /** Default: mFscore,mIoU */ @Size(max = 100) @NotNull @Column(name = "metrics", nullable = false, length = 100) - private String metrics; + private String metrics = "mFscore,mIoU"; + /** Default: changed_fscore */ @Size(max = 30) @NotNull @Column(name = "save_best", nullable = false, length = 30) - private String saveBest; + private String saveBest = "changed_fscore"; + /** Default: greater */ @Size(max = 10) @NotNull @Column(name = "save_best_rule", nullable = false, length = 10) - private String saveBestRule; + private String saveBestRule = "greater"; + /** Default: 10 */ @NotNull @Column(name = "val_interval", nullable = false) - private Integer valInterval; + private Integer valInterval = 10; + /** Default: 400 */ @NotNull @Column(name = "log_interval", nullable = false) - private Integer logInterval; + private Integer logInterval = 400; + /** Default: 1 */ @NotNull @Column(name = "vis_interval", nullable = false) - private Integer visInterval; + private Integer visInterval = 1; + // ------------------------- + // Augmentation (Default 반영) + // ------------------------- + + /** Default: 0.5 */ @NotNull @Column(name = "rot_prob", nullable = false) - private Double rotProb; + private Double rotProb = 0.5; + /** Default: 0.5 */ @NotNull @Column(name = "flip_prob", nullable = false) - private Double flipProb; + private Double flipProb = 0.5; + /** Default: -20,20 */ @Size(max = 20) @NotNull @Column(name = "rot_degree", nullable = false, length = 20) - private String rotDegree; + private String rotDegree = "-20,20"; + /** Default: 0.5 */ @NotNull @Column(name = "exchange_prob", nullable = false) - private Double exchangeProb; + private Double exchangeProb = 0.5; + /** Default: 10 */ @NotNull @Column(name = "brightness_delta", nullable = false) - private Integer brightnessDelta; + private Integer brightnessDelta = 10; + /** Default: 0.8,1.2 */ @Size(max = 20) @NotNull @Column(name = "contrast_range", nullable = false, length = 20) - private String contrastRange; + private String contrastRange = "0.8,1.2"; + /** Default: 0.8,1.2 */ @Size(max = 20) @NotNull @Column(name = "saturation_range", nullable = false, length = 20) - private String saturationRange; + private String saturationRange = "0.8,1.2"; + /** Default: 10 */ @NotNull @Column(name = "hue_delta", nullable = false) - private Integer hueDelta; + private Integer hueDelta = 10; + // ------------------------- + // Hardware (스펙상 기본은 있지만, UI에서 예외/옵션이라 했었음) + // ------------------------- + + /** Default: 4 */ @NotNull @Column(name = "gpu_cnt", nullable = false) private Integer gpuCnt; + /** Default: 0,1,2,3 */ @Size(max = 50) @Column(name = "gpu_ids", length = 50) private String gpuIds; + /** Default: 1122 */ @Column(name = "master_port") private Integer masterPort; - @Column(name = "memo", length = Integer.MAX_VALUE) + // ------------------------- + // Common + // ------------------------- + + @Column(name = "memo") private String memo; @NotNull @ColumnDefault("'N'") - @Column(name = "del_yn", nullable = false, length = Integer.MAX_VALUE) - private String delYn; + @Column(name = "del_yn", nullable = false, length = 1) + private String delYn = "N"; @NotNull @ColumnDefault("CURRENT_TIMESTAMP") @Column(name = "created_dttm", nullable = false) - private ZonedDateTime createdDttm; + private ZonedDateTime createdDttm = ZonedDateTime.now(); @Column(name = "cnn_filter_cnt") private Integer cnnFilterCnt; - @OneToMany(mappedBy = "hyperParamUuid") - private Set tbModelTrainMasters = new LinkedHashSet<>(); + @OneToMany(mappedBy = "hyperParams", fetch = FetchType.LAZY) + private Set trainMasters = new LinkedHashSet<>(); } diff --git a/src/main/java/com/kamco/cd/training/postgres/entity/ModelTrainMasterEntity.java b/src/main/java/com/kamco/cd/training/postgres/entity/ModelTrainMasterEntity.java index 4305710..43d8ec8 100644 --- a/src/main/java/com/kamco/cd/training/postgres/entity/ModelTrainMasterEntity.java +++ b/src/main/java/com/kamco/cd/training/postgres/entity/ModelTrainMasterEntity.java @@ -20,6 +20,7 @@ import lombok.Setter; import org.hibernate.annotations.ColumnDefault; import org.hibernate.annotations.OnDelete; import org.hibernate.annotations.OnDeleteAction; +import org.hibernate.annotations.UuidGenerator; @Getter @Setter @@ -37,9 +38,23 @@ public class ModelTrainMasterEntity { @Column(name = "model_ver", nullable = false, length = 50) private String modelVer; + @Size(max = 50) + @Column(name = "hyper_ver", length = 50) + private String hyperVer; + + /** tb_model_train_master.hyper_param_id -> tb_model_hyper_params.hyper_param_id */ + @NotNull + @Column(name = "hyper_param_id", nullable = false) + private Long hyperParamId; + + /** - hyperParamId 컬럼으로 저장/수정하고 - 객체로 조회할 때만 hyperParams 사용 */ @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "hyper_ver") - private ModelHyperParamEntity hyperVer; + @JoinColumn( + name = "hyper_param_id", + referencedColumnName = "hyper_param_id", + insertable = false, + updatable = false) + private ModelHyperParamEntity hyperParams; @Size(max = 50) @Column(name = "epoch_ver", length = 50) @@ -65,13 +80,13 @@ public class ModelTrainMasterEntity { @Column(name = "step1_end_dttm") private ZonedDateTime step1EndDttm; - @Column(name = "step1_duration", length = 50) + @Column(name = "step1_duration") private ZonedDateTime step1Duration; @Column(name = "step2_end_dttm") private ZonedDateTime step2EndDttm; - @Column(name = "step2_duration", length = 50) + @Column(name = "step2_duration") private ZonedDateTime step2Duration; @NotNull @@ -106,7 +121,7 @@ public class ModelTrainMasterEntity { @Column(name = "model_path") private String modelPath; - @Column(name = "error_msg", length = Integer.MAX_VALUE) + @Column(name = "error_msg") private String errorMsg; @Column(name = "step2_start_dttm") @@ -116,13 +131,14 @@ public class ModelTrainMasterEntity { @Column(name = "train_log_path", length = 1000) private String trainLogPath; - @Column(name = "memo", length = Integer.MAX_VALUE) + @Column(name = "memo") private String memo; + /** 기존 자기참조(base_model_uid)는 유지 */ @ManyToOne(fetch = FetchType.LAZY) @OnDelete(action = OnDeleteAction.SET_NULL) @JoinColumn(name = "base_model_uid") - private ModelTrainMasterEntity baseModelUid; + private ModelTrainMasterEntity baseModel; @Size(max = 1000) @Column(name = "pretrained_model_path", length = 1000) @@ -132,18 +148,16 @@ public class ModelTrainMasterEntity { private Integer lastCheckpointEpoch; @Size(max = 500) - @ColumnDefault("NULL") @Column(name = "checkpoint_path", length = 500) private String checkpointPath; - @ColumnDefault("false") @Column(name = "can_resume") private Boolean canResume; @NotNull - @ColumnDefault("uuid_generate_v4()") - @Column(name = "uuid", nullable = false) - private UUID uuid; + @UuidGenerator + @Column(name = "uuid", nullable = false, updatable = false) + private UUID uuid = UUID.randomUUID(); @Size(max = 10) @Column(name = "step1_status", length = 10) @@ -161,10 +175,6 @@ public class ModelTrainMasterEntity { @Column(name = "status_cd", length = 10) private String statusCd; - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "hyper_param_uuid", referencedColumnName = "uuid") - private ModelHyperParamEntity hyperParamUuid; - public ModelMngDto.Basic toDto() { return new ModelMngDto.Basic( this.id,