|
import os |
|
|
|
import gradio as gr |
|
import torch |
|
import re |
|
|
|
from sentence_transformers import SentenceTransformer |
|
from datasets import load_dataset,Dataset |
|
from shared_resources import shared_resources |
|
from phi.agent import Agent |
|
from phi.tools.duckduckgo import DuckDuckGo |
|
from phi.agent import Agent, RunResponse |
|
from phi.model.huggingface import HuggingFaceChat |
|
|
|
|
|
|
|
class ResponseGenerator: |
|
def __init__(self): |
|
|
|
self.ST = shared_resources.sentence_transformer |
|
self.data = shared_resources.data |
|
self.original_query = "" |
|
|
|
|
|
def search(self, query: str, usernames=None, k: int = 3): |
|
"""Function to get recommended videos based on user input""" |
|
self.embedded_query = self.ST.encode(query) |
|
self.all_retrievals=[] |
|
if usernames: |
|
dataset=self.data.to_pandas() |
|
for username in usernames: |
|
username = [username] |
|
filtered_df = dataset[dataset['username'].isin(username)] |
|
self.temp_data = Dataset.from_pandas(filtered_df) |
|
self.temp_data=self.temp_data.add_faiss_index("embeddings") |
|
self.scores, self.retrieved_examples = self.temp_data.get_nearest_examples("embeddings", self.embedded_query, k=k) |
|
self.all_retrievals.append(str(self.retrieved_examples['Caption'][0])) |
|
self.temp_data=None |
|
print('All retrievals are:',self.all_retrievals) |
|
return self.all_retrievals |
|
|
|
self.scores, self.retrieved_examples = self.data.get_nearest_examples("embeddings", self.embedded_query, k=k) |
|
return self.scores, self.retrieved_examples |
|
|
|
|
|
def generate_response(self, query, username=None, additional_focus=None): |
|
|
|
""" |
|
Generates text using the Llama 3.1 model. |
|
""" |
|
self.original_query = query |
|
|
|
|
|
if additional_focus: |
|
|
|
prompt = f""" |
|
I want to create a detailed storyline for a video primarily focusing on the sentence: **{additional_focus}**, keeping it under 500 words. Please provide the storyline in 6 concise paragraphs that must incorporate the following key features everytime: |
|
|
|
1. **Story:** How to introduce the scene and set the tone. What is happening in the scence? Describe key visuals and actions. |
|
2. **Narration or Voiceover:** Suggestions for narration or voiceover that complements the visuals. |
|
3. **Text in the Video:** Propose important text overlays for key moments. |
|
4. **Transitions:** Smooth transitions between scenes to maintain flow. |
|
5. **Emotional Tone:** The mood and energy of the scenes (e.g., excitement, calm, tension, joy). |
|
6. **Key Visuals & Sounds:** Important props, locations, sound effects, or background music to enhance the video. |
|
|
|
The storyline should flow naturally, without repeating the same information or listing individual features. Ensure the output is engaging and cohesive. |
|
|
|
Also, suggest **5 relevant hashtags** for the video that reflect its content and themes commonly used on social media for similar videos. |
|
|
|
|
|
""" |
|
|
|
else: |
|
|
|
prompt = f""" |
|
I want to create a detailed storyline for a video in any domain, keeping it under 500 words. Please provide the storyline in 6 concise paragraphs that must incorporate the following key features everytime: |
|
|
|
1. **Story:** How to introduce the scene and set the tone. What is happening in the scene? Describe key visuals and actions. |
|
2. **Narration or Voiceover:** Suggestions for narration or voiceover that complements the visuals. |
|
3. **Text in the Video:** Propose important text overlays for key moments. |
|
4. **Transitions:** Smooth transitions between scenes to maintain flow. |
|
5. **Emotional Tone:** The mood and energy of the scenes (e.g., excitement, calm, tension, joy). |
|
6. **Key Visuals & Sounds:** Important props, locations, sound effects, or background music to enhance the video. |
|
|
|
The storyline should flow naturally, without repeating the same information or listing individual features. Ensure the output is engaging and cohesive. |
|
|
|
Also, suggest **5 relevant hashtags** for the video that reflect its content and themes commonly used on social media for similar videos. |
|
|
|
""" |
|
|
|
|
|
|
|
|
|
if username: |
|
retrieved_list = self.search(query,username,1) |
|
retrieved_context = "\n".join(retrieved_list) |
|
prompt = prompt + f"\n Here is the random video story from the dataset for you. You can use it just for analysing purpose, not for similar generation. This is the story:\n{retrieved_context}" |
|
prompt = prompt + f"\nNow finally i am providing you a question to create a detailed story line for a video. The question is: **{self.original_query}**" |
|
|
|
else: |
|
prompt = prompt + f"\nNow finally i am providing you a question to create a detailed story line for a video. The question is: **{self.original_query}**" |
|
agent = Agent( |
|
model=HuggingFaceChat( |
|
id="meta-llama/Meta-Llama-3-8B-Instruct", |
|
max_tokens=4096, |
|
), |
|
|
|
markdown=True |
|
) |
|
|
|
|
|
run: RunResponse = agent.run(prompt) |
|
return run.content |
|
|
|
|
|
|
|
def extract_topics(self, story): |
|
""" |
|
Extracts 5 key sentences from the generated text using KeyBERT. |
|
""" |
|
|
|
prompt = f'''I want to brainstorm ways to diversify or improve a storyline in exactly 5 sentences. No more than 5 nor less than 5. |
|
The goal is to generate creative and actionable ideas that are not on the storyline on how the storyline can be expanded or modified for better engagement. |
|
For example: If the storyline is about creating a promotional video for a restaurant, the new suggestions might include: |
|
- I want to showcase the chef preparing a signature dish. |
|
- I want to add a sequence of customers sharing their experiences at the restaurant. |
|
- I want to highlight the farm-to-table sourcing of ingredients with a short segment showing local farms. |
|
- I want to include a time-lapse of the restaurant transforming from day to night, capturing its unique ambiance. |
|
- I want to feature a quick interview with the owner sharing the story behind the restaurant. |
|
|
|
Now, I will provide you with the storyline. The storyline is:\n{story} |
|
Please remember, don't give any introduction or explanations. Just generate 5 sentences directly, focusing on creative suggestions for diversifying or modifying the storyline. ''' |
|
|
|
|
|
agent = Agent( |
|
model=HuggingFaceChat( |
|
id="meta-llama/Meta-Llama-3-8B-Instruct", |
|
max_tokens=4096, |
|
), |
|
|
|
markdown=True |
|
) |
|
|
|
|
|
run: RunResponse = agent.run(prompt) |
|
generated_text=run.content |
|
|
|
sentences = [sentence.strip() for sentence in re.split(r'[.?]', generated_text) if sentence.strip()] |
|
print('The sentences are:',sentences) |
|
|
|
return sentences[-4:] |
|
|
|
|
|
def on_select_topic(self, selected_topic, history_stack, current_state): |
|
""" |
|
Generates new points for the selected topic and updates history. |
|
""" |
|
|
|
history_stack.append(current_state) |
|
|
|
|
|
new_response = self.generate_response(self.original_query, additional_focus=selected_topic) |
|
new_topics = self.extract_topics(new_response) |
|
|
|
|
|
new_state = { |
|
"response": new_response, |
|
"topics": new_topics, |
|
"key_topics": new_topics |
|
} |
|
|
|
return new_state, history_stack, gr.update(value=new_response), gr.update(choices=new_topics) |
|
|
|
def on_back(self, history_stack): |
|
""" |
|
Restores the previous state for all outputs. |
|
""" |
|
if history_stack: |
|
|
|
previous_state = history_stack.pop() |
|
|
|
return history_stack, gr.update(value=previous_state["response"]), \ |
|
gr.update(choices=previous_state["key_topics"]) |
|
|
|
|
|
return history_stack, gr.update(value=""), gr.update(choices=[]) |
|
|
|
class ResponseGeneratorApp: |
|
def __init__(self): |
|
self.point_generator = ResponseGenerator() |
|
|
|
def build_ui(self): |
|
with gr.Blocks() as demo: |
|
gr.Markdown( |
|
""" |
|
#Brainstorming App |
|
Enter a query to generate a detailed response and start brainstroming for further exploration. |
|
""" |
|
) |
|
|
|
query_input = gr.Textbox( |
|
label="Enter your query", |
|
placeholder="Type a query, e.g., 'I want to create a promotional video of Begnas Lake.'", |
|
lines=2, |
|
) |
|
|
|
usernames = [ |
|
"_travelwithsapana", "givina_9", "rajen.rb", "wh0z.khu5h1", "palam061", |
|
"prettiest_sky", "explorepokhara", "ggkaam610", "anjana_dhl1" |
|
] |
|
|
|
|
|
|
|
username_inputs = gr.CheckboxGroup(choices=usernames,label="Choose one or more username of whose you want similar story::",type="value") |
|
|
|
|
|
|
|
generate_btn = gr.Button(value="Generate") |
|
|
|
|
|
response_output = gr.Textbox( |
|
label="Generated Response", |
|
lines=10, |
|
interactive=False |
|
) |
|
|
|
|
|
topics_radio = gr.Radio( |
|
label="Brain Stroming Areas....", |
|
choices=[], |
|
type="value", |
|
interactive=True |
|
) |
|
|
|
back_btn = gr.Button(value="Back") |
|
|
|
|
|
current_state = gr.State({}) |
|
history_stack = gr.State([]) |
|
|
|
|
|
generate_btn.click( |
|
fn=lambda query,usernames: self.generate_handler(query,usernames), |
|
inputs=[query_input,username_inputs], |
|
outputs=[current_state, response_output, topics_radio], |
|
) |
|
|
|
|
|
topics_radio.change( |
|
fn=self.point_generator.on_select_topic, |
|
inputs=[topics_radio, history_stack, current_state], |
|
outputs=[current_state, history_stack, response_output, topics_radio] |
|
) |
|
|
|
|
|
back_btn.click( |
|
fn=self.point_generator.on_back, |
|
inputs=[history_stack], |
|
outputs=[history_stack, response_output, topics_radio] |
|
) |
|
|
|
return demo |
|
|
|
def generate_handler(self, query,usernames): |
|
""" |
|
Handles the generation of the response and topics. |
|
""" |
|
response = self.point_generator.generate_response(query,usernames) |
|
topics = self.point_generator.extract_topics(response) |
|
|
|
|
|
current_state = { |
|
"response": response, |
|
"topics": topics, |
|
"key_topics": topics |
|
} |
|
|
|
return current_state, gr.update(value=response), gr.update(choices=topics) |
|
|
|
|
|
|