AWS 기술 블로그

AWS AI 서비스를 활용한 미디어 자막 성능 개선 및 컨텐츠 현지화 방법

미디어에서 자막은 단순히 대사만을 전달하는 것이 아니라, 영상 속에서 일어나는 다양한 소리들(배경음, 음향 효과 등)도 설명해주기 때문에 영상의 내용을 이해하는 데 중요한 역할을 합니다. 자막의 대표적 종류인 폐쇄자막(Closed Caption)은 주로 청각 장애인을 위한 자막 서비스로 사용되어 모든 사람들이 접할 수 있게 되었습니다. 또한 자막을 통해  ‘오징어게임’, ‘더 글로리’와 같은 국내 미디어 컨텐츠의 세계화를 이룰 수 있었고, 이처럼 자막은 여러 방면으로 시청자와 미디어를 이어주는 매우 중요한 요소가 되었습니다.

Amazon Translate는 언어 번역을 빠르게 제공하는 신경망 기계 번역 서비스로 영상 콘텐츠 제작 시, 대본이나 자막을 빠르게 다국어로 번역할 수 있습니다. 다만, 영상 번역 시 가장 많이 사용되는 자막 포맷인 SRT(SubRip), WebVTT 파일등에 대해서 직접 번역을 할 수 없기 때문에 기존 자막 파일을 번역이 가능한 파일 형태인 text 혹은 HTML로 변경하고 의미 손실없이 번역된 자막 파일로 전환해주는 것이 매우 중요합니다. 이번 블로그에서는 Amazon Translate를 사용하여 자막 파일을 생성할 때, 자막 성능을 개선할 수 있는 방안에 대해 다루었습니다.

개요

1. 사용자가 자막파일을 만들 수 있는 방법은 여러가지가 있을 수 있습니다. 여기서는 AWS의 STT(Speech-To-Text)서비스인 Amazon Transcribe를 사용하여 샘플 영상(What is Amazon Transcribe_.mp4)에 대한 WebVTT 자막파일을 생성합니다.

2. Amazon Translate는 Input Data의 File Format으로 Plain Text(.txt), HTML(.html), Word Document(.docx), Excel Workbook(.xlsx), PowerPoint(.pptx), XLIFF 1.2(.xlf)를 지원합니다. 여기서는 Amazon Transcribe로부터 생성된 WebVTT 자막 파일을 Text(.txt) 형태로 변환하여 번역합니다.

3. 번역 전 Text파일의 전처리 및 번역 후, 자막 파일의 전처리 작업을 통해 자막 파일의 생성을 개선하는 방법을 다룹니다. 게시 글에선 Amazon SageMaker StudioNotebook 인스턴스에서 해당 작업을 수행합니다. (그림1)

그림 1. AWS AI 서비스를 활용한 WebVTT자막 전처리 및 번역 아키텍쳐

4. 다음 AWS의 TTS서비스인  Amazon Polly를 활용하여 컨텐츠를 쉽게 현지화하는 방법을 다루겠습니다. (그림 2)

그림 2. AWS AI 서비스를 활용한 컨텐츠 현지화 아키텍쳐

단계 요약

  • 단계1 : Amazon Transcribe로 WebVTT 생성
  • 단계 2 : Amazon SageMaker Studio에서 파일 전처리
    • WebVTT파일을 Text파일로 변환 및 기본 작업
    • Amazon Translate로 번역
  • 단계 3 : WebVTT파일 생성을 위한 후처리 방법 소개
  • 단계 4 : Amazon Polly 활용

사전 준비사항

실습을 진행하기 위해 아래와 같은 사항을 준비 해야 합니다.

  • AWS 계정
  • Amazon SageMaker Studio
    • Execution Role에는 추가적으로 Amazon S3, Amazon Polly등 필요한 역할 부여
  • 새로운 S3 bucket

단계 1: Amazon Transcribe로 WebVTT 생성

먼저 Amazon Transcribe를 활용하여 샘플 영상에 대한 WebVTT파일을 생성합니다.

1.     새롭게 생성한 S3 버킷에 ‘MP4’폴더를 생성한 뒤, 다운받은 샘플 영상(What is Amazon Transcribe_.mp4)을 업로드합니다.

그림 3. S3 버킷에 mp4 파일 업로드

2.     Amazon Transcribe에서 ‘Create Job’을 클릭한 뒤, 아래와 같이 Input경로와 Output경로를 지정합니다. Output경로는 ‘Customer specified’로 선택하고 생성된 WebVTT 파일을 저장할 신규 폴더를 지정합니다. 여기서는 ‘TrasncribeVTT’를 선택하였습니다.

그림 4. WebVTT 파일 저장을 위한 신규 폴더 생성

3.     나머지 설정은 그대로하고 Job생성을 완료합니다.

4.     Status가 Complete되면 S3에 WebVTT파일이 생성된 것을 확인합니다.

단계 2 : Amazon SageMaker Studio에서 파일 전처리

Amazon SageMaker Studio에 접속하여 신규 노트북을 생성합니다. 여기서 Kernel은 ‘Python 3’, Instance type은 기본값으로 하고 진행합니다.

그림5. 신규 노트북 생성 시 설정 화면

원활한 진행을 위해 아래 코드를 먼저 실행합니다.

!pip install webvtt-py
!pip install -U boto3 botocore

아래 코드를 통해 저장된 WebVTT파일의 구조를 이해합니다.

#vtt file 구조 확인
import boto3
s3 = boto3.client('s3')


bucket_name = ‘{버킷이름}’
key_name = '{폴더명/vtt파일명}’

obj = s3.get_object(Bucket=bucket_name, Key=key_name)
text = obj['Body'].read().decode('utf-8')

print(text)

위에 설명한 대로 WebVTT 파일을 Amazon Translate에서 지원되는 파일 포맷중 하나인 Text(.txt)로 변환합니다. 여기서는 변경된 Text파일을 ‘txt’ 신규 폴더에 ‘textconverted.txt’ 명으로 저장하였습니다.

#vtt파일 txt로 변환
import webvtt
import io
s3 = boto3.client('s3')

# S3 locations
bucket = ‘{버킷이름}'
vtt_key = ‘{폴더명/vtt파일명}’
txt_key = '{txt/textconverted.txt}'

# Download WebVTT file
vtt_obj = s3.get_object(Bucket=bucket, Key=vtt_key)
vtt_text = vtt_obj['Body'].read().decode('utf-8')

# Parse WebVTT and extract text
vtt = webvtt.read_buffer(io.StringIO(vtt_text))
text = []
for line in vtt:
    if line.text:
        text.append(line.text)
text = '\n'.join(text) 

# Upload text file to S3
s3.put_object(Body=text, Bucket=bucket, Key=txt_key)

Text구조를 확인해보면 기존 WebVTT구조처럼 문장이 끝맺음없이 다음 줄로 넘어가기 때문에 이 상태로 번역을 실행할 경우, 전반적인 번역 품질을 낮추는 요인이 될 수 있습니다.

그림6. Amazon Transcribe로 생성한 WebVTT 파일의 영문 Text 구조

그림7. 그림 6 영문 Text를 Amazon Translate로 번역한 한글 Text

따라서 아래와 같은 처리를 통해 완성된 문장을 S3버킷에 저장합니다.

#"\n" 구분을 " "로 replace
import boto3
s3 = boto3.client('s3')

bucket_name = ‘{버킷이름}’
key_name = 'txt/textconverted.txt'

obj = s3.get_object(Bucket=bucket_name, Key=key_name)
text = obj['Body'].read().decode('utf-8') 

#띄어쓰기 부분을 붙여서 한 문장으로 변경
text = text.replace("\n", " ")
print (text)

#txt파일 폴더에 저장
new_key = 'txt/ new/new_textconverted.txt'
s3.put_object(Body=text, Bucket=bucket_name, Key=new_key)

[예시]

그림7. 전처리한 영문 Text

이어서 아래 문구를 통해 Amazon Translate를 활용한 Text파일의 번역을 수행합니다.

#정제처리된 txt파일 대상 translate job실행
client = boto3.client('translate')
response = client.start_text_translation_job(
    JobName='TextTranslation',
    InputDataConfig={
        'S3Uri': '{새로운 Text파일의 URI}',
        'ContentType': 'text/plain'
    },
    OutputDataConfig={
        'S3Uri': 's3://{버킷이름}/translated',
    },
    DataAccessRoleArn='{Role ARN(콘솔에서 생성시, 무슨 role이 있는지 참고할 수 있음)}',
    SourceLanguageCode='en',
    TargetLanguageCodes=[
        'ko',
    ], 
)

[예시]

그림8. 전처리한 영문 Text로 Amazon Translate Job 실행

결과적으로 다음과 같은 번역 결과물을 확인할 수 있으며, 이제 해당 Text file을 WebVTT파일로 변경하는 방안에 대해 다루겠습니다.

그림9. Amazon Translate Job 실행 결과

단계 3: WebVTT 파일 생성을 위한 후처리 방법 소개

미디어 자막에서는 문장이 길어지는 경우, 시간대별로 문장의 일부만 자막으로 등장하게 됩니다. 번역 성능의 개선을 위해서는 이러한 문장의 일부들을 합쳐야 하고, 필요에 따라서 번역된 문장을 시간대에 맞게 배분하는 후처리 작업이 필요합니다.

해당 데이터를 기반으로 번역된 WebVTT 후처리 방법에 대해서 소개 드리겠습니다.

먼저 원문 VTT 텍스트의 경우, 아래와 같이 자막이 등장하는 시간과 문장으로 구성되어 있습니다.

00:00:01.970 –> 00:00:06.119Transcribing audio can be complex, time consuming and expensive.
00:00:06.329 –> 00:00:10.800You either need to hire someone to do it manually implement applications that are
00:00:10.810 –> 00:00:15.710difficult to maintain or use hard to integrate services that yield poor results.

원문 VTT 파일에서 문장의 끝은 “.”로 끝납니다. “.”를 기준으로 문장의 끝을 구분하고, Buffer 만큼의 자막을 조합하여 번역된 문장을 만듭니다. VTT 텍스트의 원문 자막은 아래와 같은 3가지 경우로 나누고, 각각의 경우에 대한 후처리 작업은 다음과 같습니다.

방법 1. 문장 번역 후, 전체 문장을 토큰

단계 3-1에서 진행하는 후처리 절차는 다음과 같습니다.

  1. 문장의 일부가 등장하는 영어 자막을 합쳐서 하나의 문장 완성
  2. 완성된 문장을 번역
  3. 문장의 토큰 위치에 전체 번역된 문장 위치

그림 10. 문장의 토큰 위치에 전체 번역된 문장을 반복적으로 위치

방법 2. 문장 번역 후, 전체 문장을 배분

  1. 문장의 일부가 등장하는 영어 자막을 합쳐서 하나의 문장 완성
  2. 완성된 문장을 번역
  3. 문장의 토큰 위치에 전체 번역된 문장 위치

다음과 같은 후처리 작업을 통해 한국어 번역된 WebVTT 파일 생성하기 위해서는 아래의 3가지 데이터가 필요합니다.

  • 원문(영어) VTT 데이터
  • 원문(영어) 텍스트 리스트
  • 번역(한국어) 텍스트 리스트 (Amazon Translate로 번역)

번역된 문장을 적절한 화면에 배치하기 위한 방법은 다음과 같습니다.

  1. 문장이 한 자막에 들어가는 경우, 자막 전체를 번역하고, 번역된 문장을 배치합니다.
  2. 전체 문장이 여러 자막으로 나뉜 경우, lag값을 증가시켜 번역된 문장과 현재 자막의 인덱스를 조정합니다. 이후, divide_sentence() 함수를 사용하여 사용한 자막의 크기(buffer)에 맞게 문장을 나누어, 자막을 배치합니다.
  3. 한 자막에 여러 문장이 들어간 경우, lead 값을 증가시켜 번역된 문장의 인덱스를 조정합니다. 이후, 번역된 여러 문장들을 해당 자막에 배치합니다.
def divide_sentence(a, n):
    k, m = divmod(len(a), n)
    return (a[i*k+min(i, m):(i+1)*k+min(i+1, m)] for i in range(n))

origin_sentences = orig_text.split(".")
translated_sentences = trans_text.split(".")

buffer, lag, lead = 0, 0, 0

origin_vtt_sentences = orig_vtt.split('\n\n')[1:]
org_sent = []
results = []

for idx, sent in enumerate(origin_vtt_sentences):
    no, time, sent = sent.split('\n')
    
    cur_lead = max(len(sent.split('.')) - 2, 0)
    lead += cur_lead
    
    matched_sentences = [t.strip() for t in translated_sentences[idx-lag + lead:idx-lag + lead + cur_lead+1]]
    target_sentence = " ".join(matched_sentences)
    results.append(
        {'no': no, 'time': time, 'origin': sent, 'translated': target_sentence}
    )
    if sent.endswith("."):
        if buffer > 1:
            sentences = list(divide_sentence(target_sentence.split(' '), buffer))
            for idx, sent in enumerate(sentences):
                results[-buffer+idx]["translated"] = " ".join(sent)
        buffer = 0
    else:
        lag += 1
    buffer += 1

결과 예시

그림 11. 타임라인별 자막 재배치

위의 후처리 결과를 활용하여, VTT 텍스트 파일 포맷으로 변환하면, 번역된 VTT 자막을 생성할 수 있습니다.

00:00:01.970 –> 00:00:06.119오디오 텍스트 변환은 복잡하고 시간이 많이 걸리며 비용이 많이 들 수 있습니다.
00:00:06.329 –> 00:00:10.800유지 관리가 어려운 애플리케이션을 수동으로 구현할 사람을 고용하거나, 통합이
00:00:10.810 –> 00:00:15.710어려운 서비스를 사용하여 결과가 좋지 않을 수 있습니다.

그림 12. 타임라인별 자막 재배치 적용

단계 4: Amazon Polly를 활용하는 방법

Amazon Polly는 어플리케이션 및 도구에서 활용가능한 클라우드 기반 음성 합성 서비스입니다. Amazon Polly를 사용하면 별도의 모델 학습이나 서버 구축 없이 필요한 음성 문장을 만들 수 있습니다. 흔히 TTS(Text-to-Speech)라고 알려진 음성 합성은 미디어 서비스에서 자막에 대한 나레이션으로 활용 가능할 뿐 아니라, 번역 후 생성된 자막 데이터를 음성 데이터로 변환하여 자막의 위치를 좀 더 자연스럽게 조정할 때 활용할 수 있습니다.

아래의 aws-cli 기반이나 SDK를 활용하여 간단하게 한국어 문장을 mp3 파일 형태로 변환이 가능하며 생성된 mp3 파일을 기반으로 미디어 작업시 읽기 속도에 맞추어 자막의 노출 속도를 제어하거나 나레이션으로 활용할 수 있습니다.

[AWS CLI 기반]

aws polly synthesize-speech --output-format mp3 --voice-id Seoyeon --text "오디오 텍스트 변환은 복잡하고 시간이 많이 걸리며 비용이 많이 들 수 있습니다." seoyeon.mp3

[AWS SDK python Boto3 기반]

from boto3 import client
polly = client("polly", region_name="ap-northeast-2")
response = polly.synthesize_speech(
        Text="오디오 텍스트 변환은 복잡하고 시간이 많이 걸리며 비용이 많이 들 수 있습니다.",
        OutputFormat="mp3",
        VoiceId="Seoyeon")

그림 13. Amazon Polly를 활용한 아키텍처 예시

위처럼 Translate로 번역된 텍스트를 Amazon Polly를 이용하여 음성 파일 형태로 생성하고, Amazon Transcribe를 활용하여 음성 미디어 파일을 WebVTT 형태로 추출하여 미디어 자막 생성의 플로우를 구성할 수 있습니다. 대표적인 예시로 숏폼(short form) 영상을 타국가 구독자에게 다국어로 변환하여 내레이션으로 제공하고자 할때 Amazon Polly를 활용할 수 있습니다.

결론

이번 블로그에서는 AWS의 미디어 서비스를 활용하여 미디어 자막 성능을 개선하는 방법에 대해서 소개했습니다. 일반적으로 미디어 영상에 대한 자막 처리를 위해서는 컴퓨팅뿐 아니라 다양한 도구 및 전문가들과의 협업을 통해서 이루어지게 됩니다. AWS의 AI 서비스를 활용함으로써 별도의 팀이 없이도 자막 초안을 쉽게 작성할 수 있고, 필요 시점에 전문가의 개입으로 완성도 높은 자막을 제공할 수가 있습니다. 이를 통해 고객은 미디어 컨텐츠의 자막 생성 및 현지화 작업 시 반복되는 작업에 대한 비용을 감소시키고, 자막 생성 및 미디어 작업의 품질을 높이는 등 다양하게 활용할 수 있습니다.

TaeHoon Kyeong

TaeHoon Kyeong

Kyeong Tae-Hoon (Nick) is a solutions architect at AWS responsible for optimizing architecture for media and entertainment customers to achieve their desired business results. 경태훈(Nick) 솔루션즈 아키텍트는 미디어 및 엔터테인먼트 고객이 원하는 비즈니스 결과를 얻을 수 있도록 아키텍처를 최적화하는 역할을 담당하고 있습니다.

Taekyung Han

Taekyung Han

한태경 솔루션즈 아키텍트는 AWS 클라우드 고객을 대상으로 고객의 비즈니스 성과 달성을 위해 고객과 함께 최적의 아키텍처를 구성하는 역할을 수행하고 있습니다. 백엔드 엔지니어와 DevOps 경험을 기반으로 안전한 클라우드 환경을 구성하는 방법에 대한 기술적인 도움을 드리고 있습니다.