Home [Web] Text-Rank 요약 API 배포해보기
Post
Cancel

[Web] Text-Rank 요약 API 배포해보기

Flask 어플리케이션 생성

아래와 같은 구조를 갖는다.

1
2
3
4
5
.
ㄴ app.py
ㄴ summary.py
ㄴ Dockfile
ㄴ requirements.txt

app.py

처음 플라스크를 실행하면 아래와 같은 구성이 기본값으로 입력되어 있을 것이다.

1
2
3
4
5
6
7
8
9
10
from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello World!'

if __name__ == '__main__':
    app.run()

요약할 텍스트가 POST 타입으로 입력되었을 때 summary.py에 정의되어 있는 간단한 요약 알고리즘을 통과해 결과를 반환하도록 구성했다.

1
2
3
4
5
6
7
8
from flask import jsonify, request
from summary import summary_content

@app.route('/summarize', methods=['POST'])
def summarize():
    text = request.args.get('text')
    summary = summary_content(text)
    return jsonify(summary)

배포 후 접속을 위해 포트 관련 설정을 진행해준다.

1
2
if __name__ == '__main__':
    app.run('0.0.0.0', port=5000, debug=True)

종합해보면 app.py는 아래와 같은 구성을 갖는다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from flask import Flask, jsonify, request
from summary import summary_content

app = Flask(__name__)


@app.route('/', methods=['GET'])
def hello_world():
    return 'Hello World!'


@app.route('/summarize', methods=['POST'])
def summarize():
    text = request.args.get('text')
    summary = summary_content(text)
    return jsonify(summary)


if __name__ == '__main__':
    app.run('0.0.0.0', port=5000, debug=True)


summary.py

요약을 실행해보기 위한 함수로 구성되어 있다.

우선 아래와 같은 라이브러리를 이용한다.

1
2
3
4
5
6
7
8
9
10
from gensim.summarization.summarizer import summarize
from konlpy.tag import Kkma

kkma = Kkma()
import sys
import os
import re
import tensorflow
import keras
from hanspell import spell_checker

gensim의 경우, 최신 버전부터는 summarization을 제공하지 않으니 알맞는 버전을 사용해야 한다.

1
pip install gensim==3.8.3

본 프로젝트에서는 3.8.3 버전의 gensim을 이용했다.

수정할 부분이 많은 코드이나 배포 테스트를 위한 것이니 일단 아래 코드를 사용해보았다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def summary_content(contents):
    sentence = []
    contents = [contents]
    for content in contents:
        processed = preprocessing([content])
        if len(processed.split(".")) < 5:
            continue
        summary = summarize(processed, word_count=35)
        summary = re.sub("\n", " ", summary)
        if len(summary) == 0:
            continue
        spelled_summary = spell_checker.check(summary)
        summary = spelled_summary.checked
        sentence.append(summary)
    return sentence[0]

입력받은 원본 텍스트에 대한 preprocessing 과정을 거치고, 5문장 이상의 텍스트에 대해서만 요약을 수행하도록 구성했다.

word_count가 35 이내인 요약 결과를 반환하게 되고, 스펠링을 체크한 후 최종적인 결과를 반환한다.

(여러 원본 텍스트에 대한 요약을 한번에 진행하기 위해 텍스트 배열을 입력받아 사용했으나, 테스트를 위한 것이니 ‘contents = [contents]’를 통해 하나의 원본만 받아 처리하도록 약간의 수정을 거쳤다.)

앞서 요약을 진행하기 전 preprocessing을 진행했다. 그 코드는 아래와 같다.

1
2
3
4
5
6
7
8
9
10
11
12
13
def preprocessing(content):
    total_content = ''
    for idx in range(len(content)):
        r = content[idx]
        for sentence in kkma.sentences(r):
            sentence = re.sub('([a-zA-Z])', '', sentence)
            sentence = re.sub('[ㄱ-ㅎㅏ-ㅣ]+', '', sentence)
            sentence = re.sub('[-=+,#/\?:^$.@*\"※~&%ㆍ!』\\‘|\(\)\[\]\<\>`\'…》]', '', sentence)
            if len(sentence) == 0:
                continue
            sentence += '. '
            total_content += sentence
    return total_content

정규식을 활용한 텍스트 전처리를 진행한 후, 각 문장의 끝에 ‘.’을 붙여 결과를 반환한다.


Check

우선 작성한 코드가 잘 동작하는지 확인이 필요하다.

1
python3 app.py

를 통해 flask를 실행해본다.

잘 동작한다면 해당 버전의 라이브러리를 사용할 수 있도록 requirements.txt로 구성해준다.

1
pip freeze > requirements.txt


Dockerfile

python 만을 이용해 진행하려 했으나 본 프로젝트에서 konlpy를 사용하고 있다. konlpy는 자바를 활용하고 있으니 java와 python에 대한 설치가 모두 진행되어야 동작한다.

1
2
3
4
5
6
7
8
9
10
# basing on ubuntu OS
FROM ubuntu:latest
LABEL maintainer="Younghwani <younghwankim624@gmail.com>"

# apt init
ENV LANG=C.UTF-8
ENV TZ=Asia/Seoul
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && \
    apt-get install -y --no-install-recommends tzdata g++ git curl

⬆️ 우분투를 사용하니 설치를 진행하고 apt-get를 사용하기 위한 초기 설정을 진행한다.

1
2
3
4
5
6
7
8
9
10
# install Java jdk
RUN apt-get install -y openjdk-8-jdk
ENV JAVA_HOME="/usr/lib/jvm/java-1.8-openjdk"

# install Python and pip
RUN apt-get install -y python3-pip python3-dev
RUN cd /usr/local/bin && \
    ln -s /usr/bin/python3 python && \
    ln -s /usr/bin/pip3 pip && \
    pip3 install --upgrade pip

⬆️ 자바와 설치와 환경변수(path) 설정 및 파이썬 설치를 진행한다.

1
2
3
# apt clean
RUN apt-get clean && \
    rm -rf /var/lib/apt/lists/*

⬆️ 설치가 끝났으니 apt-get 리스트에 대한 정리를 진행한다.

1
2
3
4
5
6
7
8
9
10
# copy resource
COPY . .

# install python package
RUN pip install -r requirements.txt

#Expose port to 5000
EXPOSE 5000

CMD python ./app.py

⬆️ 프로젝트를 docker image를 구성할 위치에서 사용하기 위해 복사하고 필요한 라이브러리를 설치한다. 포트는 5000번을 사용한다.


Docker

Build

1
docker build -t younghwani/text-rank .

Run

1
docker run -p 8000:5000 younghwani/text-rank

Check

실행한 후 localhost:8000 또는 127.0.0.1:8000에 진입해 결과를 확인해본다. 위 app.py 코드를 그대로 사용했다면 “Hello World!”가 반환될 것이다.


DockerHub

구성한 이미지를 AWS EC2에서 사용하기 위해 도커 허브로 push 한다.

1
docker push <tag_name>:<version>


AWS EC2

도커 허브에 Push 한 이미지를 Pull 해서 사용한다.

1
docker pull <tag_name>:<version>

테스트를 위해 한번 실행해본다.

1
sudo docker run -p 8000:5000 <tag_name>:<version>

‘인스턴스_IP:8000’에 접속하면 ‘Hello World!’가 잘 반환되는 것을 확인할 수 있다.

This post is licensed under younghwani by the author.

[Web] Spring boot를 Docker 이미지를 이용해 AWS EC2에 배포

[Env] 자바 버전 변경

Comments powered by Disqus.