第1章 深度神经网络基础与计算框架
1.1 深度学习基本流程
Q1:深度学习方法的基本三步是什么?
- 定义带参数的函数,也就是神经网络:输入样本 ,输出预测 。
- 定义优化目标:最小化损失函数 。
- 计算梯度并更新参数:通常使用梯度下降或其变体更新 。
Q2:为什么说深度学习系统不仅是算法问题?
A:因为深度学习成功依赖四个部分:算法、算力、数据、框架
Q3:计算框架一般包含哪些核心组件?
- 前端接口:Python、C++ 等,面向用户编程。
- 统一模型表示:计算流图。
- 自动求导:根据计算图生成反向传播。
- 图优化与调度执行:Batching、Cache、Overlap 等。
- 后端执行:CPU、GPU、RDMA 等硬件。
- 内核代码优化与编译:GPU kernel、自动代码生成等。
1.2 计算图与自动求导
Q4:计算图是什么?
A:计算图是用节点和边表示神经网络计算过程的图结构。节点通常表示算子或变量,边表示数据依赖。例如 x,w,b 经过乘法、加法得到 y。
Q5:计算图有什么作用?
- 统一表示模型。
- 方便自动求导。
- 支持图优化,如公共子表达式消除、算子融合、常量传播。
- 支持跨设备调度和后端代码生成。
Q6:自动求导的核心思想是什么?
A:前向计算时记录计算关系,反向传播时根据链式法则自动计算每个变量的梯度
Q7:动态图和静态图有什么区别?
- 动态图:边执行边构图,灵活,调试方便,PyTorch 典型。
- 静态图:先定义完整计算图,再统一执行,便于全局优化。
1.3 常见神经网络结构
Q8:CNN 为什么适合图像任务?
A:CNN利用局部连接、权值共享和池化操作,能减少参数量并提取空间局部特征。
Q9:卷积、池化、全连接分别负责什么?
- 卷积:提取局部特征。
- 激活:引入非线性。
- 池化:降采样,减少计算量,提高一定平移鲁棒性。
- 全连接:将特征映射到类别或输出空间。
Q10:Max Pooling 和 Average Pooling 区别?
- Max Pooling 取局部窗口最大值,更强调显著特征。
- Average Pooling 取局部平均值,更平滑。
第2章 PyTorch基础与实践
2.1 nn.Module 与网络搭建
Q1:PyTorch 中如何定义一个神经网络?
A:继承 torch.nn.Module,在 __init__() 中定义可学习层,在 forward() 中定义前向传播逻辑。
Q2:nn.Module 的作用是什么?
A:它是网络的封装,包含网络层定义、参数管理、前向传播、设备迁移、训练/评估模式切换等功能。
Q3:为什么定义了 forward() 后不需要手写反向传播?
A:因为 PyTorch 的 Autograd 会根据前向计算过程自动构建计算图,并自动求梯度。
2.2 数据集与 DataLoader
Q4:torchvision.transforms.ToTensor() 的作用是什么?
A:将 PIL 图像或 NumPy 格式图像转换为 PyTorch Tensor
Q5:自定义数据集一般需要实现哪些函数?
__init__():初始化数据路径、标签、transform。__len__():返回数据集大小。__getitem__():根据索引读取样本并返回数据和标签。
Q6:数据增强通常发生在哪里?
A:通常在 transform 中完成,例如随机裁剪、翻转、归一化
2.3 GPU 训练
Q7:PyTorch 中把数据或模型转移到 GPU 的方法有哪些?
A:常用方法是:
.cuda().to(device)
Q8:GPU 训练环境一般包括哪些组件?
A:Nvidia Driver、CUDA、cuDNN、PyTorch
第3章 矩阵计算与计算机体系结构
3.1 神经网络为什么大量依赖矩阵计算?
Q1:神经网络中哪些操作可以映射为矩阵乘法?
- 全连接层:本质是矩阵乘法。
- 卷积层:可通过 im2col 等方式转换为矩阵乘法。
- RNN/LSTM:包含大量矩阵乘和 element-wise 运算。
- Attention:核心计算如 QK^T、Softmax 后乘 V,本质也大量依赖矩阵乘法
Q2:卷积如何映射为矩阵乘法?
A:通过重组输入特征图,把每个卷积窗口展开成矩阵的一列或一行,卷积核也展开成矩阵,然后用矩阵乘法完成卷积计算
3.2 CPU 与 GPU 结构特点
Q3:CPU 的结构特点是什么?
A:CPU 适合复杂控制逻辑和低延迟任务,拥有复杂控制单元、较深缓存层级、较强单线程性能,但并行计算单元数量相对少。
Q4:GPU 的结构特点是什么?
A:GPU 拥有大量简单计算核心,适合大规模数据并行和高吞吐矩阵计算,但控制逻辑弱、分支性能差,更依赖高并行度。
Q5:CPU 和 GPU 的考试答法怎么写?
- CPU:少量强核心,复杂控制,缓存层级深,适合串行和分支复杂任务。
- GPU:大量弱核心,SIMT/SIMD 风格,高吞吐,适合矩阵乘、卷积等数据并行任务。
3.3 SIMD 与矩阵计算优化
Q6:SIMD 是什么?
A:SIMD 是 Single Instruction Multiple Data,即单指令多数据流。一条指令同时作用于多个数据。
Q7:判断题“SIMD 是多数据多指令”对吗?
A:错误。多指令多数据是 MIMD,SIMD 是单指令多数据。这个点在
3.4 矩阵分块
Q8:为什么矩阵乘法要分块?
A:分块可以提高缓存命中率,减少从慢速内存读取数据的次数,让数据在寄存器、Cache 或片上存储中被多次复用。
Q9:综合题“矩阵相乘不分块与分块的内存读取次数”考什么?
A:考察的是数据复用。标准答题思路:
- 不分块时,每次计算元素都可能重复读取矩阵 A、B 的数据,访存次数高。
- 分块后,一个块加载到高速缓存后可参与多个乘加运算,减少主存访问。
- 结论:分块降低访存、提高局部性、提升矩阵乘吞吐。
Q10:ASIC 减少访存的核心是什么?
A:核心是提高数据复用、减少对外部存储器的访问。可从片上缓存、数据流设计、计算靠近数据、阵列结构复用输入/权重/输出几个角度作答
第4章 AI编译器与编译优化
4.1 传统编译器
Q1:传统编译器的基本组成是什么?
A:Front-End、Optimizer、Back-End。
- Front-End:词法/语法/语义分析,生成抽象语法树或中间表示。
- Optimizer:对中间代码进行优化。
- Back-End:把优化后的中间代码转成目标机器代码。
Q2:Pass 是什么?
A:Pass 是对程序进行一次完整扫描与优化处理的过程
4.2 IR 中间表示
Q3:IR 的定义是什么?
A:IR,即 Intermediate Representation,中间表示,是用于表示中间代码的数据结构。
Q4:IR 的作用是什么?
- 解耦前端和后端。
- 提升跨平台能力。
- 方便支持新语言和新硬件。
- 方便做统一优化。
Q5:AI 编译器中的 IR 有哪些形式?
A:常见有:
- 计算图 IR:DAG,表示算子依赖。
- 算子表达式 IR:描述算子内部计算。
- 更底层的硬件相关 IR:面向 CPU/GPU/TPU/NPU 后端
4.3 传统编译器与 AI 编译器区别
Q6:传统编译器和 AI 编译器输入输出有什么区别?
- 传统编译器:输入高级语言代码,输出机器代码。
- AI 编译器:输入计算图或算子,输出可执行代码或机器代码。
Q7:传统编译器和 AI 编译器目标有什么区别?
- 传统编译器主要降低编程难度,其次优化性能。
- AI 编译器主要优化程序性能,其次降低编程难度。
4.4 前端优化
Q8:前端优化的对象是什么?
A:主要是计算图,也就是算子之间的关系和数据依赖。
Q9:前端优化有哪些例子?
A:常考例子:
- 算术表达式化简。
- 公共子表达式消除。
- 常量传播。
- 死代码消除。
- 算子融合。
- 算子替换。
- 图剪枝。
Q10:公共子表达式消除是什么?
A:如果多个表达式中存在相同子表达式,就只计算一次并复用结果,减少重复计算
Q11:算子融合能减少什么?
A:通常减少:
- 中间结果的内存读写。
- Kernel 启动开销 / 算子调度开销。
4.5 后端优化
Q12:后端优化的对象是什么?
A:主要是算子内部计算、循环、内存访问、硬件指令和并行执行策略。
Q13:后端优化有哪些例子?
- 循环展开。
- 循环拆分。
- 循环重排。
- 分块 / Tiling。
- 向量化。
- 内存访问合并。
- 寄存器复用。
- 面向 GPU 的线程块调度。
Q14:循环拆分有什么作用?
A:把一个大循环拆成多个小循环或多个阶段,使不同计算部分更易优化,例如改善缓存局部性、便于向量化、减少不必要计算、方便并行调度
第5章 稀疏化
5.1 稀疏化背景
Q1:为什么需要模型稀疏化?
A:模型规模越来越大,计算和存储需求快速增长,而硬件算力增长跟不上模型需求。稀疏化可用于模型压缩、降低计算量、加速推理,是资源受限平台部署的重要手段
Q2:稀疏化的来源有哪些?
- 权重稀疏。
- 激活稀疏。
- 梯度稀疏。
- 结构化数据本身的稀疏性。
5.2 权重稀疏
Q3:权重稀疏是什么?
A:把神经网络中不重要的权重置零或删除,以减少参数量和计算量。
Q4:非结构化剪枝是什么?
A:以单个权重为单位剪枝,保留位置不规则。优点是压缩率和精度通常较好,缺点是计算不规则,普通硬件难以加速。
Q5:结构化剪枝是什么?
A:以通道、卷积核、块、行列等结构为单位剪枝。优点是规则、硬件友好、容易加速;缺点是可能牺牲压缩率或准确率。
Q6:判断题“结构化剪枝比非结构化剪枝的稀疏度更高”对吗?
A:通常错误
5.3 激活稀疏
Q7:激活稀疏是什么?
A:神经元激活值中大量为 0,尤其 ReLU 会把负数变成 0,因此可以跳过部分无效计算。
Q8:为什么说激活稀疏是数据驱动的?
A:因为激活是否为 0 取决于输入数据,不同输入会产生不同稀疏模式,所以它属于数据驱动的稀疏化。
Q9:APoZ 指标是什么?
A:APoZ 表示 Average Percentage of Zeros,即平均零激活比例。APoZ 接近 1 的神经元说明其输出经常为 0,对后续计算和最终结果贡献较小。
5.4 梯度稀疏
Q10:梯度稀疏是什么?
A:分布式训练中只传输较大的梯度,小梯度暂时累积在本地,以减少通信量。
Q11:梯度稀疏 SGD 的基本策略是什么?
A:大于阈值的梯度被传输,小梯度在本地累积
5.5 模型量化
Q12:模型量化的作用是什么?
- 降低模型存储空间。
- 减少内存带宽需求。
- 加快推理速度。
- 降低能耗。
- 便于部署到边缘设备。
第6章 分布式训练
6.1 并行计算基础
Q1:为什么深度学习需要分布式训练?
A:模型和数据规模越来越大,单设备训练速度和显存容量无法满足需求
Q2:Amdahl 定律说明什么?
A:加速比受串行部分限制,仅提高并行部分不够,串行部分会成为理论上限
Q3:Gustafson 定律说明什么?
A:当问题规模随处理器数量增加而扩大时,线性加速是可能的
6.2 数据并行、模型并行、流水并行
Q4:数据并行是什么?
A:每个 worker 保存完整模型,处理不同 mini-batch 数据,反向传播后同步梯度。
Q5:模型并行是什么?
A:把模型不同部分切分到不同设备上,不同设备负责不同层或不同参数。
Q6:流水并行是什么?
A:把模型切成多个阶段,不同 mini-batch 在不同阶段流水执行,提高设备利用率。
Q7:算子间并行主要有哪些方式?
A:可从以下角度答:
- 数据并行:同一算子处理不同数据分片。
- 模型/算子切分并行:一个大算子按维度切分到多个设备。
- 流水并行:不同算子或层在不同设备上形成流水。
- 任务图并行:计算图中无依赖的算子并行执行。
6.3 All-Reduce
Q8:All-Reduce 的作用是什么?
A:在分布式数据并行训练中汇总所有 worker 的梯度,并把聚合后的梯度返回给所有 worker,使各个模型副本保持一致。
Q9:All-Reduce 有哪两种实现方式?
A:常见答法如下:
- Reduce + Broadcast。
- Scatter-Reduce + All-Gather。 题目中写作“All-together”大概率是对 All-Gather 的回忆表述。
Q10:Ring AllReduce 的过程怎么描述?
A:Ring AllReduce 通常分两阶段:
- Scatter-Reduce:每个节点把梯度切块,在环上发送并累加,最终每个节点得到一部分聚合结果。
- All-Gather:每个节点继续沿环交换已聚合的块,最终所有节点得到完整聚合梯度。 综合题考过“ring allreduce 过程图的绘制”。
6.4 同步、异步、阻塞、非阻塞
Q11:同步通信和异步通信是什么?
- 同步通信:多个 worker 按统一节奏等待并交换信息。
- 异步通信:worker 不必等待所有其他 worker,可独立推进。
Q12:阻塞通信和非阻塞通信是什么?
- 阻塞通信:调用后必须等待通信完成才能继续执行。
- 非阻塞通信:发起通信后可以继续执行后续计算,之后再检查或等待通信完成。
Q13:判断题“阻塞式通信就是同步通信,非阻塞式通信就是异步通信”对吗?
A:错误。阻塞/非阻塞描述的是调用是否等待完成;同步/异步描述的是多个进程或 worker 的协作时序,它们不是同一组概念
Q14:PyTorch 实现 GPU/节点同步常用通信原语是什么?
A:常见是 torch.distributed 中的 collective communication primitives,例如 all_reduce、broadcast、reduce、all_gather、barrier 等
Q15:Horovod 4 个 worker、gloo 后端、文件名 test.py 的运行命令怎么写?
A:常见写法:
horovodrun -np 4 -H localhost:4 python test.pyhorovodrun -np 4 -H localhost:4 python test.py如果题目强调 gloo 后端,可写成:
horovodrun -np 4 --gloo python test.pyhorovodrun -np 4 --gloo python test.py有的环境也可能写:
horovodrun -np 4 -H localhost:4 --gloo python test.pyhorovodrun -np 4 -H localhost:4 --gloo python test.py考试时按老师
第7章 调度、容器与集群管理
7.1 深度学习作业生命周期
Q1:深度学习作业 Job 的生命周期是什么?
- 作业提交与排队。
- 作业资源分配与调度。
- 作业执行完成与释放。
Q2:GPU 集群多租户场景面临哪些问题?
- 多用户、多作业共享 GPU。
- 作业环境需求不同。
- 作业资源需求不同。
- 服务器软件环境单一。
- 空闲资源碎片化。
7.2 Docker、镜像与容器
Q3:Docker 包括哪些主要技术?
A:重点包括:
- 镜像 Image。
- 容器 Container。
- 仓库 Registry。 虚拟机不是 Docker 的主要组成技术。
Q4:Image、Container、Registry 分别是什么?
- Image:打包作业环境依赖。
- Container:运行时作业资源管理与隔离。
- Registry:共享、上传、下载镜像
Q5:镜像和容器的关系是什么?
A:容器 = 镜像 + 顶层读写层。镜像是静态、只读的;容器是动态、可读写的
Q6:判断题“一个容器包含多层镜像,容器可读可写,镜像只读”对吗?
A:基本正确。更准确地说,镜像由多层只读 layer 构成,容器在镜像之上加一个可读写层
Q7:Docker 的优点有哪些?
- 轻量级。
- 标准化。
- 一致的运行环境。
- 快速启动。
- 隔离性。
7.3 Dockerfile 命令
Q8:FROM 是什么?
A:指定基础镜像。
Q9:RUN 是什么?
A:构建镜像时执行命令,比如安装依赖。
Q10:WORKDIR 是什么?
A:设置容器中的工作目录。
Q11:ENV 是什么?
A:设置环境变量。
Q12:ENTRYPOINT 是什么?
A:设置容器启动时默认执行的命令。
Q13:Dockerfile 综合题怎么答?
A:按“从基础镜像开始 → 安装环境依赖 → 设置工作目录/环境变量 → 复制代码 → 指定启动命令”的顺序解释
7.4 调度算法与资源分配
Q14:DRF 是什么?
A:DRF,即 Dominant Resource Fairness,主导资源公平算法。它在多资源场景下比较每个用户占用比例最大的资源,也就是 dominant share,然后优先给 dominant share 最小的用户分配资源。
Q15:DRF 资源分配题怎么做?
A:步骤:
- 写出集群总资源,例如 CPU、GPU、内存。
- 写出每个用户每个任务的资源需求。
- 每轮计算用户当前 dominant share。
- 给 dominant share 最小的用户分配一个任务。
- 重复直到某资源不足。
7.5 HiveD 与抢占
Q16:HiveD 算法的核心思想是什么?
A:HiveD 面向 GPU 集群调度,核心是通过 cell / buddy 等层次化资源抽象和拓扑感知调度,减少资源碎片,提高 GPU 作业局部性,并支持多租户、优先级和抢占。
Q17:深度学习作业被抢占会怎样?
A:YARN 抢占中,Resource Manager 可能强行杀死被标记的容器
Q18:判断题“深度学习作业下,被抢占的作业当前只能失败,checkpoint 之后的训练成果将被丢弃”对吗?
A:通常可以判断为正确。
第8章 安全与隐私
8.1 AI 安全相关性质
Q1:AI 安全与隐私关注哪些性质?
A:主要包括:
- 完整性 Integrity。
- 保密性 Confidentiality。
- 伦理 Ethics。
Q2:完整性 Integrity 是什么?
A:模型学习和预测过程应不受干扰,输出结果符合模型正常表现。对抗攻击与防御属于完整性问题。
Q3:保密性 Confidentiality 是什么?
A:模型使用过程中,参数和数据不能被窃取或泄露
Q4:伦理 Ethics 涉及什么?
A:算法应用和结果应符合法律、道德和伦理,包括 AI 偏见、Deepfake、AI 生成假新闻等问题。
8.2 对抗攻击
Q5:对抗攻击是什么?
A:攻击者对输入样本加入精心构造的小扰动,使人类难以察觉,但模型预测错误。
Q6:哪些情况不属于对抗攻击?
A:以下情况通常不属于对抗攻击:
- 天气原因导致物体识别出错。
- 数据集不完善导致模型效果不好。 这些通常不属于对抗攻击,因为它们不是攻击者有意构造扰动导致的错误。
8.3 主动防御与被动防御
Q7:被动防御是什么意思?
A:不改变或少改变模型训练过程,而是在攻击发生后检测、过滤、净化输入,或通过外部机制降低攻击影响。
Q8:主动防御是什么意思?
A:主动提高模型鲁棒性,典型方法是对抗训练:在训练阶段加入对抗样本,让模型学习抵抗攻击。
Q9:主动防御过程怎么简述?
- 用当前模型生成对抗样本。
- 把干净样本和对抗样本一起加入训练。
- 优化模型,使其在正常样本和对抗样本上都表现良好。
- 得到更鲁棒的模型。
Q10:主动防御的缺点是什么?
- 训练成本高。
- 对特定攻击有效,对未知攻击泛化有限。
- 可能降低干净样本准确率。
- 难以覆盖所有攻击形式。
高频综合题专项
综合1:矩阵乘分块访存次数
Q:矩阵乘法中,不分块和分块的内存读取次数怎么答?
A:答题思路:
- 不分块:每计算一个输出元素,需要反复读取 A 的一行和 B 的一列,数据复用差,主存访问次数高。
- 分块:把 A、B 的子块加载到 cache/shared memory 后,子块内多次复用,显著减少慢速内存访问。
- 结论:分块提升局部性,减少访存,提高矩阵乘吞吐。
- 如果题目给具体矩阵大小,就按块大小计算每个 block 加载次数,再乘 block 数。
综合2:循环拆分 63 次循环
Q:按三次拆分一个 63 次循环怎么解释?
A:如果按三段拆,可以拆为 21、21、21 三个循环段。也可以根据题目要求拆成主循环和尾循环,例如按向量宽度或 tile 大小拆。核心解释:
- 拆分后每段循环结构更简单。
- 有利于缓存局部性。
- 有利于并行、向量化、流水化。
- 有利于把不同计算阶段分开优化。
综合3:Ring AllReduce 图
Q:Ring AllReduce 图怎么画?
- 画 N 个节点成环。
- 把每个节点梯度切成 N 份。
- 第一阶段 Scatter-Reduce:每轮每个节点发送一块给下家,同时接收上家一块并累加,经过 N-1 轮后,每个节点得到一块完整 reduce 结果。
- 第二阶段 All-Gather:继续环上传播 reduce 后的块,经过 N-1 轮后,每个节点拥有完整梯度。
- 标注“通信量均衡、无中心瓶颈”。
综合4:DRF 表格
Q:DRF 表格怎么画?
A:表头建议写: | 轮次 | 分配给用户 | 用户A已分配任务 | 用户B已分配任务 | A dominant share | B dominant share | 剩余资源 |
每一轮:
- 计算每个用户 CPU/GPU/内存占总资源比例。
- 取最大值作为 dominant share。
- 给 dominant share 最小的用户分配。
- 资源不足则停止。
综合5:Dockerfile 命令解释
Q:Dockerfile 命令综合题怎么写?
FROM:指定基础镜像。RUN:构建镜像阶段执行命令,常用于安装依赖。WORKDIR:设置工作目录。ENV:设置环境变量。COPY/ADD:复制代码或文件到镜像中。EXPOSE:声明容器对外服务端口。ENTRYPOINT:设置容器启动后执行的主命令。CMD:设置默认参数或默认启动命令。
实验一:深度学习框架及工具入门
实验一重点是:训练流程、TensorBoard 可视化、Profiler 性能分析、Batch Size、CPU/GPU 对比
Q1:一个 PyTorch 训练程序的基本流程是什么?
- 加载数据集,构造
Dataset和DataLoader。 - 定义模型,例如 CNN、MLP。
- 定义损失函数,例如
CrossEntropyLoss。 - 定义优化器,例如 SGD、Adam。
- 前向传播得到输出。
- 计算 loss。
optimizer.zero_grad()清空梯度。loss.backward()反向传播。optimizer.step()更新参数。- 在测试集上评估准确率。
简洁答法:
PyTorch 训练流程包括数据加载、模型定义、前向传播、损失计算、反向传播、参数更新和测试评估。自动求导机制会根据前向计算图自动计算梯度。
Q2:TensorBoard 在实验一中主要用来观察什么?
A:主要观察:
- loss 曲线;
- accuracy 曲线;
- 模型结构;
- 计算图;
- 训练是否收敛;
- 是否震荡、过拟合或收敛缓慢。
Q3:Profiler 主要看什么?
A:看训练中哪些操作最耗时,比如:
- 卷积;
- 矩阵乘法;
- 数据加载;
- 数据搬运 CPU → GPU;
- loss 计算;
- backward;
- optimizer step。
Q4:Batch Size 增大通常会发生什么?
- 吞吐率通常提高,因为 GPU 并行利用率更高。
- 单步耗时可能增加,但每秒处理样本数可能增加。
- 显存占用增加。
- 梯度估计更稳定,但可能影响泛化。
- 如果 batch size 过大,可能导致显存不足或收敛变慢。
Batch size 增大后,单次迭代计算量增加,但 GPU 并行度提高,吞吐量通常上升;同时显存占用增加,通信或数据加载占比可能下降。但过大的 batch size 可能降低泛化能力或导致显存溢出。
Q5:为什么 GPU 比 CPU 快?
A:GPU 有大量并行计算核心,适合卷积、矩阵乘法等大规模数据并行操作。CPU 更适合复杂控制逻辑和串行任务。实验一要求对比 CPU/GPU 训练时间和算子执行情况,并分析 GPU 加速效果及适合 GPU 执行的计算类型。
Q6:为什么有时 GPU 利用率不高?
A:可能原因:
- batch size 太小,GPU 吃不饱;
- 数据加载太慢,CPU/DataLoader 成为瓶颈;
- 频繁 CPU-GPU 数据拷贝;
- 模型太小,计算量不足;
- I/O 慢;
- 代码中同步操作太多。
实验二:定制新的张量运算
实验二非常容易出简答题。重点是:自定义 forward/backward、Python API、C++ API、pybind11、性能对比
Q1:基于 Python API 自定义算子需要哪几步?
- 继承
torch.autograd.Function。 - 实现
forward(ctx, ...)。 - 在 forward 中用
ctx.save_for_backward()保存反向传播需要的 Tensor。 - 实现
backward(ctx, grad_output)。 - 用
.apply()调用自定义 Function。 - 如果要作为网络层,再封装成
nn.Module。
Q2:为什么自定义算子要写 backward?
A:因为 PyTorch 需要知道该算子对输入的梯度计算公式。对于框架已有算子,Autograd 可以自动组合求导;但自定义底层算子需要用户明确告诉系统反向传播逻辑。
backward 函数定义了损失函数对输入张量和参数的梯度计算方式,是自定义算子接入自动求导系统的关键。
Q3:不带 bias 的 Linear 前向和反向公式是什么?
假设:
Y = X W^TY = X W^T其中:
X: [batch, in_features]
W: [out_features, in_features]
Y: [batch, out_features]X: [batch, in_features]
W: [out_features, in_features]
Y: [batch, out_features]如果上游梯度是:
dY = grad_outputdY = grad_output则:
dX = dY W
dW = dY^T XdX = dY W
dW = dY^T X考试写法:
前向为 Y=XW^T。反向传播中,输入梯度为 \frac{\partial L}{\partial X}=\frac{\partial L}{\partial Y}W,权重梯度为 \frac{\partial L}{\partial W}=(\frac{\partial L}{\partial Y})^T X。
Q4:用 pybind11 将 C++ 张量运算扩展到 PyTorch 的 5 步是什么?
- 编写 C++ Tensor 运算函数。
- 用 pybind11 /
PYBIND11_MODULE绑定 Python 接口。 - 编写
setup.py,配置CppExtension和BuildExtension。 - 编译生成 Python 可调用扩展模块。
- 在 Python/PyTorch 中
import并调用该扩展算子。
Q5:Python 实现和 C++ 实现为什么性能不同?
- Python 有解释器开销;
- Python 层循环慢;
- C++ 更接近底层,函数调用和内存访问更高效;
- C++ 更容易做编译优化;
- 原生框架算子通常还有 CUDA kernel、向量化、内存布局优化;
- 小算子可能 C++ 优势不明显,因为 Python/C++ 绑定调用也有开销。
Q6:实验二性能通常怎么排序?
A:一般可能是:
原生 PyTorch 算子最快
C++ 自定义算子次之
Python 自定义算子较慢原生 PyTorch 算子最快
C++ 自定义算子次之
Python 自定义算子较慢但要注意:如果 C++ 实现没有做优化,可能不如 PyTorch 原生算子。因为 PyTorch 原生算子通常调用高度优化的 BLAS/cuDNN/CUDA kernel。
实验三:自动机器学习 AutoML / NNI
实验三重点是:手动调参 vs 自动调参、NNI、搜索空间、Tuner、NAS
Q1:AutoML 是什么?
AutoML 是自动机器学习,目的是自动化完成模型选择、超参数调优、神经网络架构搜索等流程,减少人工调参成本,提高模型优化效率。
Q2:NNI 自动调参的基本流程是什么?
- 修改基准模型代码,加入 NNI 接口。
- 用 NNI 获取超参数。
- 训练模型。
- 把验证准确率或 loss 上报给 NNI。
- 定义搜索空间。
- 配置 Tuner 和实验参数。
- 启动实验,在 Web 控制台查看结果。
- 记录最优超参数和准确率。
Q3:搜索空间是什么?
A:搜索空间是 AutoML 可以尝试的超参数范围,例如:
learning_rate: [0.1, 0.01, 0.001]
batch_size: [32, 64, 128]
dropout: [0.2, 0.5]
num_layers: [2, 3, 4]learning_rate: [0.1, 0.01, 0.001]
batch_size: [32, 64, 128]
dropout: [0.2, 0.5]
num_layers: [2, 3, 4]搜索空间定义了自动调参算法可探索的超参数取值范围,直接影响搜索效率和最终模型性能。
Q4:Random、TPE、Hyperband 有什么区别?
- Random:随机采样超参数,简单、并行友好,但搜索效率不一定高。
- TPE:基于历史结果建模,倾向于搜索更可能得到好结果的区域,通常比随机更高效。
- Hyperband:强调资源分配,先给很多配置少量资源,淘汰差的配置,再给好的配置更多训练资源,适合训练成本高的场景。
Q5:手动调参和 NNI 自动调参怎么比较?
A:从四个角度:
- 精度:谁找到更优配置;
- 耗时:总搜索成本;
- 操作复杂度:人工参与程度;
- 可复现性:实验记录是否系统化。
Q6:NAS 是什么?
NAS,即 Neural Architecture Search,神经网络架构搜索。它不是只调学习率、batch size 这类训练超参数,而是自动搜索网络结构,例如层数、通道数、连接方式、算子类型等。
实验四:分布式训练任务
实验四很可能出理论+实验分析题。重点是:DDP、rank/world size、GPU 数量、batch size、通信开销、模型参数规模、Gloo/NCCL
Q1:DDP 是什么?
DDP,即 Distributed Data Parallel,是 PyTorch 的分布式数据并行训练方式。每个进程/GPU 保存一份完整模型,处理不同数据分片,反向传播后通过通信原语同步梯度,使各模型副本保持一致。
Q2:rank 和 world size 是什么?
rank:当前进程在分布式任务中的编号。world_size:参与分布式训练的总进程数。rank=0通常作为主进程,负责日志、保存模型等。
Q3:DDP 为什么要用 DistributedSampler?
A:为了让不同进程读取不同的数据子集,避免每个 GPU 都训练同一批数据。否则数据并行就失去意义。
DistributedSampler 将数据集按 rank 切分,使每个进程处理不同 mini-batch,从而实现数据并行并避免重复采样。
Q4:GPU 数量增加,为什么加速比通常达不到线性?
A:因为增加 GPU 后不只有计算,还有额外开销:
- 梯度同步通信;
- 进程同步等待;
- 数据加载瓶颈;
- 小模型计算量不足;
- GPU 负载不均衡;
- 通信和计算不能完全重叠;
- 多机时还有网络延迟。
Q5:通信开销怎么近似测量?
通信时间 ≈ 单次迭代总时间 - 关闭梯度同步后的纯计算时间通信时间 ≈ 单次迭代总时间 - 关闭梯度同步后的纯计算时间通信占比:
通信占比 = 通信时间 / 单次迭代总时间通信占比 = 通信时间 / 单次迭代总时间Q6:Batch size 增大,通信占比为什么通常下降?
A:因为 batch size 增大后,每次迭代计算量增加;但梯度通信量主要由模型参数量决定,不随 batch size 成比例增加。因此计算时间增加,通信时间相对占比下降。
Q7:模型参数规模增大,通信开销为什么增加?
A:DDP 中每轮反向传播后需要同步梯度,梯度大小约等于模型参数大小。模型参数越多,需要传输的梯度越多,通信时间越长。大模型训练中通信可能成为主要瓶颈
Q8:Gloo 和 NCCL 区别?
- Gloo:通用通信后端,CPU/GPU 都可用,适合 CPU 或简单分布式实验。
- NCCL:NVIDIA GPU 通信库,专门优化 GPU 间通信,通常多 GPU 训练性能更好。
- GPU DDP 一般优先用 NCCL。
实验五:基于容器的云上训练和推理
实验五重点:Docker 基本概念、Dockerfile、镜像构建、容器运行、TorchServe 推理服务
Q1:Docker 在深度学习中的作用是什么?
- 封装环境;
- 保证训练和部署环境一致;
- 提高可复现性;
- 方便迁移到服务器或云端;
- 隔离不同项目依赖;
- 支持训练和推理服务化部署。
Q2:镜像和容器的区别?
- 镜像 Image:静态模板,包含代码、依赖、环境。
- 容器 Container:镜像运行后的实例,有独立进程空间和文件系统视图。
- 镜像只读,容器有可写层。
Q3:Dockerfile 常见命令解释?
FROM:指定基础镜像
RUN:构建镜像时执行命令
WORKDIR:设置工作目录
COPY:复制本地文件到镜像
ENV:设置环境变量
EXPOSE:声明服务端口
CMD:设置容器启动默认命令
ENTRYPOINT:设置容器启动入口FROM:指定基础镜像
RUN:构建镜像时执行命令
WORKDIR:设置工作目录
COPY:复制本地文件到镜像
ENV:设置环境变量
EXPOSE:声明服务端口
CMD:设置容器启动默认命令
ENTRYPOINT:设置容器启动入口Q4:docker build -f Dockerfile -t train_dl . 各部分什么意思?
docker build:构建镜像;-f Dockerfile:指定 Dockerfile 文件;-t train_dl:给镜像打标签;.:构建上下文路径,表示当前目录。
Q5:docker run --name training train_dl 是什么?
A:用 train_dl 镜像创建并启动一个名为 training 的容器,执行镜像中定义的默认启动命令,例如运行 PyTorch MNIST 训练程序
Q6:TorchServe 的主要组件有哪些?
- Model Archiver:把 PyTorch 模型打包成 TorchServe 支持的格式;
- Model Loader:加载并初始化模型;
- Model Predictor:接收输入并返回预测结果;
- MVC:路由请求到正确模型和服务实例;
- Management API:管理服务和模型;
- Metrics API:收集吞吐量、延迟等指标;
- Logging/Metrics:记录和监控服务状态。
Q7:容器化训练和容器化推理有什么区别?
- 容器化训练:重点是封装训练环境、数据路径、训练脚本、GPU 依赖。
- 容器化推理:重点是模型加载、服务启动、端口映射、API 请求和响应。
- 训练偏离线批处理,推理偏在线服务。
实验六:对抗攻击实验
实验六最容易出公式和现象分析。重点是:FGSM、无目标/有目标、epsilon、MNIST/ImageNet、Foolbox、PGD/BIM/DeepFool、防御
Q1:FGSM 的核心思想是什么?
FGSM 是基于梯度的对抗样本生成方法,在输入图像上添加沿梯度符号方向的小扰动,使模型损失增大或减小,从而导致分类错误或分类到目标类别。
Q2:无目标攻击公式是什么?
x_adv = x + ε · sign(∇x J(θ, x, y_true))x_adv = x + ε · sign(∇x J(θ, x, y_true))含义:沿着让真实类别损失增大的方向加扰动,让模型分错。
Q3:有目标攻击公式是什么?
x_adv = x - ε · sign(∇x J(θ, x, y_target))x_adv = x - ε · sign(∇x J(θ, x, y_target))含义:沿着让目标类别损失减小的方向加扰动,让模型更倾向于输出指定目标类
Q4:ε 变大有什么影响?
- 扰动更强;
- 无目标攻击中,模型准确率通常下降;
- 有目标攻击中,攻击成功率通常上升;
- 图像视觉质量下降;
- ε 过大时,人眼可明显看到噪声,样本不再“不可察觉”。
Q5:无目标攻击和有目标攻击哪个更难?
A:通常有目标攻击更难。
原因:
- 无目标攻击只要让模型分类错即可;
- 有目标攻击必须让模型分类到指定类别;
- 有目标攻击约束更强,成功条件更苛刻。
Q6:MNIST 和 ImageNet 上哪个扰动人眼更敏感?
A:一般 MNIST 上更敏感。
原因:
- MNIST 图像简单,黑白手写数字,背景干净;
- 少量扰动可能明显改变笔画观感;
- ImageNet 图像纹理复杂、颜色丰富,小扰动更容易被自然纹理掩盖。
Q7:ImageNet 有目标攻击中,对抗样本会出现目标类别视觉特征吗?
A:通常不会明显出现。
这说明 FGSM 不是“真的把图片改成目标类别”,而是在模型判别边界附近添加对人眼不明显、但能影响模型特征响应的扰动。也就是说,对抗攻击利用的是模型的脆弱性和高维决策边界,而不是生成语义上真实的目标物体。
Q8:PGD、BIM、DeepFool 和 FGSM 有什么区别?
- FGSM:单步攻击,速度快,但攻击强度相对弱。
- BIM:多步迭代版 FGSM,逐步添加扰动,攻击更强。
- PGD:带投影约束的迭代攻击,通常更强、更稳定,是常见强基线。
- DeepFool:寻找接近决策边界的最小扰动,扰动可能更小、更不可察觉。
Q9:添加随机噪声为什么能防御部分对抗样本?
A:对抗扰动通常依赖精细、特定方向的像素变化。添加随机噪声或高斯滤波可能破坏这种精细结构,使部分对抗扰动失效,从而提升对抗样本上的准确率
Q10:随机噪声防御有什么局限?
- 防御不稳定;
- 可能降低干净样本准确率;
- 对强攻击或自适应攻击效果有限;
- 噪声强度不好选;
- 不能从根本上提升模型鲁棒性。
实验七:OpenPAI 集群资源调度与管理
实验七重点:Kubernetes、OpenPAI、master/worker/dev-box、HiveD、VC、cell、拓扑保证
Q1:OpenPAI 是什么?
OpenPAI 是面向 AI 任务的集群管理和调度平台,用于管理异构计算资源,支持深度学习任务提交、运行、资源分配和用户管理。
Q2:Kubernetes 集群中 master 节点有哪些核心组件?
kube-apiserver:提供 Kubernetes API,是集群操作入口;etcd:保存集群配置、节点信息、Pod 状态等;kube-scheduler:为新 Pod 选择运行节点;kube-controller-manager:维护集群期望状态,如副本数、节点状态等。
Q3:worker 节点有哪些核心组件?
kubelet:节点代理,保证容器按要求运行在 Pod 中;kube-proxy:网络代理,维护网络规则;- Container Runtime:容器运行时,如 Docker;
- 如果要跑 GPU 容器,还需要
nvidia-container-runtime。
Q4:dev-box、master、worker 分别干什么?
- dev-box:管理员操作节点,用于部署和管理,不加入集群;
- master:集群核心节点,负责管理、调度,不运行具体任务;
- worker:运行实际训练任务。
Q5:HiveD Scheduler 的核心思想是什么?
HiveD 面向多租户 GPU 集群,通过 Virtual Cluster 和 cell 机制,为不同租户提供 GPU 数量和拓扑结构保证,同时允许租户低优先级使用其他 VC 的空闲资源。
Q6:为什么 GPU 调度不能只看数量,还要看拓扑?
A:因为深度学习训练中,多 GPU 之间通信频繁。如果 8 张 GPU 分散在不同机器或不同拓扑层级,通信效率会差,甚至不能满足单机 8 卡任务需求。
传统调度只保证 GPU 数量,但不保证这些 GPU 是否位于同一机器、同一 PCIe/NUMA 拓扑或高速网络域内。HiveD 通过 cell 保证拓扑结构,有利于多卡训练任务获得高通信效率。
高频综合题
综合题 1:实验二自定义 Linear 算子
题目可能问
请说明基于 PyTorch 自定义 Linear 算子的 forward/backward 实现方式,并比较 Python API 与 C++ API 实现的性能差异。
参考答案
Linear 前向为 Y=XW^T。Python API 实现时继承 torch.autograd.Function,在 forward 中计算输出并保存输入和权重,在 backward 中根据上游梯度计算 dX=dY W、dW=dY^T X。C++ API 实现则将前向和反向计算写在 C++ 文件中,通过 pybind11 绑定并用 setup.py 编译为 Python 模块。性能上,原生 PyTorch 算子通常最快,因为调用底层高度优化库;C++ 自定义算子一般比 Python 自定义算子少解释器开销,但若未做底层优化,也可能慢于原生算子。
综合题 2:实验四通信开销分析
题目可能问
如何估算 DDP 中通信开销?Batch size 和模型参数规模分别如何影响通信占比?
参考答案
通信时间可用单次迭代总时间减去关闭梯度同步后的纯计算时间近似估算,通信占比为通信时间除以总迭代时间。Batch size 增大时,每步计算量增加,而梯度通信量主要由模型参数量决定,变化较小,因此通信占比通常下降。模型参数规模增大时,需要同步的梯度数据量增加,通信时间上升,大模型训练中通信可能成为主要瓶颈。
综合题 3:实验六 FGSM 攻击
题目可能问
说明 FGSM 无目标攻击和有目标攻击的区别,并分析 ε 对攻击效果和视觉质量的影响。
参考答案
无目标 FGSM 沿输入梯度符号方向添加扰动,使真实标签损失增大,目标是让模型分类错误;有目标 FGSM 沿目标类别损失梯度符号的反方向添加扰动,使模型倾向于输出指定目标类别。ε 控制扰动强度,ε 越大,攻击越强,无目标攻击准确率下降,有目标攻击成功率上升,但图像质量下降;ε 过大时扰动会被人眼明显察觉。
综合题 4:实验五 Dockerfile
题目可能问
解释 Dockerfile 中 FROM、RUN、WORKDIR、COPY、ENV、CMD 的作用,并说明 Docker 如何运行训练程序。
参考答案
FROM 指定基础镜像,RUN 在构建镜像时执行安装依赖等命令,WORKDIR 设置工作目录,COPY 将训练代码复制到镜像中,ENV 设置环境变量,CMD 设置容器启动后的默认命令。Docker 先根据 Dockerfile 构建包含代码和依赖的镜像,再通过 docker run 创建容器并执行训练脚本,从而保证训练环境一致和可复现。
综合题 5:实验七 HiveD
题目可能问
HiveD 为什么要引入 Virtual Cluster 和 cell?
参考答案
Virtual Cluster 用于为不同租户提供资源隔离和资源保证,使每个租户像使用私有集群一样使用资源;cell 用于描述一定数量 GPU 及其硬件拓扑结构。HiveD 不仅保证 GPU 数量,还保证 GPU 的拓扑位置,例如同一机器、同一 NUMA 或高速互联域,从而减少资源碎片,提高多 GPU 训练性能。
最后复习优先级
最后复习重点
- 自定义算子 forward/backward,尤其 Linear 梯度。
- pybind11/C++ 扩展 PyTorch 的步骤。
- DDP 的 rank、world size、DistributedSampler、all_reduce。
- 通信开销估算:总时间 - 纯计算时间。
- batch size、GPU 数量、模型参数规模对训练性能的影响。
- Dockerfile 命令解释。
- FGSM 无目标/有目标公式和 ε 影响。
- PGD/BIM/DeepFool 与 FGSM 对比。
- Kubernetes master/worker 组件。
- HiveD 的 VC、cell、拓扑保证。
一句话总结
实验考点围绕“框架训练流程、算子扩展、自动调参、分布式通信、容器部署、对抗攻击、集群调度”七条线展开;答题时不要只写操作步骤,一定要写清楚原理、指标、现象和原因。