Skip to content

Commit

Permalink
Update benchmark script for yolo
Browse files Browse the repository at this point in the history
osw282 committed Jan 29, 2025

Verified

This commit was signed with the committer’s verified signature.
osw282 Oscar
1 parent 4ab1e62 commit 611da7a
Showing 10 changed files with 151,479 additions and 150,206 deletions.
61 changes: 43 additions & 18 deletions jetson/power_logging/model/benchmark_pruned_model.py
Original file line number Diff line number Diff line change
@@ -126,6 +126,30 @@ def layer_time_hook(layer_time_dict, layer_name, start_event, end_event, module,
layer_time_dict[layer_name]["start_time"] = start_event.get_time_stamp()


def get_layers_for_pruning(model: torch.nn.Module) -> tuple[(torch.nn.Module, str)]:
"""
Recursively get all layers in a pytorch model.
Args:
model: the pytorch model to look for layers.
name_prefix: Use to identify the parents layer. Defaults to "".
Returns:
a list of tuple containing the layer name and the layer.
"""
children = list(model.named_children())

if len(children) == 0:
result = [(model, "weight")]
else:
result = []
for _, child in children:
layers = get_layers_for_pruning(child)
result.extend(layers)

return tuple(result)


def benchmark(args: argparse.Namespace) -> None:
"""Benchmark latency and throughput across all backends.
@@ -138,24 +162,25 @@ def benchmark(args: argparse.Namespace) -> None:

try:
input_data = torch.randn(args.input_shape, device=DEVICE)
model = load_model(args.model, args.model_repo)
model.eval().to(DEVICE)

## PRUNING CODE FOR LENET ONLY
parameters_to_prune = (
(model.feat.conv1, 'weight'),
(model.feat.conv2, 'weight'),
(model.classifer.fc1, 'weight'),
(model.classifer.fc2, 'weight'),
(model.classifer.fc3, 'weight'),
)

prune.global_unstructured(
parameters_to_prune,
pruning_method=prune.L1Unstructured,
amount=0.3,
)

# model = load_model(args.model, args.model_repo)
# model.eval().to(DEVICE)

# ## PRUNING CODE FOR LENET ONLY
# parameters_to_prune = (
# (model.feat.conv1, 'weight'),
# (model.feat.conv2, 'weight'),
# (model.classifer.fc1, 'weight'),
# (model.classifer.fc2, 'weight'),
# (model.classifer.fc3, 'weight'),
# )

# prune.global_unstructured(
# parameters_to_prune,
# pruning_method=prune.L1Unstructured,
# amount=0.5,
# )
# Thus should load the pruned yolo model
model = torch.load("pruned_30_yolov5su.pt")
model.eval().to(DEVICE)

dtype = torch.float32
190 changes: 133 additions & 57 deletions jetson/power_logging/model_pruning_experiment.py
Original file line number Diff line number Diff line change
@@ -6,67 +6,143 @@
from model.model_utils import load_model


model = load_model("lenet", "pytorch/vision:v0.16.0")

parameters_to_prune = (
(model.feat.conv1, 'weight'),
(model.feat.conv2, 'weight'),
(model.classifer.fc1, 'weight'),
(model.classifer.fc2, 'weight'),
(model.classifer.fc3, 'weight'),
)
def get_layers_for_pruning(model: torch.nn.Module) -> tuple[(torch.nn.Module, str)]:
"""
Recursively get all layers in a pytorch model.
Args:
model: the pytorch model to look for layers.
name_prefix: Use to identify the parents layer. Defaults to "".
Returns:
a list of tuple containing the layer name and the layer.
"""
children = list(model.named_children())

if len(children) == 0:
result = [(model, "weight")]
else:
result = []
for _, child in children:
layers = get_layers_for_pruning(child)
result.extend(layers)

return tuple(result)

# Lenet experiment
# model = load_model("lenet", "pytorch/vision:v0.16.0")

# parameters_to_prune = (
# (model.feat.conv1, 'weight'),
# (model.feat.conv2, 'weight'),
# (model.classifer.fc1, 'weight'),
# (model.classifer.fc2, 'weight'),
# (model.classifer.fc3, 'weight'),
# )

# prune.global_unstructured(
# parameters_to_prune,
# pruning_method=prune.L1Unstructured,
# amount=0.3,
# )

# print(
# "Sparsity in conv1.weight: {:.2f}%".format(
# 100. * float(torch.sum(model.feat.conv1.weight == 0))
# / float(model.feat.conv1.weight.nelement())
# )
# )
# print(
# "Sparsity in conv2.weight: {:.2f}%".format(
# 100. * float(torch.sum(model.feat.conv2.weight == 0))
# / float(model.feat.conv2.weight.nelement())
# )
# )
# print(
# "Sparsity in fc1.weight: {:.2f}%".format(
# 100. * float(torch.sum(model.classifer.fc1.weight == 0))
# / float(model.classifer.fc1.weight.nelement())
# )
# )
# print(
# "Sparsity in fc2.weight: {:.2f}%".format(
# 100. * float(torch.sum(model.classifer.fc2.weight == 0))
# / float(model.classifer.fc2.weight.nelement())
# )
# )
# print(
# "Sparsity in fc3.weight: {:.2f}%".format(
# 100. * float(torch.sum(model.classifer.fc3.weight == 0))
# / float(model.classifer.fc3.weight.nelement())
# )
# )
# print(
# "Global sparsity: {:.2f}%".format(
# 100. * float(
# torch.sum(model.feat.conv1.weight == 0)
# + torch.sum(model.feat.conv2.weight == 0)
# + torch.sum(model.classifer.fc1.weight == 0)
# + torch.sum(model.classifer.fc2.weight == 0)
# + torch.sum(model.classifer.fc3.weight == 0)
# )
# / float(
# model.feat.conv1.weight.nelement()
# + model.feat.conv2.weight.nelement()
# + model.classifer.fc1.weight.nelement()
# + model.classifer.fc2.weight.nelement()
# + model.classifer.fc3.weight.nelement()
# )
# )
# )



# # VGG19
# model = load_model("vgg19", "pytorch/vision:v0.16.0")

# parameters_to_prune = get_layers_for_pruning(model)

# parameters_to_prune = [(layer, "weight") for layer, _ in parameters_to_prune if isinstance(layer, torch.nn.modules.conv.Conv2d)\
# or isinstance(layer, torch.nn.modules.pooling.MaxPool2d)\
# or isinstance(layer, torch.nn.modules.linear.Linear)]

# prune.global_unstructured(
# parameters_to_prune,
# pruning_method=prune.L1Unstructured,
# amount=0.5,
# )

#
# YOLOV5 MODEL DETECTION
from ultralytics import YOLO
# model = torch.hub.load('ultralytics/yolov5', 'yolov5su', pretrained=True)

model = YOLO("yolov5su.pt")
parameters_to_prune = get_layers_for_pruning(model)
parameters_to_prune = [(layer, "weight") for layer, _ in parameters_to_prune if isinstance(layer, torch.nn.modules.conv.Conv2d) or isinstance(layer, torch.nn.modules.linear.Linear)]
# print(parameters_to_prune)

prune.global_unstructured(
parameters_to_prune,
pruning_method=prune.L1Unstructured,
amount=0.3,
)
model.save("pruned_30_yolov5su.pt")

print(
"Sparsity in conv1.weight: {:.2f}%".format(
100. * float(torch.sum(model.feat.conv1.weight == 0))
/ float(model.feat.conv1.weight.nelement())
)
)
print(
"Sparsity in conv2.weight: {:.2f}%".format(
100. * float(torch.sum(model.feat.conv2.weight == 0))
/ float(model.feat.conv2.weight.nelement())
)
)
print(
"Sparsity in fc1.weight: {:.2f}%".format(
100. * float(torch.sum(model.classifer.fc1.weight == 0))
/ float(model.classifer.fc1.weight.nelement())
)
)
print(
"Sparsity in fc2.weight: {:.2f}%".format(
100. * float(torch.sum(model.classifer.fc2.weight == 0))
/ float(model.classifer.fc2.weight.nelement())
)
)
print(
"Sparsity in fc3.weight: {:.2f}%".format(
100. * float(torch.sum(model.classifer.fc3.weight == 0))
/ float(model.classifer.fc3.weight.nelement())
)
)
print(
"Global sparsity: {:.2f}%".format(
100. * float(
torch.sum(model.feat.conv1.weight == 0)
+ torch.sum(model.feat.conv2.weight == 0)
+ torch.sum(model.classifer.fc1.weight == 0)
+ torch.sum(model.classifer.fc2.weight == 0)
+ torch.sum(model.classifer.fc3.weight == 0)
)
/ float(
model.feat.conv1.weight.nelement()
+ model.feat.conv2.weight.nelement()
+ model.classifer.fc1.weight.nelement()
+ model.classifer.fc2.weight.nelement()
+ model.classifer.fc3.weight.nelement()
)
)
)
# print(list(parameters_to_prune[0][0].named_buffers()))
# model = torch.load("pruned_yolov5su.pt") # local model
model = YOLO("pruned_30_yolov5su.pt")
# Run evaluation on COCO dataset
results = model.val(data="coco.yaml")


# model = torch.load("yolov5su.pt") # local model, yolo weight
# parameters_to_prune = get_layers_for_pruning(model['model'])
# parameters_to_prune = [(layer, "weight") for layer, _ in parameters_to_prune if isinstance(layer, torch.nn.modules.conv.Conv2d) or isinstance(layer, torch.nn.modules.linear.Linear)]

# prune.global_unstructured(
# parameters_to_prune,
# pruning_method=prune.L1Unstructured,
# amount=0.3,
# )
# model.save("pruned_yolov5su.pt")
2 changes: 2 additions & 0 deletions jetson/power_logging/pyproject.toml
Original file line number Diff line number Diff line change
@@ -7,9 +7,11 @@ requires-python = ">=3.11"
dependencies = [
"boto3<1.36",
"dvc-s3>=3.2.0",
"opencv-python>=4.11.0.86",
"pandas>=2.2.3",
"pillow>=11.1.0",
"torch==2.2.2",
"ultralytics>=8.3.69",
]

[dependency-groups]
400 changes: 377 additions & 23 deletions jetson/power_logging/uv.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions model_training/.gitignore
Original file line number Diff line number Diff line change
@@ -165,6 +165,7 @@ results
raw_data

preprocessed_data
preprocessed_pruned_data

training_data
training_data_pruned
819 changes: 817 additions & 2 deletions model_training/notebooks/model_pruning_experiment.ipynb

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
layer_name,count,mean,std,min,25%,50%,75%,max
_classifer_fc1,391.0,2987833.3775048805,129046.58960477269,2868940.201034292,2880204.201034292,2920332.201034292,3120972.201034292,4030796.201034292
_classifer_fc2,294.0,2972540.962939054,118832.8817470928,2868940.201034292,2880204.201034292,2920332.201034292,3080844.201034292,3910604.201034292
_classifer_fc3,302.0,2978571.5652727024,101075.53600634467,2868940.201034292,2920332.201034292,2920332.201034292,3120972.201034292,3201228.201034292
_feat_conv1,1295.0,2969174.8265169174,117281.44489422483,2840076.201034292,2880204.201034292,2920332.201034292,3080844.201034292,4471500.201034293
_feat_conv2,1186.0,2975337.88062957,125012.05664853119,2868940.201034292,2880204.201034292,2920332.201034292,3080844.201034292,4150988.201034292
_classifer_fc1,3329.0,1039591.8531274738,7067.844457781049,997143.6849087896,1037271.6849087896,1037271.6849087896,1037271.6849087896,1085783.6849087896
_classifer_fc2,3272.0,1039617.7386985207,6860.524084077199,997143.6849087896,1037271.6849087896,1037271.6849087896,1037271.6849087896,1085783.6849087896
_classifer_fc3,3220.0,1039593.7917410877,7092.436870725182,997143.6849087896,1037271.6849087896,1037271.6849087896,1037271.6849087896,1085783.6849087896
_feat_conv1,4659.0,1039547.538096169,6682.685868258468,997143.6849087896,1037271.6849087896,1037271.6849087896,1037271.6849087896,1085783.6849087896
_feat_conv2,5670.0,1039552.173092211,6695.120810189197,997143.6849087896,1037271.6849087896,1037271.6849087896,1037271.6849087896,1085783.6849087896
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
layer_name,count,mean,std,min,25%,50%,75%,max
_classifer_fc1,30000.0,0.03271889597699042,0.08344154189025607,0.0225280001759529,0.0240640006959438,0.0241919998079538,0.0244159996509552,1.7739520072937012
_classifer_fc2,30000.0,0.016303278033745743,0.006474929616569975,0.0125120002776384,0.0161920003592968,0.0162240006029605,0.016287999227643,0.8745599985122681
_classifer_fc3,30000.0,0.015319187155148593,0.016917499832368725,0.0124479997903108,0.0126719996333122,0.0161920003592968,0.0165119990706443,1.0595519542694092
_feat_conv1,30000.0,0.09303836935671664,0.1452975595775661,0.0619199983775615,0.0681599974632263,0.0687040016055107,0.0693759992718696,1.8226879835128784
_feat_conv2,30000.0,0.0897523371003568,0.12151731998927569,0.0647680014371872,0.0706240013241767,0.0728320032358169,0.07668000273406504,1.827839970588684
_classifer_fc1,30000.0,0.1410618037243684,0.005823612067364417,0.1296640038490295,0.1382080018520355,0.1400000005960464,0.1419840008020401,0.2832320034503937
_classifer_fc2,30000.0,0.13753255145425597,0.0056683130046175124,0.1244480013847351,0.1348160058259964,0.1366399973630905,0.1384319961071014,0.1914239972829818
_classifer_fc3,30000.0,0.13637421754722795,0.005872467489681823,0.1239359974861145,0.1335999965667724,0.1354559957981109,0.1373119950294494,0.3209919929504394
_feat_conv1,30000.0,0.1975842976247271,0.010320115721285607,0.1783040016889572,0.1903360038995742,0.1933120042085647,0.2053119987249374,0.4440639913082123
_feat_conv2,30000.0,0.23883284374773503,0.008114767476086611,0.2211840003728866,0.2341759949922561,0.2375040054321289,0.2409600019454956,0.4228799939155578
192 changes: 96 additions & 96 deletions model_training/preprocessed_pruned_data/lenet/model_summary.json
Original file line number Diff line number Diff line change
@@ -1,98 +1,98 @@
{
"_feat_conv1": {
"input_shape": [
1,
1,
32,
32
],
"output_shape": [
1,
128,
30,
30
],
"kernel_size": [
3,
3
],
"stride": [
1,
1
],
"padding": [
0,
0
],
"type": "Conv2d"
},
"_feat_conv2": {
"input_shape": [
1,
128,
15,
15
],
"output_shape": [
1,
16,
13,
13
],
"kernel_size": [
3,
3
],
"stride": [
1,
1
],
"padding": [
0,
0
],
"type": "Conv2d"
},
"_classifer_fc1": {
"input_shape": [
1,
576
],
"output_shape": [
1,
120
],
"kernel_size": null,
"stride": null,
"padding": null,
"type": "Linear"
},
"_classifer_fc2": {
"input_shape": [
1,
120
],
"output_shape": [
1,
84
],
"kernel_size": null,
"stride": null,
"padding": null,
"type": "Linear"
},
"_classifer_fc3": {
"input_shape": [
1,
84
],
"output_shape": [
1,
10
],
"kernel_size": null,
"stride": null,
"padding": null,
"type": "Linear"
}
"_feat_conv1": {
"input_shape": [
1,
1,
32,
32
],
"output_shape": [
1,
128,
30,
30
],
"kernel_size": [
3,
3
],
"stride": [
1,
1
],
"padding": [
0,
0
],
"type": "Conv2d"
},
"_feat_conv2": {
"input_shape": [
1,
128,
15,
15
],
"output_shape": [
1,
16,
13,
13
],
"kernel_size": [
3,
3
],
"stride": [
1,
1
],
"padding": [
0,
0
],
"type": "Conv2d"
},
"_classifer_fc1": {
"input_shape": [
1,
576
],
"output_shape": [
1,
120
],
"kernel_size": null,
"stride": null,
"padding": null,
"type": "Linear"
},
"_classifer_fc2": {
"input_shape": [
1,
120
],
"output_shape": [
1,
84
],
"kernel_size": null,
"stride": null,
"padding": null,
"type": "Linear"
},
"_classifer_fc3": {
"input_shape": [
1,
84
],
"output_shape": [
1,
10
],
"kernel_size": null,
"stride": null,
"padding": null,
"type": "Linear"
}
}
300,000 changes: 150,000 additions & 150,000 deletions model_training/preprocessed_pruned_data/lenet/power_runtime_mapping_layerwise.csv

Large diffs are not rendered by default.

0 comments on commit 611da7a

Please sign in to comment.