26
26
]
27
27
28
28
29
+ def _init_var_node (var_node , value , scope , place ):
30
+ assert isinstance (value ,
31
+ np .ndarray ), 'The type of value should be numpy array.'
32
+ assert scope is not None , \
33
+ 'The scope cannot be set None.'
34
+ assert place is not None , \
35
+ 'The place cannot be set None.'
36
+ tensor = scope .var (var_node .name ()).get_tensor ()
37
+ tensor .set (value , place )
38
+
39
+
29
40
class QuantizationTransformPass (object ):
30
41
def __init__ (self ,
31
42
scope = None ,
@@ -88,14 +99,14 @@ def __init__(self,
88
99
assert activation_quantize_type != 'channel_wise_abs_max' , "The activation quantization type does not support 'channel_wise_abs_max'."
89
100
if activation_quantize_type not in quant_type :
90
101
raise ValueError (
91
- "Unknown activation_quantize_type : '%s'. It can only be " ,
92
- "'abs_max' or 'range_abs_max' or 'moving_average_abs_max'." ,
93
- str (activation_quantize_type ))
102
+ "Unknown activation_quantize_type : '%s'. It can only be "
103
+ "'abs_max' or 'range_abs_max' or 'moving_average_abs_max'." %
104
+ ( str (activation_quantize_type ) ))
94
105
if weight_quantize_type not in quant_type :
95
106
raise ValueError (
96
- "Unknown weight_quantize_type: '%s'. It can only be " ,
97
- "'abs_max' or 'channel_wise_abs_max' or 'range_abs_max' or 'moving_average_abs_max'." ,
98
- str (weight_quantize_type ))
107
+ "Unknown weight_quantize_type: '%s'. It can only be "
108
+ "'abs_max' or 'channel_wise_abs_max' or 'range_abs_max' or 'moving_average_abs_max'."
109
+ % ( str (weight_quantize_type ) ))
99
110
100
111
self ._activation_quantize_type = activation_quantize_type
101
112
self ._weight_quantize_type = weight_quantize_type
@@ -121,8 +132,6 @@ def apply(self, graph):
121
132
"""
122
133
assert isinstance (graph ,
123
134
IrGraph ), 'graph must be the instance of IrGraph.'
124
- #sequential_execution = core.get_pass('sequential_execution_pass')
125
- #sequential_execution.apply(graph.graph)
126
135
self ._is_test = graph .is_test ()
127
136
# marked the variable which has been dequantized.
128
137
dequantized_vars = collections .OrderedDict ()
@@ -203,9 +212,12 @@ def _create_global_step(self, graph):
203
212
var_type = core .VarDesc .VarType .LOD_TENSOR ,
204
213
shape = [1 ],
205
214
var_dtype = core .VarDesc .VarType .INT64 )
206
- self ._init_var_node (
207
- global_step_in , np .zeros (
208
- [1 ], dtype = 'int64' ))
215
+ _init_var_node (
216
+ global_step_in ,
217
+ np .zeros (
218
+ [1 ], dtype = 'int64' ),
219
+ self ._scope ,
220
+ self ._place )
209
221
global_step_out = graph .create_var_node_from_desc (
210
222
global_step_in .var ())
211
223
# The attribute of `op_role` is needed by ParallelExecutor.
@@ -284,7 +296,12 @@ def _insert_quant_range_abs_max_op(self, graph, var_node, quant_bits):
284
296
var_dtype = var_node .dtype ())
285
297
data_type = 'float64' if var_node .dtype (
286
298
) == core .VarDesc .VarType .FP64 else 'float32'
287
- self ._init_var_node (scale_in_node , np .array ([0.001 ], dtype = data_type ))
299
+ _init_var_node (
300
+ scale_in_node ,
301
+ np .array (
302
+ [0.001 ], dtype = data_type ),
303
+ self ._scope ,
304
+ self ._place )
288
305
289
306
scale_out_node = graph .create_var_node_from_desc (scale_in_node .var ())
290
307
inputs = {'X' : var_node , 'InScale' : scale_in_node }
@@ -299,9 +316,13 @@ def _insert_quant_range_abs_max_op(self, graph, var_node, quant_bits):
299
316
var_dtype = var_node .dtype ())
300
317
data_type = 'float64' if var_node .dtype (
301
318
) == core .VarDesc .VarType .FP64 else 'float32'
302
- self ._init_var_node (
303
- scales_node , np .zeros (
304
- [self ._window_size ], dtype = data_type ))
319
+ _init_var_node (
320
+ scales_node ,
321
+ np .zeros (
322
+ [self ._window_size ], dtype = data_type ),
323
+ self ._scope ,
324
+ self ._place )
325
+
305
326
inputs ['Iter' ] = self ._global_step
306
327
outputs ['OutScales' ] = scales_node
307
328
attrs = {
@@ -343,7 +364,12 @@ def _insert_quant_moving_average_abs_max_op(self, graph, var_node,
343
364
var_dtype = var_node .dtype ())
344
365
data_type = 'float64' if var_node .dtype (
345
366
) == core .VarDesc .VarType .FP64 else 'float32'
346
- self ._init_var_node (scale_in_node , np .array ([0.001 ], dtype = data_type ))
367
+ _init_var_node (
368
+ scale_in_node ,
369
+ np .array (
370
+ [0.001 ], dtype = data_type ),
371
+ self ._scope ,
372
+ self ._place )
347
373
348
374
scale_out_node = graph .create_var_node_from_desc (scale_in_node .var ())
349
375
ins = {'X' : var_node , 'InScale' : scale_in_node }
@@ -356,13 +382,23 @@ def _insert_quant_moving_average_abs_max_op(self, graph, var_node,
356
382
shape = [1 ])
357
383
data_type = 'float64' if var_node .dtype (
358
384
) == core .VarDesc .VarType .FP64 else 'float32'
359
- self ._init_var_node (scale_in_node , np .ones ([1 ], dtype = data_type ))
385
+ _init_var_node (
386
+ scale_in_node ,
387
+ np .ones (
388
+ [1 ], dtype = data_type ),
389
+ self ._scope ,
390
+ self ._place )
360
391
accum_in_node = graph .create_persistable_node (
361
392
name = unique_name .generate ('accum' ),
362
393
var_type = core .VarDesc .VarType .LOD_TENSOR ,
363
394
var_dtype = var_node .dtype (),
364
395
shape = [1 ])
365
- self ._init_var_node (accum_in_node , np .ones ([1 ], dtype = data_type ))
396
+ _init_var_node (
397
+ accum_in_node ,
398
+ np .ones (
399
+ [1 ], dtype = data_type ),
400
+ self ._scope ,
401
+ self ._place )
366
402
state_out_node = graph .create_var_node_from_desc (state_in_node .var (
367
403
))
368
404
accum_out_node = graph .create_var_node_from_desc (accum_in_node .var (
@@ -482,16 +518,6 @@ def _insert_channel_dequant_op(self, graph, var_node, scale_var_nodes,
482
518
graph .link_to (dequant_op_node , dequant_var_node )
483
519
return dequant_var_node
484
520
485
- def _init_var_node (self , var_node , value ):
486
- assert isinstance (
487
- value , np .ndarray ), 'The type of value should be numpy array.'
488
- assert self ._scope is not None , \
489
- 'The scope cannot be set None when activation_quantize_type equals to range_abs_max.'
490
- assert self ._place is not None , \
491
- 'The place cannot be set None when activation_quantize_type equals to range_abs_max.'
492
- tensor = self ._scope .var (var_node .name ()).get_tensor ()
493
- tensor .set (value , self ._place )
494
-
495
521
def _quantized_var_name (self , var_name ):
496
522
"""
497
523
Return quantized variable name for the input `var_name`.
@@ -594,8 +620,8 @@ def apply(self, graph):
594
620
self ._weight_bits )
595
621
self ._restore_var (input_arg_name , quantized_param_v )
596
622
else :
597
- scale_v = self . _to_node ( op_node . outputs ,
598
- op_node .output ('OutScale' )[0 ])
623
+ scale_v = graph . _find_node_by_name (
624
+ op_node . outputs , op_node .output ('OutScale' )[0 ])
599
625
self ._var_scale_map [input_arg_name ] = scale_v
600
626
601
627
ops = graph .all_op_nodes ()
@@ -627,8 +653,8 @@ def apply(self, graph):
627
653
return graph
628
654
629
655
def _remove_fake_quant_and_dequant_op (self , graph , op_node ):
630
- k = self . _to_node (op_node .outputs , op_node .output ('Out' )[0 ])
631
- v = self . _to_node (op_node .inputs , op_node .input ('X' )[0 ])
656
+ k = graph . _find_node_by_name (op_node .outputs , op_node .output ('Out' )[0 ])
657
+ v = graph . _find_node_by_name (op_node .inputs , op_node .input ('X' )[0 ])
632
658
if v .node not in self ._op_input_rename_map :
633
659
self ._op_input_rename_map [k .node ] = v
634
660
else :
@@ -663,16 +689,18 @@ def _insert_post_channel_dequant_op(self, graph, op_node):
663
689
raise ValueError ("Only support one output, but op %s has"
664
690
" more than one output." % (op_node .name ()))
665
691
666
- output_var_node = self . _to_node ( op_node . outputs ,
667
- op_node .output_arg_names ()[0 ])
692
+ output_var_node = graph . _find_node_by_name (
693
+ op_node . outputs , op_node .output_arg_names ()[0 ])
668
694
weight_scale_node = graph .create_persistable_node (
669
695
name = unique_name .generate ('channel_scale' ),
670
696
var_type = core .VarDesc .VarType .LOD_TENSOR ,
671
697
shape = [channel_scale .shape [0 ]],
672
698
var_dtype = output_var_node .dtype ())
673
699
data_type = 'float64' if output_var_node .dtype (
674
700
) == core .VarDesc .VarType .FP64 else 'float32'
675
- self ._init_var_node (weight_scale_node , channel_scale .astype (data_type ))
701
+ _init_var_node (weight_scale_node ,
702
+ channel_scale .astype (data_type ), self ._scope ,
703
+ self ._place )
676
704
dequant_var_node = graph .create_var_node (
677
705
name = self ._dequantized_var_name (output_var_node .name ()),
678
706
var_type = output_var_node .type (),
@@ -724,8 +752,8 @@ def _insert_post_dequant_op(self, graph, op_node):
724
752
raise ValueError ("Only support one output, but op %s has"
725
753
" more than one output." % (op_node .name ()))
726
754
727
- output_var_node = self . _to_node ( op_node . outputs ,
728
- op_node .output_arg_names ()[0 ])
755
+ output_var_node = graph . _find_node_by_name (
756
+ op_node . outputs , op_node .output_arg_names ()[0 ])
729
757
dequant_var_node = graph .create_var_node (
730
758
name = self ._dequantized_var_name (output_var_node .name ()),
731
759
var_type = output_var_node .type (),
@@ -746,24 +774,6 @@ def _insert_post_dequant_op(self, graph, op_node):
746
774
self ._op_output_rename_map [output_var_node .node ] = dequant_var_node
747
775
return dequant_var_node
748
776
749
- def _init_var_node (self , var_node , value ):
750
- assert isinstance (
751
- value , np .ndarray ), 'The type of value should be numpy array.'
752
- assert self ._scope is not None , \
753
- 'The scope cannot be set None when activation_quantize_type equals to range_abs_max.'
754
- assert self ._place is not None , \
755
- 'The place cannot be set None when activation_quantize_type equals to range_abs_max.'
756
- tensor = self ._scope .var (var_node .name ()).get_tensor ()
757
- tensor .set (value , self ._place )
758
-
759
- def _to_node (self , nodes , node_name ):
760
- target_node = None
761
- for n in nodes :
762
- if n .name () == node_name :
763
- target_node = n
764
- assert target_node is not None , "Cannot find the target node in the giving set."
765
- return target_node
766
-
767
777
def _load_var (self , name ):
768
778
return np .array (self ._scope .find_var (name ).get_tensor ())
769
779
0 commit comments