-
Notifications
You must be signed in to change notification settings - Fork 0
/
table1.py
148 lines (121 loc) · 5.12 KB
/
table1.py
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
142
143
144
145
146
147
148
import os
import json
import logging
import argparse
from collections import defaultdict
import re
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
def parse_filename(filename):
pattern = r"ckpt@([\w-]+)-bs@(\d+)-dtype@(\w+)-qtype@(\w+)-qte@(\d+)-fuse@(\d+)"
match = re.match(pattern, filename)
if match:
return {
"ckpt": match.group(1),
"bs": int(match.group(2)),
"dtype": match.group(3),
"qtype": match.group(4),
"qte": int(match.group(5)),
"fuse": int(match.group(6)),
}
return None
def write_sorted_table(file, configs, sort_key):
file.write(
"| Data Type | Quantization | Quantize TE | Fuse QKV | Memory (GB) | Latency (s) |\n"
)
file.write(
"|-----------|--------------|-------------|----------|-------------|-------------|\n"
)
sorted_configs = sorted(configs.items(), key=lambda x: x[1][sort_key])
for (dtype, qtype, qte, fuse), metrics in sorted_configs:
qte_str = "Yes" if qte else "No"
fuse_str = "Yes" if fuse else "No"
file.write(
f"| {dtype:<9} | {qtype.upper() or 'None':<12} | {qte_str:<11} | {fuse_str:<8} | {metrics['memory']:<11.3f} | {metrics['time']:<11.3f} |\n"
)
file.write("\n")
def create_image_table(images, titles, input_dir):
table = "<table>\n"
for i in range(0, len(images), 3):
table += "<tr>\n"
for j in range(3):
if i + j < len(images):
img_path = f"http://localhost:8000/{input_dir}/{images[i+j]}"
title = titles[i + j]
table += f"<td><img src='{img_path}' alt='{title}' width='300'/><br>{title}</td>\n"
table += "</tr>\n"
table += "</table>\n"
return table
def generate_markdown(input_dir, output_file):
results = defaultdict(lambda: defaultdict(dict))
image_files = defaultdict(list)
image_titles = defaultdict(list)
for filename in os.listdir(input_dir):
if filename.endswith("_info.json"):
try:
with open(os.path.join(input_dir, filename), "r") as f:
info = json.load(f)
parsed = parse_filename(filename.replace("_info.json", ""))
if parsed is None:
continue
key = (parsed["ckpt"], parsed["bs"])
config = (
parsed["dtype"],
parsed["qtype"],
parsed["qte"],
parsed["fuse"],
)
results[key][config] = {
"memory": float(info["memory"]),
"time": float(info["time"]),
}
except json.JSONDecodeError:
logger.error(f"Error decoding JSON from file {filename}")
except KeyError as e:
logger.error(f"Missing key in JSON file {filename}: {str(e)}")
elif filename.endswith(".png"):
parsed = parse_filename(filename.replace(".png", ""))
if parsed:
key = parsed["ckpt"]
image_files[key].append(filename)
image_titles[key].append(
f"dtype: {parsed['dtype']}, qtype: {parsed['qtype']}, qte: {parsed['qte']}, fuse: {parsed['fuse']}"
)
with open(output_file, "w") as readme:
readme.write("# Experiment Results\n\n")
for (ckpt, bs), configs in results.items():
readme.write(f"## {ckpt.capitalize()} - Batch Size: {bs}\n\n")
# Add image table
if ckpt in image_files:
readme.write(
create_image_table(image_files[ckpt], image_titles[ckpt], input_dir)
)
readme.write("\n")
# Generate table sorted by memory
readme.write("### Sorted by Memory Usage (Ascending)\n\n")
write_sorted_table(readme, configs, sort_key="memory")
# Generate table sorted by latency
readme.write("### Sorted by Latency (Ascending)\n\n")
write_sorted_table(readme, configs, sort_key="time")
readme.write("\n")
logger.info(f"Markdown with embedded images generated and written to {output_file}")
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description="Generate markdown with embedded images and tables from experiment results"
)
parser.add_argument(
"--input",
default="experiment_results",
help="Input directory containing experiment results and images",
)
parser.add_argument("--output", default="README.md", help="Output markdown file")
args = parser.parse_args()
generate_markdown(args.input, args.output)
print("\nTo view the markdown file with images:")
print(
"1. Open a terminal in the directory containing your README.md and experiment_results folder"
)
print("2. Run the following command to start a local HTTP server:")
print(" python -m http.server")
print("3. Open a web browser and go to http://localhost:8000")
print("4. Click on the README.md file to view it with images")