추론실행 수정, develop pull 반영, 국유인 파일경로 dir 하드코딩 수정 #103
@@ -14,6 +14,9 @@ import lombok.ToString;
|
|||||||
@ToString
|
@ToString
|
||||||
public class InferenceSendDto {
|
public class InferenceSendDto {
|
||||||
|
|
||||||
|
private static final String DEV_PATH_PREFIX = "kamco-nfs";
|
||||||
|
private static final String PROD_PATH_PREFIX = "data";
|
||||||
|
|
||||||
private pred_requests_areas pred_requests_areas;
|
private pred_requests_areas pred_requests_areas;
|
||||||
private String model_version;
|
private String model_version;
|
||||||
private String cd_model_path;
|
private String cd_model_path;
|
||||||
@@ -23,12 +26,17 @@ public class InferenceSendDto {
|
|||||||
private String cd_model_type;
|
private String cd_model_type;
|
||||||
private Double priority;
|
private Double priority;
|
||||||
|
|
||||||
public String getCd_model_path() {
|
// 프로덕션은 경로가 바뀜
|
||||||
return cd_model_path == null ? null : cd_model_path.replace("kamcd-nfs", "data");
|
public void changeValForProd() {
|
||||||
}
|
if (pred_requests_areas != null) {
|
||||||
|
pred_requests_areas.changeValForProd();
|
||||||
public String getCls_model_path() {
|
}
|
||||||
return cls_model_path == null ? null : cls_model_path.replace("kamcd-nfs", "data");
|
if (this.cd_model_path != null) {
|
||||||
|
this.cd_model_path = this.cd_model_path.replace(DEV_PATH_PREFIX, PROD_PATH_PREFIX);
|
||||||
|
}
|
||||||
|
if (this.cls_model_path != null) {
|
||||||
|
this.cls_model_path = this.cls_model_path.replace(DEV_PATH_PREFIX, PROD_PATH_PREFIX);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@@ -43,13 +51,18 @@ public class InferenceSendDto {
|
|||||||
private String input1_scene_path;
|
private String input1_scene_path;
|
||||||
private String input2_scene_path;
|
private String input2_scene_path;
|
||||||
|
|
||||||
public String getInput1_scene_path() {
|
public void changeValForProd() {
|
||||||
|
// ai팀에서 kamco-nfs를 data로 세팅했음
|
||||||
return input1_scene_path == null ? null : input1_scene_path.replace("kamcd-nfs", "data");
|
if (this.input1_scene_path != null) {
|
||||||
}
|
this.input1_scene_path =
|
||||||
|
this.input1_scene_path.replace(
|
||||||
public String getInput2_scene_path() {
|
InferenceSendDto.DEV_PATH_PREFIX, InferenceSendDto.PROD_PATH_PREFIX);
|
||||||
return input2_scene_path == null ? null : input2_scene_path.replace("kamcd-nfs", "data");
|
}
|
||||||
|
if (this.input2_scene_path != null) {
|
||||||
|
this.input2_scene_path =
|
||||||
|
this.input2_scene_path.replace(
|
||||||
|
InferenceSendDto.DEV_PATH_PREFIX, InferenceSendDto.PROD_PATH_PREFIX);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -713,6 +713,14 @@ public class InferenceResultService {
|
|||||||
sendDto.setCls_model_version(modelInfo.getModelVer());
|
sendDto.setCls_model_version(modelInfo.getModelVer());
|
||||||
sendDto.setCd_model_type(modelType);
|
sendDto.setCd_model_type(modelType);
|
||||||
sendDto.setPriority(5d);
|
sendDto.setPriority(5d);
|
||||||
|
|
||||||
|
// 운영환경일때 경로수정 dean 260226
|
||||||
|
if (profile != null && profile.equals("prod")) {
|
||||||
|
log.info("profile = {} change inforence req", profile);
|
||||||
|
sendDto.changeValForProd();
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("[Inference Send]SendDto={}", sendDto);
|
||||||
return sendDto;
|
return sendDto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,229 @@
|
|||||||
|
package com.kamco.cd.kamcoback.inference.service;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.kamco.cd.kamcoback.common.exception.CustomApiException;
|
||||||
|
import com.kamco.cd.kamcoback.common.geometry.GeoJsonFileWriter.Scene;
|
||||||
|
import com.kamco.cd.kamcoback.config.resttemplate.ExternalHttpClient;
|
||||||
|
import com.kamco.cd.kamcoback.config.resttemplate.ExternalHttpClient.ExternalCallResult;
|
||||||
|
import com.kamco.cd.kamcoback.inference.dto.InferenceSendDto;
|
||||||
|
import com.kamco.cd.kamcoback.inference.dto.InferenceSendDto.pred_requests_areas;
|
||||||
|
import com.kamco.cd.kamcoback.model.dto.ModelMngDto.Basic;
|
||||||
|
import com.kamco.cd.kamcoback.model.dto.ModelMngDto.ModelType;
|
||||||
|
import com.kamco.cd.kamcoback.postgres.core.MapSheetMngCoreService;
|
||||||
|
import com.kamco.cd.kamcoback.postgres.core.ModelMngCoreService;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.log4j.Log4j2;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
|
import org.springframework.http.HttpMethod;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@Log4j2
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class InferenceRunService {
|
||||||
|
private final ExternalHttpClient externalHttpClient;
|
||||||
|
private final MapSheetMngCoreService mapSheetMngCoreService;
|
||||||
|
private final ModelMngCoreService modelMngCoreService;
|
||||||
|
private final ObjectMapper objectMapper;
|
||||||
|
|
||||||
|
@Value("${spring.profiles.active}")
|
||||||
|
private String profile;
|
||||||
|
|
||||||
|
@Value("${inference.url}")
|
||||||
|
private String inferenceUrl;
|
||||||
|
|
||||||
|
public void run(Integer compareYear, Integer targetYear, UUID modelUuid) {
|
||||||
|
|
||||||
|
List<String> compareList = mapSheetMngCoreService.getMapSheetMngHst(compareYear);
|
||||||
|
List<String> targetList = mapSheetMngCoreService.getMapSheetMngHst(targetYear);
|
||||||
|
|
||||||
|
log.info(
|
||||||
|
"hst list count compareList = {}, targetList = {}", compareList.size(), targetList.size());
|
||||||
|
|
||||||
|
Set<String> compareSet = new HashSet<>(compareList);
|
||||||
|
Set<String> targetSet = new HashSet<>(targetList);
|
||||||
|
|
||||||
|
long intersectionCount =
|
||||||
|
targetSet.stream()
|
||||||
|
.distinct()
|
||||||
|
.filter(compareSet::contains)
|
||||||
|
.count(); // compare와 target에 공통으로 존재하는 도협 수
|
||||||
|
|
||||||
|
long excludedTargetCount =
|
||||||
|
targetSet.stream()
|
||||||
|
.distinct()
|
||||||
|
.filter(s -> !compareSet.contains(s))
|
||||||
|
.count(); // target 에만 존재하는 도협 수 (compare 에는 없음)
|
||||||
|
|
||||||
|
long onlyCompareCount =
|
||||||
|
compareSet.stream()
|
||||||
|
.distinct()
|
||||||
|
.filter(s -> !targetSet.contains(s))
|
||||||
|
.count(); // compare 에만 존재하는 도협 수 (target 에는 없음)
|
||||||
|
|
||||||
|
log.info(
|
||||||
|
"""
|
||||||
|
===== MapSheet Year Comparison =====
|
||||||
|
target Total: {}
|
||||||
|
compare Total: {}
|
||||||
|
Intersection: {}
|
||||||
|
target Only (Excluded from compare): {}
|
||||||
|
compare Only: {}
|
||||||
|
====================================
|
||||||
|
""",
|
||||||
|
targetSet.size(),
|
||||||
|
compareSet.size(),
|
||||||
|
intersectionCount,
|
||||||
|
excludedTargetCount,
|
||||||
|
onlyCompareCount);
|
||||||
|
|
||||||
|
List<String> filteredTargetList =
|
||||||
|
targetSet.stream() // target 기준으로
|
||||||
|
.filter(compareSet::contains) // compare에 있는 도협만 남김
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
Scene modelComparePath = getSceneInference(compareYear.toString(), filteredTargetList, "", "");
|
||||||
|
|
||||||
|
Scene modelTargetPath = getSceneInference(targetYear.toString(), filteredTargetList, "", "");
|
||||||
|
|
||||||
|
// ai 서버에 전달할 파라미터 생성
|
||||||
|
pred_requests_areas predRequestsAreas = new pred_requests_areas();
|
||||||
|
predRequestsAreas.setInput1_year(compareYear);
|
||||||
|
predRequestsAreas.setInput2_year(targetYear);
|
||||||
|
predRequestsAreas.setInput1_scene_path(modelComparePath.getFilePath());
|
||||||
|
predRequestsAreas.setInput2_scene_path(modelTargetPath.getFilePath());
|
||||||
|
|
||||||
|
InferenceSendDto m1 = this.getModelInfo(modelUuid);
|
||||||
|
m1.setPred_requests_areas(predRequestsAreas);
|
||||||
|
|
||||||
|
// ai 추론 실행 api 호출
|
||||||
|
Long batchId = ensureAccepted(m1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Scene getSceneInference(
|
||||||
|
String yyyy, List<String> mapSheetNums, String mapSheetScope, String detectOption) {
|
||||||
|
return mapSheetMngCoreService.getSceneInference(
|
||||||
|
yyyy, mapSheetNums, mapSheetScope, detectOption);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 추론 AI API 호출
|
||||||
|
*
|
||||||
|
* @param dto
|
||||||
|
*/
|
||||||
|
private Long ensureAccepted(InferenceSendDto dto) {
|
||||||
|
|
||||||
|
if (dto == null) {
|
||||||
|
log.warn("not InferenceSendDto dto");
|
||||||
|
throw new CustomApiException("BAD_REQUEST", HttpStatus.BAD_REQUEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1) 요청 로그
|
||||||
|
try {
|
||||||
|
log.debug("Inference request dto={}", objectMapper.writeValueAsString(dto));
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
log.warn("Failed to serialize inference dto", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3) HTTP 호출
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||||
|
headers.setAccept(List.of(MediaType.APPLICATION_JSON));
|
||||||
|
|
||||||
|
ExternalCallResult<String> result =
|
||||||
|
externalHttpClient.call(inferenceUrl, HttpMethod.POST, dto, headers, String.class);
|
||||||
|
|
||||||
|
if (result.statusCode() < 200 || result.statusCode() >= 300) {
|
||||||
|
log.error("Inference API failed. status={}, body={}", result.statusCode(), result.body());
|
||||||
|
throw new CustomApiException("BAD_GATEWAY", HttpStatus.BAD_GATEWAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4) 응답 파싱
|
||||||
|
try {
|
||||||
|
List<Map<String, Object>> list =
|
||||||
|
objectMapper.readValue(result.body(), new TypeReference<>() {});
|
||||||
|
|
||||||
|
if (list.isEmpty()) {
|
||||||
|
throw new IllegalStateException("Inference response is empty");
|
||||||
|
}
|
||||||
|
|
||||||
|
Object batchIdObj = list.get(0).get("batch_id");
|
||||||
|
if (batchIdObj == null) {
|
||||||
|
throw new IllegalStateException("batch_id not found in response");
|
||||||
|
}
|
||||||
|
|
||||||
|
return Long.valueOf(batchIdObj.toString());
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Failed to parse inference response. body={}", result.body(), e);
|
||||||
|
throw new CustomApiException("INVALID_INFERENCE_RESPONSE", HttpStatus.BAD_GATEWAY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 모델정보 조회 dto 생성 후 반환
|
||||||
|
*
|
||||||
|
* @param uuid
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private InferenceSendDto getModelInfo(UUID uuid) {
|
||||||
|
|
||||||
|
Basic modelInfo = modelMngCoreService.findByModelUuid(uuid);
|
||||||
|
|
||||||
|
String cdModelPath = "";
|
||||||
|
String cdModelConfigPath = "";
|
||||||
|
String cdClsModelPath = "";
|
||||||
|
|
||||||
|
if (modelInfo.getCdModelPath() != null && modelInfo.getCdModelFileName() != null) {
|
||||||
|
cdModelPath =
|
||||||
|
Paths.get(modelInfo.getCdModelPath(), modelInfo.getCdModelFileName()).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (modelInfo.getCdModelConfig() != null && modelInfo.getCdModelConfigFileName() != null) {
|
||||||
|
cdModelConfigPath =
|
||||||
|
Paths.get(modelInfo.getCdModelConfig(), modelInfo.getCdModelConfigFileName()).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (modelInfo.getClsModelPath() != null && modelInfo.getClsModelFileName() != null) {
|
||||||
|
cdClsModelPath =
|
||||||
|
Paths.get(modelInfo.getClsModelPath(), modelInfo.getClsModelFileName()).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
String modelType = "";
|
||||||
|
|
||||||
|
if (modelInfo.getModelType().equals(ModelType.G1.getId())) {
|
||||||
|
modelType = ModelType.G1.getId();
|
||||||
|
} else if (modelInfo.getModelType().equals(ModelType.G2.getId())) {
|
||||||
|
modelType = ModelType.G2.getId();
|
||||||
|
} else {
|
||||||
|
modelType = ModelType.G3.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
InferenceSendDto sendDto = new InferenceSendDto();
|
||||||
|
sendDto.setModel_version(modelInfo.getModelVer());
|
||||||
|
sendDto.setCd_model_path(cdModelPath);
|
||||||
|
sendDto.setCd_model_config(cdModelConfigPath);
|
||||||
|
sendDto.setCls_model_path(cdClsModelPath);
|
||||||
|
sendDto.setCls_model_version(modelInfo.getModelVer());
|
||||||
|
sendDto.setCd_model_type(modelType);
|
||||||
|
sendDto.setPriority(5.0);
|
||||||
|
// 운영환경일때 경로수정 dean 260226
|
||||||
|
if (profile != null && profile.equals("prod")) {
|
||||||
|
log.info("profile = {} change inforence req", profile);
|
||||||
|
sendDto.changeValForProd();
|
||||||
|
}
|
||||||
|
|
||||||
|
return sendDto;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -355,8 +355,12 @@ public class MapSheetInferenceJobService {
|
|||||||
m.setCls_model_version(progressDto.getClsModelVersion());
|
m.setCls_model_version(progressDto.getClsModelVersion());
|
||||||
m.setCd_model_type(type);
|
m.setCd_model_type(type);
|
||||||
m.setPriority(5d);
|
m.setPriority(5d);
|
||||||
|
// 운영환경일때 경로수정 dean 260226
|
||||||
// log.info("InferenceSendDto={}", m);
|
if (profile != null && profile.equals("prod")) {
|
||||||
|
log.info("profile = {} [M]change inforence req", profile);
|
||||||
|
m.changeValForProd();
|
||||||
|
}
|
||||||
|
log.info("[Inference]SendDto={}", m);
|
||||||
// 추론 실행 api 호출
|
// 추론 실행 api 호출
|
||||||
Long batchId = ensureAccepted(m);
|
Long batchId = ensureAccepted(m);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user