vuiseng9 commited on
Commit
925eb8b
1 Parent(s): 949837c

add analyze_ovir.py

Browse files
scripts/ADDITIONAL/analyze_ovir.py ADDED
@@ -0,0 +1,128 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from openvino.runtime import Core
2
+ from tqdm import tqdm
3
+ import torch
4
+ from collections import OrderedDict
5
+ from pathlib import Path
6
+ import numpy as np
7
+ from collections import Counter
8
+ import os
9
+
10
+ QDTYPE_SPECIAL_VALUES={
11
+ 'u4': [0, 1, 2, 4, 8],
12
+ 'u8': [0, 1, 2, 4, 8, 16, 32, 64, 128],
13
+ 'int8': [-1, -2, -4, -8, -16, -32, -64, -128, 0, 1, 2, 4, 8, 16, 32, 64]
14
+ }
15
+
16
+ zero_point_map = {
17
+ 'u4': 8,
18
+ 'u8': 128,
19
+ 'int8': 0,
20
+ }
21
+
22
+ def get_uniq_value_stats(tensor, q_dtype):
23
+ if q_dtype not in QDTYPE_SPECIAL_VALUES.keys():
24
+ raise NotImplementedError(f"Unsupported q_dtype {q_dtype}")
25
+
26
+ value_counts = Counter(tensor.flatten())
27
+ total_elements = sum(value_counts.values())
28
+
29
+ top1_val, top1_count = value_counts.most_common(1)[0]
30
+ top1_tuple = (top1_val, top1_count/total_elements)
31
+
32
+ # Calculate ratio for each value
33
+ count_ratio_dict = {value: {'count': count, 'ratio': count / total_elements}
34
+ for value, count in value_counts.items()}
35
+
36
+ # # Find unique elements and their counts
37
+ # unique_values, counts = np.unique(tensor, return_counts=True)
38
+ # # Calculate the total number of elements in the tensor
39
+ # total_elements = tensor.size
40
+ # # Calculate the relative ratio for each unique value
41
+ # ratios = counts / total_elements
42
+
43
+ special_value_count = 0
44
+ special_value_ratio = 0
45
+ sparsity = 0
46
+ zero_count = 0
47
+
48
+ # for value, count, ratio in zip(unique_values, counts, ratios):
49
+ for value, vdict in count_ratio_dict.items():
50
+ count = vdict['count']
51
+ ratio = vdict['ratio']
52
+ if value == zero_point_map[q_dtype]:
53
+ sparsity = ratio
54
+ zero_count = count
55
+
56
+ # zero will enter both above and below
57
+ if value in QDTYPE_SPECIAL_VALUES[q_dtype]:
58
+ special_value_count += count
59
+ special_value_ratio += ratio
60
+
61
+ return dict(
62
+ numel=total_elements,
63
+ sparsity=sparsity,
64
+ special_value_ratio=special_value_ratio,
65
+ top1=top1_tuple,
66
+ raw=count_ratio_dict
67
+ )
68
+
69
+
70
+ def get_ir_pair(model_dir):
71
+ p = Path(model_dir)
72
+ return p/"openvino_model.xml", p/"openvino_model.bin"
73
+
74
+
75
+ # fc_numel = {
76
+ # 'llama-2-chat-7b ': {'min': 16777216, 'max': 45088768},
77
+ # 'mistral-7b ': {'min': 4194304, 'max': 58720256},
78
+ # 'gemma-2b-it': {'min': 524288, 'max': 33554432},
79
+ # }
80
+
81
+ fc_numel = {
82
+ 'llama-2-chat-7b': [16777216, 45088768],
83
+ 'mistral-7b': [4194304, 16777216, 58720256],
84
+ 'gemma-2b-it': [524288, 4194304, 33554432],
85
+ }
86
+
87
+ ovir_folder = "stable-diffusion-pokemons-1-5-quantized/unet"
88
+
89
+ # model_key = compressed_weight_folder.split("/")[2]
90
+
91
+ ir_xml, ir_bin = get_ir_pair(ovir_folder)
92
+
93
+ ie = Core()
94
+ ir_model = ie.read_model(ir_xml)
95
+
96
+ model_params = OrderedDict()
97
+
98
+ csv_path = os.path.join(ovir_folder, "weight_dist.csv")
99
+
100
+ with open(csv_path, "w") as outfile:
101
+ outfile.write("layer,dtype,w_ndim,shape,numel,sparsity,special_val_ratio,top1_val_ratio,top1_val\n")
102
+
103
+ # for op in tqdm(ir_model.get_ordered_ops()):
104
+ for op in ir_model.get_ordered_ops():
105
+ if 'constant' in str(op.get_type_info()).lower():
106
+ shape = tuple(op.get_output_shape(0))
107
+ numel = np.prod(shape)
108
+
109
+
110
+ if op.data.dtype.name == "int8":
111
+ # print(f"{numel:15} | {str(shape):20} | {op.get_name():20} | {op.data.dtype.name}")
112
+ layer = op.get_name()
113
+ q_dtype = op.data.dtype.name
114
+
115
+ # model_params[layer] = {}
116
+
117
+ statdict = get_uniq_value_stats(op.data, op.data.dtype.name)
118
+
119
+ # print("joto")
120
+ # q_mode = "sym" if attr['q_zero_point'][0] == zero_point_map[attr['q_dtype']] else "asym"
121
+ # is_top1_zero_point = "zero_point" if statdict['top1'][0] == zero_point_map[attr['q_dtype']] else statdict['top1'][0] # zero point is per channel per group
122
+ # print(f"{layer:30} | {attr['q_dtype']} ({q_mode:>5}) | orig. shape: {str(attr['original_shape']):15} | numel: {statdict['numel']:>15,} | sparsity: {statdict['sparsity']:.2f} | special ratio: {statdict['special_value_ratio']:.2f} | top1 ratio: {statdict['top1'][1]:.2f} ({is_top1_zero_point:>10}) |")
123
+ print(f"{layer:30} | {q_dtype} | orig. shape: {str(shape):20} | numel: {statdict['numel']:>15,} | sparsity: {statdict['sparsity']:.2f} | special ratio: {statdict['special_value_ratio']:.2f} | top1 ratio: {statdict['top1'][1]:.2f} (val: {statdict['top1'][0]})")
124
+
125
+ shape_str = str(shape).replace(", "," x ")
126
+ outfile.write(f"{layer:>25},{q_dtype},{len(shape)},{shape_str:20},{statdict['numel']:>15},{statdict['sparsity']:.4f},{statdict['special_value_ratio']:.4f},{statdict['top1'][1]:.4f},{statdict['top1'][0]}\n")
127
+
128
+ print('Done!')
scripts/ADDITIONAL/readme.md ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ The whole repo was based on the objectives of evaluating how much a certain value (power of twos) in quantized weights. But there wasn't a script here to do that.
2
+
3
+ Later in July 24, found an old script `analyze_ovir.py` that does that for unet of `OpenVINO/stable-diffusion-pokemons-1-5-quantized`.