首页 > 试题广场 >

INT8 非对称量化下的全连接与误差评估

[编程题]INT8 非对称量化下的全连接与误差评估
  • 热度指数:535 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解

在移动端或边缘设备上,浮点运算成本较高。常见做法是将输入向量和全连接层权重做 INT8 非对称量化(按张量整体 per-tensor),用整数在量化域直接做点积,最后用反量化结果评估与原始浮点结果的误差。

【任务】

  • 对输入向量 x 和权重矩阵 W 分别做 INT8 非对称量化(范围 [-128, 127],不加偏置),输出量化域的 m 个整数点积结果。
  • 将量化后的 x 与 W 分别反量化为 x_dequant、W_dequant,计算二者在浮点域的全连接输出,与原始 x、W 的浮点输出做均方误差 MSE,并输出 round_half_up(MSE × 100000) 的整数。
  • 量化/反量化细节(per-tensor):
    • scale = (max(v) - min(v)) / 255
    • 若 max(v) == min(v),则 scale = 0,量化结果全为 -128;反量化直接取 min(v)
    • 量化:q = clamp(round((v - min(v)) / scale) - 128, -128, 127),round 为就近取偶
    • 反量化:v_dequant = (q + 128) * scale + min(v)
  • MSE 四舍五入采用 half-up(即对 MSE×100000 做 “x+0.5 下取整”)

输入描述:
  • 第一行:n(输入向量维度)
  • 第二行:n 个浮点数(输入向量 x)
  • 第三行:m n(权重矩阵维度)
  • 接着 m 行:每行 n 个浮点数(权重矩阵 W)


输出描述:
  • 第一行:m 个整数(使用 x_quant 与 W_quant 计算的量化域全连接输出)
  • 第二行:1 个整数(round_half_up(MSE × 100000))
示例1

输入

3
0 128 255
2 3
0 0 0
255 255 255

输出

128 -127
0

说明

  • 对 x:min=0, max=255, scale=1 → x_quant=[-128, 0, 127]
  • 对 W(按张量整体):min=0, max=255, scale=1 → 第1行量化为[-128,-128,-128],第2行为[127,127,127]
  • 量化域点积:
    • y0 = (-128)(-128) + 0(-128) + 127*(-128) = 128
    • y1 = (-128)127 + 0127 + 127*127 = -127
  • 反量化后与原始浮点结果一致,MSE=0,输出 0

备注:
本题由牛友@Charles 整理上传
from math import floor
import numpy as np
#读取
k=int(input().strip())
x=[]
x.append(list(map(float,input().split())))
x=np.array(x)
temp=[]
temp.append(list(map(int,input().split())))
m=temp[0][0]
n=temp[0][1]
w=[]
for _ in range(m):
    row=list(map(float,input().split()))
    w.append(row)
w=np.array(w)

#量化
x_min=np.min(x)
x_max=np.max(x)
if x_min==x_max:
    x_scale=0
    x_q=[-128.0]*k
    x_q=np.array(x_q)
else:
    x_scale=(x_max-x_min)/255
    x_q=np.zeros_like(x,dtype=float)
    x_q=np.clip(np.rint((x-x_min)/x_scale)-128,-128,127)

w_min=np.min(w)
w_max=np.max(w)
if w_min==w_max:
    w_scale=0
    w_q=np.full(w.shape,-128.0)
else:
    w_scale=(w_max-w_min)/255
    w_q=np.zeros_like(w,dtype=float)
    for i in range(m):
        w_q[i]=np.clip(np.rint((w[i]-w_min)/w_scale)-128,-128,127)

y_q=(**********).flatten()

#反量化
if x_min==x_max:
    x_scale=x_min
    x_fq=(x_q+128)*x_scale+x_min
else:
    x_fq=(x_q+128)*x_scale+x_min

if w_min==w_max:
    w_scale=w_min
    w_fq=np.zeros_like(w,dtype=float)
    for i in range(m):
        w_fq[i]=(w_q[i]+128)*w_scale+w_min
else:
    w_fq=np.zeros_like(w,dtype=float)
    for i in range(m):
        w_fq[i]=(w_q[i]+128)*w_scale+w_min

y_true=w @ x.T
y_pred=w_fq @ x_fq.T

#MSE
MSE=np.mean((y_true-y_pred)**2)
ans=floor(MSE*100000+0.5)
y_q=list(y_q)
print(' '.join(f'{v:.0f}' for v in y_q))
print(ans)

发表于 2026-04-12 17:34:55 回复(0)