muellerzr's picture
Create app.py
12fd3c6 verified
import re
import gradio as gr
import pandas as pd
GPU_TFLOPS_NONSPARSE = dict(
rtx_3070=40.6,
rtx_3070_ti=43.5,
rtx_3080_mobile=30,
rtx_3080=59.5,
rtx_3090=71,
rtx_4070=58.3,
rtx_4070_ti=80.2,
rtx_4080=97.5,
rtx_4090=165.2,
rtx_5070=61.7,
rtx_5070_ti=87.9,
rtx_5080=112.6,
rtx_5090=209.5,
rtx_a6000=154.8,
rtx_6000_ada=364,
rtx_6000_blackwell_max_q=438.9,
rtx_6000_blackwell=503.8,
a100=312,
h100_sxm5=1000,
h100_pcie=800,
)
# === Categorization rules ===
categories = {
# consumer RTX cards (30xx/40xx/50xx series, including mobile)
"consumer_rtx": [
k for k in GPU_TFLOPS_NONSPARSE
if any(x in k for x in ["3070", "3080", "3090", "4070", "4080", "4090", "5070", "5080", "5090"])
],
# workstation 6000 family (A6000, Ada, Blackwell variants)
"workstation_6000": [k for k in GPU_TFLOPS_NONSPARSE if "6000" in k],
# datacenter accelerators
"datacenter": [k for k in GPU_TFLOPS_NONSPARSE if any(x in k for x in ["a100", "h100"])],
}
# === Formatting function ===
def prettify_name(key: str) -> str:
"""Convert internal GPU key names to human-friendly titles."""
name = key.replace("_", " ").upper()
name = re.sub(r"RTX A", "RTX A", name)
name = name.replace("TI", "Ti")
# Title case except GPU model identifiers (keep uppercase RTX/A/H)
name = " ".join(word.capitalize() if not word.startswith(("RTX", "A", "H")) else word for word in name.split())
name = name.replace("Max Q", "Max-Q")
name = name.replace("Pcie", "PCIe")
name = name.replace("Smx5", "SXM5")
return name
def make_df(filtered_dict: dict) -> pd.DataFrame:
df = pd.DataFrame(
[(prettify_name(k), v) for k, v in filtered_dict.items()],
columns=["GPU", "TFLOPS (non-sparse)"]
)
return df.sort_values(by="TFLOPS (non-sparse)", ascending=False, ignore_index=True)
def filter_table(hide_consumer: bool, hide_workstation: bool, hide_datacenter: bool) -> pd.DataFrame:
data = GPU_TFLOPS_NONSPARSE.copy()
if hide_consumer:
for key in categories["consumer_rtx"]:
data.pop(key, None)
if hide_workstation:
for key in categories["workstation_6000"]:
data.pop(key, None)
if hide_datacenter:
for key in categories["datacenter"]:
data.pop(key, None)
return make_df(data)
DEFAULT_DF = filter_table(False, False, False)
with gr.Blocks() as demo:
gr.Markdown("# BF16 GPU TFLOPS Viewer\nToggle categories to hide/show entries.\nWhen calculating the 'usable' TFLOPs of a particular card, these are what we call non-sparse TFLOPs. Below contains data gathered for the most commonly used CUDA cards and their BF16 with FP32 accum (what we use in PyTorch) values")
with gr.Row():
hide_consumer = gr.Checkbox(label="Hide Consumer RTX", value=False)
hide_workstation = gr.Checkbox(label="Hide Professional Workstation (6000)", value=False)
hide_datacenter = gr.Checkbox(label="Hide Datacenter Cards", value=False)
table = gr.Dataframe(
value=DEFAULT_DF,
headers=["GPU", "TFLOPS (non-sparse)"],
datatype=["str", "number"],
interactive=False,
wrap=True,
max_height=1000
)
for cb in (hide_consumer, hide_workstation, hide_datacenter):
cb.change(
fn=filter_table,
inputs=[hide_consumer, hide_workstation, hide_datacenter],
outputs=table
)
demo.load(fn=filter_table, inputs=[hide_consumer, hide_workstation, hide_datacenter], outputs=table)
if __name__ == "__main__":
demo.launch()