텍스트 요약(Text Summarization)

추출 요약(Extractive) 시스템은 문서가 무엇을 말했는지를 알려 줍니다. 생성 요약(Abstractive) 시스템은 저자가 무엇을 의미했는지를 말하려고 합니다. 서로 다른 과제(task)이고, 각자의 함정도 다릅니다.

유형: Build 언어: Python 선수 강의: Phase 5 · 02 (단어 가방과 TF-IDF; BoW + TF-IDF), Phase 5 · 11 (기계 번역; Machine Translation) 예상 시간: 약 75분

학습 목표

  • 추출 요약(Extractive summarization)과 생성 요약(Abstractive summarization)의 차이를 설명합니다.
  • 텍스트랭크(TextRank)를 구현해 문장 순위 매기기(sentence ranking) 기반 요약을 만듭니다.
  • ROUGE, BERTScore, G-Eval 같은 요약 평가 지표(metric)의 역할을 이해합니다.
  • 생성 요약의 사실성(factuality)과 환각(hallucination) 위험을 점검합니다.

문제

2,000단어 분량의 뉴스 기사가 피드(feed)에 들어왔습니다. 이를 120단어로 요약해야 합니다. 기사에서 가장 중요한 세 문장을 그대로 골라낼 수도 있고(추출 요약; extractive), 내용을 자신의 표현으로 다시 쓸 수도 있습니다(생성 요약; abstractive). 둘 다 요약(summarization)이라고 부르지만 완전히 다른 문제입니다.

추출 요약은 순위 매기기(ranking) 문제입니다. 모든 문장에 점수를 매기고 상위 k개를 반환합니다. 결과(output)는 원문에서 그대로 가져오기 때문에 항상 문법적으로 안전합니다. 위험은 기사 전체에 흩어진 내용을 놓치는 것입니다.

생성 요약은 생성(generation) 문제입니다. 트랜스포머(transformer)가 입력에 조건화(condition)되어 새로운 텍스트를 만들어 냅니다. 결과는 유창하고 압축적이지만, 원문에 없던 사실을 환각(hallucinate)할 수 있습니다. 위험은 자신감 있는 허위 정보 생성(fabrication)입니다.

이번 강의에서는 두 방식을 모두 만들어 보면서, 각 방식이 안고 있는 고유한 실패 양상을 함께 살펴봅니다.

사전 테스트

2문제 · 이 강의를 시작하기 전에 얼마나 알고 있는지 확인해보세요

1.추출 요약(extractive summarization)과 생성 요약(abstractive summarization)의 근본적인 차이는 무엇인가요?

2.규제(compliance)에 민감한 조직이 생성 요약보다 추출 요약을 선호할 수 있는 이유는 무엇인가요?

0/2 답변 완료

개념

extractive (TextRank) s1 s2 s3 s4 s5 s6 PageRank picks most connected sentences verbatim. never hallucinates. risk: misses distributed content. abstractive (BART / T5 / Pegasus) article (500-2000 tokens) tokens in transformer enc-dec cross-attention new text (60-200 tok) generates new tokens, not selects fluent, compressive. risk: hallucinated entities, flipped polarity, wrong numbers.

**추출 요약(Extractive). 기사를 그래프(graph)로 봅니다. 노드(node)는 문장이고, 간선(edge)은 문장 사이의 유사도(similarity)입니다. 이 그래프 위에서 페이지랭크(PageRank) 계열 알고리즘을 돌려, 각 문장이 다른 문장들과 얼마나 잘 연결되어 있는지를 점수로 계산합니다. 가장 높은 점수를 받은 문장들이 요약이 됩니다. 대표 구현은 텍스트랭크(TextRank)**이며, 미할체아와 타라우(Mihalcea and Tarau, 2004)가 제안했습니다.

생성 요약(Abstractive). 문서-요약 쌍(document-summary pair)으로 트랜스포머 인코더-디코더(encoder-decoder)인 BART, T5, Pegasus 같은 모델을 미세 조정(fine-tune)합니다. 추론(inference) 시에는 모델이 문서를 읽고, 교차 어텐션(cross-attention)을 통해 토큰 하나씩(token-by-token) 요약을 만들어 냅니다. 특히 Pegasus는 갭 문장(gap-sentence) 사전학습 목표를 사용하기 때문에, 별도의 미세 조정 없이도 요약 과제에서 매우 좋은 성능을 보입니다.

평가에는 ROUGE(Recall-Oriented Understudy for Gisting Evaluation)를 사용합니다. ROUGE-1과 ROUGE-2는 각각 유니그램(unigram)과 바이그램(bigram) 겹침을 측정하고, ROUGE-L은 최장 공통 부분 수열(longest common subsequence; LCS)을 측정합니다. 값이 높을수록 좋지만, 일반적으로 ROUGE-L 40 정도면 "양호(good)"한 수준이고 50이면 "매우 뛰어남(exceptional)" 수준입니다. 거의 모든 논문은 이 세 지표를 모두 보고합니다. 구현체로는 rouge-score 패키지를 사용합니다.

직접 만들기

Step 1: 텍스트랭크(TextRank, 추출 요약)

import math
import re
from collections import Counter


def sentence_split(text):
    return re.split(r"(?<=[.!?])\s+", text.strip())


def similarity(s1, s2):
    w1 = Counter(s1.lower().split())
    w2 = Counter(s2.lower().split())
    intersection = sum((w1 & w2).values())
    denom = math.log(len(w1) + 1) + math.log(len(w2) + 1)
    if denom == 0:
        return 0.0
    return intersection / denom


def textrank(text, top_k=3, damping=0.85, iterations=50, epsilon=1e-4):
    sentences = sentence_split(text)
    n = len(sentences)
    if n <= top_k:
        return sentences

    sim = [[0.0] * n for _ in range(n)]
    for i in range(n):
        for j in range(n):
            if i != j:
                sim[i][j] = similarity(sentences[i], sentences[j])

    scores = [1.0] * n
    for _ in range(iterations):
        new_scores = [1 - damping] * n
        for i in range(n):
            total_out = sum(sim[i]) or 1e-9
            for j in range(n):
                if sim[i][j] > 0:
                    new_scores[j] += damping * sim[i][j] / total_out * scores[i]
        if max(abs(s - ns) for s, ns in zip(scores, new_scores)) < epsilon:
            scores = new_scores
            break
        scores = new_scores

    ranked = sorted(range(n), key=lambda k: scores[k], reverse=True)[:top_k]
    ranked.sort()
    return [sentences[i] for i in ranked]

두 가지를 짚을 만합니다. 유사도 함수는 로그 정규화된 단어 겹침(log-normalized word overlap)을 사용하는데, 이는 텍스트랭크 원논문에서 쓴 방식입니다. TF-IDF 벡터의 코사인 유사도를 써도 됩니다. 감쇠 계수(damping factor) 0.85와 반복 횟수(iteration count)는 페이지랭크의 기본값입니다.

Step 2: BART 기반 생성 요약

from transformers import pipeline

summarizer = pipeline("summarization", model="facebook/bart-large-cnn")

article = """(긴 뉴스 기사 본문)"""

summary = summarizer(article, max_length=120, min_length=60, do_sample=False)
print(summary[0]["summary_text"])

BART-large-CNN은 CNN/DailyMail 말뭉치(corpus)에 미세 조정되어 있어, 별도 학습 없이도 뉴스 스타일의 요약을 바로 만들어 줍니다. 다른 도메인(과학 논문, 대화, 법률 문서 등)에서는 그에 맞는 Pegasus 체크포인트(checkpoint)를 쓰거나, 대상 데이터로 직접 미세 조정해야 합니다.

Step 3: ROUGE 평가

from rouge_score import rouge_scorer

scorer = rouge_scorer.RougeScorer(["rouge1", "rouge2", "rougeL"], use_stemmer=True)
scores = scorer.score(reference_summary, generated_summary)
print({k: round(v.fmeasure, 3) for k, v in scores.items()})

어간 추출(stemming)은 항상 켜는 것이 좋습니다. 그렇지 않으면 runningrun이 서로 다른 단어로 잡혀 ROUGE가 과소평가됩니다.

ROUGE 너머의 2026 요약 평가

ROUGE는 지난 20년간 요약 평가의 지배적인(dominant) 지표였지만, 2026년 시점에서는 단독으로 쓰기에는 부족합니다. 자연어 생성(NLG) 논문들을 대규모로 메타 분석한 결과는 다음과 같습니다.

  • BERTScore. 문맥 임베딩(contextual embedding) 유사도를 사용합니다. 2023년까지 꾸준히 자리를 잡았고, 이제는 대부분의 요약 논문에서 ROUGE와 함께 보고됩니다.
  • BARTScore. 평가를 생성 문제로 다룹니다. 원문이 주어졌을 때 사전 학습된 BART가 그 요약에 부여하는 우도(likelihood)를 점수로 사용합니다.
  • MoverScore. 문맥 임베딩 사이의 어스 무버스 거리(Earth Mover's Distance)를 측정합니다. ROUGE보다 의미적 겹침(semantic overlap)을 더 잘 포착하기 때문에, 2025년 요약 벤치마크에서 가장 좋은 자리를 차지했습니다.
  • FactCC와 QA 기반 사실성(QA-based faithfulness). 2021~2023년에 흔히 쓰였고, 이제는 G-Eval(GPT-4 프롬프트 체인이 일관성(coherence), 일치성(consistency), 유창성(fluency), 적절성(relevance)을 사고의 흐름(chain-of-thought) 방식으로 채점)로 대체되는 경우가 많습니다.
  • G-Eval과 LLM 심사관(LLM-judge) 계열. 채점 기준(rubric)이 잘 설계되면 사람의 판단과 약 80% 수준으로 일치합니다.

운영 환경(production) 권장 구성은, 기존과의 비교를 위해 ROUGE-L을, 의미적 겹침을 보기 위해 BERTScore를, 일관성과 사실성을 보기 위해 G-Eval을 함께 보고하는 것입니다. 50~100건의 사람 라벨링 요약으로 보정(calibration)해야 합니다.

Step 4: 사실성(factuality) 문제

생성 요약은 환각에 취약합니다. 추출 요약은 결과가 원문에서 그대로 가져온 것이기 때문에 환각 위험이 훨씬 낮지만, 그렇다고 안전한 것은 아닙니다. 원문 문장이 맥락을 잃은 채 잘려 나오거나, 시점이 지난 정보이거나, 순서가 뒤바뀐 채 인용되면 여전히 오해를 만들 수 있습니다. 이것이 규제(compliance)에 가까운 콘텐츠에서 운영 시스템이 여전히 추출 요약을 선호하는 가장 큰 이유입니다.

대표적인 환각 유형은 다음과 같습니다.

  • 개체 바꿔치기(Entity swap). 원문에는 John Smith로 나오는데, 요약에는 John Brown으로 나옵니다.
  • 숫자 흘러내림(Number drift). 원문의 25,000이 요약에서는 25 million이 됩니다.
  • 극성 뒤집기(Polarity flip). 원문의 rejected the offer(제안을 거절했다)가 요약에서는 accepted the offer(제안을 받아들였다)가 됩니다.
  • 사실 날조(Fact invention). 원문에는 CEO 이야기가 전혀 없는데, 요약은 CEO가 승인했다고 말합니다.

효과가 입증된 평가 접근은 다음과 같습니다.

  • FactCC. 원문 문장과 요약 문장 사이의 함의 관계(entailment)를 학습한 이진 분류기(binary classifier)입니다. 사실/비사실(factual / not-factual)을 예측합니다.
  • QA 기반 사실성(QA-based factuality). 원문에 답이 있는 질문을 질의응답(QA) 모델에 묻습니다. 요약이 그와 다른 답을 지지하면 표시(flag)합니다.
  • 개체 수준 F1(Entity-level F1). 원문과 요약의 개체명(named entity)을 비교합니다. 요약에만 등장하는 개체는 의심 대상입니다.

뉴스, 의료, 법률, 금융처럼 사실성이 중요한 사용자 대면(user-facing) 콘텐츠에서는 추출 요약이 더 안전한 기본값입니다. 생성 요약을 쓴다면 반드시 사실성 점검(factuality check)을 함께 돌려야 합니다.

사용하기

2026년 기준 권장 구성은 다음과 같습니다.

사용 사례권장
영어 뉴스, 3~5문장 요약facebook/bart-large-cnn
과학 논문(Scientific papers)google/pegasus-pubmed 또는 미세 조정한 T5
다중 문서, 장문(Multi-document, long-form)32k+ 컨텍스트(context)를 가진 임의의 LLM에 프롬프트 사용
대화 요약(Dialog summarization)philschmid/bart-large-cnn-samsum
구조적으로 환각 위험이 낮은 추출 요약텍스트랭크 또는 sumy의 LSA / LexRank

컴퓨팅 자원(compute) 제약이 적다면, 긴 컨텍스트를 갖는 LLM이 2026년에 종종 전용 모델을 이깁니다. 다만 비용(cost)과 재현성(reproducibility)이 트레이드오프이며, 전용 모델 쪽이 출력 일관성(consistency)이 더 좋습니다.

산출물 만들기

outputs/skill-summary-picker.md로 저장합니다.

---
name: summary-picker
description: Pick extractive or abstractive, named library, factuality check.
version: 1.0.0
phase: 5
lesson: 12
tags: [nlp, summarization]
---

Given a task (document type, compliance requirement, length, compute budget), output:

Guide the student in Korean.

1. Approach. Extractive or abstractive. Explain in one sentence why.
2. Starting model / library. Name it. `sumy.TextRankSummarizer`, `facebook/bart-large-cnn`, `google/pegasus-pubmed`, or an LLM prompt.
3. Evaluation plan. ROUGE-1, ROUGE-2, ROUGE-L (use rouge-score with stemming). Plus factuality check if abstractive.
4. One failure mode to probe. Entity swap is the most common in abstractive news summarization; flag samples where source entities do not appear in summary.

Refuse abstractive summarization for medical, legal, financial, or regulated content without a factuality gate. Flag input over the model's context window as needing chunked map-reduce summarization (not just truncation).

연습문제

  1. 쉬움. 뉴스 기사 5개에 텍스트랭크를 실행합니다. 상위 3개 문장과 참조 요약(reference summary)을 비교해 ROUGE-L을 측정합니다. CNN/DailyMail 스타일 기사라면 ROUGE-L이 30~45 정도 나오는 것이 일반적입니다.
  2. 중간. 개체 수준 사실성을 직접 구현합니다. spaCy로 원문과 요약의 개체명을 추출한 뒤, 원문 개체가 요약에 얼마나 들어왔는지를 재현율(recall)로, 요약 개체가 원문에 얼마나 등장하는지를 정밀도(precision)로 계산합니다. 정밀도는 높지만 재현율이 낮으면 안전하지만 너무 짧다는 뜻이고, 정밀도가 낮으면 요약이 개체를 환각하고 있다는 뜻입니다.
  3. 어려움. CNN/DailyMail 기사 50개에서 BART-large-CNN과 LLM(Claude 또는 GPT-4)의 요약을 비교합니다. ROUGE-L, 개체 F1 기반 사실성, 요약 1건당 비용(cost per summary)을 보고하고, 각 방식이 어디서 우위에 있는지 정리합니다.

핵심 용어

용어흔한 설명실제 의미
추출 요약(Extractive)문장 고르기원문에서 문장을 그대로 가져와 반환합니다. 환각이 발생하지 않습니다.
생성 요약(Abstractive)다시 쓰기원문에 조건화되어 새 텍스트를 만들어 냅니다. 환각이 발생할 수 있습니다.
ROUGE요약 지표시스템 출력과 참조 요약 사이의 n-그램 / 최장 공통 부분 수열(LCS) 겹침입니다.
텍스트랭크(TextRank)그래프 기반 추출 요약문장 유사도 그래프 위에서 돌리는 페이지랭크입니다.
사실성(Factuality)맞는가요약의 주장이 원문에 의해 뒷받침되는지의 여부입니다.
환각(Hallucination)만들어 낸 내용원문이 지지하지 않는 요약 내용입니다.

더 읽을거리

실습 코드

이 강의의 실습 코드 1개

main
Code

산출물

이 강의에서 생성된 프롬프트, 스킬, 코드 산출물 1개

summary-picker

Pick extractive or abstractive, name the library, add a factuality check.

Skill

확인 문제

3문제 · 모두 맞추면 완료 표시가 가능합니다

1.텍스트랭크(TextRank)에서 감쇠 계수(damping factor, 보통 0.85)가 알고리즘 수렴에 필요한 이유는 무엇인가요?

2.생성 요약기가 'CEO John Brown이 합병을 승인했다'라고 출력했습니다. 그런데 원문 기사에는 'John Smith'라고 나오며 CEO 승인에 대한 언급은 전혀 없습니다. 이 출력에는 몇 가지 유형의 환각(hallucination)이 나타나나요?

3.추출 요약기의 ROUGE-L이 42인데 중요한 정보를 놓치고 있다고 의심됩니다. 이 차이를 가장 잘 드러낼 수 있는 추가 평가는 무엇인가요?

0/3 답변 완료

추가 문제 풀기

AI가 강의 내용을 바탕으로 새로운 문제를 생성합니다