ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

深度学习系统研发工程师笔试核心考点:CUDA、分布式训练与优化实战

深度学习系统研发工程师笔试核心考点:CUDA、分布式训练与优化实战 1. 岗位解析与备考方向1.1 深度学习系统研发工程师到底是做什么的很多同学看到“深度学习系统研发工程师”这个岗位名称第一反应是“这不就是算法工程师吗”。其实这个理解有偏差而且偏差还挺大。网易2020校招提前批这个岗位从笔试内容和JD来看它定位的是深度学习基础设施方向简单说就是你不是在训练模型你是在让模型训练得更快、更稳、更省资源。打个比方算法工程师是开车的司机系统研发工程师是修路、造车、建加油站的人。司机关心的是“这条路能不能到目的地”系统工程师关心的是“这条路能不能让100辆车同时跑、跑得更快、油耗更低”。所以这个岗位笔试不会像算法岗那样疯狂考你Attention机制的各种变体而是把重点放在系统层面算子实现、显存管理、分布式训练、推理优化这些硬核内容。我当年参加笔试的时候第一感受就是“这题怎么这么底层”。如果你只是刷过几本深度学习入门书、跑过几个开源项目看到这套卷子大概率会懵。但如果你的日常工作是折腾TensorFlow/PyTorch源码、研究过CUDA编程、对GPU架构有了解那这套题做起来反而会觉得顺手。1.2 岗位能力模型与常见认知误区从笔试题目反推这个岗位需要的能力模型大概分四层第一层是深度学习算法基础包括神经网络结构、反向传播原理、常见优化器。这一层不需要你达到算法岗的水平但基础原理必须扎实因为系统优化本质上是在算法不变的前提下做加速不懂算法的系统工程师做出来的优化方案经常是错的。第二层是系统编程能力包括C、内存管理、并发编程、性能分析。这一层是区分度最大的因为大部分算法背景的同学在这一块比较薄弱。笔试题目里会出现大量“这段代码的内存布局是什么”“并发场景下如何保证线程安全”这类问题。第三层是硬件与编译原理包括GPU架构、CUDA编程模型、算子的底层实现方式。这一层决定了你能不能做真正的性能优化而不只是调库。第四层是工程化思维包括分布式训练、模型部署、推理引擎设计、性能调优工具链。常见的认知误区有两个。第一个误区是“深度学习系统研发 深度学习 普通后端开发”实际上面向AI的基础设施和普通后端差异很大你需要同时理解数值计算、张量内存布局、GPU调度这类特殊性很强的东西。第二个误区是“只要算法好就够了”在系统岗这里完全不成立算法好只是敲门砖真正的筛选点在系统能力上。2. 笔试核心考点深度拆解2.1 深度学习基础概念题看似送分实则暗藏深意笔试的第一部分通常是选择题加简答题覆盖深度学习基础。别以为这部分简单系统研发岗考基础概念的角度和算法岗完全不一样。算法岗可能问你“Transformer的多头注意力头数怎么选”系统岗更可能问“给定一个卷积层计算它的FLOPs和参数量并估算在特定GPU上的理论计算时间”。我印象很深的一道题是给出一个输入尺寸为224x224x3的图像经过一个卷积核大小为7x7、输出通道为64、步长为2的卷积层问输出的特征图尺寸是多少以及这个卷积层的参数量和计算量是多少。第一问很简单但第二问很多人会漏掉偏置项的参数或者忘记计算量需要乘以输出特征图的尺寸。这道题背后的用意很明显模型压缩、算子融合、内存规划所有这些系统层面的优化工作都建立在你能够精确估算每一层的计算代价和存储代价之上。如果你连参数量和FLOPs都算不清楚后续做性能分析就没有任何基础。另外一类常考的基础题是梯度消失和梯度爆炸的原理以及Batch Normalization在训练和推理阶段的差异。BN这道题非常经典训练时是用当前batch的均值和方差推理时是用训练阶段滑动平均得到的全局均值和方差。系统岗问你这个问题是因为推理引擎里做BN融合把BN合并到前面的卷积层的时候你必须知道推理阶段的BN是一个纯线性变换才能安全地做算子融合。2.2 CUDA与GPU编程区分度最高的拉分题CUDA和GPU编程相关的题目是这套笔试卷子里区分度最高的部分。如果你没写过CUDA这部分基本只能靠蒙如果你写过难度其实不高考的是基本功。高频考点包括GPU的线程层次结构grid、block、thread、共享内存与全局内存的区别、bank conflict、内存合并访问、原子操作、warp divergence。这些概念在《CUDA C Programming Guide》和《Professional CUDA C Programming》里都有详细讲解但笔试题目会用很实际的问题来考你。举个例子题目可能会给出一个简单的向量求和kernel问你为什么这个kernel在GPU上跑得不够快然后让你从内存访问模式、线程利用率、bank conflict几个角度分析。要答好这道题你必须理解GPU的性能瓶颈通常不在计算而在访存而访存性能又取决于内存访问是否合并。如果相邻线程访问的地址不连续硬件会把一次内存事务拆成多次性能就会急剧下降。还有一类题目是共享内存的使用典型场景是矩阵分块乘法或者卷积的im2col优化。这里的关键点有两个一是共享内存需要手动管理要记得用__syncthreads()做同步二是要分析bank conflict如果你访问共享内存时多个线程同时落在同一个bank上访问会被串行化。我对准备这部分内容的建议是不要只刷题一定要自己动手写几个CUDA kernel。哪怕只是把矩阵乘法从最朴素的版本一路优化到使用共享内存和寄存器tiling的版本你对GPU编程模型的理解会有一个质的提升。2.3 分布式训练与并行策略大厂笔试的必考模块网易这种规模的公司在2020年做深度学习系统研发分布式训练是绕不开的话题。笔试题目里有一类专门考察分布式训练的基础知识包括数据并行、模型并行、参数服务器架构以及AllReduce算法的基本原理和通信量分析。数据并行是最常考的概念核心逻辑是每个GPU上复制一份完整的模型输入数据切分成多份分给不同GPU前向计算各自独立反向传播时梯度需要跨卡同步。最常用的梯度同步算法是AllReduce一次AllReduce操作分为Reduce-Scatter和All-Gather两个阶段总通信量是模型参数量乘以2。有一道题我印象很深刻给定模型参数量为1GB使用8张GPU做数据并行训练问每轮迭代的梯度同步通信量是多少。答案是2GB很多人会算成8GB因为他们错误地以为每个GPU都要发送自己的完整梯度给其他所有GPU。实际上AllReduce的通信量是2倍模型大小不随GPU数量增长。模型并行和流水线并行的题目也会出现通常考察的是切分策略和通信瓶颈。比如模型并行中每一层跨设备切分前向和反向传播都需要设备间通信通信量和切分粒度高度相关流水线并行中关键是处理bubble开销和梯度累积的时序问题。对于这部分备考我建议把Ring AllReduce的通信过程画一遍理解每个阶段每个节点在做什么。同时搞清楚PS架构参数服务器和AllReduce架构的适用场景差异PS适合稀疏模型、超大模型参数、异构集群AllReduce适合稠密模型、同构集群、同步训练。2.4 推理部署与模型压缩提前批笔试题的隐藏重点2020年这个时间点深度学习推理部署已经非常火热网易的笔试自然不会放过这个方向。题目会涉及模型量化、知识蒸馏、模型剪枝、TensorRT这类推理优化技术的基础概念。模型量化是重头戏常见考题是把FP32的权重量化到INT8需要注意哪些问题。答案的核心包括量化参数scale和zero point的确定方法、校准数据集的使用、量化误差对精度的影响、以及哪些层不适合量化比如BatchNorm在推理时可以被融合到卷积里但如果量化不到位反而会引入更大误差。这里我特别想说一下浮点数格式这块。最近网上关于FP32、FP16、BF16、TF32的讨论非常多其实这类知识点在大厂笔试里早就是常客。FP32是32位浮点数1位符号8位指数23位尾数FP16是16位浮点数1位符号5位指数10位尾数它的指数范围比FP32小很多所以训练时容易出现上溢或下溢BF16是1位符号8位指数7位尾数指数范围和FP32完全一致只是尾数精度降低TF32是NVIDIA Ampere架构引入的格式1位符号8位指数10位尾数用于Tensor Core的加速计算。笔试题目可能会让你分析为什么FP16在梯度更新时需要配合Loss Scaling而BF16通常不需要。答案是FP16的指数范围太小梯度值可能小到低于FP16能表示的最小正数导致下溢为0BF16的指数范围和FP32一致所以能表示极小值不会出现下溢问题。部署相关的题目还会涉及ONNX、TensorRT的模型转换流程以及推理引擎中常见的优化手段算子融合比如ConvBNReLU融合成一个算子、动态shape处理、内存池复用。这些内容在校招笔试里通常以选择题或简答题出现但到了面试环节会直接让你手写一个算子融合的伪代码或者分析推理引擎的内存分配策略。3. 实操案例复盘四道典型笔试题的完整解题思路3.1 手写反向传播从公式到代码的落地能力笔试里有一道经典题是要求手写一个简单神经网络的反向传播通常是一个两层的MLP输入维度是D隐藏层维度是H输出维度是C激活函数是ReLU损失函数是Softmax交叉熵。很多人看到这道题会觉得“这不是算法岗的题吗”但其实系统岗考手写反向传播重点不在公式推导而在代码的数值稳定性。比如实现Softmax的时候如果不减去最大值当logits很大时exp会溢出为inf实现交叉熵损失的时候如果直接用log(softmax(x))而不是log_softmax(x)数值精度会受影响。我当时写的代码大致是这样import numpy as np def two_layer_mlp_backward(X, W1, b1, W2, b2, y, reg1e-3): N, D X.shape C W2.shape[1] # 前向 Z1 X.dot(W1) b1 A1 np.maximum(0, Z1) scores A1.dot(W2) b2 # Softmax交叉熵损失 正则化 scores - np.max(scores, axis1, keepdimsTrue) exp_scores np.exp(scores) probs exp_scores / np.sum(exp_scores, axis1, keepdimsTrue) loss -np.sum(np.log(probs[np.arange(N), y])) / N loss 0.5 * reg * (np.sum(W1 * W1) np.sum(W2 * W2)) # 反向 dscores probs.copy() dscores[np.arange(N), y] - 1 dscores / N dW2 A1.T.dot(dscores) reg * W2 db2 np.sum(dscores, axis0) dA1 dscores.dot(W2.T) dZ1 dA1 * (Z1 0) dW1 X.T.dot(dZ1) reg * W1 db1 np.sum(dZ1, axis0) return loss, dW1, db1, dW2, db2这里面的细节值得展开说明。第一dscores[np.arange(N), y] - 1这一步是Softmax交叉熵反向传播的核心技巧它的原理是Softmax与交叉熵组合后的梯度恰好是probs - onehot不需要先对Softmax求导再对交叉熵求导这样既省计算又更稳定。第二ReLU的反向传播要用Z1 0构造掩码而不是用A1 0虽然在这个例子里两者等价但在Dying ReLU问题下用Z1更安全。第三正则化项的梯度要加在权重梯度上且注意0.5 * reg * W^2对W求导是reg * W。这类题目的评分标准通常不只看最终数值对不对还会看你代码的规范性和注释质量。系统岗非常看重代码的可读性和可维护性如果你能顺便写出时间复杂度分析和内存占用分析比如这个两层MLP的反向传播需要存储Z1和A1用于梯度计算内存开销是O(ND NH)会是不小的加分项。3.2 卷积计算复杂度分析系统优化的基本功另一道高频题是卷积层的计算复杂度分析。题目通常给一个具体的卷积层配置要求计算FLOPs和参数量然后分析计算瓶颈和优化空间。假设输入特征图是[N, C_in, H, W]卷积核是[C_out, C_in, K, K]输出特征图是[N, C_out, H_out, W_out]那么参数量 C_out * C_in * K * K不考虑偏置计算量 N * C_out * H_out * W_out * C_in * K * K以ResNet50为例第一个卷积层输入是224x224x3卷积核是7x7输出通道64步长2padding 3。输出尺寸是112x112计算量大约为1 * 64 * 112 * 112 * 3 * 7 * 7 118MFLOPs参数量为64 * 3 * 49 9408。这个计算量在整个ResNet50的4.1G FLOPs中占比不大但因为它作用于高分辨率特征图内存访问量其实很大。笔试题目可能会进一步问如何优化这个卷积层。从系统优化角度答案至少要包含几个方向im2col GEMM将卷积转化为矩阵乘法以利用高度优化的BLAS库Winograd算法减少乘法次数利用Tensor Core做混合精度计算算子融合减少内存读写。我建议复习这部分时把常用卷积优化的几种思路都过一遍。im2col是最容易理解的方案但显存开销大隐式GEMM是主流推理引擎如TensorRT、cuDNN采用的方式不显式展开数据而是通过GEMM的kernel直接对原始输入做计算Winograd适合小卷积核3x3FFT方法因为内存开销和变换开销太大现在基本不用于常规卷积优化。3.3 混合精度训练的Loss Scaling原理为什么需要它混合精度训练是深度学习系统研发的必备知识点。笔试中关于混合精度的问题一般会从FP16的数值范围切入。FP16能表示的最大正数是65504最小正规格化数是约6.1e-5最小非规格化数是约5.96e-8。在训练过程中梯度值经常远小于这个范围导致在反向传播时梯度变成0模型无法更新。Loss Scaling的思路很直接在计算损失之后、反向传播之前给损失值乘以一个大数比如1024或8192这样反向传播得到的梯度也放大了同样的倍数避免了FP16下溢出为0。更新参数之前再把梯度缩小回原来的尺度。因为FP16的乘法精度可以接受而参数更新通常使用FP32来累积所以整体精度损失可控。笔试题目如果问“为什么权重更新要使用FP32主副本”答案是权重更新的幅度通常非常小往往远小于FP16能表示的最小增量。如果权重一直存成FP16小更新会被舍入掉模型很难收敛。所以混合精度训练的标准做法是前向和反向计算使用FP16有时BF16权重保存一份FP32主副本更新后再转成FP16用于前向。这个知识点在系统岗笔试中频繁出现是因为它在实际工程中影响面极大。一个模型是FP32训练还是混合精度训练会直接影响显存占用FP16训练可以减少一半激活值显存、训练速度Tensor Core加速、以及代码复杂度需要处理梯度缩放和精度损失。如果你能给出一个完整的混合精度训练实现思路从Loss Scaling的选择到Master Weights的更新策略再到梯度裁剪时的缩放处理那这部分基本能拿满分。3.4 分布式AllReduce通信量分析手推一遍才踏实前面提到过AllReduce通信量这里用一道具体题目来演示完整的推导过程。题目模型参数大小为M使用P张GPU做数据并行每次迭代需要同步梯度。问使用Ring AllReduce的总通信量是多少。Ring AllReduce分为两步。第一步是Reduce-Scatter将P张GPU上的梯度向量切成P块每张GPU分成P份然后按环形拓扑做P-1次通信每次通信量为M/P最终每张GPU上有一个块包含所有GPU对应块的累加和。这一步的总通信量是(P-1) * M/P如果忽略P-1和P的区别近似为M。第二步是All-Gather每个GPU把自己持有的累加块发送给其他GPU还是做P-1次通信每次通信量也是M/P。总通信量同样是(P-1) * M/P近似为M。两步加起来总通信量约为2M与GPU数量无关。这就是为什么Ring AllReduce的扩展性优于朴素AllReduce朴素算法是每个GPU把完整梯度广播给所有其他GPU总通信量为P*M随GPU数线性增长。笔试题目可能还会进一步问如果使用NCCL执行AllReduce底层用什么实现。答案是NCCL在英伟达GPU上实现了Ring AllReduce并且针对NVLink和InfiniBand做了优化通信量仍然是2M但实际耗时取决于拓扑结构和带宽。我强烈建议备考时自己画一遍Ring AllReduce的通信过程标注每一步每个节点的数据状态。这个推导过程不仅帮助你理解笔试题目也为你后续做分布式训练调优打下基础。4. 备考路线与实战建议4.1 按优先级排序的知识点清单结合网易这套笔试题和同类大厂笔试的共性我整理了一份按优先级排序的知识点清单供大家备考参考第一梯队必考且分值高深度学习基础反向传播、卷积计算、BatchNorm、CUDA编程模型线程层次、内存层次、同步机制、分布式训练AllReduce、数据并行、参数服务器。第二梯队常考且区分度高推理优化算子融合、模型量化、TensorRT、混合精度训练FP16、BF16、TF32、内存管理显存池、内存复用、零拷贝。第三梯队偶尔出现但准备成本高图优化计算图优化、算子调度、编译原理TVM、XLA的IR设计、硬件知识GPU架构、NVLink拓扑、PCIe带宽。我的建议是优先搞定第一梯队这部分内容确定性最强投入产出比最高。第二梯队也需要重点准备因为这些内容经常以场景题出现比如“部署一个BERT模型到GPU上总显存不够怎么办”这种题综合考察了你对算子融合、量化、内存复用等多项知识的理解。第三梯队如果时间充裕再深入面试阶段聊到分布式训练性能优化时如果你能引用TVM的AutoTVM机制或者XLA的HLO优化流程会让面试官觉得你的技术视野比较开阔。4.2 高效备考方法与时间分配如果从现在开始准备我给一个比较合理的备考时间规划以两个月为周期第一周快速过一遍深度学习核心概念重点复习反向传播推导、常见激活函数、优化器原理、BatchNorm和LayerNorm的区别。这个阶段不需要刷难题目标是建立知识框架看到任何算法岗面试题都不会慌。第二周至第三周主攻CUDA和系统编程。学CUDA编程建议直接上手写Kernel从向量加法和矩阵乘法开始逐步优化到使用共享内存和寄存器Tiling。配套阅读《CUDA C Programming Guide》的内存模型章节和《Professional CUDA C Programming》的矩阵乘法章节。这个阶段如果投入扎实笔试中CUDA相关题目基本能搞定。第四周集中学习分布式训练。把数据并行、模型并行、流水线并行、混合并行的原理过一遍重点理解梯度同步的通信过程。强烈建议自己推导Ring AllReduce的通信量并且读一下NCCL的官方文档了解实际实现。第五周学习推理优化和模型压缩。复习算子的融合策略ConvBNReLUINT8量化的校准方法常见推理引擎TensorRT、ONNX Runtime、OpenVINO的优化流程。第六周至第七周刷题和复盘。收集历年大厂系统研发岗位笔试题限时做模拟。做完一定复盘把错题对应的知识点标出来重新回到教材中查漏补缺。第八周查漏补缺和面试准备。把之前整理的错题全部过一遍同时开始准备面试中的系统设计题比如“设计一个大模型推理服务要求高并发低延迟”这类题目。4.3 笔试过程中的时间分配与答题策略网易这套卷子的时间通常比较紧凑我建议按分值比例分配时间。如果选择题和填空题分值占30%建议控制在30%的时间内完成不会的题先标记跳过不要恋战。简答题占30%这部分考察深度值得多花时间。代码题和综合题占40%通常放在最后集中精力做尤其是代码题写完后一定要检查边界条件和数值稳定性问题比如有没有溢出、有没有除零。这里分享一个实战技巧碰到综合设计题比如“设计一个分布式训练系统要求支持模型并行和数据并行混合说明通信策略和容错机制”不要只写文字描述用图画出来会清晰很多。笔试答题界面如果支持绘图就画图不支持就画出简化的拓扑连接比如GPU用方块表示、数据流用箭头标出来这样既便于自己组织思路也方便阅卷人抓重点。还有一个容易被忽视的坑审题时注意区分“计算复杂度”和“通信复杂度”。分布式训练题目中没有明确说要算哪种复杂度时尽量两种都算出来并注明结论。系统岗笔试考察的就是对细节的把控多写清楚反而是加分项。4.4 常用开发环境与工具链推荐备考和实际工作中我建议提前把开发环境搭好边学边动手。操作系统用Ubuntu 20.04或22.04预装CUDA和PyTorch。我自己踩过的坑是Ubuntu安装深度学习驱动后没有重启导致nvidia-smi命令没有反应重启之后一切正常。如果你也遇到类似情况先别急着重装驱动先重启试试然后再检查驱动版本和CUDA版本是否匹配。工具链方面必装的是PyTorch调试模型和训练逻辑、NVIDIA Nsight Systems或Nsight Compute做性能分析、CUDA Toolkit写CUDA kernel、cuDNN和NCCL跑分布式训练时需要。如果你做推理优化方向再加一个TensorRT和ONNX Runtime这两个工具是工业界推理引擎的事实标准。另外建议安装一个性能监控工具比如nvidia-smi的dmon模式或者nvidia-top实时盯GPU利用率和显存占用。系统研发工程师的日常就是和这些指标打交道越早熟悉越好。5. 常见问题与避坑实录5.1 笔试备考中的典型翻车现场结合我自己的经验和身边同学的反馈这里整理几个典型的翻车现场希望大家引以为戒。翻车一只会调库不会原理。有位同学用PyTorch做了一年多模型训练对torch.nn.Conv2d的用法烂熟于心但笔试考到卷积的FLOPs计算时完全算不出来。原因是他从来没有真正去理解卷积的计算过程只知道“调用这个API就是做卷积”。系统岗位考察的是底层原理不是API熟练度。翻车二忽略数值稳定性问题。有个同学手写Softmax交叉熵的时候没有减去最大值导致部分输入情况下exp溢出成inf得到一个NaN的loss。他花了很多时间debug最后发现是数值问题。其实这个坑在笔试和面试中都很常见准备的时候一定要养成“任何数学运算都要考虑数值稳定性”的习惯。翻车三分布式通信量分析错误。很多人会犯一个错误就是把AllReduce的通信量算成和GPU数量成正比。前面推导过Ring AllReduce的通信量是2M不随GPU数量增长。这一点在笔试中经常出大家一定要把推导过程吃透不要只背结论。翻车四对推理部署的理解停留在“调用工具”。笔试如果问到TensorRT的优化流程直接回答“我们把模型转成TensorRT就可以了”显然是拿不到分的。你需要说清楚模型解析-图优化包括算子融合-精度校准如果做INT8量化-kernel自动调优-序列化引擎每一步的具体作用是什么。5.2 面试环节的延伸问法与应对思路笔试顺利通过后面试官会在笔试内容基础上做延伸。系统研发工程师的面试题风格通常是“你提到了A那我问你A的第B个细节”。比如你提到用了混合精度训练面试官会追问Loss Scaling的scale因子怎么配置梯度裁剪放在缩放之前还是之后为什么。这些问题都是看似简单但需要深度理解的。实际上梯度裁剪的时机是有讲究的如果先裁剪再缩放梯度值已经被放大裁剪阈值可能失效如果先缩放再裁剪需要把裁剪阈值也除以scale。标准做法是在缩放后裁剪然后做梯度更新时再除以scale。另外一个面试常问的是“如何定位训练速度瓶颈”。面试官期待的回答不是“用profile工具看一看”而是希望你能说出完整的排查流程先用nvidia-smi看GPU利用率如果利用率低再看CPU是否成为瓶颈利用Nsight Systems看kernel执行时间分布看通信和计算是否重叠利用Nsight Compute分析单个kernel的瓶颈是访存受限还是计算受限最后针对性优化。这些面试问题的共同特点是没有标准答案但有标准思路。面试官想看的是你有没有一套系统化的问题分析方法论而不是零散的知识点。5.3 笔试中如何合理取舍与判断题目价值最后分享一个很重要但很多人忽略的经验笔试时间有限遇到不会的题要学会合理取舍。如果一道选择题完全不会先蒙一个答案标记起来快速跳到下一题。如果一道代码题写了一半卡住了先把已有部分写清楚注释说明思路最后的得分通常比空着要好得多。有一个小的判断技巧如果一道题你完全看不懂它问什么翻一下前后几题大概率能猜到出题方向。如果整张卷子都偏难不要慌因为你不会别人也不会这时候比的不是谁做得多而是谁拿到的稳定分更高。优先保证简答题和代码题的完整性因为这部分按点给分写得多且准确就能拿分。我在实际考试中还有一个习惯每做完一道大题花30秒回看一下自己的答案检查题目有没有看漏、单位有没有写错、复杂度有没有漏掉。这30秒的投入非常值得因为很多丢分不是不会做而是粗心。6. 写在最后一些实在话这套笔试刷完之后我最大的感触是深度学习系统研发工程师这个岗位考察的不是某一个领域的深度而是从算法到工程的完整链条。你既要有算法基础去理解模型的结构和计算方式又要有系统能力去优化性能、分配资源、设计架构。这种复合型的要求确实会在一定程度上劝退很多只专注单一方向的同学但反过来说一旦你建立起这套完整的方法论它的价值在未来的职业发展里会非常明显。我个人在备考过程中的体会是与其刷一百道零散的题目不如把几个核心知识点彻底吃透。比如把Ring AllReduce的通信过程从头到尾推导一遍把卷积优化的几种方案自己写代码实现一遍把混合精度训练的数值问题实际跑一遍看结果。这些深度工作带来的收益是刷题远远比不上的。最后再分享一个小技巧笔试和面试前可以把自己熟悉的技术栈写在一张A4纸上每个技术点配套一个关键结论和一张图。不用写得很详细关键是看到关键词能立刻回忆起完整逻辑。我每次面试前都会做这个动作效果比反复翻书好很多。
返回列表