code: def from_linear(
      cls,
      linear,
      bits,
      group_size,
      backend,
      init_only=False,
      scales=None,
      zeros=None,
  ):
      awq_linear = cls(
          bits,
          group_size,
          linear.in_features,
          linear.out_features,
          linear.bias is not None,
          linear.weight.device,
      )
      if init_only:  # just prepare for loading sd
          return awq_linear
  
      # need scales and zeros info for real quantization
      invalidInputError(
          scales is not None and zeros is not None,
          "Scales and zeros should not be None.",
      )
      scale_zeros = zeros * scales
  
      pack_num = 32 // awq_linear.bits
      qscales = torch.zeros(
          (
              scales.shape[0],
              calculate_zeros_width(linear.in_features, group_size)
              * pack_num,
          ),
          dtype=torch.float16,
          device=scales.device,
      )
      qscales[:, : scales.shape[1]] = scales
      awq_linear.scales = qscales
      if linear.bias is not None:
          awq_linear.bias = linear.bias.clone().half()
  
      intweight = []
      for idx in range(awq_linear.in_features):
          intweight.append(
              torch.round(
                  (
                      linear.weight.data[:, idx]
                      + scale_zeros[:, idx // group_size]
                  )
                  / awq_linear.scales[:, idx // group_size]
              ).to(torch.int)[:, None]
          )
      intweight = torch.cat(intweight, dim=1)
      intweight = intweight.to(dtype=torch.int32)
      qweight = torch.zeros(
          (
              intweight.shape[0],
              intweight.shape[1] // 32 * awq_linear.bits,
          ),
          dtype=torch.int32,
          device=intweight.device,
      )
  
      for col in range(intweight.shape[1] // pack_num):
          if awq_linear.bits == 4:
              if backend == AwqBackendPackingMethod.AUTOAWQ:
                  order_map = [0, 2, 4, 6, 1, 3, 5, 7]
              elif backend == AwqBackendPackingMethod.LLMAWQ:
                  order_map = [0, 1, 2, 3, 4, 5, 6, 7]
          else:
              invalidOperationError(
                  False, "Only 4-bit are supported for now."
              )
          for i in range(pack_num):
              qweight_col = intweight[:, col * pack_num + order_map[i]]
              qweight[:, col] |= qweight_col << (i * awq_linear.bits)
      awq_linear.qweight = qweight
  
      zeros = zeros.to(dtype=torch.int32)
      qzeros = torch.zeros(
          (
              zeros.shape[0],
              calculate_zeros_width(linear.in_features, group_size),
          ),
          dtype=torch.int32,
          device=zeros.device,
      )
  
      for col in range((zeros.shape[1] + pack_num - 1) // pack_num):
          if awq_linear.bits == 4:
              if backend == AwqBackendPackingMethod.AUTOAWQ:
                  order_map = [0, 2, 4, 6, 1, 3, 5, 7]
              elif backend == AwqBackendPackingMethod.LLMAWQ:
                  order_map = [0, 1, 2, 3, 4, 5, 6, 7]
          else:
              invalidOperationError(
                  False, "Only 4-bit are supported for now."
              )
          for i in range(pack_num):
              if col * pack_num + order_map[i] >= zeros.shape[1]:
                  continue
              qzero_col = zeros[:, col * pack_num + order_map[i]]
              qzeros[:, col] |= qzero_col << (i * awq_linear.bits)
      awq_linear.qzeros = qzeros
      return awq_linear
  
file_path: BigDL/python/llm/src/bigdl/llm/transformers/awq/linear.py
imports: import torch
  import torch.nn
  from bigdl.llm.utils.common import invalidOperationError, invalidInputError
  from transformers import AwqConfig
  from transformers.utils.quantization_config import AwqBackendPackingMethod
label_desc: Use image node_id 2 for calling the WQLinear_GEMV obj's underlying member method code with example usage: obj.from_linear(cls, linear, bits, group_size, backend, init_only, scales, zeros) and returns: awq_linear, awq_linear