yiyii commited on
Commit
c207bc8
1 Parent(s): 2e3f267
Files changed (4) hide show
  1. README.md +16 -0
  2. app.py +228 -0
  3. requirements.txt +24 -0
  4. story.txt +306 -0
README.md CHANGED
@@ -10,3 +10,19 @@ pinned: false
10
  ---
11
 
12
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  ---
11
 
12
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
13
+
14
+
15
+
16
+
17
+
18
+
19
+
20
+ RAG:
21
+ let user to upload pdf or url istead of using story.txx
22
+
23
+ let user decide the value of chunk_size and top-k
24
+
25
+ tell it in the prompt directly how long the story should approximately be.
26
+
27
+
28
+
app.py ADDED
@@ -0,0 +1,228 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from deepface import DeepFace
3
+ from transformers import pipeline
4
+ import io
5
+ import base64
6
+ import pandas as pd
7
+ import numpy as ny
8
+ from huggingface_hub import InferenceClient
9
+
10
+ from langchain.text_splitter import TokenTextSplitter
11
+ # from langchain.text_splitter import RecursiveCharacterTextSplitter
12
+ from langchain.embeddings import HuggingFaceBgeEmbeddings
13
+ from langchain.vectorstores import Chroma
14
+ # from langchain.chain import RetrievalQA
15
+ # from langchain import PromptTemplate
16
+
17
+ get_blip = pipeline("image-to-text",model="Salesforce/blip-image-captioning-large")
18
+
19
+ # using deepface to detect age, gender, emotion(happy,neutral,surprise,sad,angry,fear,disgust)
20
+ def analyze_face(image):
21
+ #convert PIL image to numpy array
22
+ image_array = ny.array(image)
23
+ face_result = DeepFace.analyze(image_array, actions=['age','gender','emotion'], enforce_detection=False)
24
+ #convert the resulting dictionary to a dataframe
25
+ df = pd.DataFrame(face_result)
26
+ return df['dominant_gender'][0],df['age'][0],df['dominant_emotion'][0]
27
+ #The [0] at the end is for accessing the value at the first row in a DataFrame column.
28
+
29
+ #using blip to generate caption
30
+ #image_to_base64_str function to convert image to base64 format
31
+ def image_to_base64_str(pil_image):
32
+ byte_arr = io.BytesIO()
33
+ pil_image.save(byte_arr, format='PNG')
34
+ byte_arr = byte_arr.getvalue()
35
+ return str(base64.b64encode(byte_arr).decode('utf-8'))
36
+ #captioner function to take an image
37
+ def captioner(image):
38
+ base64_image = image_to_base64_str(image)
39
+ caption = get_blip(base64_image)
40
+ return caption[0]['generated_text']
41
+ #The [0] at the beginning is for accessing the first element in a container (like a list or dictionary).
42
+
43
+ def get_image_info(image):
44
+ #call captioner() function
45
+ image_caption = captioner(image)
46
+
47
+ #call analyze_face() function
48
+ gender, age, emotion = analyze_face(image)
49
+
50
+ #return image_caption,face_attributes
51
+ return image_caption, gender, age, emotion
52
+
53
+
54
+ # loading the embedding model
55
+ model_name = "BAAI/bge-large-en-v1.5"
56
+ model_kwargs = {'device':'cpu'}
57
+ #encode_kwargs = {'normalize_embeddings':False}
58
+ # the embeddings will be normalized, normalization can make cosine similarity(angular distance) calculations more effective,
59
+ # bacause it is comparison tasks based on directional similarity between vectors.
60
+ encode_kwargs = {'normalize_embeddings':True}
61
+ # initialize embeddings
62
+ embeddings = HuggingFaceBgeEmbeddings(model_name=model_name, model_kwargs=model_kwargs, encode_kwargs=encode_kwargs)
63
+ print("embeddings model loaded....................")
64
+ # load the txt file
65
+ with open("story.txt", "r") as f:
66
+ # r: read mode, reading only
67
+ state_of_the_union = f.read()
68
+ # read the file into a single string
69
+ # split the content into chunks
70
+ text_splitter = TokenTextSplitter(chunk_size=200, chunk_overlap=20)
71
+ # TokenTextSplitter() can ensure the integrity of words
72
+ # each chunk to overlap with the previous chunk by 20 tokens
73
+ texts = text_splitter.split_text(state_of_the_union)
74
+ print("...........................................")
75
+ # print the first chunk
76
+ print("text[0]: ", texts[0])
77
+ # create embeddings for chunks by using bge model, and then save these vectors into chroma vector database
78
+ # use hnsw(hierarchical navigable small world) index to facilitate efficient searching
79
+ # use cosine similarity to measure similiarity.(similarity is crucial in performing similarity search.)
80
+ # hnsw: builds a graph-based index for approximate nearest neighber searches.
81
+ # hnsw is used for organizing the data into an efficient structure that supports rapid retrieval operations(speed up the search).
82
+ # cosine similarity is used for telling the hnsw algorithm how to measure the distance between vectors.
83
+ # by setting space to cosine space, the index will operate using cosine similarity to measuer the vectors' similarity.
84
+ vector_store = Chroma.from_texts(texts, embeddings, collection_metadata = {"hnsw:space":"cosine"}, persist_directory="stores/story_cosine" )
85
+ print("vector store created........................")
86
+
87
+ load_vector_store = Chroma(persist_directory="stores/story_cosine", embedding_function=embeddings)
88
+ # persist_directory="stores/story_cosine": laod the existing vector store form "stores/story_cosine"
89
+ # embedding_function=embeddings: using the bge embedding model when add the new data to the vector store
90
+
91
+ # Only get the 3 most similar document from the dataset
92
+ retriever = load_vector_store.as_retriever(search_kwargs={"k":3})
93
+
94
+ client = InferenceClient(
95
+ "mistralai/Mistral-7B-Instruct-v0.1"
96
+ )
97
+
98
+ def generate(image, temperature=0.9, max_new_tokens=1500, top_p=0.95, repetition_penalty=1.0):
99
+ image_caption, gender, age, emotion = get_image_info(image)
100
+ print("............................................")
101
+ print("image_caption:", image_caption)
102
+ print("age:", age)
103
+ print("gender:", gender)
104
+ print("emotion:", emotion)
105
+ print("............................................")
106
+ query = f"{image_caption}. {emotion}{age} years old {gender}"
107
+ # retrieve documents based on query
108
+ documents = retriever.get_relevant_documents(query)
109
+ # the embedding of the query abd comparing query embedding and chunks embedding are handle internally by the get_relevant_documents() method.
110
+ # embedding query: When a query is made, the retriever first converts the query text into a vector using the same embedding model
111
+ # that was used for creating the document vectors in the store. This ensures that the query vector and document vectors are compatible for similarity comparisons.
112
+ # the method of comparing the similarity between query vector and chunk vectors is:
113
+ # cosine similarity and hnsw. because we've configured the vector store with {"hnsw:space":"cosine"}.
114
+ # the methods used for both embedding the query and comparing the query vector with the stored document vectors are directly influenced by the configurations of the vector store we set up.
115
+ # get_relevant_document() use the embedding function specified when we set up the Chroma database.
116
+ if documents:
117
+ print("document:", dir(documents[0]))
118
+ # print the directory of the methods and attributes of the first document
119
+ print(documents[0])
120
+ print(".....................................")
121
+ print(documents)
122
+ else:
123
+ print("no documents")
124
+
125
+ # dir(documents[0]):
126
+ """
127
+ document: ['Config', '__abstractmethods__', '__annotations__', '__class__', '__class_vars__', '__config__', '__custom_root_type__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__exclude_fields__',
128
+ '__fields__', '__fields_set__', '__format__', '__ge__', '__get_validators__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__include_fields__', '__init__', '__init_subclass__', '__iter__', '__json_encoder__',
129
+ '__le__', '__lt__', '__module__', '__ne__', '__new__', '__post_root_validators__', '__pre_root_validators__', '__pretty__', '__private_attributes__', '__reduce__', '__reduce_ex__', '__repr__', '__repr_args__', '__repr_name__',
130
+ '__repr_str__', '__rich_repr__', '__schema_cache__', '__setattr__', '__setstate__', '__signature__', '__sizeof__', '__slots__', '__str__', '__subclasshook__', '__try_update_forward_refs__', '__validators__', '_abc_impl', '_calculate_keys',
131
+ '_copy_and_set_values', '_decompose_class', '_enforce_dict_if_root', '_get_value', '_init_private_attributes', '_iter', 'construct', 'copy', 'dict', 'from_orm', 'get_lc_namespace', 'is_lc_serializable', 'json', 'lc_attributes', 'lc_id',
132
+ 'lc_secrets', 'metadata', 'page_content', 'parse_file', 'parse_obj', 'parse_raw', 'schema', 'schema_json', 'to_json', 'to_json_not_implemented', 'type', 'update_forward_refs', 'validate']
133
+ """
134
+
135
+ # context = ' '.join([doc.page_content for doc in documents])
136
+ #context = '\n'.join([f"Document {index + 1}: {doc}" for index, doc in enumerate(documents)])
137
+ # make the documents' format more clear
138
+ context = '\n'.join([f"Document {index + 1}: {doc.page_content}" for index, doc in enumerate(documents)])
139
+ #prompt = f"[INS] Generate a story based on person’s emotion: {emotion}, age: {age}, gender: {gender} of the image, and image’s caption: {image_caption}. Please use simple words and a child-friendly tone for children, a mature tone for adults, and a considerate, reflective tone for elders.[/INS]"
140
+ print("....................................................................")
141
+ print("context:",context)
142
+ #prompt = f"[INS] Generate a story based on person’s emotion: {emotion}, age: {age}, gender: {gender} of the image, and image’s caption: {image_caption}. The following are some sentence examples: {context}[/INS]"
143
+ prompt = (
144
+ f"[INS] Please generate a detailed and engaging story based on the person's emotion: {emotion}, "
145
+ f"age: {age}, and gender: {gender} shown in the image. Begin with the scene described in the image's caption: '{image_caption}'. "
146
+ f"Just use the following example story plots and formats as an inspiration: "
147
+ f"{context} "
148
+ f"Feel free to develop a complete story in depth and the generated story should approximately be {max_new_tokens} words long.[/INS]"
149
+ )
150
+
151
+ temperature = float(temperature)
152
+ if temperature < 1e-2:
153
+ temperature = 1e-2
154
+ top_p = float(top_p)
155
+
156
+ generate_kwargs = dict(
157
+ temperature=temperature,
158
+ max_new_tokens=max_new_tokens,
159
+ top_p=top_p,
160
+ repetition_penalty=repetition_penalty,
161
+ do_sample=True,
162
+ seed=42,
163
+ )
164
+ stream = client.text_generation(prompt, **generate_kwargs, stream=True, details=True, return_full_text=False)
165
+ # return_full_text=False: only has generated story
166
+ # return_full_text=True: include original prompt and generated story
167
+ output = ""
168
+ for response in stream:
169
+ output += response.token.text
170
+ # yield "".join(output)
171
+ yield output
172
+ print("..........................................................")
173
+ print("generated story:", output)
174
+ return output
175
+
176
+ demo = gr.Interface(fn=generate,
177
+ inputs=[
178
+ #gr.Video(sources=["webcam"], label="video")
179
+ gr.Image(sources=["upload", "webcam"], label="Upload Image", type="pil"),
180
+
181
+ gr.Slider(
182
+ label="Temperature",
183
+ value=0.9,
184
+ minimum=0.0,
185
+ maximum=1.0,
186
+ step=0.05,
187
+ interactive=True,
188
+ info="Higher values produce more diverse outputs",
189
+ ),
190
+
191
+ gr.Slider(
192
+ label="Max new tokens",
193
+ value=1500,
194
+ minimum=0,
195
+ maximum=3000,
196
+ step=1.0,
197
+ interactive=True,
198
+ info="The maximum numbers of new tokens"),
199
+
200
+ gr.Slider(
201
+ label="Top-p (nucleus sampling)",
202
+ value=0.90,
203
+ minimum=0.0,
204
+ maximum=1,
205
+ step=0.05,
206
+ interactive=True,
207
+ info="Higher values sample more low-probability tokens",
208
+ ),
209
+ gr.Slider(
210
+ label="Repetition penalty",
211
+ value=1.2,
212
+ minimum=1.0,
213
+ maximum=2.0,
214
+ step=0.05,
215
+ interactive=True,
216
+ info="Penalize repeated tokens",
217
+ )
218
+ ],
219
+ outputs=[gr.Textbox(label="Generated Story")],
220
+ title="story generation",
221
+ description="generate a story for you",
222
+ allow_flagging="never"
223
+
224
+ )
225
+ demo.launch(debug=(True))
226
+
227
+
228
+
requirements.txt ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ tensorflow==2.15.0
2
+ #bitsandbytes==0.42.0
3
+ #accelerate
4
+ deepface
5
+ transformers
6
+ tf-keras
7
+ #torch
8
+ huggingface_hub
9
+
10
+ langchain
11
+ tiktoken
12
+ sentence_transformers
13
+ chromadb
14
+
15
+ #Your currently installed version of Keras is Keras 3, but this is not yet supported in Transformers,
16
+ #Please install the backwards-compatible tf-keras package with `pip install tf-keras`.
17
+
18
+ #after install tf-keras still got new error: ValueError: The layer sequential has never been called and thus has no defined input.
19
+ # something wrong in analyze_face function. solution: try to use another model rather than the default model
20
+ # solution: downgrade tf version, beacuse Serengil added the dependencies last week
21
+
22
+
23
+
24
+
story.txt ADDED
@@ -0,0 +1,306 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 1.Birthday Party
2
+ They were a couple in their late thirties, and they looked unmistakably married. They sat on the banquette opposite us in a little narrow restaurant, having dinner. The man had a round, self-satisfied face, with glasses on it; the woman was fadingly pretty, in a big hat.
3
+
4
+ There was nothing conspicuous about them, nothing particularly noticeable, until the end of their meal, when it suddenly became obvious that this was an Occasion—in fact, the husband’s birthday, and the wife had planned a little surprise for him.
5
+
6
+ It arrived, in the form of a small but glossy birthday cake, with one pink candle burning in the center. The headwaiter brought it in and placed it before the husband, and meanwhile the violin-and-piano orchestra played “Happy Birthday to You,” and the wife beamed with shy pride over her little surprise, and such few people as there were in the restaurant tried to help out with a pattering of applause. It became clear at once that help was needed, because the husband was not pleased. Instead, he was hotly embarrassed, and indignant at his wife for embarrassing him.
7
+
8
+ You looked at him and you saw this and you thought, “Oh, now, don’t be like that!” But he was like that, and as soon as the little cake had been deposited on the table, and the orchestra had finished the birthday piece, and the general attention had shifted from the man and the woman, I saw him say something to her under his breath—some punishing thing, quick and curt and unkind. I couldn’t bear to look at the woman then, so I stared at my plate and waited for quite a long time. Not long enough, though. She was still crying when I finally glanced over there again. Crying quietly and heartbrokenly and hopelessly, all to herself, under the gay big brim of her best hat.
9
+
10
+ 2.The Flowers
11
+ It seemed to Myop as she skipped lightly from hen house to pigpen to smokehouse that the days had never been as beautiful as these. The air held a keenness that made her nose twitch. The harvesting of the corn and cotton, peanuts and squash, made each day a golden surprise that caused excited little tremors to run up her jaws.
12
+
13
+ Myop carried a short, knobby stick. She struck out at random at chickens she liked, and worked out the beat of a song on the fence around the pigpen. She felt light and good in the warm sun. She was ten, and nothing existed for her but her song, the stick clutched in her dark brown hand, and the tat‐de‐ta‐ta‐ta of accompaniment,
14
+
15
+ Turning her back on the rusty boards of her family's sharecropper cabin, Myop walked along the fence till it ran into the stream made by the spring. Around the spring, where the family got drinking water, silver ferns and wildflowers grew. Along the shallow banks pigs rooted. Myop watched the tiny white bubbles disrupt the thin black scale of soil and the water that silently rose and slid away down the stream.
16
+
17
+ She had explored the woods behind the house many times. Often, in late autumn, her mother took her to gather nuts among the fallen leaves. Today she made her own path, bouncing this way and that way, vaguely keeping an eye out for snakes. She found, in addition to various common but pretty ferns and leaves, an armful of strange blue flowers with velvety ridges and a sweet suds bush full of the brown, fragrant buds.
18
+
19
+ By twelve o'clock, her arms laden with sprigs of her findings, she was a mile or more from home. She had often been as far before, but the strangeness of the land made it not as pleasant as her usual haunts. It seemed gloomy in the little cove in which she found herself. The air was damp, the silence close and deep.
20
+
21
+ Myop began to circle back to the house, back to the peacefulness of the morning. It was then she stepped smack into his eyes. Her heel became lodged in the broken ridge between brow and nose, and she reached down quickly, unafraid, to free herself. It was only when she saw his naked grin that she gave a little yelp of surprise.
22
+
23
+ He had been a tall man. From feet to neck covered a long space. His head lay beside him. When she pushed back the leaves and layers of earth and debris Myop saw that he'd had large white teeth, all of them cracked or broken, long fingers, and very big bones. All his clothes had rotted away except some threads of blue denim from his overalls. The buckles of the overall had turned green.
24
+
25
+ Myop gazed around the spot with interest. Very near where she'd stepped into the head was a wild pink rose. As she picked it to add to her bundle she noticed a raised mound, a ring, around the rose's root. It was the rotted remains of a noose, a bit of shredding plowline, now blending benignly into the soil. Around an overhanging limb of a great spreading oak clung another piece. Frayed, rotted, bleached, and frazzled‐‐barely there‐‐but spinning restlessly in the breeze. Myop laid down her flowers.
26
+
27
+ And the summer was over.
28
+
29
+ 3.The Story of An Hour
30
+ Knowing that Mrs. Mallard was afflicted with a heart trouble, great care was taken to break to her as gently as possible the news of her husband's death.
31
+
32
+ It was her sister Josephine who told her, in broken sentences; veiled hints that revealed in half concealing. Her husband's friend Richards was there, too, near her. It was he who had been in the newspaper office when intelligence of the railroad disaster was received, with Brently Mallard's name leading the list of "killed." He had only taken the time to assure himself of its truth by a second telegram, and had hastened to forestall any less careful, less tender friend in bearing the sad message.
33
+
34
+ She did not hear the story as many women have heard the same, with a paralyzed inability to accept its significance. She wept at once, with sudden, wild abandonment, in her sister's arms. When the storm of grief had spent itself she went away to her room alone. She would have no one follow her.
35
+
36
+ There stood, facing the open window, a comfortable, roomy armchair. Into this she sank, pressed down by a physical exhaustion that haunted her body and seemed to reach into her soul.
37
+
38
+ She could see in the open square before her house the tops of trees that were all aquiver with the new spring life. The delicious breath of rain was in the air. In the street below a peddler was crying his wares. The notes of a distant song which some one was singing reached her faintly, and countless sparrows were twittering in the eaves.
39
+
40
+ There were patches of blue sky showing here and there through the clouds that had met and piled one above the other in the west facing her window.
41
+
42
+ She sat with her head thrown back upon the cushion of the chair, quite motionless, except when a sob came up into her throat and shook her, as a child who has cried itself to sleep continues to sob in its dreams.
43
+
44
+ She was young, with a fair, calm face, whose lines bespoke repression and even a certain strength. But now there was a dull stare in her eyes, whose gaze was fixed away off yonder on one of those patches of blue sky. It was not a glance of reflection, but rather indicated a suspension of intelligent thought.
45
+
46
+ There was something coming to her and she was waiting for it, fearfully. What was it? She did not know; it was too subtle and elusive to name. But she felt it, creeping out of the sky, reaching toward her through the sounds, the scents, the color that filled the air.
47
+
48
+ Now her bosom rose and fell tumultuously. She was beginning to recognize this thing that was approaching to possess her, and she was striving to beat it back with her will--as powerless as her two white slender hands would have been. When she abandoned herself a little whispered word escaped her slightly parted lips. She said it over and over under hte breath: "free, free, free!" The vacant stare and the look of terror that had followed it went from her eyes. They stayed keen and bright. Her pulses beat fast, and the coursing blood warmed and relaxed every inch of her body.
49
+
50
+ She did not stop to ask if it were or were not a monstrous joy that held her. A clear and exalted perception enabled her to dismiss the suggestion as trivial. She knew that she would weep again when she saw the kind, tender hands folded in death; the face that had never looked save with love upon her, fixed and gray and dead. But she saw beyond that bitter moment a long procession of years to come that would belong to her absolutely. And she opened and spread her arms out to them in welcome.
51
+
52
+ There would be no one to live for during those coming years; she would live for herself. There would be no powerful will bending hers in that blind persistence with which men and women believe they have a right to impose a private will upon a fellow-creature. A kind intention or a cruel intention made the act seem no less a crime as she looked upon it in that brief moment of illumination.
53
+
54
+ And yet she had loved him--sometimes. Often she had not. What did it matter! What could love, the unsolved mystery, count for in the face of this possession of self-assertion which she suddenly recognized as the strongest impulse of her being!
55
+
56
+ "Free! Body and soul free!" she kept whispering.
57
+
58
+ Josephine was kneeling before the closed door with her lips to the keyhold, imploring for admission. "Louise, open the door! I beg; open the door--you will make yourself ill. What are you doing, Louise? For heaven's sake open the door."
59
+
60
+ "Go away. I am not making myself ill." No; she was drinking in a very elixir of life through that open window.
61
+
62
+ Her fancy was running riot along those days ahead of her. Spring days, and summer days, and all sorts of days that would be her own. She breathed a quick prayer that life might be long. It was only yesterday she had thought with a shudder that life might be long.
63
+
64
+ She arose at length and opened the door to her sister's importunities. There was a feverish triumph in her eyes, and she carried herself unwittingly like a goddess of Victory. She clasped her sister's waist, and together they descended the stairs. Richards stood waiting for them at the bottom.
65
+
66
+ Some one was opening the front door with a latchkey. It was Brently Mallard who entered, a little travel-stained, composedly carrying his grip-sack and umbrella. He had been far from the scene of the accident, and did not even know there had been one. He stood amazed at Josephine's piercing cry; at Richards' quick motion to screen him from the view of his wife.
67
+
68
+ When the doctors came they said she had died of heart disease--of the joy that kills.
69
+
70
+ 4.Entropy
71
+ I need to make myself smaller. I need to not take up so much room. I suck the oxygen out of the house, this family. I’m busy shrinking myself when she comes into the only room in the house with empty hinges.
72
+
73
+ Mom has those eyes, and I know she’s about to say again (and again, and again) “Did you take your meds?” Yes. It’s always yes. I swallow the pills every morning, round like a buoy. I do what I’m supposed to do even though nothing keeps me afloat.
74
+
75
+ Those eyes walk away, but they’ve rent my skin, and I seep, the blood rising. I try to unfurl my wings to fly away because the window still works, but my wings are sticky, and I can’t rise. A single feather falls. More will follow unless I’m very still, so I fold in on myself and try not to look up.
76
+
77
+ I need to make myself smaller. I need to not take up so much room. There’s not enough space, enough air for me in this house, in this family. Mom walks through the doorway to the open portal to where I live, the only room without a door.
78
+
79
+ Her eyes swallow me, and she digests me at a glance; I’m getting better at being small.
80
+
81
+ “Did you take your meds?” she asks. I nod because I need to take away the sadness, a darkness over the hope and the love. If I’m smaller, I won’t cast a shadow.
82
+
83
+ Besides, it’s always yes. I swallow the pills every morning, but I’m still the heaviest thing in the house, in the world. I will sink us all, and Mom’s eyes say she knows that, but she will always reach out her hand and let me drown her.
84
+
85
+ Mom’s eyes walk away, and I look at my window. I will be able to fly away, far, far, far, and Mom’s eyes won’t see me. I imagine I have wings, but I’m not a bird. I’m an anchor. My only view is the bottom, and I will sink down, down, down.
86
+
87
+ I need to make myself smaller. I need to not take up so much room. I am a vacuum that takes every breath meant for others. Mom pauses where my door used to be.
88
+
89
+ They all stop when they pass, but Mom is the one whose eyes hurt. She asks me in the only language we now speak, “Did you take your meds?”
90
+
91
+ Yes. It’s always yes. The pills are round like a seashell, but I can’t hear my own voice no matter what I press my ear to.
92
+
93
+ Mom walks away, and I’m tired. So, so tired. I think of sun. The beach. A single gull that circles the sky. I want to find that child who collected shells, holding them out to her mother who put them in a bucket like treasure. It’s too far away to see clearly, but I keep looking out the window.
94
+
95
+ 5.And No More Shall We Part
96
+ Not in our home, Joe and Katherine agreed, but there’d been some debate about accommodations. Joe wanted luxury while Katherine argued any old rattrap would do. Eventually they compromised – they’d long ago perfected the art – on a deluxe room in mid-priced chain halfway between the city and the airport.
97
+
98
+ They checked into their room at two and hung the Do Not Disturb sign on the knob before locking the door behind them. Katherine opened the window and tossed out their plastic key card.
99
+
100
+ “Gimme your phone.”
101
+
102
+ Joe nodded. “Hadn’t thought of that.”
103
+
104
+ Out went both phones, cracked dead rectangles now on the sidewalk below.
105
+
106
+ “What about the room phone?”
107
+
108
+ “We might want room service.”
109
+
110
+ They chuckled at the idea, faces hot with tenderness for one another.
111
+
112
+ Joe disconnected the phone line then settled onto the bed nearer the window. Katherine glanced at its twin, but her eyes stung at the thought of lying too far from her husband. When she turned back to him, he smiled and patted the spot beside him. Katherine climbed in, snuggling into the soft corduroy of his favorite jacket.
113
+
114
+ “How do you feel?” he whispered.
115
+
116
+ “Happy.”
117
+
118
+ Joe flipped channels on the TV until he found a sitcom rerun. They’d missed the first ten minutes, but Katherine had seen it before. When the episode was over, another started up. Halfway through, Katherine’s hands began to tremble. A heat was building deep in her belly, and then it rose like mercury in a thermometer up the back of her throat.
119
+
120
+ “It’s here.”
121
+
122
+ She leapt from the bed and raced into the bathroom. She retched four times into the toilet bowl, until she was emptied out, then fell back against the cool tile.
123
+
124
+ Joe looked on from the doorway, his body filling the frame almost completely. So sturdy, Joe. Those broad shoulders. She remembered nibbling the skin on his left shoulder after they’d made love for the first time, raking her little fingers through the cloud of hair on his chest. She’d laughed that night at the contrast of their bodies, delighted that two specimens of the same species could look so different from one another.
125
+
126
+ “Feel better?”
127
+
128
+ “If only.”
129
+
130
+ “It starts quicker in women. Ends quicker for men, though.”
131
+
132
+ “Don’t,” said Katherine.
133
+
134
+ “It’s okay. It’s true. And you won’t be far behind.”
135
+
136
+ Joe stepped into the room and flushed away her mess. His big hands took hold of her beneath the shoulders, guiding her to her feet.
137
+
138
+ It went on like that until around midnight. At the end, Katherine felt so much lighter, nothing left to heave up but acrid air.
139
+
140
+ “I think I have a fever,” she said with mild surprise.
141
+
142
+ It came for Joe soon after. He didn’t bother with the toilet, spilled his guts into the room’s little trash can instead.
143
+ “Sleep,” he urged Katherine when the first wave had passed.
144
+
145
+ “I should look after you,” she protested, but her body gave her no choice.
146
+
147
+ She woke to sunlight and stiff joints, a nest of her own black hair on the pillow case. When she ran a hand along her scalp, more strands slip free. Beside her, Joe slept, one arm encircling the trash can half-filled with his vomit. Vicious little lesions – bright red, seeping – speckled his chest and jawline. Katherine’s fingers skimmed along her own skin and found the same raw marks on the back of her arms. She gave one a curious prod and hissed. At the sound, Joe stirred but didn’t wake. Katherine gathered her hair from the pillow, braided it into a wreath and laid it over her husband’s chest, a talisman to ward off further harm.
148
+
149
+ That evening, they discovered they could pluck their fingernails loose, easy as flower petals. They arranged them into a garden on the bathroom counter, and within a few hours they’d encircled the garden with a fence built from their broken teeth. Blood dribbled from their mouths as they reminisced about the tulips they’d seen on a trip to Holland years before. Their words were gummy and would’ve been unintelligible to anyone else. They talked until their hearing went then made their eyes say the words instead. Ready, said Joe’s eyes, and Katherine’s answered, Wait. They repeated the words until shapes began to blur and the light in the room grew dim then, blind, dragged themselves back to bed.
150
+
151
+ There was no way for Katherine to know what time it was when the pain in her ankles woke her. The tendons there had snapped like two guitar strings. A scream clawed its way out of her, shaking the bed with its force. Behind her, Joe quickened, but whether it was her pain or some pain all his own that startled him, Katherine couldn’t know. He buried his face into her neck and kissed her over and over, spilling hot tears into what was left of her hair.
152
+
153
+ After that, Katherine didn’t sleep again. She pinched Joe’s arm once every few minutes, waited for him to pinch back. She did this until he stopped pinching.
154
+
155
+ It took Katherine half an hour to strip away their clothes, another hour still to roll Joe into the bathroom and lay him in the tub. He’d been breathing shallowly when she’d begun. By the time she flung herself over the rim, her fall broken by his soft body, he’d stopped breathing altogether.
156
+
157
+ Her foot inched up the wall, and she toed the faucet handle until the showerhead emitted its lukewarm spray. Water streamed over her face, her belly. It trickled between her legs. Eventually it sought the spaces where her skin met Joe’s, filled those spaces then dissolved them, melding their bodies together until there was no Katherine, no Joe, only one silent mass of bone and flesh and, minutes later, only white bone. In time, the bones dissolved, too, and the whole mess was carried down the drain in a neat little stream, and the water ran clear again.
158
+
159
+ 6.Popular Mechanics
160
+ Early that day the weather turned, and the snow was melting into dirty water. Streaks of it ran down from the little shoulder-high window that faced the backyard. Cars slushed by on the street outside, where it was getting dark. But it was getting dark on the inside too. He was in the bedroom pushing clothes into a suitcase when she came to the door. I’m glad you’re leaving! I’m glad you’re leaving! She said. Do you hear? He kept on putting his things into the suitcase.
161
+
162
+ Son of a bitch! I’m so glad you’re leaving! She began to cry. You can’t even look me in the face, can you? Then she noticed the baby’s picture on the bed and picked it up.
163
+
164
+ He looked at her, and she wiped her eyes and stared at him before turning and going back to the living room.
165
+
166
+ Bring that back, he said. Just get your things and get out, she said. He did not answer. He fastened the suitcase, put on his coat, looked around the bedroom before turning off the light. Then he went out to the living room. She stood in the doorway of the little kitchen, holding the baby.
167
+
168
+ I want the baby, he said. Are you crazy? No, but I want the baby. I’ll get someone to come by for his things. The baby had begun to cry, and she uncovered the blanket from around his head. Oh, oh, she said, looking at the baby.
169
+
170
+ He moved toward her. For God’s sake! she said. She took a step back into the kitchen. I want the baby.
171
+ Get out of here!She turned and tried to hold the baby over in a corner behind the stove. But he came up. He reached across the stove and tightened his hands on the baby. Let go of him, he said.
172
+ Get away, get away! she cried. The baby was red-faced and screaming. In the scuffle, they knocked down a flowerpot that hung behind the stove. He crowded her into the wall then, trying to break her grip. He held on to the baby and pushed with all his weight.
173
+
174
+ Let go of him, he said. Don’t, she said. You’re hurting the baby, she said.
175
+ I’m not hurting the baby, he said. The kitchen window gave no light. In the near-dark he worked on her fisted fingers with one hand and with the other hand he gripped the screaming baby up under an arm near the shoulder. She felt her fingers being forced open. She felt the baby going from her.
176
+
177
+ No! she screamed just as her hands came loose.
178
+ She would have it, this baby. She grabbed for the baby’s other arm. She caught the baby around the wrist and leaned back. But he would not let go. He felt the baby slipping out of his hands and he pulled back very hard.
179
+
180
+ In this manner, the issue was decided.
181
+
182
+ 7.Girl
183
+ Wash the white clothes on Monday and put them on the stone heap; wash the color clothes on Tuesday and put them on the clothesline to dry; don’t walk bare-head in the hot sun; cook pumpkin fritters in very hot sweet oil; soak your little cloths right after you take them off; when buying cotton to make yourself a nice blouse, be sure that it doesn’t have gum in it, because that way it won’t hold up well after a wash; soak salt fish overnight before you cook it; is it true that you sing benna in Sunday school?; always eat your food in such a way that it won’t turn someone else’s stomach; on Sundays try to walk like a lady and not like the slut you are so bent on becoming; don’t sing benna in Sunday school; you mustn’t speak to wharf-rat boys, not even to give directions; don’t eat fruits on the street—flies will follow you; but I don’t sing benna on Sundays at all and never in Sunday school; this is how to sew on a button; this is how to make a buttonhole for the button you have just sewed on; this is how to hem a dress when you see the hem coming down and so to prevent yourself from looking like the slut I know you are so bent on becoming; this is how you iron your father’s khaki shirt so that it doesn’t have a crease; this is how you iron your father’s khaki pants so that they don’t have a crease; this is how you grow okra—far from the house, because okra tree harbors red ants; when you are growing dasheen, make sure it gets plenty of water or else it makes your throat itch when you are eating it; this is how you sweep a corner; this is how you sweep a whole house; this is how you sweep a yard; this is how you smile to someone you don’t like too much; this is how you smile to someone you don’t like at all; this is how you smile to someone you like completely; this is how you set a table for tea; this is how you set a table for dinner; this is how you set a table for dinner with an important guest; this is how you set a table for lunch; this is how you set a table for breakfast; this is how to behave in the presence of men who don’t know you very well, and this way they won’t recognize immediately the slut I have warned you against becoming; be sure to wash every day, even if it is with your own spit; don’t squat down to play marbles—you are not a boy, you know; don’t pick people’s flowers—you might catch something; don’t throw stones at blackbirds, because it might not be a blackbird at all; this is how to make a bread pudding; this is how to make doukona; this is how to make pepper pot; this is how to make a good medicine for a cold; this is how to make a good medicine to throw away a child before it even becomes a child; this is how to catch a fish; this is how to throw back a fish you don’t like, and that way something bad won’t fall on you; this is how to bully a man; this is how a man bullies you; this is how to love a man, and if this doesn’t work there are other ways, and if they don’t work don’t feel too bad about giving up; this is how to spit up in the air if you feel like it, and this is how to move quick so that it doesn’t fall on you; this is how to make ends meet; always squeeze bread to make sure it’s fresh; but what if the baker won’t let me feel the bread?; you mean to say that after all you are really going to be the kind of woman who the baker won’t let near the bread?
184
+
185
+ 8.The Cranes
186
+ Oh!'' she said, ''What are those, the huge white ones?'' Along the marshy shore two tall and stately birds, staring motionless toward the Gulf, towered above the bobbing egrets and scurrying plovers.
187
+
188
+ ''Well, I can't believe it,'' he said. ''I've been coming here for years and never saw one. . . . ''
189
+
190
+ “But what are they?” she persisted. “Don’t make me guess or anything, it makes me feel dumb.” They leaned forward in the car and the shower curtain spread over the front seat crackled and hissed.
191
+
192
+ “They’ve got to be whooping cranes, nothing else so big!” One of the birds turned gracefully, as if to acknowledge the old Dodge parked alone in the tall grasses. “See the black legs and black wingtips? Big! Why don’t I have my binoculars?” He looked at his wife and smiled.
193
+
194
+ “Well,” he continued after a while, “I’ve seen enough birds. But whooping cranes, they’re rare. Not many left.”
195
+
196
+ “They’re lovely. They make the little birds look like clowns.”
197
+
198
+ “I could use a few dozen,” he said. “A few laughs never hurt anybody.”
199
+
200
+ “Are you all right?” She put a hand on his thin arm. “Maybe this is the wrong thing. I feel I’m responsible.”
201
+
202
+ “God, no!” His voice changed. “No way. I can’t smoke, can’t drink martinis, no coffee, no candy. I not only can’t leap buildings in a single bound, I can hardly get up the goddamn stairs.”
203
+
204
+ She was smiling. “Do you remember the time you drank 13 martinis and asked that young priest to step outside and see whose side God was on?”
205
+
206
+ “What a jerk I was! How have you put up with me all this time?”
207
+
208
+ “Oh, no! I was proud of you! You were so funny, and that priest was a snot.”
209
+
210
+ “Now you tell me.” The cranes were moving slowly over a small hillock, wings opening and closing like bellows. “It’s all right. It’s enough,” he said again. “How old am I anyway, 130?”
211
+
212
+ “Really,” she said. “It’s me. Ever since the accident it’s been one thing after another. I’m just a lot of trouble to everybody.”
213
+
214
+ “Let’s talk about something else,” he said. “Do you want to listen to the radio? How about turning on that preacher station so we can throw up?”
215
+
216
+ “No,” she said, “I just want to watch the birds. And listen to you.”
217
+
218
+ “You must be pretty tired of that.”
219
+
220
+ She turned her head from the window and looked into his eyes. “I never got tired of listening to you. Never.”
221
+
222
+ “Well, that’s good,” he said. “It’s just that when my mouth opens, your eyes tend to close.”
223
+
224
+ “They do not!” she said, and began to laugh, but the laugh turned into a cough and he had to pat her back until she stopped. They leaned back in the silence and looked toward the Gulf stretching out beyond the horizon. In the distance, the water looked like metal, still and hard.
225
+
226
+ “I wish they’d court,” he said. “I wish we could see them court, the cranes. They put on a show. He bows like Nijinsky and jumps straight up in the air.”
227
+
228
+ “What does she do?”
229
+
230
+ “She lies down and he lands on her.”
231
+
232
+ “No,” she said, “I’m serious.”
233
+
234
+ “Well, I forget. I’ve never seen it. But I do remember that they mate for life and live a long time. They’re probably older than we are! Their feathers are falling out and their kids never write.”
235
+
236
+ She was quiet again. He turned in his seat, picked up an object wrapped in a plaid towel, and placed it between them in the front.
237
+
238
+ “Here’s looking at you, kid,” he said.
239
+
240
+ “Do they really mate for life? I’m glad — they’re so beautiful.”
241
+
242
+ “Yep. Audubon said that’s why they’re almost extinct: a failure of imagination.”
243
+
244
+ “I don’t believe that,” she said. “I think there’ll always be whooping cranes.”
245
+
246
+ “Why not?” he said.
247
+
248
+ “I wish the children were more settled. I keep thinking it’s my fault.”
249
+
250
+ “You think everything’s your fault. Nicaragua. Ozone depletion. Nothing is your fault. They’ll be fine, and anyway, they’re not children anymore. Kids are different today, that’s all. You were terrific.” He paused. “You were terrific in ways I couldn’t tell the kids about.”
251
+
252
+ “I should hope not.” She laughed and began coughing again, but held his hand when he reached over. When the cough subsided they sat quietly, looking down at their hands as if they were objects in a museum.
253
+
254
+ “I used to have pretty hands,” she said.
255
+
256
+ “I remember.”
257
+
258
+ “Do you? Really?”
259
+
260
+ “I remember everything,” he said.
261
+
262
+ “You always forgot everything.”
263
+
264
+ “Well, now I remember.”
265
+
266
+ “Did you bring something for your ears?”
267
+
268
+ “No, I can hardly hear anything anyway!” But his head turned at a sudden squabble among the smaller birds. The cranes were stepping delicately away from the commotion.
269
+
270
+ “I’m tired,” she said.
271
+
272
+ “Yes.” He leaned over and kissed her, barely touching her lips. “Tell me,” he said, “did I really drink 13 martinis?”
273
+
274
+ But she had already closed her eyes and only smiled. Outside the wind ruffled the bleached-out grasses, and the birds in the white glare seemed almost transparent. The hull of the car gleamed beetle-like — dull and somehow sinister in its metallic isolation from the world around it.
275
+
276
+ At the shot, the two cranes plunged upward, their great wings beating the air and their long slender necks pointed like arrows toward the sun.
277
+
278
+ 9.The Pie
279
+ I knew enough about hell to stop me from stealing. I was holy in almost every bone. Some days I recognized the shadows of angels flopping on the backyard grass, and other days I heard faraway messages in the plumbing that howled beneath the house when I crawled there looking for something to do.
280
+
281
+ But boredom made me sin. Once, at the German Market, I stood before a rack of pies, my sweet tooth gleaming and the juice of guilt wetting my underarms. I gazed at the nine kinds of pie, pecan and apple being my favorites, although cherry looked good, and my dear, fat-faced chocolate was always a good bet. I nearly wept trying to decide which to steal and, forgetting the flowery dust priests give off, the shadow of angels and the proximity of God howling in the plumbing underneath the house, sneaked a pie behind my coffee-lid Frisbee and walked to the door, grinning to the bald grocer whose forehead shone with a window of light.
282
+
283
+ "No one saw," I muttered to myself, the pie like a discus in my hand, and hurried across the street where I sat on someone's lawn. The sun wavered between the branches of a yellowish
284
+ sycamore. A squirrel nailed itself high on the trunk, where it forked into two large bark-scabbed limbs. Just as I was going to work my cleanest finger into the pie, a neighbor came out to the porch for his mail. He looked at me, and I got up and headed for home. I raced on skinny legs to my block, but slowed to a quick walk when I couldn't wait any longer. I held the pie to my nose and breathed in its sweetness. I licked some of the crust and closed my eyes as I took a small bite.
285
+
286
+ In my front yard, I leaned against a car fender and panicked about stealing the apple pie. I knew an apple got Eve in deep trouble with snakes because Sister Marie had shown us a film about Adam and Eve being cast into the desert, and what scared me more than falling from grace was being thirsty for the rest of my life. But even that didn't
287
+ stop me from clawing a chunk from the pie tin and pushing it into the cavern of my mouth. The slop was sweet and gold-colored in the afternoon sun. I laid more pieces on my tongue, wet finger-dripping pieces, until I was finished and felt like crying because it was about the best thing I had ever tasted. I realized right there and then, in my sixth year, in my tiny body of two hundred bones and three or four sins, that the best things in life came stolen. I wiped my sticky fingers on the grass and rolled my tongue over the corners of my mouth. A burp perfumed the air.
288
+
289
+ I felt bad not sharing with Cross-Eyed Johnny, a neighbor kid. He stood over my shoulder and asked, "Can I have some?" Crust fell from my mouth, and my teeth were bathed with the jam-like filling. Tears blurred my eyes as I remembered the grocer's forehead. I remembered the other pies on the rack, the warm air of the fan above the door and the car that honked as I crossed the street without looking.
290
+
291
+ "Get away," I had answered Cross-Eyed Johnny. He watched my fingers greedily push big chunks of pie down my throat. He swallowed and said in a whisper, "Your hands are dirty," then
292
+ returned home to climb his roof and sit watching me eat the pie by myself. After a while, he jumped off and hobbled away because the fall had hurt him.
293
+
294
+ I sat on the curb. The pie tin glared at me and rolled away when the wind picked up. My face was sticky with guilt. A car honked, and the driver knew. Mrs. Hancock stood on her lawn, hands on hip, and she knew. My mom, peeling a mountain of potatoes at the Redi-Spud factory, knew. I got to my feet, stomach taut, mouth tired of chewing, and flung my Frisbee across the street, its shadow like the shadow of an angel fleeing bad deeds. I retrieved it, jogging slowly. I flung it again until was bored and thirsty
295
+
296
+ I returned home to drink water and help my sister glue bottle caps onto cardboard, a project for summer school. But the bottle caps bored me, and the water soon filled me up more than the pie. With the kitchen stifling with heat and lunatic flies, I decided to crawl underneath out house and lie in the cool shadows listening to the howling sound of plumbing. Was it God? Was it Father, speaking from death, or Uncle with his last shiny dime? I listened, ear pressed to a cold pipe, and heard a howl like the sea. I lay until I was cold and the crawled back to the light, rising from one knee, then another, to dust off my pants and squint in the harsh light. I looked and saw the glare of a pie tin on a hot day. I knew sin was what you took and didn't give back.
297
+
298
+
299
+
300
+
301
+
302
+
303
+
304
+
305
+
306
+