Spaces:
Running
Running
Create app.py
Browse filesCreate app.py file
app.py
ADDED
@@ -0,0 +1,141 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import gradio as gr
|
2 |
+
from gradio_folium import Folium
|
3 |
+
from folium import Map
|
4 |
+
import pandas as pd
|
5 |
+
import folium
|
6 |
+
from huggingface_hub import InferenceClient
|
7 |
+
from ast import literal_eval
|
8 |
+
|
9 |
+
repo_id = "mistralai/Mixtral-8x7B-Instruct-v0.1"
|
10 |
+
llm_client = InferenceClient(model=repo_id, timeout=180)
|
11 |
+
|
12 |
+
description_sf = "A one-day walk through San Francisco for my first visit. I want to take no cab or bike, everything should be on foot."
|
13 |
+
output_example_sf = """
|
14 |
+
Since this is on foot, walking distances should be kept to a minimum. I'll make sure to provide a step by step visit and reorder points of interest to minimize the walking distance between each point.
|
15 |
+
I want to start at Fisherman's Wharf, then head to Ghirardelli Square, followed by the Cable Car Museum, Union Square, Chinatown, and finally Coit Tower, to provide a full day of sightseeing, with a mix of history, culture, and beautiful views.
|
16 |
+
|
17 |
+
Key points: [
|
18 |
+
{"name": "Fisherman's Wharf", "lat": 37.8081, "lon": -122.4082, "description": "Fisherman's Wharf is a popular tourist destination in San Francisco, featuring Pier 39, the Maritime National Historical Park, and Boudin Bakery. It's a great place to start your day with breakfast and enjoy the sea lions."},
|
19 |
+
{"name": "Ghirardelli Square", "lat": 37.8094, "lon": -122.4154, "description": "Ghirardelli Square is a historic square in San Francisco, known for its chocolate shop and various boutiques. It's a great place to grab a sweet treat and do some shopping."},
|
20 |
+
{"name": "Cable Car Museum", "lat": 37.7931, "lon": -122.4058, "description": "The Cable Car Museum is a museum in San Francisco that showcases the history of the city's iconic cable cars. It's a great place to learn about the technology and history behind these unique vehicles."},
|
21 |
+
{"name": "Union Square", "lat": 37.7873, "lon": -122.4062, "description": "Union Square is a public plaza in San Francisco, known for its shopping, dining, and entertainment options. It's a great place to relax, grab a bite to eat, and do some shopping."},
|
22 |
+
{"name": "Chinatown", "lat": 37.7937, "lon": -122.4081, "description": "Chinatown is a vibrant neighborhood in San Francisco, known for its Chinese culture, history, and cuisine. It's a great place to explore the streets, try some delicious food, and learn about Chinese culture."},
|
23 |
+
{"name": "Coit Tower", "lat": 37.8024, "lon": -122.4058, "description": "Coit Tower is a historic tower in San Francisco, known for its panoramic views of the city. It's a great place to end your day, taking in the sights and sounds of the city from above."}
|
24 |
+
]
|
25 |
+
"""
|
26 |
+
|
27 |
+
description_loire = "A 3-day bike trip through the Loire Valley."
|
28 |
+
output_example_loire = """
|
29 |
+
To make the most of the trip, we will bike between the châteaux to enjoy the beautiful scenery and explore the Loire Valley at a leisurely pace. Here is a suggested itinerary for a 3-day bike trip through the Loire Valley:
|
30 |
+
1. Start at Château de Cheverny, a smaller but equally charming château with beautiful gardens.
|
31 |
+
2. Bike to Château de Chambord, the largest and most recognizable château in the Loire Valley.
|
32 |
+
3. Continue to Château de Blois, a historic château with a rich history.
|
33 |
+
4. End the day at Château de Chaumont-sur-Loire, a château with a stunning view of the Loire River.
|
34 |
+
5. On the second day, bike to Château de Chenonceau, a stunning château built over the River Cher.
|
35 |
+
6. Continue to Château d'Amboise, a historic château with ties to the French Renaissance.
|
36 |
+
7. End the day at Château d'Azay-le-Rideau, a charming château with a moat.
|
37 |
+
8. On the third day, bike to Château d'Ussé, a fairy-tale like château said to have inspired Sleeping Beauty.
|
38 |
+
9. End the trip at Château de Villandry, known for its beautiful gardens.
|
39 |
+
|
40 |
+
Key points: [
|
41 |
+
{"name": "Château de Cheverny", "lat": 47.6333, "lon": 1.5667, "description": "Château de Cheverny is a smaller but equally charming château with beautiful gardens, known for its French classical architecture and rich history."},
|
42 |
+
{"name": "Château de Chambord", "lat": 47.6111, "lon": 1.5167, "description": "Château de Chambord is the largest and most recognizable château in the Loire Valley, known for its French Renaissance architecture and beautiful gardens."},
|
43 |
+
{"name": "Château de Blois", "lat": 47.5833, "lon": 1.3333, "description": "Château de Blois is a historic château with a rich history, known for its stunning architecture and beautiful gardens."},
|
44 |
+
{"name": "Château de Chaumont-sur-Loire", "lat": 47.5167, "lon": 1.3167, "description": "Château de Chaumont-sur-Loire is a château with a stunning view of the Loire River, known for its beautiful gardens and rich history."},
|
45 |
+
{"name": "Château de Chenonceau", "lat": 47.3917, "lon": 1.3667, "description": "Château de Chenonceau is a stunning château built over the River Cher, known for its beautiful gardens and rich history."},
|
46 |
+
{"name": "Château d'Amboise", "lat": 47.4167, "lon": 1.0500, "description": "Château d'Amboise is a historic château with ties to the French Renaissance, known for its beautiful gardens and stunning views of the Loire Valley."},
|
47 |
+
{"name": "Château d'Azay-le-Rideau", "lat": 47.3333, "lon": 0.6167, "description": "Château d'Azay-le-Rideau is a charming château with a moat, known for its French Renaissance architecture and beautiful gardens."},
|
48 |
+
{"name": "Château d'Ussé", "lat": 47.2667, "lon": 0.5167, "description": "Château d'Ussé is a fairy-tale like château said to have inspired Sleeping Beauty, known for its beautiful gardens and stunning views of the Indre Valley."},
|
49 |
+
{"name": "Château de Villandry", "lat": 47.1667, "lon": 0.4167, "description": "Château de Villandry is known for its beautiful gardens, featuring a water garden, ornamental flower gardens, and vegetable gardens."}
|
50 |
+
]
|
51 |
+
"""
|
52 |
+
|
53 |
+
|
54 |
+
def generate_key_points(text):
|
55 |
+
prompt = f"""
|
56 |
+
Please generate a set of key geographical points for the following description: {text}, as a json list of less than 10 dictionnaries with the following keys: 'name', 'lat', 'lon', 'description'.
|
57 |
+
Generally try to minimze the distance between locations.
|
58 |
+
|
59 |
+
For instance:
|
60 |
+
Description: {description_sf}
|
61 |
+
Thought: {output_example_sf}
|
62 |
+
|
63 |
+
Description: {description_loire}
|
64 |
+
Thought: {output_example_loire}
|
65 |
+
|
66 |
+
Now begin. You can make the descriptions a bit more verbose than in the examples.
|
67 |
+
|
68 |
+
Description: {text}
|
69 |
+
Thought:
|
70 |
+
"""
|
71 |
+
return llm_client.text_generation(prompt, max_new_tokens=2000)
|
72 |
+
|
73 |
+
|
74 |
+
def parse_llm_output(output):
|
75 |
+
rationale = "Thought: " + output.split("Key points:")[0]
|
76 |
+
key_points = output.split("Key points:")[1]
|
77 |
+
output = key_points.replace(" ", "")
|
78 |
+
parsed_output = literal_eval(output)
|
79 |
+
dataframe = pd.DataFrame.from_dict(parsed_output)
|
80 |
+
return dataframe, rationale
|
81 |
+
|
82 |
+
|
83 |
+
def create_map_from_markers(dataframe):
|
84 |
+
f_map = Map(
|
85 |
+
location=[dataframe["lat"].mean(), dataframe["lon"].mean()],
|
86 |
+
zoom_start=5,
|
87 |
+
tiles="CartoDB Voyager",
|
88 |
+
)
|
89 |
+
|
90 |
+
|
91 |
+
dataframe.apply(
|
92 |
+
lambda row: folium.CircleMarker(
|
93 |
+
location=[row["lat"], row["lon"]],
|
94 |
+
radius=10,
|
95 |
+
popup=folium.Popup(
|
96 |
+
f"<h4>{row['name']}</h4><p>{row['description']}</p>", max_width=450
|
97 |
+
),
|
98 |
+
fill=True,
|
99 |
+
fill_color="blue",
|
100 |
+
fill_opacity=0.6,
|
101 |
+
color="blue",
|
102 |
+
weight=1,
|
103 |
+
).add_to(f_map),
|
104 |
+
axis=1,
|
105 |
+
)
|
106 |
+
|
107 |
+
bounds = [[row["lat"], row["lon"]] for _, row in dataframe.iterrows()]
|
108 |
+
f_map.fit_bounds(bounds, padding=(100, 100))
|
109 |
+
return f_map
|
110 |
+
|
111 |
+
|
112 |
+
def run_display(text):
|
113 |
+
output = generate_key_points(text)
|
114 |
+
dataframe, rationale = parse_llm_output(output)
|
115 |
+
map = create_map_from_markers(dataframe)
|
116 |
+
return map, rationale
|
117 |
+
|
118 |
+
|
119 |
+
with gr.Blocks(
|
120 |
+
theme=gr.themes.Soft(
|
121 |
+
primary_hue=gr.themes.colors.yellow,
|
122 |
+
secondary_hue=gr.themes.colors.blue,
|
123 |
+
)
|
124 |
+
) as demo:
|
125 |
+
text = gr.Textbox(
|
126 |
+
label="Trip description",
|
127 |
+
value=description_sf,
|
128 |
+
)
|
129 |
+
button = gr.Button()
|
130 |
+
gr.Markdown("### LLM Output\n_Click the map to see information about the places._")
|
131 |
+
|
132 |
+
# Get initial map and rationale
|
133 |
+
example_dataframe, example_rationale = parse_llm_output(output_example_sf)
|
134 |
+
display_rationale = gr.Markdown(example_rationale)
|
135 |
+
starting_map = create_map_from_markers(example_dataframe)
|
136 |
+
map = Folium(value=starting_map, height=600, label="Chosen locations")
|
137 |
+
|
138 |
+
button.click(run_display, inputs=[text], outputs=[map, display_rationale])
|
139 |
+
|
140 |
+
if __name__ == "__main__":
|
141 |
+
demo.launch()
|