update,
This commit is contained in:
@@ -0,0 +1,143 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (c) 2023 Intel Corporation
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import os
|
||||
import shutil
|
||||
import time
|
||||
import unittest
|
||||
|
||||
import numpy as np
|
||||
import tensorflow as tf
|
||||
from tensorflow import keras
|
||||
|
||||
from neural_compressor.data.dataloaders.dataloader import DataLoader
|
||||
|
||||
|
||||
def build_model():
|
||||
# Load MNIST dataset
|
||||
mnist = keras.datasets.mnist
|
||||
# 60000 images in train and 10000 images in test, but we don't need so much for ut
|
||||
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
|
||||
train_images, train_labels = train_images[:1000], train_labels[:1000]
|
||||
test_images, test_labels = test_images[:200], test_labels[:200]
|
||||
# Normalize the input image so that each pixel value is between 0 to 1.
|
||||
train_images = train_images / 255.0
|
||||
test_images = test_images / 255.0
|
||||
|
||||
# Define the model architecture.
|
||||
model = keras.Sequential(
|
||||
[
|
||||
keras.layers.InputLayer(input_shape=(28, 28)),
|
||||
keras.layers.Reshape(target_shape=(28, 28, 1)),
|
||||
keras.layers.Conv2D(filters=12, kernel_size=(3, 3), activation="relu"),
|
||||
keras.layers.MaxPooling2D(pool_size=(2, 2)),
|
||||
keras.layers.Flatten(),
|
||||
keras.layers.Dense(10),
|
||||
]
|
||||
)
|
||||
# Train the digit classification model
|
||||
model.compile(
|
||||
optimizer="adam", loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True), metrics=["accuracy"]
|
||||
)
|
||||
|
||||
model.fit(
|
||||
train_images,
|
||||
train_labels,
|
||||
epochs=1,
|
||||
validation_split=0.1,
|
||||
)
|
||||
|
||||
_, baseline_model_accuracy = model.evaluate(test_images, test_labels, verbose=0)
|
||||
|
||||
print("Baseline test accuracy:", baseline_model_accuracy)
|
||||
model.save("baseline_model")
|
||||
|
||||
|
||||
class Dataset(object):
|
||||
def __init__(self, batch_size=100):
|
||||
mnist = keras.datasets.mnist
|
||||
# 60000 images in train and 10000 images in test, but we don't need so much for ut
|
||||
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
|
||||
train_images, train_labels = train_images[:1000], train_labels[:1000]
|
||||
test_images, test_labels = test_images[:200], test_labels[:200]
|
||||
# Normalize the input image so that each pixel value is between 0 to 1.
|
||||
self.train_images = train_images / 255.0
|
||||
self.test_images = test_images / 255.0
|
||||
self.train_labels = train_labels
|
||||
self.test_labels = test_labels
|
||||
|
||||
def __len__(self):
|
||||
return len(self.test_images)
|
||||
|
||||
def __getitem__(self, idx):
|
||||
return self.test_images[idx].astype(np.float32), self.test_labels[idx]
|
||||
|
||||
|
||||
class TestBigSavedModel(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(self):
|
||||
build_model()
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(self):
|
||||
shutil.rmtree("baseline_model", ignore_errors=True)
|
||||
shutil.rmtree("int8_model", ignore_errors=True)
|
||||
|
||||
def test_newapi_sq_big_saved_model(self):
|
||||
def weight_name_mapping(name):
|
||||
"""The function that maps name from AutoTrackable variables to graph nodes."""
|
||||
name = name.replace("dense", "StatefulPartitionedCall/sequential/dense/MatMul")
|
||||
name = name.replace("conv2d", "StatefulPartitionedCall/sequential/conv2d/Conv2D")
|
||||
name = name.replace("kernel:0", "ReadVariableOp")
|
||||
return name
|
||||
|
||||
from neural_compressor import Model, quantization
|
||||
from neural_compressor.config import PostTrainingQuantConfig
|
||||
|
||||
model = Model("baseline_model", modelType="llm_saved_model")
|
||||
model.weight_name_mapping = weight_name_mapping
|
||||
|
||||
output_node_names = model.output_node_names
|
||||
self.assertEqual(output_node_names, ["Identity"])
|
||||
|
||||
calib_dataloader = DataLoader(framework="tensorflow", dataset=Dataset())
|
||||
recipes = {"smooth_quant": True, "smooth_quant_args": {"alpha": 0.6}}
|
||||
op_name_dict = {
|
||||
"StatefulPartitionedCall/sequential/conv2d/Conv2D": {
|
||||
"weight": {"dtype": ["fp32"]},
|
||||
"activation": {"dtype": ["fp32"]},
|
||||
}
|
||||
}
|
||||
config = PostTrainingQuantConfig(
|
||||
quant_level=1,
|
||||
recipes=recipes,
|
||||
op_name_dict=op_name_dict,
|
||||
calibration_sampling_size=[500],
|
||||
)
|
||||
model.weight_name_mapping = weight_name_mapping
|
||||
q_model = quantization.fit(model, config, calib_dataloader=calib_dataloader)
|
||||
q_model.save("int8_model")
|
||||
quant_count = 0
|
||||
for i in q_model.graph_def.node:
|
||||
if i.op == "QuantizeV2":
|
||||
quant_count += 1
|
||||
|
||||
self.assertEqual(quant_count, 3)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
@@ -0,0 +1,186 @@
|
||||
import unittest
|
||||
|
||||
import numpy as np
|
||||
import tensorflow as tf
|
||||
from tensorflow.compat.v1 import graph_util
|
||||
|
||||
from neural_compressor.adaptor.tf_utils.util import disable_random
|
||||
from neural_compressor.config import PostTrainingQuantConfig
|
||||
from neural_compressor.data.dataloaders.dataloader import DataLoader
|
||||
from neural_compressor.quantization import fit
|
||||
from neural_compressor.utils.utility import set_random_seed
|
||||
|
||||
|
||||
class TestSmoothQuantTFNewApi(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(self):
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(self):
|
||||
pass
|
||||
|
||||
@disable_random()
|
||||
def test_newapi_conv_sq(self):
|
||||
x = tf.compat.v1.placeholder(tf.float32, [1, 56, 56, 16], name="input")
|
||||
top_relu = tf.nn.relu(x)
|
||||
paddings = tf.constant([[0, 0], [1, 1], [1, 1], [0, 0]])
|
||||
x_pad = tf.pad(top_relu, paddings, "CONSTANT")
|
||||
conv_weights = tf.compat.v1.get_variable(
|
||||
"weight", [3, 3, 16, 16], initializer=tf.compat.v1.random_normal_initializer()
|
||||
)
|
||||
conv = tf.nn.conv2d(x_pad, conv_weights, strides=[1, 2, 2, 1], padding="VALID")
|
||||
normed = tf.compat.v1.layers.batch_normalization(conv)
|
||||
|
||||
conv_weights2 = tf.compat.v1.get_variable(
|
||||
"weight2", [3, 3, 16, 16], initializer=tf.compat.v1.random_normal_initializer()
|
||||
)
|
||||
conv2 = tf.nn.conv2d(top_relu, conv_weights2, strides=[1, 2, 2, 1], padding="SAME")
|
||||
normed2 = tf.compat.v1.layers.batch_normalization(conv2)
|
||||
add = tf.raw_ops.Add(x=normed, y=normed2, name="addv2")
|
||||
relu = tf.nn.relu(add)
|
||||
relu6 = tf.nn.relu6(relu, name="op_to_store")
|
||||
|
||||
out_name = relu6.name.split(":")[0]
|
||||
with tf.compat.v1.Session() as sess:
|
||||
sess.run(tf.compat.v1.global_variables_initializer())
|
||||
output_graph_def = graph_util.convert_variables_to_constants(
|
||||
sess=sess, input_graph_def=sess.graph_def, output_node_names=[out_name]
|
||||
)
|
||||
|
||||
set_random_seed(9527)
|
||||
config = PostTrainingQuantConfig(
|
||||
quant_level=1,
|
||||
recipes={"smooth_quant": True, "smooth_quant_args": {"alpha": 0.5}},
|
||||
calibration_sampling_size=[500],
|
||||
)
|
||||
|
||||
from neural_compressor.data import Datasets
|
||||
|
||||
dataset = Datasets("tensorflow")["dummy"](shape=(100, 56, 56, 16), label=True)
|
||||
dataloader = DataLoader(framework="tensorflow", dataset=dataset, batch_size=1)
|
||||
from neural_compressor import Metric
|
||||
|
||||
top1 = Metric(name="topk", k=1)
|
||||
output_graph = fit(
|
||||
model=output_graph_def,
|
||||
conf=config,
|
||||
calib_dataloader=dataloader,
|
||||
eval_dataloader=dataloader,
|
||||
eval_metric=top1,
|
||||
)
|
||||
|
||||
mul_count = 0
|
||||
for i in output_graph.graph_def.node:
|
||||
if i.op == "Mul":
|
||||
mul_count += 1
|
||||
|
||||
self.assertEqual(mul_count, 2)
|
||||
|
||||
@disable_random()
|
||||
def test_newapi_sq_matmul(self):
|
||||
x_data = np.random.rand(1024, 1024).astype(np.float32)
|
||||
y_data = np.random.rand(1024, 1024).astype(np.float32)
|
||||
import tensorflow.compat.v1 as tf
|
||||
|
||||
x = tf.placeholder(tf.float32, shape=[1024, 1024], name="x")
|
||||
y = tf.constant(y_data, dtype=tf.float32, shape=[1024, 1024])
|
||||
z = tf.matmul(x, y)
|
||||
bias = np.random.rand(1024).astype(np.float32)
|
||||
z = tf.nn.bias_add(z, bias)
|
||||
z = tf.nn.relu(z, name="op_to_store")
|
||||
|
||||
with tf.Session() as sess:
|
||||
sess.run(z, feed_dict={x: x_data, y: y_data})
|
||||
output_graph_def = sess.graph.as_graph_def()
|
||||
|
||||
set_random_seed(9527)
|
||||
config = PostTrainingQuantConfig(
|
||||
quant_level=1,
|
||||
recipes={"smooth_quant": True, "smooth_quant_args": {"alpha": 0.5}},
|
||||
calibration_sampling_size=[1024],
|
||||
)
|
||||
|
||||
from neural_compressor.data import Datasets
|
||||
|
||||
dataset = Datasets("tensorflow")["dummy"](shape=(1024, 1024), label=True)
|
||||
dataloader = DataLoader(framework="tensorflow", dataset=dataset, batch_size=1024)
|
||||
from neural_compressor import Metric
|
||||
|
||||
top1 = Metric(name="topk", k=1)
|
||||
output_graph = fit(
|
||||
model=output_graph_def,
|
||||
conf=config,
|
||||
calib_dataloader=dataloader,
|
||||
eval_dataloader=dataloader,
|
||||
eval_metric=top1,
|
||||
)
|
||||
|
||||
mul_count = 0
|
||||
for i in output_graph.graph_def.node:
|
||||
if i.op == "Mul":
|
||||
mul_count += 1
|
||||
|
||||
self.assertEqual(mul_count, 1)
|
||||
|
||||
@disable_random()
|
||||
def test_newapi_sq_conv_matmul(self):
|
||||
x = tf.compat.v1.placeholder(tf.float32, [1, 56, 56, 16], name="input")
|
||||
top_relu = tf.nn.relu(x)
|
||||
paddings = tf.constant([[0, 0], [1, 1], [1, 1], [0, 0]])
|
||||
x_pad = tf.pad(top_relu, paddings, "CONSTANT")
|
||||
conv1_weights = tf.compat.v1.get_variable(
|
||||
"weight_conv1", [3, 3, 16, 16], initializer=tf.compat.v1.random_normal_initializer()
|
||||
)
|
||||
conv1 = tf.nn.conv2d(x_pad, conv1_weights, strides=[1, 2, 2, 1], padding="VALID")
|
||||
matmul_weights = tf.compat.v1.get_variable(
|
||||
"weight_matmul", [28 * 28 * 16, 7 * 7 * 32], initializer=tf.compat.v1.random_normal_initializer()
|
||||
)
|
||||
conv1_reshaped = tf.reshape(conv1, shape=[-1, 28 * 28 * 16])
|
||||
matmul = tf.matmul(conv1_reshaped, matmul_weights)
|
||||
reshape = tf.reshape(matmul, (1, 7, 7, 32))
|
||||
conv2_weights = tf.compat.v1.get_variable(
|
||||
"weight_conv2", [7, 7, 32, 1], initializer=tf.compat.v1.random_normal_initializer()
|
||||
)
|
||||
conv2 = tf.nn.conv2d(reshape, conv2_weights, strides=[1, 2, 2, 1], padding="VALID")
|
||||
leaky_relu = tf.nn.leaky_relu(conv2, name="op_to_store")
|
||||
|
||||
out_name = leaky_relu.name.split(":")[0]
|
||||
with tf.compat.v1.Session() as sess:
|
||||
sess.run(tf.compat.v1.global_variables_initializer())
|
||||
output_graph_def = graph_util.convert_variables_to_constants(
|
||||
sess=sess, input_graph_def=sess.graph_def, output_node_names=[out_name]
|
||||
)
|
||||
|
||||
set_random_seed(9527)
|
||||
config = PostTrainingQuantConfig(
|
||||
quant_level=1,
|
||||
recipes={"smooth_quant": True, "smooth_quant_args": {"alpha": 0.6}},
|
||||
calibration_sampling_size=[500],
|
||||
)
|
||||
|
||||
from neural_compressor.data import Datasets
|
||||
|
||||
dataset = Datasets("tensorflow")["dummy"](shape=(100, 56, 56, 16), label=True)
|
||||
dataloader = DataLoader(framework="tensorflow", dataset=dataset)
|
||||
from neural_compressor import Metric
|
||||
|
||||
top1 = Metric(name="topk", k=1)
|
||||
output_graph = fit(
|
||||
model=output_graph_def,
|
||||
conf=config,
|
||||
calib_dataloader=dataloader,
|
||||
eval_dataloader=dataloader,
|
||||
eval_metric=top1,
|
||||
)
|
||||
|
||||
mul_count = 0
|
||||
for i in output_graph.graph_def.node:
|
||||
if i.op == "Mul":
|
||||
mul_count += 1
|
||||
|
||||
self.assertEqual(mul_count, 3)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
Reference in New Issue
Block a user