Zekun Wu commited on
Commit
d9565d9
·
1 Parent(s): 55101ef
Files changed (3) hide show
  1. app.py +109 -0
  2. model_util.py +127 -0
  3. requirements.txt +4 -0
app.py ADDED
@@ -0,0 +1,109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import pandas as pd
3
+ from model_util import get_mode_from_hf, calculate_flops_in_hugging_space
4
+
5
+
6
+ def calculate_flops_architecture(num_params, num_tokens):
7
+ """
8
+ Calculate FLOPs based on model architecture.
9
+ """
10
+ total_flops = 6 * num_params * num_tokens
11
+ threshold_flops = 10 ** 25
12
+ meets_criteria = total_flops > threshold_flops
13
+
14
+ return {
15
+ "total_flops": total_flops,
16
+ "meets_criteria": meets_criteria
17
+ }
18
+
19
+
20
+ def calculate_flops_gpu(gpu_hours, power_consumption_w, flops_per_gpu_s):
21
+ """
22
+ Calculate FLOPs based on GPU hours and type.
23
+ """
24
+ threshold_flops = 10 ** 25
25
+ total_energy_wh = gpu_hours * power_consumption_w
26
+ total_flops = gpu_hours * flops_per_gpu_s * 3600
27
+ meets_criteria = total_flops > threshold_flops
28
+
29
+ return {
30
+ "total_energy_wh": total_energy_wh,
31
+ "total_flops": total_flops,
32
+ "meets_criteria": meets_criteria
33
+ }
34
+
35
+
36
+ def calculate_flops_hf(model_name, input_shape, access_token, bp_factor, output_unit):
37
+ """
38
+ Calculate FLOPs using Hugging Face model information.
39
+ """
40
+ model = get_mode_from_hf(model_name=model_name, library="auto", access_token=access_token)
41
+ data, return_print = calculate_flops_in_hugging_space(model_name=model_name, empty_model=model,
42
+ access_token=access_token, input_shape=input_shape,
43
+ bp_factor=bp_factor, output_unit=output_unit)
44
+ df = pd.DataFrame(data)
45
+ total_flops = df['Forward+Backward FLOPs'][0] * 10 ** 9 # Convert GFLOPs to FLOPs
46
+ threshold_flops = 10 ** 25
47
+ meets_criteria = total_flops > threshold_flops
48
+
49
+ return {
50
+ "total_flops": total_flops,
51
+ "meets_criteria": meets_criteria,
52
+ "dataframe": df,
53
+ "return_print": return_print
54
+ }
55
+
56
+
57
+ st.title("FLOPs Calculator for EU AI Act High Impact Capabilities")
58
+
59
+ # Choose calculation method
60
+ calculation_method = st.selectbox("Choose Calculation Method:",
61
+ ["Model Architecture", "GPU Hours and Type", "Hugging Face Model"])
62
+
63
+ if calculation_method == "Model Architecture":
64
+ num_params = st.number_input("Number of Parameters (N):", min_value=0.0, value=float(7.0 * 10 ** 9), step=1.0)
65
+ num_tokens = st.number_input("Number of Training Tokens (D):", min_value=0.0, value=float(1500 * 10 ** 9), step=1.0)
66
+
67
+ if st.button("Calculate FLOPs (Model Architecture)"):
68
+ result = calculate_flops_architecture(num_params, num_tokens)
69
+ st.write(f"Total FLOPs: {result['total_flops']:.2e} FLOPs")
70
+ st.write(f"Meets high impact capabilities criteria: {result['meets_criteria']}")
71
+
72
+ elif calculation_method == "GPU Hours and Type":
73
+ # Define GPU types and their corresponding FLOPs per second
74
+ gpu_types = {
75
+ "Nvidia A100": {"flops_per_s": 312 * 10 ** 12, "power": 400},
76
+ "Nvidia V100": {"flops_per_s": 125 * 10 ** 12, "power": 300},
77
+ "Nvidia H100": {"flops_per_s": 1.25 * 10 ** 15, "power": 700},
78
+ "Nvidia T4": {"flops_per_s": 65 * 10 ** 12, "power": 70}
79
+ }
80
+
81
+ gpu_type = st.selectbox("Select GPU type:", list(gpu_types.keys()))
82
+ flops_per_gpu_s = gpu_types[gpu_type]["flops_per_s"]
83
+ power_consumption_w = gpu_types[gpu_type]["power"]
84
+
85
+ gpu_hours = st.number_input("Total GPU hours used for training:", min_value=0.0, value=float(7.7 * 10 ** 6),
86
+ step=1.0)
87
+
88
+ if st.button("Calculate FLOPs (GPU Hours and Type)"):
89
+ result = calculate_flops_gpu(gpu_hours, power_consumption_w, flops_per_gpu_s)
90
+ st.write(f"Total energy consumption: {result['total_energy_wh']:.2e} Wh")
91
+ st.write(f"Total FLOPs: {result['total_flops']:.2e} FLOPs")
92
+ st.write(f"Meets high impact capabilities criteria: {result['meets_criteria']}")
93
+
94
+ elif calculation_method == "Hugging Face Model":
95
+ model_name = st.text_input("Model Name:", "tiiuae/falcon-40b")
96
+ batch_size = st.number_input("Batch Size:", min_value=1, value=1)
97
+ max_seq_length = st.number_input("Max Sequence Length:", min_value=1, value=128)
98
+ input_shape = (batch_size, max_seq_length)
99
+ access_token = st.text_input("Hugging Face Access Token:", "")
100
+ bp_factor = st.number_input("Backward Pass Factor (BP Factor):", min_value=0.0, value=1.0, step=0.1)
101
+ output_unit = st.selectbox("Output Unit:", ["auto", "MFLOPs", "GFLOPs", "TFLOPs", "PFLOPs"])
102
+
103
+ if st.button("Calculate FLOPs (Hugging Face Model)"):
104
+ result = calculate_flops_hf(model_name, input_shape, access_token, bp_factor, output_unit)
105
+ st.write(f"Total FLOPs: {result['total_flops']:.2e} FLOPs")
106
+ st.write(f"Meets high impact capabilities criteria: {result['meets_criteria']}")
107
+ st.write("Detailed FLOPs Data:")
108
+ st.dataframe(result["dataframe"])
109
+ st.text(result["return_print"])
model_util.py ADDED
@@ -0,0 +1,127 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import torch
3
+
4
+ from urllib.parse import urlparse
5
+ from huggingface_hub.utils import GatedRepoError
6
+ from huggingface_hub.utils import RepositoryNotFoundError
7
+
8
+ from calflops import create_empty_model
9
+ from calflops import calculate_flops_hf
10
+ from calflops import flops_to_string
11
+ from calflops import macs_to_string
12
+ from calflops import params_to_string
13
+
14
+
15
+ def calculate_flops_in_hugging_space(model_name: str,
16
+ empty_model: torch.nn.modules,
17
+ access_token: str,
18
+ input_shape: tuple,
19
+ bp_factor: float,
20
+ output_unit: str):
21
+ "Calculates the FLOPs and Params usage for a model init on `meta` device"
22
+
23
+ try:
24
+ flops, macs, params, return_print = calculate_flops_hf(model_name=model_name,
25
+ empty_model=empty_model,
26
+ access_token=access_token,
27
+ input_shape=input_shape,
28
+ return_results=True,
29
+ output_as_string=False)
30
+ except Exception as e:
31
+ print("Error info:", e)
32
+ raise gr.Error(
33
+ f"Model `{model_name}` does not support inference on the meta device, You can download the complete model parameters to your local and using the python package calflops to calculate FLOPs and Params of model `{model_name}`."
34
+ )
35
+
36
+ fw_bp_flops = flops * (1.0 + bp_factor)
37
+ fw_bp_macs = macs * (1.0 + bp_factor)
38
+
39
+ if output_unit == "":
40
+ pass
41
+ elif output_unit == "auto":
42
+ params = params_to_string(params, units=None, precision=3)
43
+ flops = flops_to_string(flops, units=None, precision=3)
44
+ macs = macs_to_string(macs, units=None, precision=3)
45
+ fw_bp_flops = flops_to_string(fw_bp_flops, units=None, precision=3)
46
+ fw_bp_macs = macs_to_string(fw_bp_macs, units=None, precision=3)
47
+ elif output_unit == "T" or output_unit == "G" or output_unit == "M" or output_unit == "K" or output_unit == "m" or output_unit == "u":
48
+ params = params_to_string(params, units=output_unit, precision=3)
49
+ flops = flops_to_string(flops, units=output_unit, precision=3)
50
+ macs = macs_to_string(macs, units=output_unit, precision=3)
51
+ fw_bp_flops = flops_to_string(fw_bp_flops, units=output_unit, precision=3)
52
+ fw_bp_macs = macs_to_string(fw_bp_macs, units=output_unit, precision=3)
53
+
54
+ return_lines = return_print.split("\n")
55
+ return_start = False
56
+ return_print = ""
57
+ for line in return_lines[:-2]:
58
+ if return_start:
59
+ return_print += line + "\n"
60
+ if "Detailed" in line:
61
+ return_start = True
62
+
63
+ data = []
64
+ data.append(
65
+ {"Total Training Params": params,
66
+ "Forward FLOPs": flops,
67
+ "Forward MACs": macs,
68
+ "Forward+Backward FLOPs": fw_bp_flops,
69
+ "Forward+Backward MACs": fw_bp_macs
70
+ }
71
+ )
72
+ return data, return_print
73
+
74
+
75
+ def extract_from_url(name: str):
76
+ "Checks if `name` is a URL, and if so converts it to a model name"
77
+ is_url = False
78
+ try:
79
+ result = urlparse(name)
80
+ is_url = all([result.scheme, result.netloc])
81
+ except Exception:
82
+ is_url = False
83
+ # Pass through if not a URL
84
+ if not is_url:
85
+ return name
86
+ else:
87
+ path = result.path
88
+ return path[1:]
89
+
90
+
91
+ def translate_llama2(text):
92
+ "Translates llama-2 to its hf counterpart"
93
+ if not text.endswith("-hf"):
94
+ return text + "-hf"
95
+ return text
96
+
97
+
98
+ def get_mode_from_hf(model_name: str, library: str, access_token: str):
99
+ "Finds and grabs model from the Hub, and initializes on `meta`"
100
+ if "meta-llama" in model_name:
101
+ model_name = translate_llama2(model_name)
102
+ if library == "auto":
103
+ library = None
104
+ model_name = extract_from_url(model_name)
105
+ try:
106
+ model = create_empty_model(model_name, library_name=library, trust_remote_code=True, access_token=access_token)
107
+ except GatedRepoError:
108
+ raise gr.Error(
109
+ f"Model `{model_name}` is a gated model, please ensure to pass in your access token and try again if you have access. You can find your access token here : https://huggingface.co/settings/tokens. "
110
+ )
111
+ except RepositoryNotFoundError:
112
+ raise gr.Error(f"Model `{model_name}` was not found on the Hub, please try another model name.")
113
+ except ValueError:
114
+ raise gr.Error(
115
+ f"Model `{model_name}` does not have any library metadata on the Hub, please manually select a library_name to use (such as `transformers`)"
116
+ )
117
+
118
+ except ImportError:
119
+ # hacky way to check if it works with `trust_remote_code=False`
120
+ model = create_empty_model(
121
+ model_name, library_name=library, trust_remote_code=False, access_token=access_token
122
+ )
123
+ except Exception as e:
124
+ raise gr.Error(
125
+ f"Model `{model_name}` had an error, please open a discussion on the model's page with the error message and name: `{e}`"
126
+ )
127
+ return model
requirements.txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ gradio
2
+ torch==2.0.1
3
+ calflops
4
+ pandas