华为ai算法 华为笔试 华为秋招 1112

笔试时间:2025年11月12日

往年笔试合集:

2023春招秋招笔试合集

2024春招秋招笔试合集

第一题:INT8非对称量化

在移动设备部署深度学习模型时,浮点运算会消耗大量计算资源。通过INT8非对称量化,可将全连接层的浮点运算转化为整数运算,显著提高推理速度。实际应用中:

  • 量化后模型大小缩小4倍(32bit→8bit)
  • 整数运算指令比浮点指令快2-4倍
  • 广泛应用于移动端NLP模型(如BERT最后一层分类头)
  • 在物联网设备上可降低能耗并减少内存占用

请实现以下功能:

  1. 量化和全连接层计算:对输入向量x和权重矩阵W执行INT8非对称量化,使用量化后的整数值x_quant和W_quant进行全连接层计算,输出计算结果。为简化起见,本题中全连接层不考虑偏置。
  2. 计算量化误差:对量化的整数进行反量化得到x_dequant和W_dequant并进行全连接层计算,与原始浮点x、W的全连接层计算结果进行比较,计算两个全连接层输出之间的均方误差(MSE),并将MSE×100000后四舍五入后输出。

算法原理

INT8非对称量化

  • 尺度:scale_v = (max(v) - min(v))/255,当max(v) == min(v),即张量v的所有值相等时,scale_v = 0
  • 量化:对张量v进行量化得到v_quant,量化后的整数区间为[-128,127] 当scale_v = 0时量化结果为v_quant = -128采用就近取偶(round(x))
  • 反量化:对v_quant进行反量化后得到v_dequant,当v_quant = -128时,反量化值v_dequant = min(v)
  • 全连接层计算:Y = xW^T
  • 量化误差:MSE = (1/m)Σ_{i=0}^{m-1}(Y_float,i - Y_dequant,i)^2,m为权重矩阵的行数

输入描述

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

  • 第一行 m个整数(使用量化数据x_quant和W_quant计算的全连接层输出)
  • 第二行 1个整数(量化误差MSE,注意是MSE×100000后四舍五入输出整数)
  • 样例输入

    3 1.0 2.0 3.0 2 3 0.1 0.2 0.3 0.4 0.5 0.6

    样例输出

    13082 12929 0

    参考题解

  • 量化计算流程: 分别量化输入向量x和权重矩阵W找到各自的最小值和最大值,计算各自的尺度因子应用量化公式得到整数表示
  • 整数全连接层计算:使用量化后的整数进行矩阵乘法
  • 误差计算:反量化恢复近似值,比较原始与量化结果,计算均方误差
  • Python:

    import sys
    import math
    
    def clamp(t, lo, hi):
        return max(lo, min(hi, t))
    
    def quantize(tensor):
        is_matrix = isinstance(tensor[0], list)
        
        if is_matrix:
            flat_list = [val for row in tensor for val in row]
        else:
            flat_list = tensor
        
        if not flat_list:
            return ([], 0.0, 0.0) if not is_matrix else ([[]], 0.0, 0.0)
        
        min_v = float(min(flat_list))
        max_v = float(max(flat_list))
        
        scale_v = 0.0
        if min_v != max_v:
            scale_v = (max_v - min_v) / 255.0
        
        def quant_val(v):
            if scale_v == 0:
                return -128
            val_scaled = (v - min_v) / scale_v
            val_rounded = round(val_scaled)
            val_shifted = val_rounded - 128
            val_clamped = clamp(val_shifted, -128, 127)
            return int(val_clamped)
        
        if is_matrix:
            quantized_tensor = [[quant_val(v) for v in row] for row in tensor]
        else:
            quantized_tensor = [quant_val(v) for v in tensor]
        
        return quantized_tensor, min_v, scale_v
    
    def dequantize(quantized_tensor, min_v, scale_v):
        is_matrix = isinstance(quantized_tensor[0], list)
        
        def dequant_val(q_v):
            if scale_v == 0:
                return min_v
            return (q_v + 128) * scale_v + min_v
        
        if is_matrix:
            dequantized_tensor = [[dequant_val(v) for v in row] for row in quantized_tensor]
        else:
            dequantized_tensor = [dequant_val(v) for v in quantized_tensor]
        
        return dequantized_tensor
    
    def fc_layer(x_vec, w_matrix):
        m = len(w_matrix)
        n = len(x_vec)
        output = []
        
        for i in range(m):
            dot_product = 0
            for j in range(n):
                dot_product += x_vec[j] * w_matrix[i][j]
            output.append(dot_product)
        
        return output
    
    def main():
        n = int(sys.stdin.readline())
        x = [float(v) for v in sys.stdin.readline().strip().split()]
        m, n_check = map(int, sys.stdin.readline().strip().split())
        
        W = []
        for _ in range(m):
            W.append([float(v) for v in sys.stdin.readline().strip().split()])
        
        x_quant, min_x, scale_x = quantize(x)
        W_quant, min_w, scale_w = quantize(W)
        
        Y_quant = fc_layer(x_quant, W_quant)
        print(" ".join(map(str, Y_quant)))
        
        Y_float = fc_layer(x, W)
        x_dequant = dequantize(x_quant, min_x, scale_x)
        W_dequant = dequantize(W_quant, min_w, scale_w)
        Y_dequant = fc_layer(x_dequant, W_dequant)
        
        sum_sq_err = 0.0
        for i in range

    剩余60%内容,订阅专栏后可继续查看/也可单篇购买

    2025 春招笔试合集 文章被收录于专栏

    2025打怪升级记录,大厂笔试合集 C++, Java, Python等多种语言做法集合指南

    全部评论

    相关推荐

    程序员牛肉:可以说含金量不如王者荣耀省标。
    点赞 评论 收藏
    分享
    __Offer__:认识的室友啥也不回细节,线下面联想大模型一次通关我给我干不回了
    点赞 评论 收藏
    分享
    评论
    点赞
    收藏
    分享

    创作者周榜

    更多
    牛客网
    牛客网在线编程
    牛客网题解
    牛客企业服务