|
|
|
|
|
|
|
|
|
|
|
import numpy as np |
|
from scipy.spatial.distance import cdist |
|
|
|
index = np.array([0, 1, 2, 3, 4, 5, 6, 7]) |
|
values = np.linspace(-1.0, 1.0, 8) |
|
print('quantization values:', values) |
|
|
|
|
|
|
|
|
|
rand_inputs = np.random.randn(1024, 1024).astype(np.float32) |
|
|
|
absmax = np.max(np.abs(rand_inputs)) |
|
normed = rand_inputs / absmax |
|
print('normalized min and max range', np.min(normed), np.max(normed)) |
|
|
|
|
|
|
|
|
|
|
|
dist = cdist(normed.flatten().reshape(-1, 1), values.reshape(-1, 1)) |
|
closest_idx = np.argmin(dist, 1).reshape(rand_inputs.shape) |
|
|
|
val, count = np.unique(closest_idx, return_counts=True) |
|
print('Values:', val) |
|
print('Count:', count) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
dequant = values[closest_idx]*absmax |
|
|
|
error = np.abs(dequant-rand_inputs).mean() |
|
print(f'Absolute linear 3-bit quantization error: {error:.4f}') |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
index = np.array([0, 1, 2, 3, 4, 5, 6, 7]) |
|
values = np.array([-1.0, -0.5, -0.25, -0.075, 0.075, 0.25, 0.5, 1.0]) |
|
|
|
dist = cdist(normed.flatten().reshape(-1, 1), values.reshape(-1, 1)) |
|
closest_idx = np.argmin(dist, 1).reshape(rand_inputs.shape) |
|
|
|
val, count = np.unique(closest_idx, return_counts=True) |
|
print('Values:', val) |
|
print('Count:', count) |
|
|
|
dequant = values[closest_idx]*absmax |
|
error = np.abs(dequant-rand_inputs).mean() |
|
print(f'Absolute non-linear 3-bit quantization error: {error:.4f}') |
|
|
|
|
|
|
|
def create_dynamic_map(signed=True, n=7): |
|
''' |
|
Creates the dynamic quantiztion map. |
|
The dynamic data type is made up of a dynamic exponent and |
|
fraction. As the exponent increase from 0 to -7 the number |
|
of bits available for the fraction shrinks. |
|
This is a generalization of the dynamic type where a certain |
|
number of the bits and be reserved for the linear quantization |
|
region (the fraction). n determines the maximum number of |
|
exponent bits. |
|
For more details see |
|
(8-Bit Approximations for Parallelism in Deep Learning)[https://arxiv.org/abs/1511.04561] |
|
''' |
|
|
|
data = [] |
|
|
|
|
|
|
|
additional_items = 2**(7-n)-1 |
|
if not signed: additional_items = 2*additional_items |
|
for i in range(n): |
|
fraction_items = 2**(i+7-n)+1 if signed else 2**(i+7-n+1)+1 |
|
boundaries = np.linspace(0.1, 1, fraction_items) |
|
means = (boundaries[:-1]+boundaries[1:])/2.0 |
|
data += ((10**(-(n-1)+i))*means).tolist() |
|
if signed: |
|
data += (-(10**(-(n-1)+i))*means).tolist() |
|
|
|
if additional_items > 0: |
|
boundaries = np.linspace(0.1, 1, additional_items+1) |
|
means = (boundaries[:-1]+boundaries[1:])/2.0 |
|
data += ((10**(-(n-1)+i))*means).tolist() |
|
if signed: |
|
data += (-(10**(-(n-1)+i))*means).tolist() |
|
|
|
data.append(0) |
|
data.append(1.0) |
|
data.sort() |
|
return np.array(data) |
|
|
|
import time |
|
|
|
values = create_dynamic_map(signed=True) |
|
|
|
t0 = time.time() |
|
dist = cdist(normed.flatten().reshape(-1, 1), values.reshape(-1, 1)) |
|
closest_idx = np.argmin(dist, 1).reshape(rand_inputs.shape) |
|
quant_time = time.time()-t0 |
|
|
|
dequant = values[closest_idx]*absmax |
|
error = np.abs(dequant-rand_inputs).mean() |
|
print(f'Absolute dynamic 8-bit quantization error: {error:.4f}') |
|
print(f'Total time taken: {quant_time:.4f} seconds.') |
|
|
|
|
|
|
|
|
|
import torch |
|
import bitsandbytes.functional as F |
|
|
|
rand_inputs = torch.from_numpy(rand_inputs) |
|
t0 = time.time() |
|
quant_values, quant_state = F.quantize_blockwise(rand_inputs) |
|
quant_time = time.time()-t0 |
|
dequant_values = F.dequantize_blockwise(quant_values, quant_state) |
|
|
|
error = torch.abs(dequant_values-rand_inputs).mean().item() |
|
print(f'Absolute dynamic block-wise 8-bit quantization error: {error:.4f}') |
|
print(f'Total time taken (CPU): {quant_time:.4f} seconds.') |
|
|
|
rand_inputs = rand_inputs.cuda() |
|
t0 = time.time() |
|
quant_values, quant_state = F.quantize_blockwise(rand_inputs) |
|
quant_time = time.time()-t0 |
|
print(f'Total time taken (GPU): {quant_time:.4f} seconds.') |
|
|
|
|
|
|