华为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等多种语言做法集合指南

    全部评论

    相关推荐

    11-06 09:17
    门头沟学院 Java
    近几年计算机行业的就业版图,早就不是当年“学后端=铁饭碗”的时代了。现在的后端岗位卷到什么程度?用惨烈都不够形容。你随便刷一眼招聘平台,后端岗位的候选人背景简直可以当“互联网人才博物馆”展览:•985/211 本科不搞算法了,转头扎堆后端;•硕士研究生不做科研了,跑来后端“降维打击”;•原本学AI、CV、NLP的,也因为行情冷,开始和你抢后端岗。结果就是,一个普通后端岗位,简历一堆亮眼学霸打底,竞争强度堪比国足进世界杯。你会写 CRUD?会微服务?懂分布式?不好意思,这些早就是简历基础款,没有中台/高并发/大模型落地经验,上桌都难。更扎心的是,过去大家觉得后端“稳定、高薪、有提升空间”。但现实呢?岗位数量不够分,供大于求,薪资水平早就不再一骑绝尘。不信你去看看数据:同一年经验,后端的薪资水平已经被不少方向追平甚至反超,而且加班经常更狠。而另一边——前端、客户端、测开,是真的缺人!不是那种“纸面缺人”,是真的企业硬缺、急缺、招不到人!为什么反而这三类越来越吃香?✅ 前端:需求持续爆发,人才断层明显新技术层出不穷:React、Vue、Next.js、WebAssembly、低代码……应用形态不断扩展:H5、小程序、跨端、Web3、3D可视化……结果就是:会点皮毛的多,但能独立搞复杂业务的稀缺!企业急得不行,好的前端比同等经验后端更吃香完全不是例外。🚀 客户端(iOS/Android):岗位稳、壁垒高、薪资强移动端永远有需求,而且门槛比前端略高,自学者少、转行难。因此 供给少但需求稳定,是目前为数不多还在逆势涨薪的方向之一。你会发现,同级别简历里,客户端竞争对手远少于后端。🧪 测开(测试开发):行业从“补位角色”跃升为香饽饽智能化测试、自动化平台、质量工程体系建设正迅速升级,对测试开发的技术要求逼近后端,但竞争却没那么夸张。会自动化 + 会点开发 = 市场抢着要。许多测开薪资甚至早就赶上甚至超过同级后端。说句扎心但现实的话:后端已经不是当年的金饭碗,而更像一个“人满为患的内卷中心”。而前端、客户端、测开,则是红利仍在、缺口巨大、进入正当时的方向。现在还冲着后端挤?那真的得慎重考虑了。与其去后端卷生卷死,不如选择一个更有成长空间、更缺人才、更能脱颖而出的赛道。不吹不黑:想进大厂、想快速拿到不错薪资、想提升竞争力,前端 / 客户端 / 测开真的比后端更现实、更明智。如果你正站在择方向的十字路口,一定记住一句话:方向选对了,努力才有价值;往人群最密的地方硬挤,只能越挤越疼。真的,慎重考虑后端,多看看前端、客户端、测开。别再冲着最拥挤的方向跑了。
    点赞 评论 收藏
    分享
    评论
    点赞
    收藏
    分享

    创作者周榜

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