Spaces:
Sleeping
Sleeping
Commit ·
c0a2ac4
1
Parent(s): d84b463
Bundle OpenModelLab package in Space
Browse files- openmodellab/__init__.py +0 -0
- openmodellab/auditor/__init__.py +0 -0
- openmodellab/benchmark.py +35 -0
- openmodellab/cli/__init__.py +0 -0
- openmodellab/cli/main.py +189 -0
- openmodellab/common/__init__.py +0 -0
- openmodellab/comparison/__init__.py +0 -0
- openmodellab/comparison/compare.py +106 -0
- openmodellab/comparison/table.py +37 -0
- openmodellab/genome/__init__.py +0 -0
- openmodellab/genome/analyzer.py +54 -0
- openmodellab/genome/inspectors/__init__.py +0 -0
- openmodellab/genome/inspectors/batch.py +70 -0
- openmodellab/genome/inspectors/execution.py +28 -0
- openmodellab/genome/inspectors/fingerprint.py +24 -0
- openmodellab/genome/inspectors/hardware.py +27 -0
- openmodellab/genome/inspectors/latency.py +78 -0
- openmodellab/genome/inspectors/memory.py +56 -0
- openmodellab/genome/inspectors/precision.py +40 -0
- openmodellab/genome/inspectors/throughput.py +57 -0
- openmodellab/genome/inspectors/tokenizer.py +10 -0
- openmodellab/genome/model_loader.py +49 -0
- openmodellab/reporting/__init__.py +0 -0
- openmodellab/reporting/benchmark_writer.py +18 -0
- openmodellab/reporting/csv_writer.py +34 -0
- openmodellab/reporting/html_writer.py +50 -0
- openmodellab/reporting/json_writer.py +16 -0
- openmodellab/visualization/__init__.py +0 -0
- openmodellab/visualization/charts.py +90 -0
- requirements.txt +0 -1
openmodellab/__init__.py
ADDED
|
File without changes
|
openmodellab/auditor/__init__.py
ADDED
|
File without changes
|
openmodellab/benchmark.py
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from datetime import datetime, UTC
|
| 2 |
+
|
| 3 |
+
from openmodellab.genome.inspectors.hardware import inspect_hardware
|
| 4 |
+
from openmodellab.genome.inspectors.latency import inspect_latency
|
| 5 |
+
from openmodellab.genome.inspectors.memory import inspect_memory
|
| 6 |
+
from openmodellab.genome.inspectors.throughput import inspect_throughput
|
| 7 |
+
from openmodellab.genome.inspectors.batch import inspect_batch_scaling
|
| 8 |
+
|
| 9 |
+
|
| 10 |
+
def analyze_benchmark(model, tokenizer):
|
| 11 |
+
return {
|
| 12 |
+
"report": {
|
| 13 |
+
"tool": "OpenModelLab",
|
| 14 |
+
"tool_version": "0.1.0-alpha",
|
| 15 |
+
"schema_version": "1.0",
|
| 16 |
+
"generated_at": datetime.now(UTC).isoformat(),
|
| 17 |
+
},
|
| 18 |
+
"hardware": inspect_hardware(),
|
| 19 |
+
"latency": inspect_latency(
|
| 20 |
+
model,
|
| 21 |
+
tokenizer
|
| 22 |
+
),
|
| 23 |
+
"memory": inspect_memory(
|
| 24 |
+
model,
|
| 25 |
+
tokenizer
|
| 26 |
+
),
|
| 27 |
+
"throughput": inspect_throughput(
|
| 28 |
+
model,
|
| 29 |
+
tokenizer
|
| 30 |
+
),
|
| 31 |
+
"batch_scaling": inspect_batch_scaling(
|
| 32 |
+
model,
|
| 33 |
+
tokenizer
|
| 34 |
+
)
|
| 35 |
+
}
|
openmodellab/cli/__init__.py
ADDED
|
File without changes
|
openmodellab/cli/main.py
ADDED
|
@@ -0,0 +1,189 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import argparse
|
| 2 |
+
|
| 3 |
+
from openmodellab.comparison.compare import generate_comparison
|
| 4 |
+
from openmodellab.comparison.table import print_table
|
| 5 |
+
|
| 6 |
+
from openmodellab.genome.model_loader import load_model
|
| 7 |
+
from openmodellab.genome.analyzer import analyze_model
|
| 8 |
+
|
| 9 |
+
from openmodellab.benchmark import analyze_benchmark
|
| 10 |
+
|
| 11 |
+
from openmodellab.reporting.json_writer import save_json
|
| 12 |
+
from openmodellab.reporting.benchmark_writer import save_benchmark
|
| 13 |
+
from openmodellab.reporting.csv_writer import save_csv
|
| 14 |
+
from openmodellab.reporting.html_writer import save_html
|
| 15 |
+
|
| 16 |
+
from openmodellab.visualization.charts import (
|
| 17 |
+
save_latency_chart,
|
| 18 |
+
save_throughput_chart
|
| 19 |
+
)
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
def main():
|
| 23 |
+
|
| 24 |
+
parser = argparse.ArgumentParser(
|
| 25 |
+
prog="openmodellab",
|
| 26 |
+
description="OpenModelLab - Model Genome Generator"
|
| 27 |
+
)
|
| 28 |
+
|
| 29 |
+
subparsers = parser.add_subparsers(
|
| 30 |
+
dest="command"
|
| 31 |
+
)
|
| 32 |
+
|
| 33 |
+
|
| 34 |
+
# Genome command
|
| 35 |
+
genome = subparsers.add_parser(
|
| 36 |
+
"genome",
|
| 37 |
+
help="Generate a model genome report"
|
| 38 |
+
)
|
| 39 |
+
|
| 40 |
+
genome.add_argument(
|
| 41 |
+
"--model",
|
| 42 |
+
required=True,
|
| 43 |
+
help="Hugging Face model name"
|
| 44 |
+
)
|
| 45 |
+
|
| 46 |
+
|
| 47 |
+
# Compare command
|
| 48 |
+
compare = subparsers.add_parser(
|
| 49 |
+
"compare",
|
| 50 |
+
help="Compare model reports"
|
| 51 |
+
)
|
| 52 |
+
|
| 53 |
+
compare.add_argument(
|
| 54 |
+
"--reports",
|
| 55 |
+
required=True,
|
| 56 |
+
help="Directory containing genome and benchmark reports"
|
| 57 |
+
)
|
| 58 |
+
|
| 59 |
+
compare.add_argument(
|
| 60 |
+
"--format",
|
| 61 |
+
choices=[
|
| 62 |
+
"table",
|
| 63 |
+
"csv",
|
| 64 |
+
"html",
|
| 65 |
+
"charts"
|
| 66 |
+
],
|
| 67 |
+
default="table",
|
| 68 |
+
help="Output format"
|
| 69 |
+
)
|
| 70 |
+
|
| 71 |
+
|
| 72 |
+
args = parser.parse_args()
|
| 73 |
+
|
| 74 |
+
|
| 75 |
+
if args.command == "genome":
|
| 76 |
+
|
| 77 |
+
print("=" * 60)
|
| 78 |
+
print("OpenModelLab Genome")
|
| 79 |
+
print("=" * 60)
|
| 80 |
+
|
| 81 |
+
model, tokenizer = load_model(
|
| 82 |
+
args.model
|
| 83 |
+
)
|
| 84 |
+
|
| 85 |
+
|
| 86 |
+
genome_report = analyze_model(
|
| 87 |
+
args.model,
|
| 88 |
+
model,
|
| 89 |
+
tokenizer
|
| 90 |
+
)
|
| 91 |
+
|
| 92 |
+
genome_file = save_json(
|
| 93 |
+
genome_report,
|
| 94 |
+
args.model
|
| 95 |
+
)
|
| 96 |
+
|
| 97 |
+
|
| 98 |
+
benchmark_report = analyze_benchmark(
|
| 99 |
+
model,
|
| 100 |
+
tokenizer
|
| 101 |
+
)
|
| 102 |
+
|
| 103 |
+
benchmark_file = save_benchmark(
|
| 104 |
+
benchmark_report,
|
| 105 |
+
args.model
|
| 106 |
+
)
|
| 107 |
+
|
| 108 |
+
|
| 109 |
+
print()
|
| 110 |
+
print("Genome report saved:")
|
| 111 |
+
print(genome_file)
|
| 112 |
+
|
| 113 |
+
print()
|
| 114 |
+
print("Benchmark report saved:")
|
| 115 |
+
print(benchmark_file)
|
| 116 |
+
|
| 117 |
+
|
| 118 |
+
|
| 119 |
+
elif args.command == "compare":
|
| 120 |
+
|
| 121 |
+
print("=" * 60)
|
| 122 |
+
print("OpenModelLab Model Comparison")
|
| 123 |
+
print("=" * 60)
|
| 124 |
+
|
| 125 |
+
|
| 126 |
+
results = generate_comparison(
|
| 127 |
+
args.reports
|
| 128 |
+
)
|
| 129 |
+
|
| 130 |
+
|
| 131 |
+
if args.format == "table":
|
| 132 |
+
|
| 133 |
+
print_table(
|
| 134 |
+
results
|
| 135 |
+
)
|
| 136 |
+
|
| 137 |
+
|
| 138 |
+
elif args.format == "csv":
|
| 139 |
+
|
| 140 |
+
outfile = save_csv(
|
| 141 |
+
results,
|
| 142 |
+
"comparison_report.csv"
|
| 143 |
+
)
|
| 144 |
+
|
| 145 |
+
print()
|
| 146 |
+
print("CSV report saved:")
|
| 147 |
+
print(outfile)
|
| 148 |
+
|
| 149 |
+
|
| 150 |
+
|
| 151 |
+
elif args.format == "html":
|
| 152 |
+
|
| 153 |
+
outfile = save_html(
|
| 154 |
+
results,
|
| 155 |
+
"comparison_report.html"
|
| 156 |
+
)
|
| 157 |
+
|
| 158 |
+
print()
|
| 159 |
+
print("HTML report saved:")
|
| 160 |
+
print(outfile)
|
| 161 |
+
|
| 162 |
+
|
| 163 |
+
|
| 164 |
+
elif args.format == "charts":
|
| 165 |
+
|
| 166 |
+
latency_file = "latency_comparison.png"
|
| 167 |
+
throughput_file = "throughput_comparison.png"
|
| 168 |
+
|
| 169 |
+
|
| 170 |
+
save_latency_chart(
|
| 171 |
+
results,
|
| 172 |
+
latency_file
|
| 173 |
+
)
|
| 174 |
+
|
| 175 |
+
save_throughput_chart(
|
| 176 |
+
results,
|
| 177 |
+
throughput_file
|
| 178 |
+
)
|
| 179 |
+
|
| 180 |
+
|
| 181 |
+
print()
|
| 182 |
+
print("Charts generated:")
|
| 183 |
+
print(latency_file)
|
| 184 |
+
print(throughput_file)
|
| 185 |
+
|
| 186 |
+
|
| 187 |
+
|
| 188 |
+
if __name__ == "__main__":
|
| 189 |
+
main()
|
openmodellab/common/__init__.py
ADDED
|
File without changes
|
openmodellab/comparison/__init__.py
ADDED
|
File without changes
|
openmodellab/comparison/compare.py
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import json
|
| 2 |
+
import os
|
| 3 |
+
|
| 4 |
+
|
| 5 |
+
def load_reports(report_dir):
|
| 6 |
+
|
| 7 |
+
models = {}
|
| 8 |
+
|
| 9 |
+
for file in os.listdir(report_dir):
|
| 10 |
+
|
| 11 |
+
path = os.path.join(
|
| 12 |
+
report_dir,
|
| 13 |
+
file
|
| 14 |
+
)
|
| 15 |
+
|
| 16 |
+
if file.endswith("_genome.json"):
|
| 17 |
+
|
| 18 |
+
name = file.replace(
|
| 19 |
+
"_genome.json",
|
| 20 |
+
""
|
| 21 |
+
)
|
| 22 |
+
|
| 23 |
+
models.setdefault(name, {})
|
| 24 |
+
|
| 25 |
+
with open(path, "r") as f:
|
| 26 |
+
models[name]["genome"] = json.load(f)
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
elif file.endswith("_benchmark.json"):
|
| 30 |
+
|
| 31 |
+
name = file.replace(
|
| 32 |
+
"_benchmark.json",
|
| 33 |
+
""
|
| 34 |
+
)
|
| 35 |
+
|
| 36 |
+
models.setdefault(name, {})
|
| 37 |
+
|
| 38 |
+
with open(path, "r") as f:
|
| 39 |
+
models[name]["benchmark"] = json.load(f)
|
| 40 |
+
|
| 41 |
+
return models
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
|
| 45 |
+
def generate_comparison(report_dir):
|
| 46 |
+
|
| 47 |
+
reports = load_reports(report_dir)
|
| 48 |
+
|
| 49 |
+
table = []
|
| 50 |
+
|
| 51 |
+
|
| 52 |
+
for name, data in reports.items():
|
| 53 |
+
|
| 54 |
+
genome = data.get(
|
| 55 |
+
"genome",
|
| 56 |
+
{}
|
| 57 |
+
)
|
| 58 |
+
|
| 59 |
+
benchmark = data.get(
|
| 60 |
+
"benchmark",
|
| 61 |
+
{}
|
| 62 |
+
)
|
| 63 |
+
|
| 64 |
+
|
| 65 |
+
table.append({
|
| 66 |
+
|
| 67 |
+
"model": name,
|
| 68 |
+
|
| 69 |
+
"parameters": genome.get(
|
| 70 |
+
"model",
|
| 71 |
+
{}
|
| 72 |
+
).get(
|
| 73 |
+
"parameter_count"
|
| 74 |
+
),
|
| 75 |
+
|
| 76 |
+
"layers": genome.get(
|
| 77 |
+
"model",
|
| 78 |
+
{}
|
| 79 |
+
).get(
|
| 80 |
+
"num_hidden_layers"
|
| 81 |
+
),
|
| 82 |
+
|
| 83 |
+
"hidden_size": genome.get(
|
| 84 |
+
"model",
|
| 85 |
+
{}
|
| 86 |
+
).get(
|
| 87 |
+
"hidden_size"
|
| 88 |
+
),
|
| 89 |
+
|
| 90 |
+
"latency_ms": benchmark.get(
|
| 91 |
+
"latency",
|
| 92 |
+
{}
|
| 93 |
+
).get(
|
| 94 |
+
"average_ms"
|
| 95 |
+
),
|
| 96 |
+
|
| 97 |
+
"throughput": benchmark.get(
|
| 98 |
+
"throughput",
|
| 99 |
+
{}
|
| 100 |
+
).get(
|
| 101 |
+
"samples_per_second"
|
| 102 |
+
)
|
| 103 |
+
})
|
| 104 |
+
|
| 105 |
+
|
| 106 |
+
return table
|
openmodellab/comparison/table.py
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from tabulate import tabulate
|
| 2 |
+
|
| 3 |
+
|
| 4 |
+
def print_table(results):
|
| 5 |
+
|
| 6 |
+
rows = []
|
| 7 |
+
|
| 8 |
+
for item in results:
|
| 9 |
+
|
| 10 |
+
rows.append([
|
| 11 |
+
item["model"],
|
| 12 |
+
round(
|
| 13 |
+
item["parameters"] / 1_000_000,
|
| 14 |
+
2
|
| 15 |
+
) if item["parameters"] else None,
|
| 16 |
+
item["layers"],
|
| 17 |
+
item["hidden_size"],
|
| 18 |
+
item["latency_ms"],
|
| 19 |
+
item["throughput"]
|
| 20 |
+
])
|
| 21 |
+
|
| 22 |
+
print()
|
| 23 |
+
|
| 24 |
+
print(
|
| 25 |
+
tabulate(
|
| 26 |
+
rows,
|
| 27 |
+
headers=[
|
| 28 |
+
"Model",
|
| 29 |
+
"Params(M)",
|
| 30 |
+
"Layers",
|
| 31 |
+
"Hidden",
|
| 32 |
+
"Latency(ms)",
|
| 33 |
+
"Throughput"
|
| 34 |
+
],
|
| 35 |
+
tablefmt="grid"
|
| 36 |
+
)
|
| 37 |
+
)
|
openmodellab/genome/__init__.py
ADDED
|
File without changes
|
openmodellab/genome/analyzer.py
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from huggingface_hub import model_info
|
| 2 |
+
|
| 3 |
+
from openmodellab.genome.inspectors.tokenizer import inspect_tokenizer
|
| 4 |
+
|
| 5 |
+
from openmodellab.genome.inspectors.hardware import inspect_hardware
|
| 6 |
+
|
| 7 |
+
from openmodellab.genome.inspectors.fingerprint import inspect_fingerprint
|
| 8 |
+
|
| 9 |
+
from datetime import datetime, UTC
|
| 10 |
+
|
| 11 |
+
from openmodellab.genome.inspectors.precision import inspect_precision
|
| 12 |
+
|
| 13 |
+
from openmodellab.genome.inspectors.execution import inspect_execution
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
def count_parameters(model):
|
| 17 |
+
return sum(p.numel() for p in model.parameters())
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
def inspect_model(model_name, model):
|
| 21 |
+
cfg = model.config
|
| 22 |
+
info = model_info(model_name)
|
| 23 |
+
|
| 24 |
+
return {
|
| 25 |
+
"model_name": model_name,
|
| 26 |
+
"architecture": model.__class__.__name__,
|
| 27 |
+
"model_type": getattr(cfg, "model_type", None),
|
| 28 |
+
"hidden_size": getattr(cfg, "hidden_size", None),
|
| 29 |
+
"num_hidden_layers": getattr(cfg, "num_hidden_layers", None),
|
| 30 |
+
"num_attention_heads": getattr(cfg, "num_attention_heads", None),
|
| 31 |
+
"intermediate_size": getattr(cfg, "intermediate_size", None),
|
| 32 |
+
"max_position_embeddings": getattr(cfg, "max_position_embeddings", None),
|
| 33 |
+
"parameter_count": count_parameters(model),
|
| 34 |
+
"dtype": str(next(model.parameters()).dtype),
|
| 35 |
+
"framework": "transformers",
|
| 36 |
+
"license": info.card_data.get("license") if info.card_data else None,
|
| 37 |
+
}
|
| 38 |
+
|
| 39 |
+
|
| 40 |
+
def analyze_model(model_name, model, tokenizer):
|
| 41 |
+
return {
|
| 42 |
+
"report": {
|
| 43 |
+
"tool": "OpenModelLab",
|
| 44 |
+
"tool_version": "0.1.0-alpha",
|
| 45 |
+
"schema_version": "1.0",
|
| 46 |
+
"generated_at": datetime.now(UTC).isoformat(),
|
| 47 |
+
},
|
| 48 |
+
"model": inspect_model(model_name, model),
|
| 49 |
+
"tokenizer": inspect_tokenizer(tokenizer),
|
| 50 |
+
"hardware": inspect_hardware(),
|
| 51 |
+
"fingerprint": inspect_fingerprint(model),
|
| 52 |
+
"precision": inspect_precision(model),
|
| 53 |
+
"execution": inspect_execution(model),
|
| 54 |
+
}
|
openmodellab/genome/inspectors/__init__.py
ADDED
|
File without changes
|
openmodellab/genome/inspectors/batch.py
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import time
|
| 2 |
+
import torch
|
| 3 |
+
|
| 4 |
+
|
| 5 |
+
def inspect_batch_scaling(
|
| 6 |
+
model,
|
| 7 |
+
tokenizer,
|
| 8 |
+
batch_sizes=None,
|
| 9 |
+
):
|
| 10 |
+
if batch_sizes is None:
|
| 11 |
+
batch_sizes = [1, 2, 4, 8]
|
| 12 |
+
|
| 13 |
+
model.eval()
|
| 14 |
+
|
| 15 |
+
device = next(model.parameters()).device
|
| 16 |
+
|
| 17 |
+
results = []
|
| 18 |
+
|
| 19 |
+
for batch_size in batch_sizes:
|
| 20 |
+
|
| 21 |
+
texts = [
|
| 22 |
+
"OpenModelLab batch benchmark."
|
| 23 |
+
for _ in range(batch_size)
|
| 24 |
+
]
|
| 25 |
+
|
| 26 |
+
inputs = tokenizer(
|
| 27 |
+
texts,
|
| 28 |
+
return_tensors="pt",
|
| 29 |
+
padding=True,
|
| 30 |
+
truncation=True,
|
| 31 |
+
max_length=128,
|
| 32 |
+
)
|
| 33 |
+
|
| 34 |
+
inputs = {
|
| 35 |
+
key: value.to(device)
|
| 36 |
+
for key, value in inputs.items()
|
| 37 |
+
}
|
| 38 |
+
|
| 39 |
+
with torch.no_grad():
|
| 40 |
+
_ = model(**inputs)
|
| 41 |
+
|
| 42 |
+
if str(device).startswith("cuda"):
|
| 43 |
+
torch.cuda.synchronize()
|
| 44 |
+
|
| 45 |
+
start = time.perf_counter()
|
| 46 |
+
|
| 47 |
+
with torch.no_grad():
|
| 48 |
+
_ = model(**inputs)
|
| 49 |
+
|
| 50 |
+
if str(device).startswith("cuda"):
|
| 51 |
+
torch.cuda.synchronize()
|
| 52 |
+
|
| 53 |
+
end = time.perf_counter()
|
| 54 |
+
|
| 55 |
+
latency_ms = (end - start) * 1000
|
| 56 |
+
|
| 57 |
+
results.append({
|
| 58 |
+
"batch_size": batch_size,
|
| 59 |
+
"latency_ms": round(latency_ms, 3),
|
| 60 |
+
"samples_per_second": round(
|
| 61 |
+
batch_size / (end - start),
|
| 62 |
+
3
|
| 63 |
+
)
|
| 64 |
+
})
|
| 65 |
+
|
| 66 |
+
return {
|
| 67 |
+
"device": str(device),
|
| 68 |
+
"batch_sizes": batch_sizes,
|
| 69 |
+
"results": results
|
| 70 |
+
}
|
openmodellab/genome/inspectors/execution.py
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import torch
|
| 2 |
+
|
| 3 |
+
|
| 4 |
+
def inspect_execution(model, requested_device="auto"):
|
| 5 |
+
|
| 6 |
+
actual_device = str(
|
| 7 |
+
next(model.parameters()).device
|
| 8 |
+
)
|
| 9 |
+
|
| 10 |
+
cuda_available = torch.cuda.is_available()
|
| 11 |
+
|
| 12 |
+
fallback = (
|
| 13 |
+
cuda_available
|
| 14 |
+
and not actual_device.startswith("cuda")
|
| 15 |
+
)
|
| 16 |
+
|
| 17 |
+
gpu_name = None
|
| 18 |
+
|
| 19 |
+
if cuda_available:
|
| 20 |
+
gpu_name = torch.cuda.get_device_name(0)
|
| 21 |
+
|
| 22 |
+
return {
|
| 23 |
+
"requested_device": requested_device,
|
| 24 |
+
"actual_device": actual_device,
|
| 25 |
+
"cuda_available": cuda_available,
|
| 26 |
+
"gpu_name": gpu_name,
|
| 27 |
+
"fallback": fallback
|
| 28 |
+
}
|
openmodellab/genome/inspectors/fingerprint.py
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import hashlib
|
| 2 |
+
import json
|
| 3 |
+
import transformers
|
| 4 |
+
|
| 5 |
+
|
| 6 |
+
def inspect_fingerprint(model):
|
| 7 |
+
cfg = model.config.to_dict()
|
| 8 |
+
|
| 9 |
+
config_json = json.dumps(cfg, sort_keys=True)
|
| 10 |
+
|
| 11 |
+
sha = hashlib.sha256(config_json.encode()).hexdigest()
|
| 12 |
+
|
| 13 |
+
signature = (
|
| 14 |
+
f"{cfg.get('model_type', 'unknown')}-"
|
| 15 |
+
f"{cfg.get('num_hidden_layers', '?')}L-"
|
| 16 |
+
f"{cfg.get('hidden_size', '?')}H-"
|
| 17 |
+
f"{cfg.get('num_attention_heads', '?')}A"
|
| 18 |
+
)
|
| 19 |
+
|
| 20 |
+
return {
|
| 21 |
+
"architecture_signature": signature,
|
| 22 |
+
"config_sha256": sha,
|
| 23 |
+
"transformers_version": transformers.__version__,
|
| 24 |
+
}
|
openmodellab/genome/inspectors/hardware.py
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import torch
|
| 2 |
+
|
| 3 |
+
|
| 4 |
+
def inspect_hardware():
|
| 5 |
+
report = {
|
| 6 |
+
"torch_version": torch.__version__,
|
| 7 |
+
"cuda_available": torch.cuda.is_available(),
|
| 8 |
+
"cuda_version": torch.version.cuda,
|
| 9 |
+
"device_count": torch.cuda.device_count(),
|
| 10 |
+
}
|
| 11 |
+
|
| 12 |
+
if torch.cuda.is_available():
|
| 13 |
+
props = torch.cuda.get_device_properties(0)
|
| 14 |
+
|
| 15 |
+
free_mem, total_mem = torch.cuda.mem_get_info()
|
| 16 |
+
|
| 17 |
+
report.update({
|
| 18 |
+
"device": "cuda:0",
|
| 19 |
+
"gpu_name": props.name,
|
| 20 |
+
"gpu_total_memory_mb": round(total_mem / 1024 / 1024, 2),
|
| 21 |
+
"gpu_free_memory_mb": round(free_mem / 1024 / 1024, 2),
|
| 22 |
+
"gpu_compute_capability": f"{props.major}.{props.minor}",
|
| 23 |
+
})
|
| 24 |
+
else:
|
| 25 |
+
report["device"] = "cpu"
|
| 26 |
+
|
| 27 |
+
return report
|
openmodellab/genome/inspectors/latency.py
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import statistics
|
| 2 |
+
import time
|
| 3 |
+
|
| 4 |
+
import torch
|
| 5 |
+
|
| 6 |
+
|
| 7 |
+
def inspect_latency(
|
| 8 |
+
model,
|
| 9 |
+
tokenizer,
|
| 10 |
+
text="OpenModelLab is benchmarking Hugging Face models.",
|
| 11 |
+
warmup_runs=5,
|
| 12 |
+
benchmark_runs=20,
|
| 13 |
+
):
|
| 14 |
+
model.eval()
|
| 15 |
+
|
| 16 |
+
# Detect execution device
|
| 17 |
+
if hasattr(model, "hf_device_map"):
|
| 18 |
+
devices = [
|
| 19 |
+
d for d in model.hf_device_map.values()
|
| 20 |
+
if d != "cpu"
|
| 21 |
+
]
|
| 22 |
+
|
| 23 |
+
if devices:
|
| 24 |
+
current_device = torch.device(devices[0])
|
| 25 |
+
else:
|
| 26 |
+
current_device = torch.device("cpu")
|
| 27 |
+
else:
|
| 28 |
+
current_device = next(model.parameters()).device
|
| 29 |
+
|
| 30 |
+
device = str(current_device)
|
| 31 |
+
|
| 32 |
+
inputs = tokenizer(
|
| 33 |
+
text,
|
| 34 |
+
return_tensors="pt",
|
| 35 |
+
truncation=True,
|
| 36 |
+
max_length=128,
|
| 37 |
+
)
|
| 38 |
+
|
| 39 |
+
inputs = {
|
| 40 |
+
key: value.to(current_device)
|
| 41 |
+
for key, value in inputs.items()
|
| 42 |
+
}
|
| 43 |
+
|
| 44 |
+
with torch.no_grad():
|
| 45 |
+
for _ in range(warmup_runs):
|
| 46 |
+
_ = model(**inputs)
|
| 47 |
+
|
| 48 |
+
if device.startswith("cuda"):
|
| 49 |
+
torch.cuda.synchronize()
|
| 50 |
+
|
| 51 |
+
timings = []
|
| 52 |
+
|
| 53 |
+
with torch.no_grad():
|
| 54 |
+
for _ in range(benchmark_runs):
|
| 55 |
+
|
| 56 |
+
if device.startswith("cuda"):
|
| 57 |
+
torch.cuda.synchronize()
|
| 58 |
+
|
| 59 |
+
start = time.perf_counter()
|
| 60 |
+
|
| 61 |
+
_ = model(**inputs)
|
| 62 |
+
|
| 63 |
+
if device.startswith("cuda"):
|
| 64 |
+
torch.cuda.synchronize()
|
| 65 |
+
|
| 66 |
+
end = time.perf_counter()
|
| 67 |
+
|
| 68 |
+
timings.append((end - start) * 1000)
|
| 69 |
+
|
| 70 |
+
return {
|
| 71 |
+
"device": device,
|
| 72 |
+
"warmup_runs": warmup_runs,
|
| 73 |
+
"benchmark_runs": benchmark_runs,
|
| 74 |
+
"average_ms": round(statistics.mean(timings), 3),
|
| 75 |
+
"min_ms": round(min(timings), 3),
|
| 76 |
+
"max_ms": round(max(timings), 3),
|
| 77 |
+
"std_ms": round(statistics.stdev(timings), 3),
|
| 78 |
+
}
|
openmodellab/genome/inspectors/memory.py
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import psutil
|
| 3 |
+
import torch
|
| 4 |
+
|
| 5 |
+
|
| 6 |
+
def get_process_memory_mb():
|
| 7 |
+
process = psutil.Process(os.getpid())
|
| 8 |
+
return process.memory_info().rss / (1024 ** 2)
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
def inspect_memory(model, tokenizer):
|
| 12 |
+
|
| 13 |
+
model.eval()
|
| 14 |
+
|
| 15 |
+
device = str(next(model.parameters()).device)
|
| 16 |
+
|
| 17 |
+
memory = {
|
| 18 |
+
"device": device,
|
| 19 |
+
"ram_before_mb": round(get_process_memory_mb(), 2),
|
| 20 |
+
}
|
| 21 |
+
|
| 22 |
+
text = "OpenModelLab memory benchmark."
|
| 23 |
+
|
| 24 |
+
inputs = tokenizer(
|
| 25 |
+
text,
|
| 26 |
+
return_tensors="pt",
|
| 27 |
+
truncation=True,
|
| 28 |
+
max_length=128,
|
| 29 |
+
)
|
| 30 |
+
|
| 31 |
+
inputs = {
|
| 32 |
+
key: value.to(next(model.parameters()).device)
|
| 33 |
+
for key, value in inputs.items()
|
| 34 |
+
}
|
| 35 |
+
|
| 36 |
+
if device.startswith("cuda"):
|
| 37 |
+
torch.cuda.reset_peak_memory_stats()
|
| 38 |
+
torch.cuda.empty_cache()
|
| 39 |
+
|
| 40 |
+
with torch.no_grad():
|
| 41 |
+
_ = model(**inputs)
|
| 42 |
+
|
| 43 |
+
memory["ram_after_mb"] = round(get_process_memory_mb(), 2)
|
| 44 |
+
|
| 45 |
+
if device.startswith("cuda"):
|
| 46 |
+
memory["gpu_allocated_mb"] = round(
|
| 47 |
+
torch.cuda.memory_allocated() / (1024 ** 2),
|
| 48 |
+
2
|
| 49 |
+
)
|
| 50 |
+
|
| 51 |
+
memory["gpu_peak_allocated_mb"] = round(
|
| 52 |
+
torch.cuda.max_memory_allocated() / (1024 ** 2),
|
| 53 |
+
2
|
| 54 |
+
)
|
| 55 |
+
|
| 56 |
+
return memory
|
openmodellab/genome/inspectors/precision.py
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import torch
|
| 2 |
+
|
| 3 |
+
|
| 4 |
+
def inspect_precision(model):
|
| 5 |
+
|
| 6 |
+
dtype = str(
|
| 7 |
+
next(model.parameters()).dtype
|
| 8 |
+
)
|
| 9 |
+
|
| 10 |
+
mapping = {
|
| 11 |
+
"torch.float32": {
|
| 12 |
+
"bits": 32,
|
| 13 |
+
"category": "FP32"
|
| 14 |
+
},
|
| 15 |
+
"torch.float16": {
|
| 16 |
+
"bits": 16,
|
| 17 |
+
"category": "FP16"
|
| 18 |
+
},
|
| 19 |
+
"torch.bfloat16": {
|
| 20 |
+
"bits": 16,
|
| 21 |
+
"category": "BF16"
|
| 22 |
+
},
|
| 23 |
+
"torch.int8": {
|
| 24 |
+
"bits": 8,
|
| 25 |
+
"category": "INT8"
|
| 26 |
+
}
|
| 27 |
+
}
|
| 28 |
+
|
| 29 |
+
info = mapping.get(
|
| 30 |
+
dtype,
|
| 31 |
+
{
|
| 32 |
+
"bits": None,
|
| 33 |
+
"category": "unknown"
|
| 34 |
+
}
|
| 35 |
+
)
|
| 36 |
+
|
| 37 |
+
return {
|
| 38 |
+
"dtype": dtype,
|
| 39 |
+
**info
|
| 40 |
+
}
|
openmodellab/genome/inspectors/throughput.py
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import time
|
| 2 |
+
import torch
|
| 3 |
+
|
| 4 |
+
|
| 5 |
+
def inspect_throughput(
|
| 6 |
+
model,
|
| 7 |
+
tokenizer,
|
| 8 |
+
text="OpenModelLab throughput benchmark.",
|
| 9 |
+
runs=50,
|
| 10 |
+
):
|
| 11 |
+
model.eval()
|
| 12 |
+
|
| 13 |
+
device = next(model.parameters()).device
|
| 14 |
+
device_name = str(device)
|
| 15 |
+
|
| 16 |
+
inputs = tokenizer(
|
| 17 |
+
text,
|
| 18 |
+
return_tensors="pt",
|
| 19 |
+
truncation=True,
|
| 20 |
+
max_length=128,
|
| 21 |
+
)
|
| 22 |
+
|
| 23 |
+
inputs = {
|
| 24 |
+
key: value.to(device)
|
| 25 |
+
for key, value in inputs.items()
|
| 26 |
+
}
|
| 27 |
+
|
| 28 |
+
# Warmup
|
| 29 |
+
with torch.no_grad():
|
| 30 |
+
for _ in range(5):
|
| 31 |
+
_ = model(**inputs)
|
| 32 |
+
|
| 33 |
+
if device_name.startswith("cuda"):
|
| 34 |
+
torch.cuda.synchronize()
|
| 35 |
+
|
| 36 |
+
start = time.perf_counter()
|
| 37 |
+
|
| 38 |
+
with torch.no_grad():
|
| 39 |
+
for _ in range(runs):
|
| 40 |
+
_ = model(**inputs)
|
| 41 |
+
|
| 42 |
+
if device_name.startswith("cuda"):
|
| 43 |
+
torch.cuda.synchronize()
|
| 44 |
+
|
| 45 |
+
end = time.perf_counter()
|
| 46 |
+
|
| 47 |
+
total_time = end - start
|
| 48 |
+
|
| 49 |
+
return {
|
| 50 |
+
"device": device_name,
|
| 51 |
+
"runs": runs,
|
| 52 |
+
"total_time_sec": round(total_time, 4),
|
| 53 |
+
"samples_per_second": round(
|
| 54 |
+
runs / total_time,
|
| 55 |
+
3
|
| 56 |
+
),
|
| 57 |
+
}
|
openmodellab/genome/inspectors/tokenizer.py
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
def inspect_tokenizer(tokenizer):
|
| 2 |
+
return {
|
| 3 |
+
"vocab_size": tokenizer.vocab_size,
|
| 4 |
+
"model_max_length": tokenizer.model_max_length,
|
| 5 |
+
"is_fast": tokenizer.is_fast,
|
| 6 |
+
"padding_side": tokenizer.padding_side,
|
| 7 |
+
"truncation_side": tokenizer.truncation_side,
|
| 8 |
+
"special_tokens": tokenizer.special_tokens_map,
|
| 9 |
+
"all_special_tokens": tokenizer.all_special_tokens,
|
| 10 |
+
}
|
openmodellab/genome/model_loader.py
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from transformers import AutoModel, AutoTokenizer
|
| 2 |
+
import torch
|
| 3 |
+
|
| 4 |
+
|
| 5 |
+
def load_model(model_name: str, device: str = "auto"):
|
| 6 |
+
|
| 7 |
+
print(f"Loading model: {model_name}")
|
| 8 |
+
|
| 9 |
+
tokenizer = AutoTokenizer.from_pretrained(model_name)
|
| 10 |
+
|
| 11 |
+
if device == "auto":
|
| 12 |
+
device = "cuda" if torch.cuda.is_available() else "cpu"
|
| 13 |
+
|
| 14 |
+
if device == "cuda":
|
| 15 |
+
|
| 16 |
+
try:
|
| 17 |
+
model = AutoModel.from_pretrained(
|
| 18 |
+
model_name
|
| 19 |
+
)
|
| 20 |
+
|
| 21 |
+
model = model.cuda()
|
| 22 |
+
|
| 23 |
+
print(
|
| 24 |
+
"Model loaded on CUDA:",
|
| 25 |
+
torch.cuda.get_device_name(0)
|
| 26 |
+
)
|
| 27 |
+
|
| 28 |
+
except Exception as e:
|
| 29 |
+
|
| 30 |
+
print("Standard CUDA loading failed.")
|
| 31 |
+
print(e)
|
| 32 |
+
|
| 33 |
+
print("Trying automatic device mapping...")
|
| 34 |
+
|
| 35 |
+
model = AutoModel.from_pretrained(
|
| 36 |
+
model_name,
|
| 37 |
+
device_map="auto"
|
| 38 |
+
)
|
| 39 |
+
|
| 40 |
+
else:
|
| 41 |
+
model = AutoModel.from_pretrained(
|
| 42 |
+
model_name
|
| 43 |
+
)
|
| 44 |
+
|
| 45 |
+
model = model.cpu()
|
| 46 |
+
|
| 47 |
+
print("Model loaded on CPU.")
|
| 48 |
+
|
| 49 |
+
return model, tokenizer
|
openmodellab/reporting/__init__.py
ADDED
|
File without changes
|
openmodellab/reporting/benchmark_writer.py
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from pathlib import Path
|
| 2 |
+
import json
|
| 3 |
+
|
| 4 |
+
|
| 5 |
+
def save_benchmark(report: dict, model_name: str):
|
| 6 |
+
"""
|
| 7 |
+
Save benchmark report as benchmark.json.
|
| 8 |
+
"""
|
| 9 |
+
|
| 10 |
+
outdir = Path("outputs") / model_name.replace("/", "_")
|
| 11 |
+
outdir.mkdir(parents=True, exist_ok=True)
|
| 12 |
+
|
| 13 |
+
outfile = outdir / "benchmark.json"
|
| 14 |
+
|
| 15 |
+
with open(outfile, "w", encoding="utf-8") as f:
|
| 16 |
+
json.dump(report, f, indent=2)
|
| 17 |
+
|
| 18 |
+
return str(outfile)
|
openmodellab/reporting/csv_writer.py
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import csv
|
| 2 |
+
|
| 3 |
+
|
| 4 |
+
def save_csv(results, filename):
|
| 5 |
+
|
| 6 |
+
with open(
|
| 7 |
+
filename,
|
| 8 |
+
"w",
|
| 9 |
+
newline=""
|
| 10 |
+
) as f:
|
| 11 |
+
|
| 12 |
+
writer = csv.writer(f)
|
| 13 |
+
|
| 14 |
+
writer.writerow([
|
| 15 |
+
"Model",
|
| 16 |
+
"Parameters",
|
| 17 |
+
"Layers",
|
| 18 |
+
"Hidden Size",
|
| 19 |
+
"Latency(ms)",
|
| 20 |
+
"Throughput"
|
| 21 |
+
])
|
| 22 |
+
|
| 23 |
+
for item in results:
|
| 24 |
+
|
| 25 |
+
writer.writerow([
|
| 26 |
+
item["model"],
|
| 27 |
+
item["parameters"],
|
| 28 |
+
item["layers"],
|
| 29 |
+
item["hidden_size"],
|
| 30 |
+
item["latency_ms"],
|
| 31 |
+
item["throughput"]
|
| 32 |
+
])
|
| 33 |
+
|
| 34 |
+
return filename
|
openmodellab/reporting/html_writer.py
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
def save_html(results, filename):
|
| 2 |
+
|
| 3 |
+
rows = ""
|
| 4 |
+
|
| 5 |
+
for item in results:
|
| 6 |
+
|
| 7 |
+
rows += f"""
|
| 8 |
+
<tr>
|
| 9 |
+
<td>{item['model']}</td>
|
| 10 |
+
<td>{item['parameters']}</td>
|
| 11 |
+
<td>{item['layers']}</td>
|
| 12 |
+
<td>{item['hidden_size']}</td>
|
| 13 |
+
<td>{item['latency_ms']}</td>
|
| 14 |
+
<td>{item['throughput']}</td>
|
| 15 |
+
</tr>
|
| 16 |
+
"""
|
| 17 |
+
|
| 18 |
+
html = f"""
|
| 19 |
+
<html>
|
| 20 |
+
<head>
|
| 21 |
+
<title>OpenModelLab Comparison</title>
|
| 22 |
+
</head>
|
| 23 |
+
|
| 24 |
+
<body>
|
| 25 |
+
|
| 26 |
+
<h1>OpenModelLab Model Comparison</h1>
|
| 27 |
+
|
| 28 |
+
<table border="1">
|
| 29 |
+
|
| 30 |
+
<tr>
|
| 31 |
+
<th>Model</th>
|
| 32 |
+
<th>Parameters</th>
|
| 33 |
+
<th>Layers</th>
|
| 34 |
+
<th>Hidden Size</th>
|
| 35 |
+
<th>Latency(ms)</th>
|
| 36 |
+
<th>Throughput</th>
|
| 37 |
+
</tr>
|
| 38 |
+
|
| 39 |
+
{rows}
|
| 40 |
+
|
| 41 |
+
</table>
|
| 42 |
+
|
| 43 |
+
</body>
|
| 44 |
+
</html>
|
| 45 |
+
"""
|
| 46 |
+
|
| 47 |
+
with open(filename, "w") as f:
|
| 48 |
+
f.write(html)
|
| 49 |
+
|
| 50 |
+
return filename
|
openmodellab/reporting/json_writer.py
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import json
|
| 2 |
+
from pathlib import Path
|
| 3 |
+
|
| 4 |
+
|
| 5 |
+
def save_json(report: dict, model_name: str):
|
| 6 |
+
model_dir = model_name.replace("/", "_")
|
| 7 |
+
|
| 8 |
+
out_dir = Path("outputs") / model_dir
|
| 9 |
+
out_dir.mkdir(parents=True, exist_ok=True)
|
| 10 |
+
|
| 11 |
+
output_file = out_dir / "genome.json"
|
| 12 |
+
|
| 13 |
+
with open(output_file, "w", encoding="utf-8") as f:
|
| 14 |
+
json.dump(report, f, indent=2)
|
| 15 |
+
|
| 16 |
+
return output_file
|
openmodellab/visualization/__init__.py
ADDED
|
File without changes
|
openmodellab/visualization/charts.py
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import matplotlib.pyplot as plt
|
| 2 |
+
|
| 3 |
+
|
| 4 |
+
def save_latency_chart(results, filename):
|
| 5 |
+
|
| 6 |
+
models = [
|
| 7 |
+
item["model"]
|
| 8 |
+
for item in results
|
| 9 |
+
]
|
| 10 |
+
|
| 11 |
+
latency = [
|
| 12 |
+
item["latency_ms"]
|
| 13 |
+
for item in results
|
| 14 |
+
]
|
| 15 |
+
|
| 16 |
+
plt.figure(figsize=(8, 5))
|
| 17 |
+
|
| 18 |
+
plt.bar(
|
| 19 |
+
models,
|
| 20 |
+
latency
|
| 21 |
+
)
|
| 22 |
+
|
| 23 |
+
plt.xlabel(
|
| 24 |
+
"Model"
|
| 25 |
+
)
|
| 26 |
+
|
| 27 |
+
plt.ylabel(
|
| 28 |
+
"Latency (ms)"
|
| 29 |
+
)
|
| 30 |
+
|
| 31 |
+
plt.title(
|
| 32 |
+
"Model Latency Comparison"
|
| 33 |
+
)
|
| 34 |
+
|
| 35 |
+
plt.xticks(
|
| 36 |
+
rotation=45
|
| 37 |
+
)
|
| 38 |
+
|
| 39 |
+
plt.tight_layout()
|
| 40 |
+
|
| 41 |
+
plt.savefig(
|
| 42 |
+
filename
|
| 43 |
+
)
|
| 44 |
+
|
| 45 |
+
plt.close()
|
| 46 |
+
|
| 47 |
+
|
| 48 |
+
|
| 49 |
+
def save_throughput_chart(results, filename):
|
| 50 |
+
|
| 51 |
+
models = [
|
| 52 |
+
item["model"]
|
| 53 |
+
for item in results
|
| 54 |
+
]
|
| 55 |
+
|
| 56 |
+
throughput = [
|
| 57 |
+
item["throughput"]
|
| 58 |
+
for item in results
|
| 59 |
+
]
|
| 60 |
+
|
| 61 |
+
plt.figure(figsize=(8, 5))
|
| 62 |
+
|
| 63 |
+
plt.bar(
|
| 64 |
+
models,
|
| 65 |
+
throughput
|
| 66 |
+
)
|
| 67 |
+
|
| 68 |
+
plt.xlabel(
|
| 69 |
+
"Model"
|
| 70 |
+
)
|
| 71 |
+
|
| 72 |
+
plt.ylabel(
|
| 73 |
+
"Samples / Second"
|
| 74 |
+
)
|
| 75 |
+
|
| 76 |
+
plt.title(
|
| 77 |
+
"Model Throughput Comparison"
|
| 78 |
+
)
|
| 79 |
+
|
| 80 |
+
plt.xticks(
|
| 81 |
+
rotation=45
|
| 82 |
+
)
|
| 83 |
+
|
| 84 |
+
plt.tight_layout()
|
| 85 |
+
|
| 86 |
+
plt.savefig(
|
| 87 |
+
filename
|
| 88 |
+
)
|
| 89 |
+
|
| 90 |
+
plt.close()
|
requirements.txt
CHANGED
|
@@ -4,4 +4,3 @@ torch
|
|
| 4 |
transformers
|
| 5 |
sentencepiece
|
| 6 |
safetensors
|
| 7 |
-
git+https://github.com/ajaygovinds/OpenModelLab.git
|
|
|
|
| 4 |
transformers
|
| 5 |
sentencepiece
|
| 6 |
safetensors
|
|
|