File size: 8,567 Bytes
a477b7c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
import gradio as gr
from gradio_folium import Folium
from folium import Map
import pandas as pd
import folium
from huggingface_hub import InferenceClient
from ast import literal_eval

repo_id = "mistralai/Mixtral-8x7B-Instruct-v0.1"
llm_client = InferenceClient(model=repo_id, timeout=180)

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."
output_example_sf = """
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.
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.

Key points: [
    {"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."},
    {"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."},
    {"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."},
    {"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."},
    {"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."},
    {"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."}
]
"""

description_loire = "A 3-day bike trip through the Loire Valley."
output_example_loire = """
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:
1. Start at Château de Cheverny, a smaller but equally charming château with beautiful gardens.
2. Bike to Château de Chambord, the largest and most recognizable château in the Loire Valley.
3. Continue to Château de Blois, a historic château with a rich history.
4. End the day at Château de Chaumont-sur-Loire, a château with a stunning view of the Loire River.
5. On the second day, bike to Château de Chenonceau, a stunning château built over the River Cher.    
6. Continue to Château d'Amboise, a historic château with ties to the French Renaissance.  
7. End the day at Château d'Azay-le-Rideau, a charming château with a moat.
8. On the third day, bike to Château d'Ussé, a fairy-tale like château said to have inspired Sleeping Beauty.
9. End the trip at Château de Villandry, known for its beautiful gardens.  

Key points: [
    {"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."},
    {"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."},
    {"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."},
    {"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."},
    {"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."},
    {"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."},
    {"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."},
    {"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."},
    {"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."}
]
"""


def generate_key_points(text):
    prompt = f"""             
    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'.
    Generally try to minimze the distance between locations.

    For instance:
    Description: {description_sf}
    Thought: {output_example_sf}

    Description: {description_loire}
    Thought: {output_example_loire}

    Now begin. You can make the descriptions a bit more verbose than in the examples.

    Description: {text}
    Thought: 
    """
    return llm_client.text_generation(prompt, max_new_tokens=2000)


def parse_llm_output(output):
    rationale = "Thought: " + output.split("Key points:")[0]
    key_points = output.split("Key points:")[1]
    output = key_points.replace("    ", "")
    parsed_output = literal_eval(output)
    dataframe = pd.DataFrame.from_dict(parsed_output)
    return dataframe, rationale


def create_map_from_markers(dataframe):
    f_map = Map(
        location=[dataframe["lat"].mean(), dataframe["lon"].mean()],
        zoom_start=5,
        tiles="CartoDB Voyager",
    )


    dataframe.apply(
        lambda row: folium.CircleMarker(
            location=[row["lat"], row["lon"]],
            radius=10,
            popup=folium.Popup(
                f"<h4>{row['name']}</h4><p>{row['description']}</p>", max_width=450
            ),
            fill=True,
            fill_color="blue",
            fill_opacity=0.6,
            color="blue",
            weight=1,
        ).add_to(f_map),
        axis=1,
    )

    bounds = [[row["lat"], row["lon"]] for _, row in dataframe.iterrows()]
    f_map.fit_bounds(bounds, padding=(100, 100))
    return f_map


def run_display(text):
    output = generate_key_points(text)
    dataframe, rationale = parse_llm_output(output)
    map = create_map_from_markers(dataframe)
    return map, rationale


with gr.Blocks(
    theme=gr.themes.Soft(
        primary_hue=gr.themes.colors.yellow,
        secondary_hue=gr.themes.colors.blue,
    )
) as demo:
    text = gr.Textbox(
        label="Trip description",
        value=description_sf,
    )
    button = gr.Button()
    gr.Markdown("### LLM Output\n_Click the map to see information about the places._")

    # Get initial map and rationale
    example_dataframe, example_rationale = parse_llm_output(output_example_sf)
    display_rationale = gr.Markdown(example_rationale)
    starting_map = create_map_from_markers(example_dataframe)
    map = Folium(value=starting_map, height=600, label="Chosen locations")

    button.click(run_display, inputs=[text], outputs=[map, display_rationale])

if __name__ == "__main__":
    demo.launch()