brunch

You can make anything
by writing

C.S.Lewis

by Master Seo Nov 24. 2024

AI 9탄-6. 유튜브 요약 프로그램-6/10

사용자가 입력한 유튜브 동영상 주소로부터 유튜브 영상을 요약해주는 프로그램





<17> 랭체인을 활용하여 긴글을 요약 -  ch08_longtext_summary.py  (실습)

<18> 유튜브 요약/번역 프로그램 ,  ch08_yt_sum_trans.py  (실습) - 6




<17> 랭체인을 활용하여 긴글을 요약 -  ch08_longtext_summary.py



0

구성도

사용자-유튜브 URL 입력 -- Whisper 스크립트----랭체인 ---요약----ChatGPT --------- 요약 번역 ChatGPT



Whisper와 랭체인을 이용해 유튜브 요약하기

# 앱 만들기 - 외부에 노출 하기 - 허깅페이스 이용



1

8장  

ch08_longtext_summary.py


https://github.com/chatgpt-kr/openai-api-tutorial/blob/main/ch08/ch08_longtext_summary.py


2

# 개발환경

# 가상환경 생성하기


# command 창에서


C:\0ai\07-ai\ch08\>python -m venv ch08_env


c:\0ai\07-ai\ch08> cd ch08_env\Scripts


C:\0ai\07-ai\ch08\ch07_env\Scripts> activate.bat


(ch08_env) c:\0ai\07-ai\ch08\ch08_env\Scripts>




3

# 라이블러리 설치


pip install openai

pip install langchain

pip install langchain_community

pip install langchain_openai

pip install tiktoken

pip install pymupdf

pip install streamlit





4

# VSCODE 로 풀더 열기


File > Open Folder


api key 입력



5

# 실행


(ch08_env) c:\0ai\07-ai\ch08>python ch08_longtext_summary.py

Park Minho, a talented IT professional from Korea, overcame challenges to become an AI researcher in Silicon Valley. He founded NeoTech, a leading AI company in Korea, focusing on social responsibility and innovation. His story inspires with his journey from a small village to global success, emphasizing passion, perseverance, and social impact through technology.

(ch08_env) c:\0ai\07-ai\ch08>



6

# 전체 순서 보기 


문서---- 문저를 일정 크기로 분할------각각 요약 진행 (ChatGpt)----- 각 문서의 요약문---요약 내용 취합후 최종 요약 진행 (ChatGpt)------- 최종 요약



7

# 소스 코드 보기

ch08_longtext_summary.py



from langchain.prompts import PromptTemplate

from langchain.chains.summarize import load_summarize_chain

from langchain.text_splitter import RecursiveCharacterTextSplitter

from langchain_openai import ChatOpenAI

script = '''한국의 한산한 어촌에서 세계로 뻗어나간 IT 전문가, 박민호의 여정

박민호는 한국의 동해안에 위치한 작은 어촌마을에서 태어났다. 그 마을은 바다와 맞닿아 있어 매일 아침 

:

: 요약이 필요한 장문의 스크립트

:

의 이야기는 우리에게 꿈을 향한 열정과 끈기, 그리고 사회에 대한 책임감의 중요성을 일깨워준다. 그의 삶은 기술이 단순히 이윤을 창출하는 도구가 아니라, 세상을 더 나은 곳으로 만들 수 있는 강력한 힘이 될 수 있음을 보여준다. 앞으로도 그는 새로운 도전과 성공을 이뤄낼 것이며, 그의 여정은 많은 이들에게 희망과 용기를 줄 것이다.'''

# 언어모델 설정

llm = ChatOpenAI(temperature=0,

        openai_api_key="sk-proj-eHYwDTZik9tpPMfwmnfAXVorPRsA",

        max_tokens=4000,

        model_name="gpt-3.5-turbo",

        request_timeout=120

    )

# 프롬프트 설정

prompt = PromptTemplate(

    template="""백틱으로 둘러싸인 전사본을 이용해 해당 텍스트를 요약해주세요. \

    ```{text}``` 단, 영어로 작성해주세요.

    """, input_variables=["text"]

)

combine_prompt = PromptTemplate(

    template="""백틱으로 둘러싸인 유튜브 스크립트를 모두 조합하여 \

    ```{text}```

    10문장 내외의 간결한 요약문을 제공해주세요. 단, 영어로 작성해주세요.

    """, input_variables=["text"]

)

# LangChain을 활용하여 긴 글 요약하기

# 글 쪼개기

text_splitter = RecursiveCharacterTextSplitter(chunk_size=3000, chunk_overlap=0)

texts = text_splitter.create_documents([script])

# 요약하기

chain = load_summarize_chain(llm, chain_type="map_reduce", verbose=False,

                            map_prompt=prompt, combine_prompt=combine_prompt)

summerize = chain.invoke(texts)['output_text']

# 최종 출력

print(summerize)




8

실행


PS C:\07-openai\openai-api-tutorial-main\ch08> python.exe .\ch08_longtext_summary.py



9

결과


PS C:\07-openai\openai-api-tutorial-main\ch08> python.exe .\ch08_longtext_summary.py

Park Minho, a talented student from a small fishing village in Korea, overcame setbacks to become an AI researcher in Silicon Valley. He founded NeoTech, a leading AI company in Korea, focusing on innovative solutions and social responsibility. Minho's story emphasizes passion, perseverance, and making a positive impact through technology.

PS C:\07-openai\openai-api-tutorial-main\ch08> 






<18> 유튜브 요약/번역 프로그램 ,  ch08_yt_sum_trans.py  (실습) - 6



1

#VSCODE 


pip install openai

pip install langchain

pip install langchain_community

pip install langchain_openai

pip install tiktoken

pip install pymupdf

pip install streamlit


pip install pytubefix



2

ch08_yt_sum_trans.py

api_key = '여러분의 OpenAI API Key'



3

(ch08_env) c:\0ai\07-ai\ch08>python ch08_yt_sum_trans.py



4


# 코드 내용


##### 기본 정보 입력 ####

# Streamlit 패키기 추가

import streamlit as st

# OpenAI 패키지 추가

import openai

# 유튜브 영상을 다운로드하기 위한 pytube 패키지 추가

from pytubefix import YouTube

# 유튜브 영상을 번역, 요약하기 위한 Langchain 패키지 추가

from langchain.prompts import PromptTemplate

from langchain.chains.summarize import load_summarize_chain

from langchain.text_splitter import RecursiveCharacterTextSplitter

from langchain_openai import ChatOpenAI

# 필요한 기본 패키지 추가

import re

import os

import shutil

# Whisper를 위해서 client 선언.

api_key = '0ikxWbgRKT0WxcjNMHsA'

client = openai.OpenAI(

    api_key=api_key

)

##### 기능 구현 함수 #####

# 주소를 입력받으면 유튜브 동영상의 음성(mp3)을 추출하는 함수.

def get_audio(url):

    yt = YouTube(url)

    audio = yt.streams.filter(only_audio=True).first()

    audio_file = audio.download(output_path=".")

    base, ext = os.path.splitext(audio_file)

    new_audio_file = base + '.mp3'

    shutil.move(audio_file, new_audio_file)

    return new_audio_file

# 음성 파일 위치를 전달받으면 스크립트를 추출.

def get_transcribe(file_path):

    with open(file_path, "rb") as audio_file:

        transcript = client.audio.transcriptions.create(

            model="whisper-1",

            response_format="text", # repsone_format을 text로 하면 자막이 아닌 텍스트로 반환.

            file=audio_file

        )

        return transcript

# 영어 입력이 들어오면 한글로 번역 및 불렛포인트 요약을 수행.

def trans(text):

    response = client.chat.completions.create(

            model="gpt-3.5-turbo",

            messages=[

                {"role": "system", "content": "당신은 영한 번역가이자 요약가입니다. 들어오는 모든 입력을 한국어로 번역하고 불렛 포인트 요약을 사용하여 답변하시오. 반드시 불렛 포인트 요약이어야만 합니다."},

                    {"role": "user", "content": text}

                ]

            )

    return response.choices[0].message.content

# 유튜브 주소의 형태를 정규 표현식(Regex)로 체크하는 함수. (선택적으로 사용하세요. 꼭 있어야 하는 건 아닙니다.)

def youtube_url_check(url):

    pattern = r'^https:\/\/www\.youtube\.com\/watch\?v=([a-zA-Z0-9_-]+)(\&ab_channel=[\w\d]+)?$'

    match = re.match(pattern, url)

    return match is not None

    st.set_page_config(page_title="YouTube Summarize", layout="wide")

##### 메인 함수 #####

def main():

    # session state 초기화

    if "summarize" not in st.session_state:

        st.session_state["summarize"] = ""

    # 메인공간

    st.header(" �️ YouTube Summarizer ")

    st.image('ai.png', width=200)

    youtube_video_url = st.text_input("Please write down the YouTube address. �️",placeholder="https://www.youtube.com/watch?v=**********")

    st.markdown('---')

    # URL이 실제로 입력되었을 경우.

    if len(youtube_video_url) > 2:

        # URL을 잘못 입력했을 경우

        if not youtube_url_check(youtube_video_url):

            st.error("YouTube URL을 확인하세요.")

        # URL을 제대로 입력했을 경우

        else:

            # 동영상 재생 화면 물러오기

            width = 50

            side = width/2

            _, container, _ = st.columns([side, width, side])

            container.video(data=youtube_video_url)

            # 영상 속 자막 추출하기. part2.ch02_06_자동 자막 생성 서비스 참고!

            audio_file = get_audio(youtube_video_url)

            transcript = get_transcribe(audio_file)

            st.subheader("Summary Outcome (in English)")

            # 언어모델은 ChatGPT(GPT-3.5-Turbo)를 사용. 또는 gpt-4o를 사용하셔도 무방합니다.

            llm = ChatOpenAI(model_name="gpt-3.5-turbo",

                            openai_api_key=api_key

            )

            # 맵 프롬프트 설정: 1단계 요약에서 사용.

            prompt = PromptTemplate(

                template="""백틱으로 둘러싸인 전사본을 이용해 해당 유튜브 비디오를 요약해주세요. \

                ```{text}``` 단, 영어로 작성해주세요.

                """, input_variables=["text"]

            )

            # 컴바인 프롬프트 설정: 2단계 요약에서 사용.

            combine_prompt = PromptTemplate(

                template="""백틱으로 둘러싸인 유튜브 스크립트를 모두 조합하여 \

                ```{text}```

                10문장 내외의 간결한 요약문을 제공해주세요. 단, 영어로 작성해주세요.

                """, input_variables=["text"]

            )

            # LangChain을 활용하여 긴 글 요약하기

            # 긴 문서를 문자열 길이 3000을 기준 길이로 하여 분할한다.

            text_splitter = RecursiveCharacterTextSplitter(chunk_size=3000, chunk_overlap=0)

            # 분할된 문서들은 pages라는 문자열 리스트로 저장되어져 있다

            # ex)

            # pages = ["텍스트1", "텍스트2", "텍스트3", "텍스트4"]

            pages = text_splitter.split_text(transcript)

            # pages를 load_summarize_chain이라는 Langchain 도구에서 처리 가능한 형식으로 변환.

            # 변환 후에는 더 이상 문자열 타입이 아닌 Langchain에서 제공하는 타입의 리스트로 변환됨.

            # ex)

            # text = [Document(page_content="텍스트1"), Document(page_content="텍스트2"),

            #         Document(page_content="텍스트3"), Document(page_content="텍스트4")]

            # 이렇게 Langchain에서 원하는 다소 특이한 형태로 변환해주어야 아래에서 처리 가능!

            text = text_splitter.create_documents(pages)

            # 위에서 준비한 map_prompt와 combine_prompt를 이용하여 두 단계 요약을 준비. run() 해야 실행.

            chain = load_summarize_chain(llm, chain_type="map_reduce", verbose=False,

                                            map_prompt=prompt, combine_prompt=combine_prompt)

            # 두 단계 요약의 결과를 저장.

            st.session_state["summarize"] = chain.run(text)

            st.success(st.session_state["summarize"])

            transe = trans(st.session_state["summarize"])

            st.subheader("Final Analysis Result (Reply in Korean)")

            st.info(transe)

if __name__=="__main__":

    main()




2

실행

 streamlit.cmd run .\ch08_yt_sum_trans.py




예제 url 입력

https://www.youtube.com/watch?v=exewHoMNjsQ



3

실행 결과



# 실행 결과


# 유튜브 URL  입력하기






5

# 앱 만들기 - 외부에 노출 하기 - 허깅페이스 이용



https://huggingface.co/spaces/topasvga/image1


OPENAI_API_KEY

ai.png




# 앱 오류


pytubefix.exceptions.BotDetection: exewHoMNjsQ This request was detected as a bot. Use `use_po_token=True` to view. See more details at https://github.com/JuanBindez/pytubefix/pull/209





# 참고자료

https://brunch.co.kr/@topasvga/3911




다음

https://brunch.co.kr/@topasvga/4161




                    

브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari