夜雨聆风学习资料网

ARTICLE · 1182892

华为机考AI方向10月14日笔试题与解析

华为机考AI方向10月14日笔试题与解析

写在前面

本次给大家带来2026年10月14日华为AI方向笔试题的2道题,本套题涉及到的岗位:AI算法工程师,AI应用开发工程师,AI数据科学工程师等以AI为开头的岗位,统一笔试,不区分部门。

需要我整理的AI机考速成攻略&题单可访问文章底部左侧:阅读原文

题号
题目
难度(对标leetcode)
核心做法
1
选择题
中等
选择题
2
轻量化推理引擎中的 Masked Fused RMSNorm 模块实现
中等
模拟
3
基于CART分类树预测客户购房选择
中等
决策树

选择题(15*6分 + 5*12分

1、某 Transformer 层在张量并行度为 2 时要做一次 All-Reduce,待同步张量大小为 80MB。网络带宽为 40GB/s,忽略延迟,通信时间约为多少?
  • 0.2ms
  • 20ms
  • 0.02ms
  • 2ms
2、一组测量值中混有少量极端大的尖峰。若要反映数据的中心位置,且不希望被这些尖峰明显拉动,应优先采用哪个统计量?
  • 方差
  • 众数
  • 算术平均值
  • 中位数
3、将模型权重从 BF16 量化为 INT8,主要压缩的是:
  • 网络层数
  • 词表长度
  • 单个权重所占的比特数
  • 注意力头数
4、模型训练中用 float32 替代 float64,主要是为了:
  • 提高计算精度
  • 避免过拟合
  • 降低显存占用,并加快运算
  • 简化模型结构
5、某分类模型训练集准确率为 97%,测试集准确率为 58%。这表示模型处于什么状态?
  • 欠拟合
  • 数据不足
  • 过拟合
  • 良好拟合
6、某二分类模型的混淆矩阵为 TP=28、TN=52、FP=8、FN=12,准确率约为多少?
  • 0.70
  • 0.90
  • 0.85
  • 0.80
7、合同检索用 BPE 对中英混合文本分词后,法条编号、机构专名和条款缩写被拆成大量子词,检索召回明显变差。最合理的改法是:
  • 提高向量检索的 top-k,多取一些碎片片段
  • 改为字符级分词,让稀有词不再被拆开
  • 加大文档切分长度,减弱子词碎片的影响
  • 在分词词表中加入领域词,使法条编号、机构专名和条款缩写各成为一个完整 token
8、计算  时,若  很大,控制舍入误差最有效的方法是:
  • 按原式直接相减
  • 只把浮点位数加长
  • 先做分子有理化
  • 把绝对值很小的项直接丢掉
9、对抗样本一般是如何构造的?
  • 给输入叠一层幅度很小、肉眼基本看不出来的改动,使分类结果出错
  • 必须改变输入的语义,扰动才会生效
  • 只对图像模型有效,文本模型不会出现
  • 在输入上叠加大量随机噪声,使模型完全认不出原内容
10、某分类器测试集混淆矩阵为 TP=50、FP=10、FN=15、TN=25,其 F1 分数是多少?
  • 0.833
  • 0.769
  • 0.75
  • 0.8

篇幅有限,完整题解内容(选择题解析 + 全语言解析)已经发布至小程序👇

第2题-轻量化推理引擎中的 Masked Fused RMSNorm 模块实现(150分)

在轻量化大模型推理引擎中,Transformer 的隐藏状态会在多个子模块之间不断传递。为了减少内存读写、提升推理效率,实际工程中常常会将多个操作融合到同一个算子中,例如:

  • 残差连接 Residual Add
  • RMSNorm 归一化
  • 逐元素缩放 Scale
  • 逐元素偏置 Bias
  • Padding Mask 处理

本题要求按照如下计算步骤,实现一个简化版的 Masked Fused RMSNorm 模块。

计算步骤 对于第  个输入样本向量 ,给定残差向量 、残差系数 、有效长度 、缩放向量 、偏置向量 、数值稳定项 ,计算步骤如下: 1. 残差融合:

2. 有效部分的RMS和energy: 仅前  个位置为有效位置,后续位置视为padding,不参与RMS和energy计算。  其中 

3. 归一化输出: 对于输出向量 :

  • 有效位置 (  ): 
  • 无效位置 (  ): 

任务说明 给定  个样本,请对每个样本计算并输出:

  1. Masked Fused RMSNorm 后的结果向量 
  2. 该样本有效部分的 
  3. 该样本有效部分的平方和 

样例1输入:

2 3 0.011.0 0.5 -1.00.0 1.0 0.03 1.0 3.0 4.0 0.0 0.0 0.0 0.02 0.5 -1.0 1.0 -1.0 2.0 -2.0 1.0 0.0

输出:

1.04 1.69 0.00 | 2.89 | 25.000.00 1.00 0.00 | 0.10 | 0.00

解题思路

对每个样本先做残差融合 。energy 只累加前  个有效位置的 ,分母 ,。有效位置输出 ,下标从  计时也就是 ;无效位置直接输出 ,不能把  加进去。 时没有有效位,energy 为 ,整段  都是 。若有效位上的  全是  且 ,则 RMS 为 ,此时  没有定义,但每个有效  必然是 ,归一化项按  处理,有效位只保留 。

实现时按样本各扫一遍。浮点要保留两位小数,并且是标准四舍五入:恰好满五时远离零。不要用 C++ 的 printf("%.2f")、Python 的 format 或 Java 的 String.format("%.2f"),它们对能精确表示的 、 会走银行家舍入,印成 、。绝对值小于  的数一律写成 0.00,这样不会出现 -0.00。同一行用单个空格分隔,| 两侧各有一个空格。 按位置下标取,不要误用样本编号。

python代码(C++和JAVA代码见在线OJ网址)

from decimal import Decimal, ROUND_HALF_UPdef fmt(x):# 不足 0.005 一定是 0.00,同时去掉负零if abs(x) < 0.005:return "0.00"# 对 double 的精确十进制做四舍五入,满五时远离零    s = format(Decimal(x).quantize(Decimal("0.01"), rounding=ROUND_HALF_UP), "f")if s == "-0.00":return "0.00"return sdef calc(n, l, alpha, x, r, g, b, eps):    h = [0.0] * n    energy = 0.0# 残差融合;平方和只加前 l 个有效位置for i in range(n):        h[i] = x[i] + alpha * r[i]if i < l:            energy += h[i] * h[i]# l 为 0 时分母取 1,避免除零    d = l if l > 0 else 1    rms = (energy / d + eps) ** 0.5    y = []for i in range(n):if i >= l:# 填充位置固定为 0            val = 0.0elif rms == 0.0:# 有效位全是 0 且 eps 为 0,归一化项按 0,只留偏置            val = b[i]else:            val = g[i] * h[i] / rms + b[i]        y.append(fmt(val))return " ".join(y) + " | " + fmt(rms) + " | " + fmt(energy)m, n, eps = input().split()m = int(m)n = int(n)eps = float(eps)g = list(map(float, input().split()))b = list(map(float, input().split()))for _ in range(m):    a = list(map(float, input().split()))    l = int(a[0])    alpha = a[1]    x = a[2:2 + n]    r = a[2 + n:2 + 2 * n]print(calc(n, l, alpha, x, r, g, b, eps))

第3题-基于CART分类树预测客户购房选择(300分)

CART(Classification and Regression Trees)分类树通过二元切分递归地将数据划分为不纯度最小的子集。它通过基尼系数(Gini Index)计算最优分裂特征和点,形成二叉树结构,适用于处理离散和连续数据。 本题要求应用CART分类树模型预测客户是否购房。给定一个训练数据集,通过构建CART二叉决策树,使用基尼指数选择最优特征和最优切分点,对输入的测试样本进行预测。

划分规则: 对于每个特征,尝试所有可能的取值作为切分点,将数据划分为左子集和右子集:

  • 左子集:特征值 = 切分点
  • 右子集:特征值 ≠ 切分点

数据集说明 包含4个特征和1个标签,所有取值的输入转换为整数枚举。

  • 特征1: 年龄段(0: 18-30岁; 1: 31-40岁; 2: 41-55岁; 3: 56岁及以上)
  • 特征2: 婚姻状况(0: 单身; 1: 恋爱; 2: 已婚)
  • 特征3: 是否有房(0: 无; 1: 有)
  • 特征4: 是否有工作(0: 无; 1: 有)
  • 标签: 购房结果(0: 否; 1: 是)

基尼指数计算公式 对于包含K个类别的数据集, 为指定标签的样本占比:

加权基尼指数 对于特征A的切分点v,将D划分为  和 :

预测规则 叶子节点的预测类别为该节点中样本数最多的类别;若多个类别样本数相同,取类别编号较小的。

停止分裂条件(满足任一条件即停止):

  1. 节点中所有样本标签相同
  2. 节点中样本数小于2
  3. 无法找到使基尼指数降低的切分点

平局处理规则

  1. 遍历特征时,按特征编号从小到大(特征1 → 特征2 → 特征3 → 特征4)
  2. 对于每个特征,遍历其所有可能的取值作为切分点,按取值从小到大
  3. 计算每个切分点的加权基尼指数,选择基尼指数最小的切分点
  4. 当多个特征的基尼指数相同且均为最小值时,选择特征编号较小的特征
  5. 当同一特征内多个取值的基尼指数相同且均为最小值时,选择取值较小的作为切分点(即左子集为 等于该较小值)

样例1

输入:

200 0 0 1 10 0 1 0 00 1 0 0 00 1 1 1 10 2 0 1 11 0 0 0 01 0 1 1 11 1 0 1 11 1 1 0 01 2 1 0 02 0 0 1 12 0 1 0 12 1 0 0 02 1 1 1 12 2 0 0 03 0 0 0 03 0 1 1 03 1 0 1 13 1 1 0 03 2 0 1 0101 1 1 02 0 0 13 2 0 10 0 1 01 2 1 02 1 0 03 0 1 10 1 1 11 0 0 02 2 0 0

输出:

0 1 0 0 0 0 0 1 0 0

解题思路

核心思路:按题面规则现建一棵 CART 二叉分类树。每个节点选一个特征和一个取值做二元切分,左子树放该特征等于这个取值的样本,右子树放不等于的样本。只有加权基尼指数比当前节点严格更小的切分才接受,否则停止。叶子预测人数更多的类别,两种人数相同就预测编号较小的 0。

实现方法:特征按编号从 1 到 4 枚举,每个特征里出现过的取值按从小到大枚举,基尼用分数比较,只有分子分母交叉相乘后严格变小才更新。这样平局会自然留下更小的特征编号和更小的取值。样本数小于 2,或者节点里只剩一种标签,也直接变成叶子。预测时从根往下走,测试样本的特征值等于切分值就进左子树,否则进右子树。

python代码(C++和JAVA代码见在线OJ网址)

import sysit = iter(sys.stdin.read().split())n = int(next(it))a = [[int(next(it)) for _ in range(5)] for _ in range(n)]def stat(ids):    c0 = c1 = 0for i in ids:if a[i][4] == 0:            c0 += 1else:            c1 += 1return c0, c1def build(ids):    c0, c1 = stat(ids)    tot = len(ids)# 人数较多的类别作为叶子预测;人数相同取较小编号 0    lab = 0 if c0 >= c1 else 1# 样本不足 2 个,或标签已经纯,停止分裂if tot < 2 or c0 == 0 or c1 == 0:return (-1, lab)# 当前节点基尼写成 (tot^2 - c0^2 - c1^2) / tot^2    base_n = tot * tot - c0 * c0 - c1 * c1    base_d = tot * tot    best = None# 特征编号从小到大,取值从小到大for f in range(4):for v in sorted(set(a[i][f] for i in ids)):            L = [i for i in ids if a[i][f] == v]            R = [i for i in ids if a[i][f] != v]if not L or not R:continue            l0, l1 = stat(L)            r0, r1 = stat(R)            n1, n2 = len(L), len(R)            g1 = n1 * n1 - l0 * l0 - l1 * l1            g2 = n2 * n2 - r0 * r0 - r1 * r1# 加权基尼 = (g1/n1 + g2/n2) / tot            num = g1 * n2 + g2 * n1            den = tot * n1 * n2# 不能严格降低基尼的切分丢掉if num * base_d >= base_n * den:continue# 分数相等时不替换,于是更小的特征和取值被留下if best is None or num * best[1] < best[0] * den:                best = (num, den, f, v, L, R)if best is None:return (-1, lab)return (best[2], best[3], build(best[4]), build(best[5]))def ask(node, x):if node[0] < 0:return node[1]# 等于切分值走左,否则走右if x[node[0]] == node[1]:return ask(node[2], x)return ask(node[3], x)root = build(list(range(n)))m = int(next(it))ans = []for _ in range(m):    x = [int(next(it)) for _ in range(4)]    ans.append(str(ask(root, x)))print(" ".join(ans))

刷题练习:CodeFun2000.com

相关学习资料