MCPcopy Create free account
hub / github.com/DeepRec-AI/DeepRec / QuantizeWeights

Function QuantizeWeights

tensorflow/tools/graph_transforms/quantize_weights.cc:34–141  ·  view source on GitHub ↗

Converts any large float constants into eight-bit equivalents, with a Dequantize op so that subsequent nodes can still access the results in a float form.

Source from the content-addressed store, hash-verified

32// Dequantize op so that subsequent nodes can still access the results in a
33// float form.
34Status QuantizeWeights(const GraphDef& input_graph_def,
35 const TransformFuncContext& context,
36 GraphDef* output_graph_def) {
37 int32 minimum_size;
38 TF_RETURN_IF_ERROR(
39 context.GetOneInt32Parameter("minimum_size", 1024, &minimum_size));
40 TF_RETURN_IF_ERROR(ReplaceMatchingOpTypes(
41 input_graph_def, {"Const"},
42 [minimum_size](const NodeMatch& match,
43 const std::set<string>& input_nodes,
44 const std::set<string>& output_nodes,
45 std::vector<NodeDef>* new_nodes) {
46 const NodeDef& old_const_node = match.node;
47 if (!old_const_node.attr().count("dtype")) {
48 return errors::InvalidArgument("No 'dtype' attribute for Const node ",
49 old_const_node.name());
50 }
51 if (!old_const_node.attr().count("value")) {
52 return errors::InvalidArgument("No 'value' attribute for Const node ",
53 old_const_node.name());
54 }
55 const DataType old_dtype = old_const_node.attr().at("dtype").type();
56 Tensor old_tensor;
57 if (!old_tensor.FromProto(old_const_node.attr().at("value").tensor())) {
58 return errors::InvalidArgument("Decoding Tensor failed for node",
59 old_const_node.name());
60 }
61 const size_t num_elements = old_tensor.NumElements();
62 // If this isn't a float constant, or it's too small, then reuse the
63 // same node with no changes.
64 if ((old_dtype != DT_FLOAT) || (num_elements < minimum_size)) {
65 new_nodes->push_back(old_const_node);
66 return Status::OK();
67 }
68 const float* old_values = old_tensor.flat<float>().data();
69 float min = std::numeric_limits<float>::max();
70 float max = std::numeric_limits<float>::min();
71 for (int i = 0; i < num_elements; ++i) {
72 const float value = old_values[i];
73 min = std::min(min, value);
74 max = std::max(max, value);
75 }
76 // Make sure the quantization range includes 0.0f. Not all quantized
77 // Ops behave properly if 0.0f is not in the range.
78 min = std::min(min, 0.0f);
79 max = std::max(0.0f, max);
80 // min_value == max_value is a tricky case. It can occur for general
81 // tensors, and of course for scalars. The quantized ops cannot deal
82 // with this case, so we set max_value to something else.
83 // It's a tricky question what is the numerically best solution to
84 // deal with this degeneracy.
85 // TODO(petewarden): Better use a tolerance than a hard comparison?
86 if (min == max) {
87 if (std::abs(min) < 0.000001f) {
88 max = min + 1.0f;
89 } else if (min > 0) {
90 max = 2.0f * min;
91 } else {

Callers 2

TestQuantizeWeightsMethod · 0.70
TEST_FFunction · 0.70

Calls 15

ReplaceMatchingOpTypesFunction · 0.85
InvalidArgumentFunction · 0.85
AddNodeInputFunction · 0.85
GetOneInt32ParameterMethod · 0.80
attrMethod · 0.80
set_opMethod · 0.80
SetNodeAttrFunction · 0.70
nameMethod · 0.65
typeMethod · 0.65
maxFunction · 0.50
minFunction · 0.50
absFunction · 0.50

Tested by 2

TestQuantizeWeightsMethod · 0.56
TEST_FFunction · 0.56