label-to-review 로그작성,prod수정
This commit is contained in:
@@ -33,69 +33,85 @@ public class TrainingDataLabelJobService {
|
||||
return "local".equalsIgnoreCase(profile);
|
||||
}
|
||||
|
||||
@Scheduled(cron = "0 * * * * *")
|
||||
public void runTask() {
|
||||
// 프록시를 통해 호출해야 @Transactional이 적용됨
|
||||
applicationContext
|
||||
.getBean(TrainingDataLabelJobService.class)
|
||||
.assignReviewerYesterdayLabelComplete(null);
|
||||
.getBean(TrainingDataLabelJobService.class)
|
||||
.assignReviewerYesterdayLabelComplete(null);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void assignReviewerYesterdayLabelComplete(LocalDate baseDate) {
|
||||
|
||||
// if (isLocalProfile()) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
try {
|
||||
log.info("[Step 1-1] 라벨링 완료된 데이터 목록 조회한다.");
|
||||
log.info("=== baseDate : {}", baseDate);
|
||||
log.info("=== baseDate 있으면 해당 일자, 없으면 어제일자로 조회");
|
||||
List<Tasks> tasks =
|
||||
trainingDataLabelJobCoreService.findCompletedYesterdayUnassigned(baseDate);
|
||||
trainingDataLabelJobCoreService.findCompletedYesterdayUnassigned(baseDate);
|
||||
|
||||
log.info("[Step 1-2] 목록 객체 건수 count : {}", tasks == null ? 0 : tasks.size());
|
||||
if (tasks.isEmpty()) {
|
||||
log.info("[Step 1-3] 조회된 것 없어 return");
|
||||
return;
|
||||
}
|
||||
|
||||
// 회차별로 그룹핑
|
||||
log.info("[Step 2-1] 회차별로 그룹핑 시작");
|
||||
Map<Long, List<Tasks>> taskByRound =
|
||||
tasks.stream().collect(Collectors.groupingBy(Tasks::getAnalUid));
|
||||
tasks.stream().collect(Collectors.groupingBy(Tasks::getAnalUid));
|
||||
|
||||
// 회차별 분배
|
||||
log.info("[Step 3-1] 회차별로 분배 시작");
|
||||
for (Map.Entry<Long, List<Tasks>> entry : taskByRound.entrySet()) {
|
||||
Long analUid = entry.getKey();
|
||||
List<Tasks> analTasks = entry.getValue();
|
||||
|
||||
// pending 계산
|
||||
log.info("[Step 3-2] 수행하는 회차 analUid: {}", analUid);
|
||||
log.info("해당 회차에 라벨링 할당받은 검수자별 완료 건수 count(), 완료한 게 적은 순으로 해야 일이 한 사람에게 몰리지 않음");
|
||||
List<InspectorPendingDto> pendings =
|
||||
trainingDataLabelJobCoreService.findInspectorPendingByRound(analUid);
|
||||
trainingDataLabelJobCoreService.findInspectorPendingByRound(analUid);
|
||||
|
||||
log.info("검수자 수: {}", pendings == null ? 0 : pendings.size());
|
||||
if (pendings.isEmpty()) {
|
||||
log.info("[Step 3-3] 할당된 검수자가 없으면 return");
|
||||
continue;
|
||||
}
|
||||
|
||||
log.info("[Step 4-1] 검수자 사번 List 생성");
|
||||
List<String> reviewerIds =
|
||||
pendings.stream().map(InspectorPendingDto::getInspectorUid).toList();
|
||||
pendings.stream().map(InspectorPendingDto::getInspectorUid).toList();
|
||||
|
||||
// Lock 걸릴 수 있기 때문에 엔티티 조회하는 Repository 에서 구현
|
||||
log.info("[Step 4-2] 검수자 테이블 lock 걸리지 않게 처리");
|
||||
trainingDataLabelJobCoreService.lockInspectors(analUid, reviewerIds);
|
||||
|
||||
// 균등 분배
|
||||
log.info("[Step 5-1] 검수자에게 라벨 작업 균등분배 시작");
|
||||
Map<String, List<Tasks>> assignMap = distributeByLeastPending(analTasks, reviewerIds);
|
||||
log.info("[Step 5-2] 검수자에게 라벨 작업 균등분배 완료");
|
||||
|
||||
// reviewer별 batch update
|
||||
log.info("[Step 5-3] 검수자별 할당 데이터를 batch update 시작");
|
||||
assignMap.forEach(
|
||||
(reviewerId, assignedTasks) -> {
|
||||
if (assignedTasks.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
(reviewerId, assignedTasks) -> {
|
||||
if (assignedTasks.isEmpty()) {
|
||||
log.info("[Step 5-4] 할당된 데이터 없으면 return");
|
||||
return;
|
||||
}
|
||||
|
||||
List<UUID> assignmentUids =
|
||||
assignedTasks.stream().map(Tasks::getAssignmentUid).toList();
|
||||
trainingDataLabelJobCoreService.assignReviewerBatch(assignmentUids, reviewerId);
|
||||
List<UUID> assignmentUids =
|
||||
assignedTasks.stream().map(Tasks::getAssignmentUid).toList();
|
||||
log.info("[Step 6-1] 할당 작업에 검수자 아이디 update");
|
||||
log.info("==== 검수자 사번: {}", reviewerId);
|
||||
log.info("==== 할당 갯수: {}", assignmentUids == null ? 0 : assignmentUids.size());
|
||||
trainingDataLabelJobCoreService.assignReviewerBatch(assignmentUids, reviewerId);
|
||||
|
||||
List<Long> geomUids = assignedTasks.stream().map(Tasks::getInferenceUid).toList();
|
||||
trainingDataLabelJobCoreService.updateGeomUidTestState(geomUids);
|
||||
});
|
||||
log.info("[Step 7-1] geom 테이블에 검수 상태 update");
|
||||
List<Long> geomUids = assignedTasks.stream().map(Tasks::getInferenceUid).toList();
|
||||
trainingDataLabelJobCoreService.updateGeomUidTestState(geomUids);
|
||||
});
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("배치 처리 중 예외", e);
|
||||
@@ -104,7 +120,7 @@ public class TrainingDataLabelJobService {
|
||||
}
|
||||
|
||||
private Map<String, List<Tasks>> distributeByLeastPending(
|
||||
List<Tasks> tasks, List<String> reviewerIds) {
|
||||
List<Tasks> tasks, List<String> reviewerIds) {
|
||||
Map<String, List<Tasks>> result = new LinkedHashMap<>();
|
||||
|
||||
// 순서 유지 중요 (ASC 정렬된 상태)
|
||||
|
||||
@@ -84,28 +84,28 @@ mapsheet:
|
||||
baseurl: /app/detect/result #현재사용안함
|
||||
|
||||
file:
|
||||
sync-root-dir: /data/images/
|
||||
sync-tmp-dir: /data/repo/tmp # image upload temp dir
|
||||
sync-root-dir: /kamco-nfs/images/
|
||||
sync-tmp-dir: /kamco-nfs/repo/tmp # image upload temp dir
|
||||
sync-file-extention: tfw,tif
|
||||
|
||||
#dataset-dir: D:/data/model_output/ #변경 model_output
|
||||
dataset-dir: /data/model_output/export/ # 마운트경로 AI 추론결과
|
||||
#dataset-dir: D:/kamco-nfs/model_output/ #변경 model_output
|
||||
dataset-dir: /kamco-nfs/model_output/export/ # 마운트경로 AI 추론결과
|
||||
dataset-tmp-dir: ${file.dataset-dir}tmp/
|
||||
|
||||
#model-dir: D:/data/ckpt/model/
|
||||
model-dir: /data/ckpt/model/ # 학습서버에서 트레이닝한 모델업로드경로
|
||||
#model-dir: D:/kamco-nfs/ckpt/model/
|
||||
model-dir: /kamco-nfs/ckpt/model/ # 학습서버에서 트레이닝한 모델업로드경로
|
||||
model-tmp-dir: ${file.model-dir}tmp/
|
||||
model-file-extention: pth,json,py
|
||||
|
||||
pt-path: /data/ckpt/v6-cls-checkpoints/
|
||||
pt-path: /kamco-nfs/ckpt/v6-cls-checkpoints/
|
||||
pt-FileName: yolov8_6th-6m.pt
|
||||
dataset-response: /data/dataset/response/
|
||||
dataset-response: /kamco-nfs/dataset/response/
|
||||
|
||||
inference:
|
||||
url: http://127.0.0.1:8000/jobs
|
||||
batch-url: http://127.0.0.1:8000/batches
|
||||
geojson-dir: /data/requests/ # 학습서버에서 트레이닝한 모델업로드경로
|
||||
jar-path: /data/repo/jar/shp-exporter.jar # 추론실행을 위한 파일생성경로
|
||||
geojson-dir: /kamco-nfs/requests/ # 학습서버에서 트레이닝한 모델업로드경로
|
||||
jar-path: /kamco-nfs/repo/jar/shp-exporter.jar # 추론실행을 위한 파일생성경로
|
||||
inference-server-name: server1,server2,server3,server4
|
||||
|
||||
gukyuin:
|
||||
@@ -113,7 +113,7 @@ gukyuin:
|
||||
cdi: ${gukyuin.url}/api/kcd/cdi
|
||||
|
||||
training-data:
|
||||
geojson-dir: /data/dataset/request/
|
||||
geojson-dir: /kamco-nfs/dataset/request/
|
||||
|
||||
layer:
|
||||
geoserver-url: https://kamco.geo-dev.gs.dabeeo.com
|
||||
|
||||
Reference in New Issue
Block a user