def METHOD_NAME(self, layer_name, sampled_input, act_abs_max, weight):
    act = sampled_input
    act.stop_gradient = True
    print('[smooth search] search input of %s' % layer_name)
    origin_out = paddle.matmul(act, weight)
    w_abs_max = weight.abs().max(axis=-1, keepdim=True)
    rw_abs_max = w_abs_max.reshape(act_abs_max.shape)
    np_act_abs_max = np.array(act_abs_max)
    np_rw_abs_max = np.array(rw_abs_max)
    smooth_scale_out = None
    global_loss = float('inf')
    best_scale = None
    for k_piece in range(1, self.k_piece + 1):
        if not self.search_piece:
            k_piece = self.k_piece
        print('Search {} Piece'.format(k_piece))
        centroids, labels = k_means(act_abs_max, k_piece)
        piece = ['piece_{}'.format(a) for a in range(len(centroids))]
        for i in range(len(centroids)):
            # print('search for piece {}; centroids value is {}'.format(
            #     piece[i], centroids[centroids.argsort()[i]].numpy()))
            alpha = self.search_alpha_min
            alpha_max = self.search_scale_max if self.search_scale_max is not None else self.search_alpha_max
            calibration_loss = float('inf')
            final_alpha = None
            mask_for_search = paddle.where(labels == centroids.argsort()[i],
                                           1., 0.)
            mask_for_ones = paddle.where(mask_for_search == 0., 1., 0.)
            while alpha <= alpha_max:
                if alpha < 1:
                    alpha += 0.01
                    if alpha >= self.search_alpha_max:
                        alpha = self.search_scale_min
                        if alpha is None:
                            break
                else:
                    alpha += 0.5
                alpha = round(alpha, 2)
                if alpha < 1:
                    s = (np.power(np_act_abs_max, alpha) / np.power(
                        np_rw_abs_max, 1. - alpha)).clip(min=1e-5)
                    s = paddle.to_tensor(s, dtype='float32')
                    smooth_scale = s * mask_for_search
                else:
                    smooth_scale = alpha * mask_for_search
                if smooth_scale_out is not None:
                    mask_for_ones_new = paddle.where(
                        smooth_scale_out == 0., 1., 0.)
                    mask_for_ones *= mask_for_ones_new
                    smooth_scale_ = smooth_scale_out + smooth_scale
                    smooth_scale_tmp = smooth_scale_ + mask_for_ones
                else:
                    smooth_scale_tmp = smooth_scale + mask_for_ones
                new_act = act / smooth_scale_tmp
                new_weight = weight * smooth_scale_tmp.reshape(
                    w_abs_max.shape)
                quant_scale = compute_scales(
                    new_act, method=self.act_quant_method)
                quant_act = paddle.clip(
                    paddle.round(new_act / quant_scale * self.bnt),
                    -self.bnt - 1, self.bnt)
                quant_dequant_act = quant_act / self.bnt * quant_scale
                quant_scale = compute_scales(
                    new_weight, method=self.weight_quant_method)
                quant_weight = paddle.clip(
                    paddle.round(new_weight / quant_scale * self.bnt),
                    -self.bnt - 1, self.bnt)
                quant_dequant_weight = quant_weight / self.bnt * quant_scale
                new_out = paddle.matmul(quant_dequant_act,
                                        quant_dequant_weight)
                cur_loss = self.loss_function(origin_out, new_out)
                if cur_loss <= calibration_loss:
                    calibration_loss = cur_loss
                    final_smooth_scale = smooth_scale
                    final_alpha = alpha
            # print("Layer {} Piece {}, loss: {}, alpha : {}".format(
            #     layer_name, piece[i], float(calibration_loss), final_alpha))
            if smooth_scale_out is None:
                smooth_scale_out = final_smooth_scale
            else:
                smooth_scale_out += final_smooth_scale
        if calibration_loss < global_loss:
            global_loss = calibration_loss
            best_scale = smooth_scale_out
            if self.search_piece:
                print('Find Better K-Piece {}'.format(k_piece))
        if not self.search_piece:
            break
    return best_scale