Kezovic commited on
Commit
b42ba03
·
verified ·
1 Parent(s): 76a424a

Poet example

Browse files
Files changed (1) hide show
  1. app.py +107 -72
app.py CHANGED
@@ -4,11 +4,12 @@ from huggingface_hub import hf_hub_download
4
  import time
5
 
6
  # --- Configuration ---
7
- MODEL_REPO = "Kezovic/iris-q4gguf-baseline-10k"#iris-f16gguf-test" #iris-q4gguf-lora-test" #iris-q4gguf-baseline-10k"
8
- MODEL_FILE = "llama-3.2-1b-instruct.Q4_K_M.gguf"#llama-3.2-1b-instruct.F16.gguf"#Llama-3.2-1B-Instruct.Q4_K_M.gguf"#llama-3.2-1b-instruct.Q4_K_M.gguf"
9
- CONTEXT_WINDOW = 2048
10
- MAX_NEW_TOKENS = 400
11
- TEMPERATURE = 1.5
 
12
 
13
  # --- Model Loading ---
14
  llm = None
@@ -27,75 +28,103 @@ def load_llm():
27
  print("Model loaded successfully!")
28
  except Exception as e:
29
  print(f"Error loading model: {e}")
30
-
31
  load_llm()
32
 
33
- # --- Generation Function ---
34
- def generate_poem(format_type, persona, topic, progress=gr.Progress()):
35
- # 1. VISUAL FEEDBACK: Immediately show the bar
36
- # This now works because the Textbox below has a fixed height!
37
- progress(0, desc="Consulting the Muse...")
38
- time.sleep(0.2) # Force a tiny pause so the eye catches the bar
 
39
 
40
- if not llm:
41
- return "Error: Model not loaded."
 
 
 
 
 
 
 
 
 
 
42
 
43
- if not topic:
44
- return "Please enter a topic!"
 
 
 
 
 
45
 
46
- # 2. Progress Update
47
- progress(0.2, desc=f"Summoning {persona}...")
48
- time.sleep(0.3)
 
 
49
 
50
- persona_map = {
51
- "A Grumpy Pirate": "You are a salty, grumpy pirate captain. Use nautical slang, complain about the sea, and say 'Arrr'.",
52
- "A Melancholy Philosopher": "You are a deep, existential philosopher. Use complex vocabulary, metaphor, and a somber tone.",
53
- "A Hyperactive 5-Year-Old": "You are a very excited 5-year-old. Use simple words, lots of exclamation marks, and get distracted easily.",
54
- "Shakespearean Actor": "You are a dramatic Shakespearean actor. Use Early Modern English (thee, thou), dramatic flair, and iambic rhythm."
55
- }
56
-
57
- format_map = {
58
- "Limerick": "Write a Limerick. It must have exactly 5 lines. The rhyme scheme must be A-A-B-B-A. It should be humorous.",
59
- "Sonnet": "Write a Sonnet. It must have exactly 14 lines and express a complete thought or feeling.",
60
- "Haiku": "Write a Haiku. It must have exactly 3 lines. Keep it very brief and nature-focused if possible.",
61
- "Free Verse": "Write in Free Verse. Do not worry about rhyme or strict structure, focusing instead on imagery and emotion.",
62
- "Ballad": "Write a Ballad. It must tell a narrative story with a clear beginning, middle, and end. Use four-line stanzas (quatrains) and a simple rhyme scheme like A-B-C-B. Keep the language simple and musical."
63
- }
64
 
 
 
65
  selected_voice = persona_map.get(persona, "You are a helpful assistant.")
66
  selected_constraint = format_map.get(format_type, "Write a poem.")
67
 
68
- full_prompt = (
69
- f"### Instruction:\n"
70
- f"{selected_voice}\n"
71
- f"{selected_constraint} Your response should only contain the {format_type} that you generate. Nothing else.\n"
72
- f"Write the {format_type} about this topic: '{topic}'.\n\n"
73
-
74
- )
75
-
76
- # 3. Progress Update
77
- progress(0.4, desc="Drafting Masterpiece...")
78
 
79
  output = llm(
80
- prompt=full_prompt,
81
  max_tokens=MAX_NEW_TOKENS,
82
  temperature=TEMPERATURE,
83
- stop=["### Instruction:", "### Human:"],
84
  echo=False
85
  )
 
86
 
87
- # 4. Progress Update
88
- progress(0.9, desc="Polishing rhymes...")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89
  time.sleep(0.2)
90
 
91
- return output['choices'][0]['text'].strip()
92
 
93
  # --- UI Layout ---
94
  with gr.Blocks(title="The Poetry Workshop", theme=gr.themes.Soft()) as demo:
95
-
96
- gr.Markdown("# 🖋️ The Poetry Workshop")
97
- gr.Markdown("Your own personal muse to help you get started with poetry.")
98
-
99
  with gr.Group():
100
  with gr.Row(equal_height=True):
101
  gr.Markdown("### I want to write a ")
@@ -116,33 +145,39 @@ with gr.Blocks(title="The Poetry Workshop", theme=gr.themes.Soft()) as demo:
116
  container=False,
117
  scale=3
118
  )
 
 
 
 
 
 
 
 
 
119
 
120
- with gr.Row(equal_height=True):
121
- gr.Markdown("### about this topic: ")
122
- topic_input = gr.Textbox(
123
- placeholder="e.g., my broken laptop, the smell of rain, a lost sock",
124
- label="Topic",
125
- show_label=False,
126
- scale=5
127
- )
128
- generate_btn = gr.Button("✨ Create Masterpiece", variant="primary", scale=1)
129
-
130
  gr.Markdown("---")
131
 
132
- # --- CRITICAL CHANGE HERE ---
133
- # Swapped gr.Markdown for gr.Textbox.
134
- # 'lines=10' forces the box to be visible immediately, so the loading bar has a place to live.
135
- output_display = gr.Textbox(
136
- label="Your Poem",
137
- lines=12, # Ensures a big empty box exists on load
138
- interactive=False, # Read-only
139
- placeholder="Your masterpiece will appear here..."
140
- )
 
 
 
 
 
 
141
 
 
142
  generate_btn.click(
143
  fn=generate_poem,
144
  inputs=[format_dropdown, persona_dropdown, topic_input],
145
- outputs=[output_display]
146
  )
147
 
148
  if __name__ == "__main__":
 
4
  import time
5
 
6
  # --- Configuration ---
7
+ MODEL_REPO = "Kezovic/iris-q4gguf-baseline-10k"
8
+ MODEL_FILE = "llama-3.2-1b-instruct.Q4_K_M.gguf"
9
+ CONTEXT_WINDOW = 2048
10
+ MAX_NEW_TOKENS = 400
11
+ TEMPERATURE = 0.7 # Reduced temperature for better instruction following
12
+ # Note: min_p = 0.1 is kept as requested in the configuration from the previous prompt
13
 
14
  # --- Model Loading ---
15
  llm = None
 
28
  print("Model loaded successfully!")
29
  except Exception as e:
30
  print(f"Error loading model: {e}")
 
31
  load_llm()
32
 
33
+ # --- Persona and Format Maps (Hardened Constraints) ---
34
+ persona_map = {
35
+ "A Grumpy Pirate": "You are a salty, grumpy pirate captain. Use nautical slang, complain about the sea, and say 'Arrr'.",
36
+ "A Melancholy Philosopher": "You are a deep, existential philosopher. Use complex vocabulary, metaphor, and a somber tone.",
37
+ "A Hyperactive 5-Year-Old": "You are a very excited 5-year-old. Use simple words, lots of exclamation marks, and get distracted easily.",
38
+ "Shakespearean Actor": "You are a dramatic Shakespearean actor. Use Early Modern English (thee, thou), dramatic flair, and iambic rhythm."
39
+ }
40
 
41
+ # CONSTRAINTS ARE HARDENED: Clear rules to help adherence.
42
+ format_map = {
43
+ "Limerick": "The poem MUST have exactly 5 lines (A-A-B-B-A rhyme scheme) and be HUMOROUS.",
44
+ "Sonnet": "The poem MUST have exactly 14 lines and express a complete thought or feeling.",
45
+ "Haiku": "The poem ABSOLUTELY MUST have exactly 3 lines. The syllable structure should be 5-7-5 (approximate). Focus on nature and brevity.",
46
+ "Free Verse": "The poem should be written in Free Verse. It should have 6-10 lines and focus on imagery and emotion without strict rhyme or rhythm.",
47
+ "Ballad": "The poem MUST tell a narrative story using four-line stanzas (quatrains) and a simple rhyme scheme like A-B-C-B. It should be 4-6 stanzas long."
48
+ }
49
+
50
+ # --- Prompt Construction Helper Function (Robust, Delimited Prompt) ---
51
+ def build_poem_prompt(voice_instruction, constraint_instruction, format_type, topic):
52
+ """Constructs a robust, delimited prompt for initial poem generation."""
53
 
54
+ system_context = (
55
+ f"SYSTEM: You are a highly disciplined creative writer. You ABSOLUTELY MUST follow all constraints "
56
+ f"on line count, structure, and persona. Your entire response MUST contain ONLY the poem and NOTHING else. "
57
+ f"Do NOT include any titles, headers, or extra text.\n"
58
+ f"PERSONA: {voice_instruction}\n"
59
+ f"FORMAT RULES: {constraint_instruction}\n"
60
+ )
61
 
62
+ user_task = (
63
+ f"USER: Write a {format_type} about the topic: '{topic}'. The poem MUST strictly adhere to all FORMAT RULES.\n"
64
+ )
65
+
66
+ return f"### Instruction:\n{system_context}\n{user_task}\n\n"
67
 
68
+ # --- LLM Functions ---
69
+ def generate_poem(format_type, persona, topic, progress=gr.Progress()):
70
+ # 1. VISUAL FEEDBACK & Error Checks
71
+ progress(0, desc="Consulting the Muse...")
72
+ time.sleep(0.2)
73
+ if not llm:
74
+ return "Error: Model not loaded.", "Error: Model not loaded."
75
+ if not topic:
76
+ return "Please enter a topic!", ""
 
 
 
 
 
77
 
78
+ # --- 1. POEM GENERATION ---
79
+ progress(0.2, desc=f"Summoning {persona} and drafting poem...")
80
  selected_voice = persona_map.get(persona, "You are a helpful assistant.")
81
  selected_constraint = format_map.get(format_type, "Write a poem.")
82
 
83
+ full_poem_prompt = build_poem_prompt(selected_voice, selected_constraint, format_type, topic)
 
 
 
 
 
 
 
 
 
84
 
85
  output = llm(
86
+ prompt=full_poem_prompt,
87
  max_tokens=MAX_NEW_TOKENS,
88
  temperature=TEMPERATURE,
89
+ stop=["### Instruction:", "USER:", "SYSTEM:", "### Human:"],
90
  echo=False
91
  )
92
+ poem_text = output['choices'][0]['text'].strip()
93
 
94
+ # --- 2. POET SUGGESTION (ANALYSIS) ---
95
+ progress(0.5, desc="Analyzing style for literary match...")
96
+
97
+ # Secondary prompt for the analysis task
98
+ poet_prompt = (
99
+ f"### Instruction:\n"
100
+ f"SYSTEM: You are a literary analyst specializing in poetry. Your task is to find the single most appropriate historical poet "
101
+ f"whose style and themes match the provided poem. Output only the POET'S NAME followed by a COLON, and then a brief, single-sentence justification.\n"
102
+ f"Do NOT output any other text or headers. You MUST adhere to the requested persona's style.\n"
103
+ f"PERSONA: {selected_voice}\n"
104
+ f"USER: Analyze the poem below and suggest the best matching poet:\n\n"
105
+ f"POEM:\n{poem_text}\n\n"
106
+ )
107
+
108
+ output_poet = llm(
109
+ prompt=poet_prompt,
110
+ max_tokens=150, # Keep this response short
111
+ temperature=0.4, # Lower temperature for analysis/retrieval
112
+ stop=["### Instruction:", "USER:", "SYSTEM:", "### Human:", "\n\n"],
113
+ echo=False
114
+ )
115
+
116
+ poet_suggestion = output_poet['choices'][0]['text'].strip()
117
+
118
+ progress(0.9, desc="Poem and analysis complete!")
119
  time.sleep(0.2)
120
 
121
+ return poem_text, poet_suggestion
122
 
123
  # --- UI Layout ---
124
  with gr.Blocks(title="The Poetry Workshop", theme=gr.themes.Soft()) as demo:
125
+ gr.Markdown("# 🖋️ The Poetry Workshop - Collaborative Analyst")
126
+ gr.Markdown("Generate a poem based on a topic and persona, then receive a stylistic analysis and literary comparison from the LLM.")
127
+
 
128
  with gr.Group():
129
  with gr.Row(equal_height=True):
130
  gr.Markdown("### I want to write a ")
 
145
  container=False,
146
  scale=3
147
  )
148
+ with gr.Row(equal_height=True):
149
+ gr.Markdown("### about this topic: ")
150
+ topic_input = gr.Textbox(
151
+ placeholder="e.g., my broken laptop, the smell of rain, a lost sock",
152
+ label="Topic",
153
+ show_label=False,
154
+ scale=5
155
+ )
156
+ generate_btn = gr.Button("✨ Create Masterpiece & Analyze", variant="primary", scale=1)
157
 
 
 
 
 
 
 
 
 
 
 
158
  gr.Markdown("---")
159
 
160
+ with gr.Row():
161
+ output_display = gr.Textbox(
162
+ label="Your Poem",
163
+ lines=12,
164
+ interactive=False,
165
+ placeholder="Your masterpiece will appear here..."
166
+ )
167
+
168
+ # New Textbox for the Poet Suggestion
169
+ poet_suggestion_display = gr.Textbox(
170
+ label="Literary Analysis: Suggested Poet",
171
+ lines=12,
172
+ interactive=False,
173
+ placeholder="The LLM will analyze the poem's style and suggest a similar historical poet here."
174
+ )
175
 
176
+ # Update the click handler to call the function and map outputs
177
  generate_btn.click(
178
  fn=generate_poem,
179
  inputs=[format_dropdown, persona_dropdown, topic_input],
180
+ outputs=[output_display, poet_suggestion_display] # Maps to both textboxes
181
  )
182
 
183
  if __name__ == "__main__":