프로젝트

초보자 안내 서비스 : PDF를 통해 데이터 저장

밤린 2024. 6. 25. 20:35

지난 프로젝트까지는 text를 입력해서 외부 데이터를 저장시키게끔 했습니다. 하지만 여러 데이터들을 일일이 text를 넣어서 저장시키기에는 한계가 있다고 생각하였고, 이를 pdf를 넣어 외부 데이터를 저장시키게끔 구성하였습니다.

 

Controller로 부터 MultipartFile을 받아 아래와 같은 코드를 실행하게끔 하였습니다.

public void savePdfEmbedding(MultipartFile file) throws IOException {
        TikaDocumentReader tikaDocumentReader = new TikaDocumentReader(new InputStreamResource(file.getInputStream()));
        List<Document> documents = tikaDocumentReader.read();

        List<Document> splitDocuments = new ArrayList<>();
        EncodingRegistry registry = Encodings.newDefaultEncodingRegistry();
        Encoding enc = registry.getEncodingForModel(ModelType.GPT_3_5_TURBO);
        final int maxTokens = 1000;

        for (Document doc : documents) {
            String content = doc.getContent();
            IntArrayList tokens = enc.encode(content);

            for (int i = 0; i < tokens.size(); i += maxTokens) {
                int end = Math.min(i + maxTokens, tokens.size());
                IntArrayList chunkTokens = new IntArrayList();
                for (int j = i; j < end; j++) {
                    chunkTokens.add(tokens.get(j));
                }
                String chunkText = enc.decode(chunkTokens);

                Document splitDoc = new Document(chunkText, new HashMap<>(doc.getMetadata()));
                splitDoc.getMetadata().put("chunk_id", i / maxTokens);
                splitDocuments.add(splitDoc);
            }
        }

        vectorStore.add(splitDocuments);
    }

 

 

여기서 TikaDocumentReader와 PagePdfDocumentReader 중 어느 도구를 사용할 지에 대해 고민이 있었습니다. 아래는 두 도구의 특징들입니다.

 

TikaDocumentReader

Apache Tika는 다양한 파일 형식을 자동으로 감지하고 그 내용을 추출하는 라이브러리입니다. TikaDocumentReader는 이 Tika 라이브러리를 이용하여 문서의 텍스트를 추출합니다.

  • 지원 파일 형식: Tika는 PDF, Microsoft Word, Excel, PowerPoint, OpenDocument, HTML, XML, RTF, 이미지 파일(JPEG, PNG 등) 등 수백 가지의 다양한 파일 형식을 지원합니다.
  • 텍스트 추출 방식: TikaDocumentReader는 문서의 모든 텍스트를 한꺼번에 추출하여 반환합니다. 이는 문서의 구조보다는 내용 그 자체를 추출하는 데 중점을 둡니다.
  • 메타데이터 추출: 텍스트뿐만 아니라 문서의 메타데이터(작성자, 제목, 생성 날짜 등)도 함께 추출할 수 있습니다.
  • 사용 용도: 다양한 형식의 문서에서 텍스트를 빠르게 추출해야 하는 경우에 유용합니다. 예를 들어, 문서 검색 엔진, 텍스트 마이닝, 데이터 분석 등에 활용할 수 있습니다.

PagePdfDocumentReader

PagePdfDocumentReader는 주로 PDF 문서에 특화된 도구로, PDF 문서를 페이지 단위로 읽고 처리하는 기능을 제공합니다.

  • 지원 파일 형식: 주로 PDF 파일에 특화되어 있습니다.
  • 텍스트 추출 방식: PDF 문서를 페이지 단위로 나누어 텍스트를 추출합니다. 각 페이지별로 텍스트를 읽고 처리할 수 있습니다. 이는 문서의 구조를 보다 잘 유지하면서 텍스트를 추출할 수 있게 해줍니다.
  • 페이지별 처리: 페이지 단위로 접근할 수 있으므로, 특정 페이지에서만 텍스트를 추출하거나, 페이지별로 다른 처리를 할 수 있습니다. 예를 들어, 페이지마다 다른 분석을 하거나 페이지를 넘겨가며 읽는 애플리케이션에 유용합니다.
  • 사용 용도: PDF 문서의 특정 페이지나 페이지 범위에서 텍스트를 추출하고자 할 때 유용합니다. 특히, PDF 문서의 구조와 레이아웃을 유지하면서 텍스트를 처리해야 하는 경우에 적합합니다.

제가 사용하려던 pdf문서는 해당 게임을 즐기는 유저들이 직접 작성한 나무위키의 내용을 pdf로 가져와서 사용하려 하였습니다. 그러다 보니 PagePdfDocumentReader는 페이지 단위로 나누어 텍스트를 추출하게 되는데 이 때 나무위키에는 여러표와 글꼴등이 존재하여 페이지 내용의 인식에 문제가 발생하여 사용하기에 어려움이 있었습니다. 따라서 TikaDocumentReader를 사용하게 되었습니다. 또한 PagePdfDocumentReader와 다르게 여러 파일의 형식을 받을 수 있기에 확장성 면에서도 초보자 안내 서비스에 더욱 적합할 것이라고 생각하였습니다.

 

또한, Document를 slice한 이유는 최대 token이 정해져 있기 때문에 vectorStore에 저장하기 전에  maxTokens를 1000으로 잡고 토큰 수에 따라 나눠서 저장하게끔 코드를 작성하였습니다.

 

결과

Kibana에 저장되어 있는 데이터의 정보입니다.

이전과 같이 content와 embedding이 같이 저장되어 있습니다.

 

이를 swaggger를 이용하여 요청하였습니다.

이렇게 외부 데이터를 통해 특정 목적에 맞는 데이터를 사용자에게 전달할 수 있습니다.