夜雨聆风学习资料网

ARTICLE · 1066271

华为机考AI方向9月23日笔试题与解析

华为机考AI方向9月23日笔试题与解析

写在前面

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

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

题号
题目
难度(对标leetcode)
核心做法
1
选择题
中等
选择题
2
激活检查点放置
中等
DP
3
NPU梯度任务均衡调度
中等
DFS

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

1、用 RANSAC 拟合直线时,外点占比约 70%。若希望模型仍有较大概率被正确估出,应优先采取哪一措施?
  • 改用最小二乘直接拟合全部点
  • 把最小样本集规模再加大
  • 换用更高次多项式去“吃掉”外点
  • 提高随机采样的迭代轮数
2、关于数据并行(Data Parallel)中各卡上的模型与数据,正确的是
  • 每张 GPU 只保存模型的部分层,处理同一批数据
  • 每张 GPU 保存完整模型副本,处理同一批数据
  • 每张 GPU 保存完整模型副本,各自处理不同数据批次
  • 每张 GPU 只保存模型的部分层,各自处理不同数据批次
3、用 PSNR 评估扩散模型生成图质量,得到 5 个样本:  。该样本的样本标准差为(保留两位小数)
  • 1.15
  • 1.20
  • 1.18
  • 1.12
4、要判断    是否为凸函数,可检查其 Hessian 矩阵是否为:
  • 正交矩阵
  • 负定矩阵
  • 对角矩阵
  • 正定或半正定矩阵
5、RAG 流水线里,检索模块主要负责什么?
  • 更新生成模型的权重
  • 从外部知识库取出相关文档/片段
  • 持久化用户画像
  • 调整网络拓扑
6、CNN 中“感受野”通常指
  • 卷积核边长
  • 池化窗口边长
  • 特征图上某点所对应的输入图像区域
  • 全连接层入口维度
7、若两向量点积等于 0,则二者
  • 模长相同
  • 同向
  • 反向
  • 互相垂直
8、已知   ,  ,  ,则  
  • 0.50
  • 0.40
  • 0.25
  • 0.20
9、用牛顿法求方程    的单根时,局部收敛阶通常是:
  • 线性收敛
  • 一阶收敛
  • 三阶收敛
  • 二阶收敛(平方收敛)
10、若   ,则    大约为
  • 0.50
  • 0.95
  • 0.84
  • 0.68

第2题-激活检查点放置(150分)

题目描述

在大模型训练中,前向传播会留下大量中间激活,反向传播时还要用到它们。当 GPU 显存吃紧时,激活重计算(Gradient Checkpointing)是一种常见的「用时间换空间」做法:只在若干「检查点」层保存激活,其余层在反向阶段再算一遍。本题要求:在给定显存预算下,求出最优的 Checkpoint 放置方案。

模型共有    层(编号为    到   ),按前向顺序依次执行。给定两个长度为    的正整数数组:

  • forward_time[i](  ):第    层前向传播的耗时;
  • memory[i](  ):在第    层保存激活(打 Checkpoint)所需的额外显存。

固定边界:

  • 第    层(输入层)的激活常驻显存,不计入额外开销,它是天然的起始 Checkpoint;
  • 第    层是终点:不必在第    层再存额外激活,也不占用 Checkpoint 显存。

操作:你可以在某些中间层   (  )打 Checkpoint。在第    层打 Checkpoint 会占用 memory[c-1] 的显存(第    层对应数组下标   )。所有 Checkpoint 的显存占用之和不得超过   。

重计算代价:设两个相邻 Checkpoint 位置为    与   (  ,中间没有别的 Checkpoint)。反向传播经过该区间时,需要从第    层的激活出发,重新前向计算以恢复中间层激活。由于反向是逐层推进的,层    只需重算一次(从    前向到   ),层    需要重算两次,以此类推。因此该区间的重计算代价为:

其中    是第    层的前向耗时,   是该层被重复计算的次数。若   (相邻 Checkpoint),代价为   。

目标:在显存预算    内选择 Checkpoint 放置方案,使整网总重计算代价最小。总代价等于所有相邻 Checkpoint 对之间的代价之和(隐含起点    与终点   )。

样例1

输入

5 35 10 5 10 201 2 1 3 1

输出

15

解题思路

核心思路

本题是在显存预算约束下,选择若干中间层打 Checkpoint,使重计算总代价最小。相邻两个 Checkpoint(含隐式起点    与终点   )之间的代价为

可先用前缀和   ,由递推   、   在    内预处理全部区间代价。

实现方法

令    表示「最后一个 Checkpoint 打在位置   ,已用显存恰好为   」时的最小代价(   为起点,  )。对   ,枚举上一个 Checkpoint   :

终点    不占显存,答案为   。

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

INF = 10**18def min_recompute(n, max_mem, f, mem):    # 前缀和,便于 O(1) 递推区间代价    s = [0] * (n + 1)    for i in range(1, n + 1):        s[i] = s[i - 1] + f[i - 1]    cost = [[0] * (n + 1) for _ in range(n + 1)]    for c in range(n):        for d in range(c + 2, n + 1):            # 终点从 d-1 扩到 d:区间内每层多重算一次            cost[c][d] = cost[c][d - 1] + (s[d - 1] - s[c])    dp = [[INF] * (max_mem + 1) for _ in range(n + 1)]    dp[0][0] = 0    for i in range(1, n):        mi = mem[i - 1]        for j in range(i):            for w in range(max_mem + 1):                if dp[j][w] >= INF:                    continue                nw = w + mi                if nw > max_mem:                    continue                val = dp[j][w] + cost[j][i]                if val < dp[i][nw]:                    dp[i][nw] = val    ans = INF    for j in range(n):        for w in range(max_mem + 1):            if dp[j][w] < INF:                # 终点 N 不占显存                ans = min(ans, dp[j][w] + cost[j][n])    return ansdef main():    n, max_mem = map(int, input().split())    f = list(map(int, input().split()))    mem = list(map(int, input().split()))    print(min_recompute(n, max_mem, f, mem))if __name__ == "__main__":    main()

第3题-NPU梯度任务均衡调度(300分)

题目描述

在大模型分布式训练场景下,要把若干梯度更新任务分配到多张 NPU 上。目标是让各卡的「梯度计算总耗时」尽量均衡(即最小化「最大卡总耗时」),再按学习率衰减规则汇总总训练成本。

规则如下:

  1. 任务分配:将    划分成    个子集(一张 NPU 对应一个子集)。每个任务必须分到恰好一个子集;在所有划分中,取「子集总和的最大值」最小的那些划分。
  2. 成本计算:记    为各卡总耗时的最大值,   为第    张卡的总耗时。则
    • 第    张卡学习率:  ;
    • 第    张卡训练成本:  ;
    • 总训练成本:所有卡成本之和。

样例1

输入

8,5,4,3,3,2,1;3;0.1;0.8

输出

9,2.4400

解题思路

每个梯度任务都要分到恰好一张卡上。直接枚举:第  个任务依次尝试  张卡,用数组记下各卡当前耗时。如果某张卡加上这个任务后,耗时已经大于目前找到的最小「最大耗时」,这一支就不用再搜。搜完得到最小的 ,以及一组达到它的各卡负载,再按

把各卡成本加起来,保留四位小数。

实现方法

  1. 按 ‎; 拆开输入,读出耗时数组、、基础学习率和衰减系数。
  2. 递归枚举每个任务的去向,维护当前最小的最大耗时和对应负载。
  3. 用上面的公式累加成本并输出。

暴力dfs做法(95%通过率)

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

def parse_line(s):    parts = s.strip().split(";")    times = [int(x) for x in parts[0].split(",") if x != ""]    k = int(parts[1])    base = float(parts[2])    decay = float(parts[3])    return times, k, base, decaydef solve(times, k, base, decay):    n = len(times)    loads = [0] * k    best_m = None    best_loads = None    def dfs(i):        nonlocal best_m, best_loads        if i == n:            m = max(loads)            if best_m is None or m < best_m:                best_m = m                best_loads = loads[:]            return        for b in range(k):            loads[b] += times[i]            if best_m is None or loads[b] <= best_m:                dfs(i + 1)            loads[b] -= times[i]    dfs(0)    total = 0.0    for s in best_loads:        total += s * base * (decay ** (best_m - s))    return best_m, totaldef main():    times, k, base, decay = parse_line(input().strip())    m, total = solve(times, k, base, decay)    print(f"{m},{total:.4f}")if __name__ == "__main__":    main()

刷题练习:CodeFun2000.com

相关学习资料