This commit is contained in:
dean
2026-04-01 08:55:17 +09:00
parent 50ad05b53b
commit 6cc9b54ba9
15 changed files with 280 additions and 325 deletions

View File

@@ -57,7 +57,7 @@ public class StartupLogger {
"""
╔════════════════════════════════════════════════════════════════════════════════╗
║ 🚀 APPLICATION STARTUP INFORMATION 2
║ 🚀 APPLICATION STARTUP INFORMATION 3
╠════════════════════════════════════════════════════════════════════════════════╣
║ PROFILE CONFIGURATION ║
╠────────────────────────────────────────────────────────────────────────────────╣

View File

@@ -48,7 +48,7 @@ public class ModelTrainDetailApiController {
private final ModelTrainDetailService modelTrainDetailService;
private final RangeDownloadResponder rangeDownloadResponder;
@Value("${train.docker.responseDir}")
@Value("${train.docker.response_dir}")
private String responseDir;
@Operation(summary = "모델학습관리> 모델관리 > 상세정보탭 > 학습 진행정보", description = "학습 진행정보, 모델학습 정보 API")

View File

@@ -53,7 +53,7 @@ public class ModelTrainDetailService {
private final ModelTrainDetailCoreService modelTrainDetailCoreService;
private final ModelTrainMngCoreService mngCoreService;
@Value("${train.docker.responseDir}")
@Value("${train.docker.response_dir}")
private String responseDir;
/**

View File

@@ -46,11 +46,14 @@ public class ModelTrainMngService {
private final TrainJobService trainJobService;
private final ModelTrainDetailService modelTrainDetailService;
@Value("${train.docker.basePath}")
@Value("${train.docker.base_path}")
private String basePath;
@Value("${train.docker.responseDir}")
@Value("${train.docker.response_dir}")
private String responseDir;
@Value("${train.docker.symbolic_link_dir}")
private String symbolicDir;
/**
* 모델학습 조회
@@ -80,7 +83,7 @@ public class ModelTrainMngService {
}
// ===== 2. 경로 생성 =====
Path tmpBase = Path.of(basePath, "tmp").toAbsolutePath().normalize();
Path tmpBase = Path.of(symbolicDir).toAbsolutePath().normalize();
Path tmp = tmpBase.resolve(model.getRequestPath()).normalize();
Path responseBase = Paths.get(responseDir).toAbsolutePath().normalize();

View File

@@ -23,11 +23,11 @@ import org.springframework.stereotype.Service;
public class DataSetCountersService {
private final ModelTrainMngCoreService modelTrainMngCoreService;
@Value("${train.docker.requestDir}")
@Value("${train.docker.request_dir}")
private String requestDir;
@Value("${train.docker.basePath}")
private String trainBaseDir;
@Value("${train.docker.symbolic_link_dir}")
private String symbolicDir;
public String getCount(Long modelId) {
ModelTrainMngDto.Basic basic = modelTrainMngCoreService.findModelById(modelId);
@@ -45,7 +45,7 @@ public class DataSetCountersService {
}
// tmp
Path tmpPath = Path.of(trainBaseDir, "tmp", basic.getRequestPath());
Path tmpPath = Path.of(symbolicDir, basic.getRequestPath());
// 차이나는거
diffMergedRequestsVsTmp(uids, tmpPath);

View File

@@ -31,27 +31,26 @@ public class DockerTrainService {
private String image;
// 학습 요청 데이터가 위치한 호스트 디렉토리
@Value("${train.docker.requestDir}")
@Value("${train.docker.request_dir}")
private String requestDir;
// 학습 결과가 저장될 호스트 디렉토리
@Value("${train.docker.responseDir}")
@Value("${train.docker.response_dir}")
private String responseDir;
// 컨테이너 이름 prefix
@Value("${train.docker.containerPrefix}")
private String containerPrefix;
// 공유메모리 사이즈 설정 (대용량 학습시 필요)
@Value("${train.docker.shmSize:16g}")
@Value("${train.docker.shm_size:16g}")
private String shmSize;
// data 경로 request,response 상위 폴더
@Value("${train.docker.basePath}")
@Value("${train.docker.base_path}")
private String basePath;
@Value("${train.docker.symbolic_link_dir}")
private String symbolicDir;
// IPC host 사용 여부
@Value("${train.docker.ipcHost:true}")
@Value("${train.docker.ipc_host:true}")
private boolean ipcHost;
@Value("${spring.profiles.active}")
@@ -260,12 +259,12 @@ public class DockerTrainService {
c.add("NCCL_SOCKET_IFNAME=eth0");
// 요청/결과 디렉토리 볼륨 마운트
// c.add("-v");
// c.add(basePath + ":" + basePath); // 심볼릭 링크와 연결되는 실제 파일 경로도 마운트를 해줘야 함
c.add("-v");
c.add(basePath + "/tmp:/data");
c.add(basePath + ":" + basePath); // 심볼릭 링크와 연결되는 실제 파일 경로도 마운트를 해줘야 함
c.add("-v");
c.add(responseDir + ":/checkpoints");
c.add(symbolicDir + ":/data"); //요청할경로
c.add("-v");
c.add(responseDir + ":/checkpoints"); //저장될경로
// 표준입력 유지 (-it 대신 -i만 사용)
c.add("-i");

View File

@@ -50,7 +50,7 @@ public class JobRecoveryOnStartupService {
*
* <p>컨테이너가 --rm 으로 삭제된 경우에도 이 경로에 val.csv / *.pth 등이 남아있으면 정상 종료 여부를 "파일 기반"으로 판정합니다.
*/
@Value("${train.docker.responseDir}")
@Value("${train.docker.response_dir}")
private String responseDir;
/**

View File

@@ -42,7 +42,7 @@ public class ModelTestMetricsJobService {
private String profile;
// 학습 결과가 저장될 호스트 디렉토리
@Value("${train.docker.responseDir}")
@Value("${train.docker.response_dir}")
private String responseDir;
@Value("${file.pt-path}")

View File

@@ -33,7 +33,7 @@ public class ModelTrainMetricsJobService {
private String profile;
// 학습 결과가 저장될 호스트 디렉토리
@Value("${train.docker.responseDir}")
@Value("${train.docker.response_dir}")
private String responseDir;
/** 결과 csv 파일 정보 등록 */

View File

@@ -14,12 +14,11 @@ import org.springframework.stereotype.Service;
@RequiredArgsConstructor
public class TmpDatasetService {
@Value("${train.docker.requestDir}")
@Value("${train.docker.request_dir}")
private String requestDir;
@Value("${train.docker.basePath}")
private String trainBaseDir;
@Value("${train.docker.symbolic_link_dir}")
private String symbolicDir;
/**
* train, val, test 폴더별로 link
*
@@ -36,7 +35,7 @@ public class TmpDatasetService {
throw new IOException("links is empty");
}
Path tmp = Path.of(trainBaseDir, "tmp", uid);
Path tmp = Path.of(symbolicDir, uid);
long linksMade = 0;
@@ -115,7 +114,7 @@ public class TmpDatasetService {
log.info("requestDir(raw)={}", requestDir);
Path BASE = toPath(requestDir);
Path tmp = Path.of(trainBaseDir, "tmp", uid);
Path tmp = Path.of(symbolicDir, uid);
log.info("BASE={}", BASE);
log.info("BASE exists? {}", Files.isDirectory(BASE));

View File

@@ -40,7 +40,7 @@ public class TrainJobService {
private final DataSetCountersService dataSetCounters;
// 학습 결과가 저장될 호스트 디렉토리
@Value("${train.docker.responseDir}")
@Value("${train.docker.response_dir}")
private String responseDir;
public Long getModelIdByUuid(UUID uuid) {

View File

@@ -5,14 +5,10 @@ spring:
jpa:
show-sql: true
hibernate:
ddl-auto: validate
properties:
hibernate:
default_batch_fetch_size: 100 # ✅ 성능 - N+1 쿼리 방지
order_updates: true # ✅ 성능 - 업데이트 순서 정렬로 데드락 방지
use_sql_comments: true # ⚠️ 선택 - SQL에 주석 추가 (디버깅용)
format_sql: true # ⚠️ 선택 - SQL 포맷팅 (가독성)
use_sql_comments: true # ⚠️ 선택 - SQL에 주석 추가 (디버깅용)
format_sql: true # ⚠️ 선택 - SQL 포맷팅 (가독성)
datasource:
url: jdbc:postgresql://192.168.2.127:15432/kamco_training_db
@@ -21,14 +17,6 @@ spring:
hikari:
minimum-idle: 10
maximum-pool-size: 20
connection-timeout: 60000 # 60초 연결 타임아웃
idle-timeout: 300000 # 5분 유휴 타임아웃
max-lifetime: 1800000 # 30분 최대 수명
leak-detection-threshold: 60000 # 연결 누수 감지
transaction:
default-timeout: 300 # 5분 트랜잭션 타임아웃
jwt:
secret: "kamco_token_dev_dfc6446d-68fc-4eba-a2ff-c80a14a0bf3a"
@@ -37,23 +25,12 @@ jwt:
token:
refresh-cookie-name: kamco-dev # 개발용 쿠키 이름
refresh-cookie-secure: false # 로컬 http 테스트면 false
springdoc:
swagger-ui:
persist-authorization: true # 스웨거 새로고침해도 토큰 유지, 로컬스토리지에 저장
member:
init_password: kamco1234!
refresh-cookie-secure: false # 로컬 http 테스트면 false
swagger:
local-port: 8080
file:
sync-root-dir: /app/original-images/
sync-tmp-dir: ${file.sync-root-dir}tmp/
sync-file-extention: tfw,tif
dataset-dir: /home/kcomu/data/request/
dataset-tmp-dir: ${file.dataset-dir}tmp/
@@ -63,10 +40,10 @@ file:
train:
docker:
image: kamco-cd-train:latest
requestDir: /home/kcomu/data/request
responseDir: /home/kcomu/data/response
basePath: /home/kcomu/data
containerPrefix: kamco-cd-train
shmSize: 16g
ipcHost: true
base_path: /home/kcomu/data
request_dir: ${train.docker.base_path}/request
response_dir: ${train.docker.base_path}/response
symbolic_link_dir: ${train.docker.base_path}/tmp
container_prefix: kamco-cd-train
shm_size: 16g
ipc_host: true

View File

@@ -3,15 +3,6 @@ spring:
activate:
on-profile: prod
jpa:
show-sql: false # 운영 환경에서는 성능을 위해 비활성화
hibernate:
ddl-auto: validate
properties:
hibernate:
default_batch_fetch_size: 100 # N+1 쿼리 방지
order_updates: true # 업데이트 순서 정렬로 데드락 방지
datasource:
url: jdbc:postgresql://kamco-cd-train-db:5432/kamco_training_db
username: kamco_training_user
@@ -19,13 +10,6 @@ spring:
hikari:
minimum-idle: 10
maximum-pool-size: 20
connection-timeout: 60000 # 60초 연결 타임아웃
idle-timeout: 300000 # 5분 유휴 타임아웃
max-lifetime: 1800000 # 30분 최대 수명
leak-detection-threshold: 60000 # 연결 누수 감지
transaction:
default-timeout: 300 # 5분 트랜잭션 타임아웃
jwt:
# ⚠️ 운영 환경에서는 반드시 별도의 강력한 시크릿 키를 사용하세요
@@ -37,36 +21,23 @@ token:
refresh-cookie-name: kamco
refresh-cookie-secure: true # HTTPS 환경에서 필수
springdoc:
swagger-ui:
persist-authorization: true # 스웨거 새로고침해도 토큰 유지, 로컬스토리지에 저장
member:
init_password: kamco1234!
swagger:
local-port: 9080
file:
# sync-root-dir: /app/original-images/
# sync-tmp-dir: ${file.sync-root-dir}tmp/
# sync-file-extention: tfw,tif
dataset-dir: /data/request/
dataset-dir: /data/training/request/
dataset-tmp-dir: ${file.dataset-dir}tmp/
pt-path: /data/response/v6-cls-checkpoints/
pt-path: /data/training/response/v6-cls-checkpoints/
pt-FileName: yolov8_6th-6m.pt
train:
docker:
image: kamco-cd-train:latest
requestDir: /data/request
responseDir: /data/response
basePath: /data
containerPrefix: kamco-cd-train
shmSize: 16g
ipcHost: true
base_path: /data/training
request_dir: ${train.docker.base_path}/request
response_dir: ${train.docker.base_path}/response
symbolic_link_dir: ${train.docker.base_path}/tmp
container_prefix: kamco-cd-train
shm_size: 16g
ipc_host: true

View File

@@ -10,25 +10,25 @@ spring:
datasource:
driver-class-name: org.postgresql.Driver
hikari:
minimum-idle: 2
maximum-pool-size: 2
connection-timeout: 20000
idle-timeout: 300000
max-lifetime: 1800000
leak-detection-threshold: 60000
connection-timeout: 60000 # 60초 연결 타임아웃
idle-timeout: 300000 # 5분 유휴 타임아웃
max-lifetime: 1800000 # 30분 최대 수명
leak-detection-threshold: 60000 # 연결 누수 감지
# minimum-idle, maximum-pool-size 는 프로파일별 설정
jpa:
hibernate:
ddl-auto: update # 스키마 자동 관리 활성화
ddl-auto: validate
properties:
hibernate:
javax:
jakarta:
persistence:
validation:
mode: none
jdbc:
batch_size: 50
default_batch_fetch_size: 100
order_updates: true
show-sql: false
servlet:
@@ -36,6 +36,10 @@ spring:
enabled: true
max-file-size: 10GB
max-request-size: 10GB
transaction:
default-timeout: 300 # 5분 트랜잭션 타임아웃
logging:
level:
org:
@@ -44,7 +48,12 @@ logging:
security: INFO
root: INFO
springdoc:
swagger-ui:
persist-authorization: true # 스웨거 새로고침해도 토큰 유지
member:
init_password: kamco1234!
# actuator
management:

View File

@@ -23,9 +23,7 @@ spring:
ddl-auto: none # 테스트 환경에서는 DDL 자동 생성/수정 비활성화
properties:
hibernate:
hbm2ddl:
auto: none
javax:
jakarta:
persistence:
validation:
mode: none
@@ -74,4 +72,3 @@ token:
member:
init_password: test1234!