import gradio as gr from transformers import pipeline, AutoModelForSequenceClassification, AutoTokenizer, AutoModelForCausalLM import matplotlib.pyplot as plt # Load sentiment and generation models as previously set up tokenizer_sentiment = AutoTokenizer.from_pretrained("cardiffnlp/twitter-roberta-base-sentiment") model_sentiment = AutoModelForSequenceClassification.from_pretrained("cardiffnlp/twitter-roberta-base-sentiment") sentiment_classifier = pipeline("sentiment-analysis", model=model_sentiment, tokenizer=tokenizer_sentiment) tokenizer_gpt = AutoTokenizer.from_pretrained("EleutherAI/gpt-neo-2.7B") model_gpt = AutoModelForCausalLM.from_pretrained("EleutherAI/gpt-neo-2.7B") # Updated generate_text function with padding token fix def generate_text(prompt): # Add '[PAD]' as a padding token if not set if tokenizer_gpt.pad_token is None: tokenizer_gpt.add_special_tokens({'pad_token': '[PAD]'}) # Prepare the input tensors with attention_mask and padding inputs = tokenizer_gpt(prompt, return_tensors="pt", padding=True, truncation=True, max_length=50) # Generate text using max_new_tokens instead of max_length outputs = model_gpt.generate( inputs["input_ids"], attention_mask=inputs["attention_mask"], max_new_tokens=50, num_return_sequences=1, no_repeat_ngram_size=2, pad_token_id=tokenizer_gpt.pad_token_id # Ensure pad_token_id is set ) generated_text = tokenizer_gpt.decode(outputs[0], skip_special_tokens=True) return generated_text.strip() # Function to analyze each line of the script def analyze_script(script): global all_scores, descriptions, music_cues lines = script.strip().split("\n") all_scores = [] descriptions = [] music_cues = [] analysis_results = [] for i, line in enumerate(lines): result = sentiment_classifier(line)[0] sentiment = result['label'] score = result['score'] description_prompt = f"Describe a scene with the sentiment '{sentiment}' for the line: '{line}'" description = generate_text(description_prompt) music_cue_prompt = f"Suggest music elements (like tempo, key, and instrumentation) that would fit a scene with the sentiment '{sentiment}': '{line}'" music_cue = generate_text(music_cue_prompt) all_scores.append(score) descriptions.append(description) music_cues.append(music_cue) analysis_results.append( { "Line": f"Line {i + 1}: {line}", "Sentiment": f"{sentiment} (Score: {round(score, 2)})", "Description Suggestion": description, "Music Cue": music_cue } ) graph_path = generate_script_graph() return analysis_results, graph_path # Generate the emotional arc graph with music cues for the entire script def generate_script_graph(): plt.figure(figsize=(12, 6)) plt.plot(all_scores, marker='o', linestyle='-', color='b', label='Sentiment Intensity') for i, score in enumerate(all_scores): plt.text(i, score, music_cues[i], fontsize=8, ha='right', rotation=45) plt.title('Emotional and Musical Arc for Entire Script') plt.xlabel('Script Lines (Accumulative)') plt.ylabel('Sentiment Intensity') plt.legend() plt.tight_layout() plot_path = "script_emotional_arc.png" plt.savefig(plot_path) plt.close() return plot_path # Custom Gradio component to display dashboard results with icons def format_dashboard(results): formatted_results = "" for result in results: formatted_results += f"""
{result['Line']}
Sentiment: {result['Sentiment']}
Description Suggestion: {result['Description Suggestion']}
Music Cue: {result['Music Cue']}