[Cowork#003] 논문 요약 GPT

Yohan·2023년 3월 27일
0

Living with GPT

목록 보기
3/3
post-thumbnail

<GPT의 주니어 Human 비서 요한 👨‍💻>

논문 쉽게 읽기 프로젝트 #3: 논문 요약 GPT

지난 번에 최지피티씨의 도움으로 PDF에서 텍스트를 출력하는 task와 ChatGPT API를 연동하는 task를 성공적으로 마치고 침대에 누웠을 때 문득 이런 생각이 들었다. 이게 맞나? 내가 굳이 목표를 작은 task들로 쪼개서 최지피티씨에게 물어볼 필요가 있었을까? 그냥 처음부터 내가 필요한 전부를 말하면 되는 게 아니었을까? 그래서 해봤다.

I'd like to ask about creating a Python program that uses the ChatGPT API to summarize research papers by chapter. The program should fulfill the following requirements:
1) The user inputs a paper's arxiv link while connected to the internet, and the program downloads the corresponding PDF as its input.
2) The program reads the text from the PDF and uses the ChatGPT API to summarize each chapter's technical key points in a single paragraph, from the abstract to the conclusion. References should be excluded.
3) The summaries for each chapter should be saved in a markdown format.

이렇게 물어보니, 필요한 라이브러리 설치부터 PDF 링크를 이용한 다운로드, GPT3 API를 이용한 문장 요약, 그리고 요약문의 저장까지 step by step으로 차근차근 알려준다. 진행을 하면서 두 가지 문제에 부딪혔는데 하나는 pdf text를 각 챕터 별로 split를 하는 부분에서 논문마다 chapter 구성이 달라 heading을 일괄적으로 뽑기 어렵다는 것이었고, 또 다른 문제는 GPT 모델의 token 수가 제한적이라는 부분이었다. 뭔가 마땅한 방법이 생각나지 않아 우선 안내해준 코드를 바탕으로 abstract 부분만 추출해서 요약하는 것으로 목표를 축소해 만들어 봤다.

import requests
import pdfplumber
import re
import openai
import spacy

nlp = spacy.load("en_core_web_sm")

## Download PDF using arxiv Link
def download_pdf(arxiv_id):
    base_url = 'https://arxiv.org/pdf/'
    url = base_url + arxiv_id + '.pdf'
    headers = {'User-Agent': 'Mozilla/5.0'}
    response = requests.get(url, headers=headers)
    if response.status_code == 200:
        with open(arxiv_id + '.pdf', 'wb') as f:
            f.write(response.content)
    else:
        print('Error:', response.content)


## Extract text from PDF
def extract_text(file_path):
    with pdfplumber.open(file_path) as pdf:
        text = ' '.join([page.extract_text() for page in pdf.pages])
    return text


# Find the abstract heading and extract the abstract chapter
def extract_abstract(text):    
    abstract_heading = re.search(r'\bAbstract\b', text, re.IGNORECASE)
    if abstract_heading:
        start = abstract_heading.end()
        end = re.search(r'\b(introduction|background|methods|results|discussion|conclusion)\b', text[start:], re.IGNORECASE)
        if end:
            end = start + end.start()
        else:
            end = len(text)
        abstract_chapter = text[start:end].strip()
        return abstract_chapter
    else:
        return None

## Summarize chapter using ChatGPT
def truncate_text(text, max_tokens):
    prompt_tokens = 25  # Approximate number of tokens for the prompt
    system_message_tokens = 7  # Number of tokens for the system message
    available_tokens = max_tokens - prompt_tokens - system_message_tokens

    doc = nlp(text, disable=["parser", "ner"])
    truncated_tokens = doc[:available_tokens]
    truncated_text = " ".join([token.text for token in truncated_tokens])
    return truncated_text
 
def summarize(api_key, text, max_tokens_len):
    openai.api_key = api_key

    truncated_text = truncate_text(text, max_tokens_len)

    prompt=f"Summarize the following text in one paragraph: {truncated_text}"

    response = openai.ChatCompletion.create(
        model="gpt-3.5-turbo",
        messages=[
            {"role": "system", "content": "You are a helpful assistant."},
            {"role": "user", "content": prompt},
        ],
        max_tokens=100,
        n=1,
        stop=None,
        temperature=0.5,
    )

    message = response.choices[0].message['content'].strip()
    return message

## Save the result
def save_summaries(summary, file_name):
    with open(file_name, 'w') as f:
        f.write(f"## abstract\n\n{summary}\n\n")


if __name__ == "__main__":
    arxiv_id = '1706.03762'
    chatgpt_api_key = 'your_chatgpt_api_key'

    download_pdf(arxiv_id)
    pdf_text = extract_text(arxiv_id + '.pdf')
    abstract = extract_abstract(pdf_text)
    summary = summarize(chatgpt_api_key, abstract, max_tokens_len=500)
    save_summaries(summary, 'summary.md')

세 번의 시도로부터 느낀 점 하나는 ChatGPT가 매직 스펠처럼 느껴지지만, 단순하게 동작하는 코드가 아니라 꽤 구체적인 요구사항을 만족시키기 위해서는 결국 단위 모듈의 기능을 반복적으로 수정하고 개선하는 작업이 필요하다는 점이다. 그럼에도 PDF에서 text를 추출하는 python 코드라던가, OpenAI의 GPT API 사용법 등을 전혀 몰랐던 내가 구글 검색 한 번 없이 GPT의 안내와 약간의 디버깅만으로 동작하는 코드를 한 두시간 내에 작성할 수 있는 것은 정말 놀라운 경험이었다.

✅ 총 작업 소요 시간: 107분 48초

profile
GPT's Human Assistant 요한👨‍💻

0개의 댓글