OpenAI를 이용한 간단한 프로그램 만들기

sliver gun·2025년 2월 5일

egovFramework

목록 보기
14/14

목차

  1. 서론
  2. GPT
  3. OCR
  4. Visual
  5. 결론
  6. 레퍼런스

서론

이전에 에티오피아에서 학생들에게 전자정부표준프레임워크를 소개해주는 과목을 맡아서 교수님을 보조했었는데 졸업 전에 인수인계 겸 그 학생들의 캡스톤 과목 실습문제를 만드는 기회를 얻게 되었다.

이 캡스톤 과목에서 사용할 실습문제는 학교에서 실제로 내가 진행했던 졸업프로젝트를 간략화 해서 만드는 것으로 결정되었다.

그래서 GPT를 끌어와서 사용해보는 파트, OCR로 글을 읽고 요약하는 파트, 긴 단락의 주요 단어를 시각화하는 파트, 총 3가지 파트로 나눠서 실습문제를 만들기로 했다.


초기세팅

eGovFramework에서 기본적으로 웹 세팅하는 것은 이전에 포스팅했던 블로그를 참고하면 된다.

이번엔 학생들에게 무언가 결과물이 나올 수 있게 페이지들은 대충 bootstrap으로 껍질만 씌워뒀다.


GPT

GPT는 theokanning 라이브러리를 사용한다.

ChatGPT를 불러오기 위한 일부 파라미터 (모델명, 토큰 등)을 미리 맞춰두고 GPT를 사용하기 위한 함수를 구성한다.

public String useGPT(String prompt, String content) {
    OpenAiService service = new OpenAiService(gptKey,Duration.ofMinutes(9999)); // OpenAI 서비스 연결

    List<ChatMessage> message = new ArrayList<ChatMessage>(); // GPT에게 보낼 메세지 어레이
    message.add(new ChatMessage("user", prompt));
    message.add(new ChatMessage("user", content));
    ChatCompletionRequest completionRequest = ChatCompletionRequest.builder() // OpenAI의 모델 선택하여 메세지 전달후 결과 텍스트 받기
            .messages(message)
            .model(gptModel) // 터보 3.5모델 사용.
            .maxTokens(4000) // 입력과 출력중 출력에 할당되는 최대 토큰 값. 현재 입출력 최대 토큰 16,385
            .temperature((double) 0.3f) // 답변의 자유도 설정
            .build();

    return service.createChatCompletion(completionRequest).getChoices().get(0)
            .getMessage().getContent();
}

이 함수를 이용해서 간단하게 POST방식으로 model에 결과를 추가하고 보내도록 구성하면 된다.

@RequestMapping(value = "/useGPT.do", method = RequestMethod.POST)
public String doGPT(String prompt, String content, Model model) {
	String result = "";
	
	UseGPT gpt = new UseGPT(gptKey, gptModel, Integer.parseInt(gptMaxInputToken), Integer.parseInt(gptMaxOutputToken));
	result = gpt.useGPT(prompt, content);
	
	System.out.println("result: " + result);

	/* 결과들을 웹페이지 모델에 요소들로 추가 */
	model.addAttribute("resultContent", result);

	return "GPT";
}


OCR

OCR은 tess4j 라이브러리를 사용했다.

tess4j 라이브러리는 maven에서 다음과 같이 dependency를 추가할 수 있다.


<dependency>
   <groupId>net.sourceforge.tess4j</groupId>
   <artifactId>tess4j</artifactId>
   <version>4.5.4 </version>  
</dependency>

하지만 모델 파일은 따로 다운받아야 한다.

그 뒤 Tesseract를 사용할 때 path를 지정해주면 사용이 가능하다.

tesseract.setDatapath("C:/Program Files/Tesseract-OCR/tessdata");

OCR을 쓰기 위해선 이미지 파일을 받아와야 한다.

웹에서 이미지를 받으면 Controller에서 MultipartFile로 받아와야 한다.

MultipartFile을 사용하려면 사전 세팅이 필요하다.

  1. @MultipartConfig을 class 상단에 적어야한다.

    @MultipartConfig(fileSizeThreshold = 1024 * 1024, maxFileSize = 1024 * 1024 * 5, maxRequestSize = 1024 * 1024 * 5 * 5)
    public class OpenAIController {
    	...
    }
  2. tomcat서버의 context.xml 설정이 필요하다.

    <Context allowCasualMultipartParsing="true" path="/">
    ...
    </Context>
  • saveUploadedFile 이미지 파일을 받고 저장한 뒤 파일 경로를 반환한다.
  • performOCR 경로에 있는 이미지 파일로 OCR을 실행하고 나온 String 결과값을 반환한다.

위 두 함수를 이용해 ocr 결과를 model로 보낸다.

@RequestMapping(value = "/useOCR.do", method = RequestMethod.POST)
public String doOCR(@RequestParam("image") MultipartFile file, Model model) {
	try {
      String filePath = saveUploadedFile(file);
      String ocrResult = performOCR(filePath);

      model.addAttribute("ocrResult", ocrResult);
  } catch (Exception e) {
      model.addAttribute("error", "Error processing the image: " + e.getMessage());
  }

	return "OCR";
}


Visual

Visual 파트에선 textarea에서 문단 내용을 받고 그 내용에서 주요 단어들의 빈도수를 JSON 형식으로 치환한 뒤 그걸 라이브러리를 통해 wordcloud로 이미지를 도출하는 것이 목적이다.

여기선 ECharts + WordCloud 플러그인을 사용하기로 하였다.

다음과 같이 CDN으로 echarts-wordcloud를 추가한다

<head>
    <script src="https://cdn.jsdelivr.net/npm/echarts/dist/echarts.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/echarts-wordcloud@2.1.0/dist/echarts-wordcloud.min.js"></script>
</head>
  • 받은 문단 내용에서 주요 단어들의 빈도수를 JSON 형식으로 치환하기

이 부분은 잘 다듬은 프롬프트를 통해 GPT에서 처리가 가능하다.

텍스트에서 키워드를 추출하고 각 키워드의 빈도를 계산하여 JSON 형식({예: 3})으로 표시하세요.
위 형식에서 쉼표 제거, 키워드 개수 조정 등 다양한 조건들을 조정해주는 프롬프트를 추가하면 보다 정확하게 JSON 형식으로 키워드를 추출할 수 있다.

@RequestMapping(value = "/useVisual.do", method = RequestMethod.POST)
public String visual(String content, Model model) {
  	String jsonTag = "";
  	String prompt = Prompt.getPrompt();
	
	UseGPT gpt = new UseGPT(gptKey, gptModel, Integer.parseInt(gptMaxInputToken), Integer.parseInt(gptMaxOutputToken));
	
	jsonTag = gpt.useGPT(prompt, content);
	
	System.out.println("jsonTag: " + jsonTag);

	model.addAttribute("jsonTag", jsonTag);

	return "Visual";
}
  • JSON을 가지고 wordcloud로 이미지를 도출

jsp파일에서 ECharts + WordCloud을 통해 JSON 데이터를 JavaScript 객체로 변환하는 과정을 추가하면 구현할 수 있다.

<script>
    var jsonTag = ${jsonTag};  
    var words = Object.entries(jsonTag).map(([word, value]) => ({ name: word, value }));

    var chart = echarts.init(document.getElementById('wordCloud'));
    var option = {
        series: [{
            type: 'wordCloud',
            shape: 'circle',
            sizeRange: [12, 50],
            rotationRange: [-90, 90],
            gridSize: 2,
            textStyle: { fontFamily: 'Arial', fontWeight: 'bold' },
            data: words
        }]
    };
    chart.setOption(option);
</script>

이 화면에서 내용을 입력하면,

jsonTag가 위와 같이 Console에서 확인 할 수 있으며,

다음과 같이 이미지가 나오게 된다.


결론

기능 구현이 대강 잡혀있긴 하지만 실제로 학생들이 따라해보고 작동시켜보기 위해선 세세한 부분들을 좀 더 보완해야 한다.
아무래도 학생들이 구현할 때 따라하기 쉽도록 코드를 짜려다보니 신경쓸 부분들이 좀 있었던 것 같다.

0개의 댓글