AI 모델 적용에 대한 고민
프로젝트 진행 도중 학습시킨 AI모델을 어떻게 적용 시키는게 좋을까에 대한 고민 과정 기록
상황
Restfull으로 개발된 SpringBoot 애플리케이션에 비즈니스 로직을 구현해두고
특정 비즈니스 로직을 실행시키기 위해서는 AI 모델에 대한 코드와 데이터에 대한 전처리 코드를 사용해야 한다.
즉 Java 코드안에서 python 스크립트를 호출하여 사용해야 하는 상황
해당 python 코드는 AI 모델이 사용되기 때문에 상당히 많은 라이브러리를 요구하며 복잡하다.
선택지
고민에대한 선택지를 제공해준 기사: https://www.baeldung.com/java-working-with-python
- ProcessBuilder 사용
- JSR-223 스크립팅 엔진 작업 (jython)
- PythonInterpretor 클래스
- Apache Common Exec 사용
- 상호 운용성을 위해 HTTP 활용 (Django)
ProcessBuilder 사용 ✅
자바의 ProcessBuilder API를 사용하여 네이티브 운영 체제 프로세스를 생성하여 파이썬을 실행하고 스크립트를 실행시키는 방법
- Python 및 필요한 라이브러리 설치: EC2 인스턴스에 Python이 설치되어 있어야 하며, 코드에서 사용하는 라이브러리(예: matplotlib, torch, torchvision 등)도 설치되어 있어야 한다.
- GPU 지원: 코드에서 CUDA를 사용하고 있으므로, GPU가 있는 EC2 인스턴스를 사용하거나, CUDA가 없는 경우 코드를 수정하여 CPU만 사용하도록 설정해야 한다.
- ProcessBuilder 사용: Java의 ProcessBuilder를 사용하여 파이썬 스크립트를 실행할 수 있습니다. 이 경우, 파이썬 스크립트는 EC2 인스턴스에 존재해야 하며, ProcessBuilder는 이 스크립트를 실행하는 데 사용됩니다.
@Test
public void givenPythonScript_whenPythonProcessInvoked_thenSuccess() throws Exception {
ProcessBuilder processBuilder = new ProcessBuilder("python", resolvePythonScriptPath("hello.py"));
processBuilder.redirectErrorStream(true);
Process process = processBuilder.start();
List<String> results = readProcessOutput(process.getInputStream());
assertThat("Results should not be empty", results, is(not(empty())));
assertThat("Results should contain output of script: ", results, hasItem(
containsString("Hello Baeldung Readers!!")));
int exitCode = process.waitFor();
assertEquals("No errors should be detected", 0, exitCode);
}
JSR-223 스크립팅 엔진 작업 ✖️
JSR-223 스크립팅 엔진을 사용하여 jython을 사용하여 JVM 위에서 코드를 실행
- Jython 이슈사항: Jython은 Python 2.7까지만 지원하기 때문에 Python 3의 기능을 사용할 수 없다. 그 밖에도 AI모델을 돌리기 위한 Pythorch 라이브러리를 사용하는 것이 불가능 따라서 해당 상황에서는 부적합하다.
아파치 커먼즈 실행 ✅
Apache Commons Exec를 사용하여 Java에서 외부 프로세스를 실행시켜 사용한다.
- Python 및 필요한 라이브러리 설치: EC2 인스턴스에 Python이 설치되어 있어야 하며, 코드에서 사용하는 라이브러리(예: matplotlib, torch, torchvision 등)도 설치되어 있어야 한다.
- GPU 지원: 코드에서 CUDA를 사용하고 있으므로, GPU가 있는 EC2 인스턴스를 사용하거나, CUDA가 없는 경우 코드를 수정하여 CPU만 사용하도록 설정해야 한다.
- executor.execute() 사용: Java에서 외부 프로세스를 실행시켜 사용한다. 프로세스의 파라미터 관리, 실행 결과 처리 관리, 프로세스 실행 시간 제어를 하는 것이 가능하다
- 아파치 커먼즈 이슈사항: Jython은 Python 2.7까지만 지원하기 때문에 Python 3의 기능을 사용할 수 없다. 그 밖에도 AI모델을 돌리기 위한 Pythorch 라이브러리를 사용하는 것이 불가능 따라서 해당 상황에서는 부적합하다.
CommandLine cmdLine = new CommandLine("python");
cmdLine.addArgument("/path/to/your/python/script.py");
DefaultExecutor executor = new DefaultExecutor();
int exitValue = executor.execute(cmdLine);
상호 운용성을 위해 HTTP 활용 ✅
Django 프레임워크를 사용하여 추가로 서버를 하나더 개발하여 프로그램을 동작시킨다.
프론트에서 Ai기능이 필요한 순간마다 Django 서버로 요청을 보내고 얻은 결과물을 스프링 서버에서 사용하여 동작 시킨다.
- Django 프레임워크 설치: python에 Django 프레임 워크를 사용한다.
- 컨트롤러 코드 작성: AI모델이 판별할 데이터를 보내는 컨트롤러 코드(urls.py)를 작성한다.
- 서버 배포: Spring과 다른 컴퓨터에서 배포시킨다.
현재의 선택, 이유
상호 운용성을 위해 HTTP 활용 하는 방향으로 추진하였다.
1. 확장성: 데이터의 전처리 과정등의 추가적인 로직이 올라 갈 수 있다는 미래 가능성 염두하였다.
2. 분산처리: 프로그램의 핵심적인 로직이기 때문에 스프링의 로직과 분리하여 적용하는 것이 효율적이라고 생각하였다.
3. 유연성, 효율성: 결국 목표는 python과 java에대한 언어의 통합인 상황에서 HTTP는 언어의 독립적인 프로토콜이기 때문에 매개로 하여 언어의 통합을 이루어 낼 수 있으며 각 언어의 장점을 최대한으로 활용 할 수 있기 때문
차후 추가 검증이 필요한 부분
1. 복수의 기기가 접근 할 때의 각 방식의 성능 테스트
- ProcessBuilder나 Apache Commons Exec를 사용하지 않은 이유는
- 실행시켜야 하는 python 코드가 여러 라이브러리를 사용해서 상당히 복잡하므로 코드의 복잡성과 성능면에서 불리 할 거라는 추측 때문이기 때문에 검증을 최소한 한 번은 해볼 필요가 있다 판단된다.