barunsaha commited on
Commit
854eca0
1 Parent(s): a62401d

Add application files

Browse files
.gitignore ADDED
@@ -0,0 +1,140 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ### Python template
2
+ # Byte-compiled / optimized / DLL files
3
+ __pycache__/
4
+ *.py[cod]
5
+ *$py.class
6
+
7
+ # C extensions
8
+ *.so
9
+
10
+ # Distribution / packaging
11
+ .Python
12
+ build/
13
+ develop-eggs/
14
+ dist/
15
+ downloads/
16
+ eggs/
17
+ .eggs/
18
+ lib/
19
+ lib64/
20
+ parts/
21
+ sdist/
22
+ var/
23
+ wheels/
24
+ share/python-wheels/
25
+ *.egg-info/
26
+ .installed.cfg
27
+ *.egg
28
+ MANIFEST
29
+
30
+ # PyInstaller
31
+ # Usually these files are written by a python script from a template
32
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
33
+ *.manifest
34
+ *.spec
35
+
36
+ # Installer logs
37
+ pip-log.txt
38
+ pip-delete-this-directory.txt
39
+
40
+ # Unit test / coverage reports
41
+ htmlcov/
42
+ .tox/
43
+ .nox/
44
+ .coverage
45
+ .coverage.*
46
+ .cache
47
+ nosetests.xml
48
+ coverage.xml
49
+ *.cover
50
+ *.py,cover
51
+ .hypothesis/
52
+ .pytest_cache/
53
+ cover/
54
+
55
+ # Translations
56
+ *.mo
57
+ *.pot
58
+
59
+ # Django stuff:
60
+ *.log
61
+ local_settings.py
62
+ db.sqlite3
63
+ db.sqlite3-journal
64
+
65
+ # Flask stuff:
66
+ instance/
67
+ .webassets-cache
68
+
69
+ # Scrapy stuff:
70
+ .scrapy
71
+
72
+ # Sphinx documentation
73
+ docs/_build/
74
+
75
+ # PyBuilder
76
+ .pybuilder/
77
+ target/
78
+
79
+ # Jupyter Notebook
80
+ .ipynb_checkpoints
81
+
82
+ # IPython
83
+ profile_default/
84
+ ipython_config.py
85
+
86
+ # pyenv
87
+ # For a library or package, you might want to ignore these files since the code is
88
+ # intended to run in multiple environments; otherwise, check them in:
89
+ # .python-version
90
+
91
+ # pipenv
92
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
93
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
94
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
95
+ # install all needed dependencies.
96
+ #Pipfile.lock
97
+
98
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow
99
+ __pypackages__/
100
+
101
+ # Celery stuff
102
+ celerybeat-schedule
103
+ celerybeat.pid
104
+
105
+ # SageMath parsed files
106
+ *.sage.py
107
+
108
+ # Environments
109
+ .env
110
+ .venv
111
+ env/
112
+ venv/
113
+ ENV/
114
+ env.bak/
115
+ venv.bak/
116
+
117
+ # Spyder project settings
118
+ .spyderproject
119
+ .spyproject
120
+
121
+ # Rope project settings
122
+ .ropeproject
123
+
124
+ # mkdocs documentation
125
+ /site
126
+
127
+ # mypy
128
+ .mypy_cache/
129
+ .dmypy.json
130
+ dmypy.json
131
+
132
+ # Pyre type checker
133
+ .pyre/
134
+
135
+ # pytype static type analyzer
136
+ .pytype/
137
+
138
+ # Cython debug symbols
139
+ cython_debug/
140
+
.idea/.gitignore ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ # Default ignored files
2
+ /shelf/
3
+ /workspace.xml
.idea/inspectionProfiles/Project_Default.xml ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <component name="InspectionProjectProfileManager">
2
+ <profile version="1.0">
3
+ <option name="myName" value="Project Default" />
4
+ <inspection_tool class="PyPackageRequirementsInspection" enabled="true" level="WARNING" enabled_by_default="true">
5
+ <option name="ignoredPackages">
6
+ <value>
7
+ <list size="1">
8
+ <item index="0" class="java.lang.String" itemvalue="numpy" />
9
+ </list>
10
+ </value>
11
+ </option>
12
+ </inspection_tool>
13
+ </profile>
14
+ </component>
.idea/inspectionProfiles/profiles_settings.xml ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ <component name="InspectionProjectProfileManager">
2
+ <settings>
3
+ <option name="USE_PROJECT_PROFILE" value="false" />
4
+ <version value="1.0" />
5
+ </settings>
6
+ </component>
.idea/misc.xml ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.10 (poem2pic)" project-jdk-type="Python SDK" />
4
+ </project>
.idea/modules.xml ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="ProjectModuleManager">
4
+ <modules>
5
+ <module fileurl="file://$PROJECT_DIR$/.idea/poem2pic.iml" filepath="$PROJECT_DIR$/.idea/poem2pic.iml" />
6
+ </modules>
7
+ </component>
8
+ </project>
.idea/poem2pic.iml ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <module type="PYTHON_MODULE" version="4">
3
+ <component name="NewModuleRootManager">
4
+ <content url="file://$MODULE_DIR$">
5
+ <excludeFolder url="file://$MODULE_DIR$/venv" />
6
+ </content>
7
+ <orderEntry type="jdk" jdkName="Python 3.10 (poem2pic)" jdkType="Python SDK" />
8
+ <orderEntry type="sourceFolder" forTests="false" />
9
+ </component>
10
+ </module>
.idea/vcs.xml ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="VcsDirectoryMappings">
4
+ <mapping directory="$PROJECT_DIR$" vcs="Git" />
5
+ </component>
6
+ </project>
app.py ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+
3
+ from config import Config
4
+ from diffusion_image import generate_image_from_text
5
+ from t5_summary import generate_summary
6
+
7
+
8
+ st.write('''
9
+ # Poem2Pic: What picture does your poem paint?
10
+
11
+ Poetry is food for the soul. An image is worth a thousand words.
12
+
13
+ With Poem2Pic, generate an image based on a very short summary of your poem!
14
+ ''')
15
+
16
+ footer = """<style>
17
+ .footer {
18
+ position: fixed;
19
+ left: 0;
20
+ bottom: 2%;
21
+ width: 100%;
22
+ text-align: center;
23
+ color: #696969;
24
+ padding: 2px;
25
+ }
26
+ </style>
27
+ <div class="footer">
28
+ <p><small>Poem2Pic is an experimental project developed for fun. It is not really intended for professional use.
29
+ Generating an image is an expensive process, so the image quality is kept low in the interest of time and cost.
30
+ By using Poem2Pic you agree to fair, responsible, and sensible usage of the solution, platform,
31
+ and the underlying AI models.</small></p>
32
+ </div>
33
+ """
34
+ st.markdown(footer, unsafe_allow_html=True)
35
+
36
+ poem = st.text_area(
37
+ f'''**Type or copy paste a poem (max. {Config.LLM_MAX_INPUT_LENGTH} characters will be considered):**''',
38
+ ''
39
+ )
40
+
41
+ if st.button('Generate image'):
42
+ progress_text = 'Generating image...give it a moment'
43
+ progress_bar = st.progress(0, text=progress_text)
44
+ progress_bar.progress(1, text=progress_text)
45
+
46
+ poem = poem.strip()
47
+ input_length = len(poem)
48
+
49
+ if input_length > 0:
50
+ print(poem)
51
+
52
+ if input_length <= 5:
53
+ summary = poem
54
+ else:
55
+ target_length = min(input_length, Config.LLM_MAX_INPUT_LENGTH)
56
+ summary = generate_summary(poem[:target_length])
57
+
58
+ print(f'Summary: {summary}')
59
+ st.write(f'''Summary: {summary}''')
60
+ progress_bar.progress(25, text='Summary generated...need a few more minutes')
61
+
62
+ image = generate_image_from_text(summary)
63
+ progress_bar.progress(100, text='Done!')
64
+
65
+ st.image(image, caption=summary)
66
+ st.info('(Right-click on the image to save it)', icon='ℹ️ ')
config.py ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from dataclasses import dataclass
2
+ from dotenv import load_dotenv
3
+ import os
4
+
5
+ load_dotenv()
6
+
7
+
8
+ @dataclass(frozen=True)
9
+ class Config:
10
+ HUGGINGFACEHUB_API_TOKEN: str = os.getenv('HUGGINGFACEHUB_API_TOKEN')
11
+
12
+ # Flan-T5
13
+ LLM_MODEL_NAME: str = 'google/flan-t5-xxl'
14
+ LLM_TEMPERATURE: float = 0.5
15
+ LLM_MAX_OUTPUT_LENGTH: int = 100
16
+ LLM_MAX_INPUT_LENGTH: int = 512
17
+
18
+ # Stable Diffusion
19
+ DIFFUSION_MODEL_NAME: str = 'stabilityai/stable-diffusion-2-1'
20
+ DIFFUSION_NUM_INFERENCE_STEPS: int = 3
diffusion_image.py ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import PIL.Image
2
+ from diffusers import StableDiffusionPipeline, DPMSolverMultistepScheduler
3
+ import torch
4
+
5
+ from config import Config
6
+
7
+
8
+ torch.set_grad_enabled(False)
9
+
10
+ dpm = DPMSolverMultistepScheduler.from_pretrained(Config.DIFFUSION_MODEL_NAME, subfolder='scheduler')
11
+ pipeline = StableDiffusionPipeline.from_pretrained(Config.DIFFUSION_MODEL_NAME, scheduler=dpm)
12
+ # pipeline.enable_xformers_memory_efficient_attention()
13
+
14
+
15
+ def generate_image_from_text(text: str) -> PIL.Image.Image:
16
+ """
17
+ Generate an image based on the input text.
18
+
19
+ :param text: The text
20
+ :return: An image instance
21
+ """
22
+
23
+ with torch.inference_mode():
24
+ output_img = pipeline(
25
+ text,
26
+ num_inference_steps=Config.DIFFUSION_NUM_INFERENCE_STEPS).images[0]
27
+ print(output_img)
28
+
29
+ return output_img
examples/Ozymandias.txt ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Ozymandias
2
+ By Percy Bysshe Shelley
3
+
4
+ I met a traveller from an antique land,
5
+ Who said—“Two vast and trunkless legs of stone
6
+ Stand in the desert. . . . Near them, on the sand,
7
+ Half sunk a shattered visage lies, whose frown,
8
+ And wrinkled lip, and sneer of cold command,
9
+ Tell that its sculptor well those passions read
10
+ Which yet survive, stamped on these lifeless things,
11
+ The hand that mocked them, and the heart that fed;
12
+ And on the pedestal, these words appear:
13
+ My name is Ozymandias, King of Kings;
14
+ Look on my Works, ye Mighty, and despair!
15
+ Nothing beside remains. Round the decay
16
+ Of that colossal Wreck, boundless and bare
17
+ The lone and level sands stretch far away.”
examples/The_Raven.txt ADDED
@@ -0,0 +1,128 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ The Raven
2
+ By Edgar Allan Poe
3
+
4
+ Once upon a midnight dreary, while I pondered, weak and weary,
5
+ Over many a quaint and curious volume of forgotten lore,
6
+ While I nodded, nearly napping, suddenly there came a tapping,
7
+ As of some one gently rapping, rapping at my chamber door. “
8
+ “'Tis some visitor,” I muttered, “tapping at my chamber door—
9
+ Only this, and nothing more.”
10
+
11
+ Ah, distinctly I remember it was in the bleak December,
12
+ And each separate dying ember wrought its ghost upon the floor.
13
+ Eagerly I wished the morrow;—vainly I had sought to borrow
14
+ From my books surcease of sorrow—sorrow for the lost Lenore—
15
+ For the rare and radiant maiden whom the angels name Lenore—
16
+ Nameless here for evermore.
17
+
18
+ And the silken sad uncertain rustling of each purple curtain
19
+ Thrilled me—filled me with fantastic terrors never felt before;
20
+ So that now, to still the beating of my heart, I stood repeating, “
21
+ “'Tis some visitor entreating entrance at my chamber door—
22
+ Some late visitor entreating entrance at my chamber door;—
23
+ This it is, and nothing more.”
24
+
25
+ Presently my soul grew stronger; hesitating then no longer,
26
+ “Sir,” said I, “or Madam, truly your forgiveness I implore;
27
+ But the fact is I was napping, and so gently you came rapping,
28
+ And so faintly you came tapping, tapping at my chamber door,
29
+ That I scarce was sure I heard you”—here I opened wide the door;—
30
+ Darkness there, and nothing more.
31
+
32
+ Deep into that darkness peering, long I stood there wondering, fearing,
33
+ Doubting, dreaming dreams no mortals ever dared to dream before;
34
+ But the silence was unbroken, and the stillness gave no token,
35
+ And the only word there spoken was the whispered word, “Lenore!”
36
+ This I whispered, and an echo murmured back the word, “Lenore!”—
37
+ Merely this, and nothing more.
38
+
39
+ Back into the chamber turning, all my soul within me burning,
40
+ Soon again I heard a tapping somewhat louder than before.
41
+ “Surely,” said I, “surely that is something at my window lattice,
42
+ Let me see, then, what thereat is, and this mystery explore—
43
+ Let my heart be still a moment and this mystery explore;—
44
+ 'Tis the wind and nothing more.”
45
+
46
+ Open here I flung the shutter, when, with many a flirt and flutter,
47
+ In there stepped a stately raven of the saintly days of yore.
48
+ Not the least obeisance made he; not a minute stopped or stayed he;
49
+ But, with mien of lord or lady, perched above my chamber door—
50
+ Perched upon a bust of Pallas just above my chamber door—
51
+ Perched, and sat, and nothing more.
52
+
53
+ Then this ebony bird beguiling my sad fancy into smiling,
54
+ By the grave and stern decorum of the countenance it wore.
55
+ “Though thy crest be shorn and shaven, thou,” I said, “art sure no craven,
56
+ Ghastly grim and ancient raven wandering from the Nightly shore—
57
+ Tell me what thy lordly name is on the Night's Plutonian shore!”
58
+ Quoth the Raven, “Nevermore.”
59
+
60
+ Much I marvelled this ungainly fowl to hear discourse so plainly,
61
+ Though its answer little meaning—little relevancy bore;
62
+ For we cannot help agreeing that no living human being
63
+ Ever yet was blest with seeing bird above his chamber door—
64
+ Bird or beast upon the sculptured bust above his chamber door,
65
+ With such name as “Nevermore.”
66
+
67
+ But the Raven, sitting lonely on the placid bust, spoke only
68
+ That one word, as if his soul in that one word he did outpour.
69
+ Nothing further then he uttered—not a feather then he fluttered—
70
+ Till I scarcely more than muttered, “other friends have flown before—
71
+ On the morrow he will leave me, as my hopes have flown before.”
72
+ Then the bird said, “Nevermore.”
73
+
74
+ Startled at the stillness broken by reply so aptly spoken,
75
+ “Doubtless,” said I, “what it utters is its only stock and store,
76
+ Caught from some unhappy master whom unmerciful Disaster
77
+ Followed fast and followed faster till his songs one burden bore—
78
+ Till the dirges of his Hope that melancholy burden bore,
79
+ Of ‘Never—nevermore’.”
80
+
81
+ But the Raven still beguiling my sad fancy into smiling,
82
+ Straight I wheeled a cushioned seat in front of bird and bust and door;
83
+ Then, upon the velvet sinking, I betook myself to linking
84
+ Fancy unto fancy, thinking what this ominous bird of yore—
85
+ What this grim, ungainly, ghastly, gaunt, and ominous bird of yore
86
+ Meant in croaking “Nevermore.”
87
+
88
+ This I sat engaged in guessing, but no syllable expressing
89
+ To the fowl whose fiery eyes now burned into my bosom's core;
90
+ This and more I sat divining, with my head at ease reclining
91
+ On the cushion's velvet lining that the lamplight gloated o'er,
92
+ But whose velvet violet lining with the lamplight gloating o'er,
93
+ She shall press, ah, nevermore!
94
+
95
+ Then, methought, the air grew denser, perfumed from an unseen censer
96
+ Swung by Seraphim whose footfalls tinkled on the tufted floor.
97
+ “Wretch,” I cried, “thy God hath lent thee—by these angels he hath sent thee
98
+ Respite—respite and nepenthe, from thy memories of Lenore;
99
+ Quaff, oh quaff this kind nepenthe and forget this lost Lenore!”
100
+ Quoth the Raven, “Nevermore.”
101
+
102
+ “Prophet!” said I, “thing of evil!—prophet still, if bird or devil!—
103
+ Whether Tempter sent, or whether tempest tossed thee here ashore,
104
+ Desolate yet all undaunted, on this desert land enchanted—
105
+ On this home by horror haunted—tell me truly, I implore—
106
+ Is there—is there balm in Gilead?—tell me—tell me, I implore!”
107
+ Quoth the Raven, “Nevermore.”
108
+
109
+ “Prophet!” said I, “thing of evil!—prophet still, if bird or devil!
110
+ By that Heaven that bends above us—by that God we both adore—
111
+ Tell this soul with sorrow laden if, within the distant Aidenn,
112
+ It shall clasp a sainted maiden whom the angels name Lenore—
113
+ Clasp a rare and radiant maiden whom the angels name Lenore.”
114
+ Quoth the Raven, “Nevermore.”
115
+
116
+ “Be that word our sign in parting, bird or fiend!” I shrieked, upstarting—
117
+ “Get thee back into the tempest and the Night's Plutonian shore!
118
+ Leave no black plume as a token of that lie thy soul hath spoken!
119
+ Leave my loneliness unbroken!—quit the bust above my door!
120
+ Take thy beak from out my heart, and take thy form from off my door!”
121
+ Quoth the Raven, “Nevermore.”
122
+
123
+ And the Raven, never flitting, still is sitting, still is sitting
124
+ On the pallid bust of Pallas just above my chamber door;
125
+ And his eyes have all the seeming of a demon's that is dreaming,
126
+ And the lamplight o'er him streaming throws his shadow on the floor;
127
+ And my soul from out that shadow that lies floating on the floor
128
+ Shall be lifted—nevermore!
examples/the_old_pond.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ By Matsuo Basho
2
+
3
+ An old silent pond
4
+ A frog jumps into the pond—
5
+ Splash! Silence again.
requirements.txt ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ python-dotenv[cli]
2
+ langchain
3
+ huggingface_hub
4
+ torch
5
+ transformers
6
+ diffusers[torch]
7
+ accelerate
8
+ streamlit
9
+ Pillow
t5_summary.py ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from langchain import HuggingFaceHub, PromptTemplate
2
+
3
+ from config import Config
4
+
5
+
6
+ llm = HuggingFaceHub(
7
+ repo_id=Config.LLM_MODEL_NAME,
8
+ huggingfacehub_api_token=Config.HUGGINGFACEHUB_API_TOKEN,
9
+ model_kwargs={'temperature': Config.LLM_TEMPERATURE, 'max_length': Config.LLM_MAX_OUTPUT_LENGTH}
10
+ )
11
+ # print(llm)
12
+
13
+ template = '''
14
+ You are a helpful assistant who can answer questions about literature and poetry. You are creative.
15
+ Consider the following poem:
16
+
17
+ {poem}
18
+
19
+ Write a creative summary of the poem in about 20 words.
20
+ The summary should try to capture the subject, objects, key themes, and sentiments.
21
+ '''
22
+
23
+ prompt = PromptTemplate.from_template(template)
24
+
25
+
26
+ def generate_summary(poem: str) -> str:
27
+ """
28
+ Generate the summary of a poem using an LLM.
29
+
30
+ :param poem: The text of the poem
31
+ :return: The summary
32
+ """
33
+
34
+ print(prompt.format(poem=poem))
35
+ summary = llm(prompt.format(poem=poem))
36
+
37
+ return summary