#P4548. 第3题-Token 与 Channel 双粒度 INT8 量化矩阵乘法
-
1000ms
Tried: 591
Accepted: 208
Difficulty: 7
所属公司 :
华为
时间 :2026年1月21日-AI方向
第3题-Token 与 Channel 双粒度 INT8 量化矩阵乘法
解题思路
本题实现一种常见的线性层 INT8 量化推理流程:对输入矩阵 X 做 per-token(按行)量化,对权重矩阵 W 做 per-channel(按列)量化,然后在 INT32 累加域中完成矩阵乘法,最后用缩放因子反量化回 FP32 输出。
核心算法分为 4 步:
-
计算缩放因子(scale)
- 对 X 的每一行 i(一个 token):
题目内容
模型部署时,为了减少内存占用并降低推理延迟,通常会将 FP32 参数压缩为低精度整数格式。本题需要实现一种 INT8 量化矩阵乘法:给定输入矩阵 X∈RM×K 和权重矩阵 W∈RK×N,对两个矩阵分别采用不同的量化粒度,最终输出带缩放因子还原后的矩阵乘积。
将 X 的每一行视为一个 Token,对每个 Token 单独计算缩放因子,称为 per-token 量化。对第 i 个 Token,其缩放因子定义为
sX(i)=127max1≤k≤K∣Xi,k∣,其中 i=1,…,M。若该行最大绝对值为 0,则规定 sX(i)=1。量化后的值以及反量化恢复值为
将 W 的每一列视为一个 Channel,对每个 Channel 单独计算缩放因子,称为 per-channel 量化。对第 j 个 Channel,其缩放因子定义为
sW(j)=127max1≤k≤K∣Wk,j∣,其中 j=1,…,N。若该列最大绝对值为 0,则规定 sW(j)=1。量化后的值以及反量化恢复值为
这里的 round(⋅) 按 Python 的 round() 逻辑处理:非 0.5 的情况遵循通常的四舍五入规则;恰好为 0.5 时舍入到最接近的偶数。clip(x,−127,127) 表示将 x 截断到区间 [−127,127] 内,超过 127 则取 127,小于 −127 则取 −127。
量化完成后,先计算 INT32 矩阵乘积:
Yint32(i,j)=k=1∑KQX(i,k)⋅QW(k,j).再乘以对应 Token 与 Channel 的缩放因子,得到最终浮点结果:
Yfp32(i,j)=Yint32(i,j)⋅sX(i)⋅sW(j).题目要求输出矩阵 Yfp32,每个元素四舍五入保留两位小数。
约束条件:
- M、K、N 均为正整数,且均不超过
128。 - 矩阵 X 和 W 中任意元素的取值均在
-1000000.0到1000000.0之间。
输入描述
输入数据按空白字符分隔,从标准输入读取。
第一行包含两个整数 M 和 K,分别表示矩阵 X 的行数和列数。
接下来 M 行,每行包含 K 个浮点数,按行优先顺序给出矩阵 X。
再接下来一行包含两个整数 K 和 N,分别表示矩阵 W 的行数和列数;这里的 K 与矩阵 X 的列数相同。
最后 K 行,每行包含 N 个浮点数,按行优先顺序给出矩阵 W。
输出描述
输出 M 行,每行对应矩阵 Yfp32 的一行。每行包含 N 个浮点数,所有数字四舍五入保留两位小数,行内数字之间用单个空格分隔,行首和行尾不要有多余空格。
样例1
输入
2 2
1.0 0.0
0.0 2.0
2 2
1.0 5.0
3.0 4.0
输出
0.99 5.00
6.00 8.03
说明
先看矩阵 X。
第一行为 [1.00.0],最大绝对值为 1.0,所以 sX(1)=1/127。该行量化后得到 QX(1)=[1270]。
第二行为 [0.02.0],最大绝对值为 2.0,所以 sX(2)=2/127。该行量化后得到 QX(2)=[0127]。
再看矩阵 W。
第一列为 [1.03.0],最大绝对值为 3.0,所以 sW(1)=3/127。该列量化时,1.0/(3/127) 约等于 42.33,舍入为 42;3.0/(3/127)=127。因此第一列量化值为 [42127]。
第二列为 [5.04.0],最大绝对值为 5.0,所以 sW(2)=5/127。该列量化时,5.0/(5/127)=127,4.0/(5/127)=101.6,舍入为 102。因此第二列量化值为 [127102]。
计算整数矩阵乘积后得到:
Yint32=[5334161291612912954]。
最后乘以对应缩放因子,得到:
Yfp32(1,1)=5334⋅1271⋅1273≈0.99,
Yfp32(1,2)=16129⋅1271⋅1275=5.00,
Yfp32(2,1)=16129⋅1272⋅1273=6.00,
Yfp32(2,2)=12954⋅1272⋅1275≈8.03。
样例2
输入
2 2
127.0 63.5
-63.5 127.0
2 2
127.0 0.0
0.0 127.0
输出
16129.00 8128.00
-8128.00 16129.00
说明
矩阵 X 的两行最大绝对值都是 127,因此 sX(1)=sX(2)=1。
第一行量化时,127/1=127;63.5/1=63.5,按照题目要求向最接近的偶数舍入,63 是奇数,64 是偶数,所以舍入为 64。于是第一行量化结果为 [12764]。
第二行中,-63.5/1=-63.5,向最接近的偶数舍入时选 -64;127/1=127。于是第二行量化结果为 [−64127]。
矩阵 W 的两列最大绝对值也都是 127,所以 sW(1)=sW(2)=1,量化后 QW 为 [12700127]。
整数矩阵乘积为:
QXQW=[127−6464127][12700127]=[16129−8128812816129]。
因为所有缩放因子均为 1,最终输出与整数乘积相同。
样例3
输入
2 2
0.0 0.0
1.0 0.0
2 2
1.0 0.0
0.0 0.0
输出
0.00 0.00
1.00 0.00
说明
矩阵 X 的第一行全为 0,最大绝对值为 0,按规则取 sX(1)=1,该行量化后仍为 [00]。
矩阵 X 的第二行为 [1.00.0],最大绝对值为 1.0,所以 sX(2)=1/127。量化后得到 [1270]。
矩阵 W 的第一列为 [1.00.0],最大绝对值为 1.0,所以 sW(1)=1/127,量化后为 [1270]。
矩阵 W 的第二列全为 0,最大绝对值为 0,按规则取 sW(2)=1,量化后仍为 [00]。
因此整数乘积第一行全为 0。
第二行中,[1270] 与第一列 [1270] 的点积为 16129,与第二列 [00] 的点积为 0。
最终第二行第一列为 16129⋅1271⋅1271=1.00,第二列为 0.00。