Update app.py
Browse files
app.py
CHANGED
|
@@ -5,32 +5,42 @@ import shutil
|
|
| 5 |
|
| 6 |
# Description and Introduction texts
|
| 7 |
DESCRIPTION = """
|
| 8 |
-
|
| 9 |
"""
|
| 10 |
|
| 11 |
INTRODUCTION = """
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 18 |
"""
|
| 19 |
|
| 20 |
HOW_WE_TESTED = """
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 28 |
"""
|
| 29 |
|
| 30 |
-
# Replace 'path/to/your/csv/folder' with the actual path to your folder containing CSV files
|
| 31 |
csv_folder_path = 'result_csv/'
|
| 32 |
|
| 33 |
-
# Function to read all CSV files from a folder and rearrange columns
|
| 34 |
def read_and_process_csv_files(folder_path):
|
| 35 |
all_data = []
|
| 36 |
for filename in os.listdir(folder_path):
|
|
@@ -41,18 +51,15 @@ def read_and_process_csv_files(folder_path):
|
|
| 41 |
|
| 42 |
combined_df = pd.concat(all_data, ignore_index=True)
|
| 43 |
|
| 44 |
-
# Rearrange columns
|
| 45 |
columns_order = [
|
| 46 |
"Model_Name", "Library", "TTFT", "Tokens-per-Second", "Token_Count",
|
| 47 |
-
"
|
| 48 |
]
|
| 49 |
|
| 50 |
-
# Ensure all required columns exist, if not, create them with NaN values
|
| 51 |
for col in columns_order:
|
| 52 |
if col not in combined_df.columns:
|
| 53 |
combined_df[col] = pd.NA
|
| 54 |
|
| 55 |
-
# Select and order the columns
|
| 56 |
return combined_df[columns_order]
|
| 57 |
|
| 58 |
df = read_and_process_csv_files(csv_folder_path)
|
|
@@ -65,60 +72,120 @@ def add_new_entry(file):
|
|
| 65 |
if file is None:
|
| 66 |
return df, "No file uploaded."
|
| 67 |
|
| 68 |
-
# Read the uploaded CSV file
|
| 69 |
new_df = pd.read_csv(file.name)
|
| 70 |
|
| 71 |
-
# Rearrange columns to match the existing DataFrame
|
| 72 |
columns_order = [
|
| 73 |
"Model_Name", "Library", "TTFT", "Tokens-per-Second", "Token_Count",
|
| 74 |
-
"
|
| 75 |
]
|
| 76 |
for col in columns_order:
|
| 77 |
if col not in new_df.columns:
|
| 78 |
new_df[col] = pd.NA
|
| 79 |
new_df = new_df[columns_order]
|
| 80 |
|
| 81 |
-
# Append the new data to the existing DataFrame
|
| 82 |
df = pd.concat([df, new_df], ignore_index=True)
|
| 83 |
|
| 84 |
-
# Save the uploaded file to the CSV folder
|
| 85 |
filename = os.path.basename(file.name)
|
| 86 |
destination = os.path.join(csv_folder_path, filename)
|
| 87 |
shutil.copy(file.name, destination)
|
| 88 |
|
| 89 |
return df, f"File '{filename}' uploaded and data added successfully!"
|
| 90 |
|
| 91 |
-
|
| 92 |
-
|
|
|
|
|
|
|
|
|
|
| 93 |
|
| 94 |
-
|
| 95 |
-
|
| 96 |
-
|
| 97 |
-
|
| 98 |
-
|
| 99 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 100 |
|
| 101 |
-
# Tabs for Leaderboard and Add New Entry
|
| 102 |
with gr.Tabs():
|
| 103 |
-
with gr.TabItem("Leaderboard"):
|
|
|
|
|
|
|
|
|
|
|
|
|
| 104 |
leaderboard = gr.DataFrame(df)
|
|
|
|
|
|
|
| 105 |
|
| 106 |
-
with gr.TabItem("Add New Entry"):
|
| 107 |
-
file_upload = gr.File(label="Upload CSV File")
|
| 108 |
-
submit_button = gr.Button("Add Entry")
|
| 109 |
result = gr.Markdown()
|
| 110 |
|
| 111 |
-
# How we tested section at the bottom
|
| 112 |
-
with gr.Column():
|
| 113 |
-
gr.Markdown("---")
|
| 114 |
-
gr.Markdown(HOW_WE_TESTED)
|
| 115 |
-
|
| 116 |
submit_button.click(
|
| 117 |
add_new_entry,
|
| 118 |
inputs=[file_upload],
|
| 119 |
outputs=[leaderboard, result]
|
| 120 |
)
|
| 121 |
|
|
|
|
|
|
|
|
|
|
| 122 |
demo.load(get_leaderboard_df, outputs=[leaderboard])
|
| 123 |
|
| 124 |
-
|
|
|
|
|
|
| 5 |
|
| 6 |
# Description and Introduction texts
|
| 7 |
DESCRIPTION = """
|
| 8 |
+
<h2 style='text-align: center; color: #cbff4d !important; text-shadow: 2px 2px 4px rgba(0,0,0,0.1);'>๐ LLM Inference Leaderboard: Pushing the Boundaries of Performance ๐</h2>
|
| 9 |
"""
|
| 10 |
|
| 11 |
INTRODUCTION = """
|
| 12 |
+
<div style='background-color: #e6ffd9; padding: 20px; border-radius: 15px; margin-bottom: 20px; box-shadow: 0 4px 6px rgba(0,0,0,0.1);'>
|
| 13 |
+
<h3 style='color: #00480a;'>๐ฌ Our Exciting Quest</h3>
|
| 14 |
+
<p style='color: #00480a;'>We're on a thrilling journey to help developers discover the perfect LLMs and libraries for their innovative projects! We've put these models through their paces using six cutting-edge inference engines:</p>
|
| 15 |
+
<ul style='color: #00480a;'>
|
| 16 |
+
<li>๐ vLLM</li>
|
| 17 |
+
<li>๐ TGI</li>
|
| 18 |
+
<li>โก TensorRT-LLM</li>
|
| 19 |
+
<li>๐ฎ Tritonvllm</li>
|
| 20 |
+
<li>๐ Deepspeed-mii</li>
|
| 21 |
+
<li>๐ฏ ctranslate</li>
|
| 22 |
+
</ul>
|
| 23 |
+
<p style='color: #00480a;'>All our tests were conducted on state-of-the-art A100 GPUs hosted on Azure, ensuring a fair and neutral battleground!</p>
|
| 24 |
+
<p style='color: #00480a; font-weight: bold;'>Our mission: Empower developers, researchers, and AI enthusiasts to find their perfect LLM match for both development and production environments!</p>
|
| 25 |
+
</div>
|
| 26 |
"""
|
| 27 |
|
| 28 |
HOW_WE_TESTED = """
|
| 29 |
+
<div style='background-color: #cbff4d; padding: 20px; border-radius: 15px; margin-top: 20px; box-shadow: 0 4px 6px rgba(0,0,0,0.1);'>
|
| 30 |
+
<h3 style='color: #00480a;'>๐งช Our Rigorous Testing Process</h3>
|
| 31 |
+
<p style='color: #00480a;'>We left no stone unturned in our quest for reliable benchmarks:</p>
|
| 32 |
+
<ul style='color: #00480a;'>
|
| 33 |
+
<li><strong>๐ฅ๏ธ Platform:</strong> A100 GPUs from Azure - the ultimate testing ground!</li>
|
| 34 |
+
<li><strong>๐ณ Setup:</strong> Docker containers for each library, ensuring a pristine environment.</li>
|
| 35 |
+
<li><strong>โ๏ธ Configuration:</strong> Standardized settings (temperature 0.5, top_p 1) for laser-focused performance comparisons.</li>
|
| 36 |
+
<li><strong>๐ Prompts & Token Ranges:</strong> Six diverse prompts, input lengths from 20 to 2,000 tokens, and generation lengths of 100, 200, and 500 tokens - pushing the boundaries of flexibility!</li>
|
| 37 |
+
<li><strong>๐ค Models & Libraries Tested:</strong> We put the best through their paces: Phi-3-medium-128k-instruct, Meta-Llama-3.1-8B-Instruct, Mistral-7B-Instruct-v0.3, Qwen2-7B-Instruct, and Gemma-2-9b-it, using TGI, vLLM, DeepSpeed Mii, CTranslate2, Triton with vLLM Backend, and TensorRT-LLM.</li>
|
| 38 |
+
</ul>
|
| 39 |
+
</div>
|
| 40 |
"""
|
| 41 |
|
|
|
|
| 42 |
csv_folder_path = 'result_csv/'
|
| 43 |
|
|
|
|
| 44 |
def read_and_process_csv_files(folder_path):
|
| 45 |
all_data = []
|
| 46 |
for filename in os.listdir(folder_path):
|
|
|
|
| 51 |
|
| 52 |
combined_df = pd.concat(all_data, ignore_index=True)
|
| 53 |
|
|
|
|
| 54 |
columns_order = [
|
| 55 |
"Model_Name", "Library", "TTFT", "Tokens-per-Second", "Token_Count",
|
| 56 |
+
"input_length", "output_length", "Input", "Output"
|
| 57 |
]
|
| 58 |
|
|
|
|
| 59 |
for col in columns_order:
|
| 60 |
if col not in combined_df.columns:
|
| 61 |
combined_df[col] = pd.NA
|
| 62 |
|
|
|
|
| 63 |
return combined_df[columns_order]
|
| 64 |
|
| 65 |
df = read_and_process_csv_files(csv_folder_path)
|
|
|
|
| 72 |
if file is None:
|
| 73 |
return df, "No file uploaded."
|
| 74 |
|
|
|
|
| 75 |
new_df = pd.read_csv(file.name)
|
| 76 |
|
|
|
|
| 77 |
columns_order = [
|
| 78 |
"Model_Name", "Library", "TTFT", "Tokens-per-Second", "Token_Count",
|
| 79 |
+
"input_length", "output_length", "Input", "Output"
|
| 80 |
]
|
| 81 |
for col in columns_order:
|
| 82 |
if col not in new_df.columns:
|
| 83 |
new_df[col] = pd.NA
|
| 84 |
new_df = new_df[columns_order]
|
| 85 |
|
|
|
|
| 86 |
df = pd.concat([df, new_df], ignore_index=True)
|
| 87 |
|
|
|
|
| 88 |
filename = os.path.basename(file.name)
|
| 89 |
destination = os.path.join(csv_folder_path, filename)
|
| 90 |
shutil.copy(file.name, destination)
|
| 91 |
|
| 92 |
return df, f"File '{filename}' uploaded and data added successfully!"
|
| 93 |
|
| 94 |
+
def filter_and_search(search_term, library_filter):
|
| 95 |
+
filtered_df = df.copy()
|
| 96 |
+
|
| 97 |
+
if search_term:
|
| 98 |
+
filtered_df = filtered_df[filtered_df['Model_Name'].str.contains(search_term, case=False, na=False)]
|
| 99 |
|
| 100 |
+
if library_filter != "All":
|
| 101 |
+
filtered_df = filtered_df[filtered_df['Library'] == library_filter]
|
| 102 |
+
|
| 103 |
+
return filtered_df
|
| 104 |
+
|
| 105 |
+
custom_css = """
|
| 106 |
+
body {
|
| 107 |
+
background-color: #f0fff0;
|
| 108 |
+
font-family: 'Roboto', sans-serif;
|
| 109 |
+
}
|
| 110 |
+
.gradio-container {
|
| 111 |
+
max-width: 1200px !important;
|
| 112 |
+
}
|
| 113 |
+
.gradio-container .prose * {
|
| 114 |
+
color: #00480a !important;
|
| 115 |
+
}
|
| 116 |
+
.gradio-container .prose h2,
|
| 117 |
+
.gradio-container .prose h3 {
|
| 118 |
+
color: #00480a !important;
|
| 119 |
+
}
|
| 120 |
+
.tabs {
|
| 121 |
+
background-color: #e6ffd9;
|
| 122 |
+
border-radius: 15px;
|
| 123 |
+
overflow: hidden;
|
| 124 |
+
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
|
| 125 |
+
}
|
| 126 |
+
.tab-nav {
|
| 127 |
+
background-color: #00480a;
|
| 128 |
+
padding: 10px;
|
| 129 |
+
}
|
| 130 |
+
.tab-nav button {
|
| 131 |
+
color: #cbff4d !important;
|
| 132 |
+
background-color: #006400;
|
| 133 |
+
border: none;
|
| 134 |
+
padding: 10px 20px;
|
| 135 |
+
margin-right: 5px;
|
| 136 |
+
border-radius: 10px;
|
| 137 |
+
cursor: pointer;
|
| 138 |
+
transition: all 0.3s ease;
|
| 139 |
+
}
|
| 140 |
+
.tab-nav button:hover {
|
| 141 |
+
background-color: #cbff4d;
|
| 142 |
+
color: #00480a !important;
|
| 143 |
+
}
|
| 144 |
+
.tab-nav button.selected {
|
| 145 |
+
background-color: #cbff4d;
|
| 146 |
+
color: #00480a !important;
|
| 147 |
+
font-weight: bold;
|
| 148 |
+
}
|
| 149 |
+
.gr-button-primary {
|
| 150 |
+
background-color: #00480a !important;
|
| 151 |
+
border-color: #00480a !important;
|
| 152 |
+
color: #cbff4d !important;
|
| 153 |
+
}
|
| 154 |
+
.gr-button-primary:hover {
|
| 155 |
+
background-color: #cbff4d !important;
|
| 156 |
+
color: #00480a !important;
|
| 157 |
+
}
|
| 158 |
+
"""
|
| 159 |
+
|
| 160 |
+
with gr.Blocks(css=custom_css) as demo:
|
| 161 |
+
gr.HTML(DESCRIPTION)
|
| 162 |
+
gr.HTML(INTRODUCTION)
|
| 163 |
|
|
|
|
| 164 |
with gr.Tabs():
|
| 165 |
+
with gr.TabItem("๐ Leaderboard"):
|
| 166 |
+
with gr.Row():
|
| 167 |
+
search_input = gr.Textbox(label="๐ Search Model Name", placeholder="Enter model name...")
|
| 168 |
+
library_dropdown = gr.Dropdown(choices=["All"] + df['Library'].unique().tolist(), label="๐ท๏ธ Filter by Library", value="All")
|
| 169 |
+
|
| 170 |
leaderboard = gr.DataFrame(df)
|
| 171 |
+
|
| 172 |
+
gr.HTML(HOW_WE_TESTED)
|
| 173 |
|
| 174 |
+
with gr.TabItem("โ Add New Entry"):
|
| 175 |
+
file_upload = gr.File(label="๐ Upload CSV File")
|
| 176 |
+
submit_button = gr.Button("๐ค Add Entry", variant="primary")
|
| 177 |
result = gr.Markdown()
|
| 178 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 179 |
submit_button.click(
|
| 180 |
add_new_entry,
|
| 181 |
inputs=[file_upload],
|
| 182 |
outputs=[leaderboard, result]
|
| 183 |
)
|
| 184 |
|
| 185 |
+
search_input.change(filter_and_search, inputs=[search_input, library_dropdown], outputs=leaderboard)
|
| 186 |
+
library_dropdown.change(filter_and_search, inputs=[search_input, library_dropdown], outputs=leaderboard)
|
| 187 |
+
|
| 188 |
demo.load(get_leaderboard_df, outputs=[leaderboard])
|
| 189 |
|
| 190 |
+
if __name__ == "__main__":
|
| 191 |
+
demo.launch()
|