DuckyBlender commited on
Commit
766eb70
·
1 Parent(s): 257b9bf
Files changed (3) hide show
  1. README.md +1 -1
  2. main.py +150 -0
  3. requirements.txt +8 -0
README.md CHANGED
@@ -1,6 +1,6 @@
1
  ---
2
  title: Phi3 Youtube Summarizer
3
- emoji: 😻
4
  colorFrom: blue
5
  colorTo: yellow
6
  sdk: gradio
 
1
  ---
2
  title: Phi3 Youtube Summarizer
3
+ emoji: 📹
4
  colorFrom: blue
5
  colorTo: yellow
6
  sdk: gradio
main.py ADDED
@@ -0,0 +1,150 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from youtube_transcript_api import YouTubeTranscriptApi
3
+ from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline, BitsAndBytesConfig
4
+ import re
5
+ import os
6
+ import torch
7
+
8
+ # import dotenv
9
+ # dotenv.load_dotenv()
10
+
11
+ import subprocess
12
+ subprocess.run(
13
+ "pip install flash_attn --no-build-isolation --break-system-packages",
14
+ env={"FLASH_ATTENTION_SKIP_CUDA_BUILD": "TRUE"},
15
+ shell=True,
16
+ )
17
+
18
+ # Uncomment and set your Hugging Face token if needed
19
+ token = os.environ["HF_TOKEN"]
20
+
21
+ # Configure 4-bit quantization for model loading
22
+ bnb_config = BitsAndBytesConfig(
23
+ load_in_4bit=True,
24
+ bnb_4bit_use_double_quant=True,
25
+ bnb_4bit_quant_type="nf4",
26
+ bnb_4bit_compute_dtype=torch.bfloat16,
27
+ attn_implementation="flash_attention_2",
28
+ )
29
+
30
+ # Load the Phi-3 model and tokenizer
31
+ print("Loading model and tokenizer...")
32
+ model_id = "microsoft/Phi-3-mini-128k-instruct"
33
+ model = AutoModelForCausalLM.from_pretrained(
34
+ model_id,
35
+ device_map="cuda",
36
+ quantization_config=bnb_config,
37
+ trust_remote_code=True,
38
+
39
+ ).eval()
40
+ tokenizer = AutoTokenizer.from_pretrained(model_id)
41
+
42
+ # Define the system prompt and generation pipeline
43
+ system_prompt = "Summarize this YouTube video. Give a brief summary of the video content with the key points and main takeaways."
44
+ messages = [{"role": "system", "content": system_prompt}]
45
+
46
+ pipe = pipeline(
47
+ "text-generation",
48
+ model=model,
49
+ tokenizer=tokenizer,
50
+ )
51
+
52
+ generation_args = {
53
+ "max_new_tokens": 32767,
54
+ "return_full_text": False,
55
+ "do_sample": True,
56
+ "temperature": 0.2,
57
+ }
58
+
59
+ # Function to extract the video ID from a YouTube URL
60
+ def extract_video_id(url):
61
+ video_id_match = re.search(r"(?:v=|\/)([0-9A-Za-z_-]{11}).*", url)
62
+ if video_id_match:
63
+ print(f"Extracted video ID: {video_id_match.group(1)}")
64
+ return video_id_match.group(1)
65
+ return None
66
+
67
+ # Function to get the transcript of a YouTube video
68
+ def get_transcript(video_id):
69
+ try:
70
+ transcript = YouTubeTranscriptApi.get_transcript(video_id)
71
+ transcription = [entry['text'] for entry in transcript]
72
+ print(f"Transcript: {transcription}")
73
+ return " ".join(transcription)
74
+ except Exception as e:
75
+ return f"Error fetching transcript: {str(e)}"
76
+
77
+ # Function to summarize the text using the model
78
+ def summarize_text(text):
79
+ messages.append({"role": "user", "content": text})
80
+ output = pipe(messages, **generation_args)
81
+ output = output[0]['generated_text'].strip() # type: ignore
82
+ print(f"Summary: {output}")
83
+ return output
84
+
85
+ # Main function to process the video URL
86
+ def process_video(url):
87
+ video_id = extract_video_id(url)
88
+ if not video_id:
89
+ print("Invalid YouTube URL")
90
+ return "Invalid YouTube URL"
91
+
92
+ transcript = get_transcript(video_id)
93
+ if transcript.startswith("Error"):
94
+ return transcript
95
+
96
+ summary = summarize_text(transcript)
97
+ return summary, transcript
98
+
99
+ # Function to update the embedded video player
100
+ def update_embed(url):
101
+ video_id = extract_video_id(url)
102
+ if video_id:
103
+ embed_url = f"https://www.youtube.com/embed/{video_id}"
104
+ return f"<div class='gradio-embed-container'><iframe class='gradio-embed' src='{embed_url}' frameborder='0' allowfullscreen></iframe></div>"
105
+ return "<div class='gradio-embed-container'><iframe class='gradio-embed' src='' frameborder='0' allowfullscreen></iframe></div>"
106
+
107
+ # Gradio UI setup
108
+ with gr.Blocks(css="""
109
+ .gradio-embed-container { position: relative; width: 100%; padding-bottom: 56.25%; height: 0; }
110
+ .gradio-embed { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
111
+ .small-font { font-size: 0.6em; }
112
+ """) as demo:
113
+
114
+ gr.Markdown("""
115
+ # YouTube Video Summarizer using Phi-3-mini-128k-instruct
116
+ Summarize any YouTube video using the Phi-3-mini-128k-instruct model.
117
+ """)
118
+
119
+ with gr.Row():
120
+ with gr.Column(scale=1):
121
+ url = gr.Textbox(
122
+ label="YouTube URL",
123
+ placeholder="https://www.youtube.com/watch?v=dQw4w9WgXcQ",
124
+ max_lines=1
125
+ )
126
+ summary = gr.Textbox(
127
+ label="Summary",
128
+ placeholder="Summary will appear here...",
129
+ lines=10,
130
+ show_label=True,
131
+ show_copy_button=True,
132
+ elem_classes="small-font"
133
+ )
134
+ transcript = gr.Textbox(
135
+ label="Transcript",
136
+ placeholder="Transcript will appear here...",
137
+ lines=1,
138
+ show_label=True,
139
+ show_copy_button=True,
140
+ elem_classes="small-font"
141
+ )
142
+ btn = gr.Button("Summarize")
143
+ btn.click(fn=process_video, inputs=url, outputs=[summary, transcript])
144
+
145
+ with gr.Column(scale=1):
146
+ video_embed = gr.HTML("<div class='gradio-embed-container'><iframe class='gradio-embed' src='' frameborder='0' allowfullscreen></iframe></div>")
147
+
148
+ url.change(fn=update_embed, inputs=url, outputs=video_embed)
149
+
150
+ demo.launch()
requirements.txt ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ gradio
2
+ torch
3
+ transformers
4
+ youtube_transcript_api
5
+ google-api-python-client
6
+ bitsandbytes
7
+ # python-dotenv
8
+ accelerate