携程 大模型算法开发 一面
1. 介绍一下你做过的一个项目
2. LoRA 的原理以及初始化方法是什么
LoRA 的核心是低秩适配。对于原始权重矩阵 (W \in \mathbb{R}^{d \times k}),全参数微调直接更新整个 (W),成本高、显存占用大。LoRA 认为下游任务需要的更新往往落在一个低秩子空间里,所以把增量写成:
W' = W + \Delta W = W + BA
其中
,并且r≪min(d,k)r≪min(d,k)。训练时冻结原始参数 (W),只训练 (A) 和 (B),这样参数量和优化器状态都能显著下降。
初始化时通常让 (A) 随机初始化,(B) 初始化为 0,或者相反。这样一开始 (\Delta W = BA = 0),模型初始前向和原模型完全一致,不会一接入 LoRA 就把预训练能力扰乱。训练开始后,低秩更新逐步学出来。缩放项通常写成:

这里的 (\alpha) 用来控制更新幅度。
import torch
import torch.nn as nn
class LoRALinear(nn.Module):
def __init__(self, in_features, out_features, r=8, alpha=16):
super().__init__()
self.weight = nn.Parameter(torch.randn(out_features, in_features))
self.weight.requires_grad = False
self.A = nn.Parameter(torch.randn(r, in_features) * 0.02)
self.B = nn.Parameter(torch.zeros(out_features, r))
self.scale = alpha / r
def forward(self, x):
delta_w = self.B @ self.A
return x @ (self.weight + self.scale * delta_w).t()
3. LoRA 里的几个关键参数分别是什么意思
r 是低秩分解的秩,决定更新子空间维度。r 越大,表达能力越强,但参数量、显存和训练成本也会上升。alpha 是缩放系数,实际作用是调节低秩更新的有效幅度,通常和 r 一起考虑,因为真正起作用的是α/r。dropout 是 LoRA 分支上的 dropout,用来防止小数据集微调时过拟合。
还有一个关键点是插入位置。LoRA 不一定每一层都加,也不一定只加在 attention 上。最常见的是加在 q_proj、v_proj,有些任务会加在 k_proj、o_proj,甚至 MLP 的 up/down projection。插在哪里,决定了微调的能力边界和训练成本。一般生成类任务对 attention 层更敏感,领域迁移较大的任务有时会连 MLP 一起加。
4. QLoRA 和 LoRA 的区别是什么
LoRA 是冻结原权重、训练低秩增量。QLoRA 则是在这个基础上,把基座模型权重量化到 4 bit 存储,同时仍然在高精度上训练 LoRA 参数。它的目标是进一步降低显存占用,让更大的模型也能在有限显存下微调。
QLoRA 的关键点有三个。第一,基座权重用 NF4 这类更适合正态分布权重的量化格式存储。第二,计算时会把量化权重反量化到更高精度参与前向。第三,优化器只更新 LoRA 参数,不更新量化后的底座。这样训练开销比普通 LoRA 更低,但如果任务非常依赖底层分布调整,QLoRA 的上限有时会稍逊于全精度 LoRA 或全参微调。
5. DeepSpeed 的 ZeRO 三个阶段分别做了什么
ZeRO 的核心是把传统数据并行里每张卡都完整保存一份模型状态的做法拆开。模型训练时主要有三类大块内存:优化器状态、梯度、参数。ZeRO 就是按阶段逐步把它们分片。
ZeRO-1 只切优化器状态。也就是 Adam 里的 momentum 和 variance 不再每卡完整保留,而是分散到不同设备上。ZeRO-2 在此基础上继续切梯度,反向传播后每张卡只保留自己那份梯度。ZeRO-3 更进一步,把模型参数本身也切开,前向和反向按需 gather。这样显存节省最大,但通信和调度复杂度也最高。
它本质上解决的是“参数冗余复制”问题,不是直接让单卡算得更快,而是让更大模型能训练起来。实际选型时,如果模型不算特别大,ZeRO-2 通常是比较稳的折中;模型继续变大时,ZeRO-3 才更有必要。
6. FSDP 和 DeepSpeed ZeRO-3 的差别是什么
FSDP 和 ZeRO-3 的目标很像,都是把参数、梯度和优化器状态做分片,降低单卡显存压力。但实现方式和工程生态上有一些差异。FSDP 属于 PyTorch 原生体系,更偏框架级封装;ZeRO-3 则来自 DeepSpeed,围绕大模型训练场景做了很多额外优化。
FSDP 通常按 module 为粒度做参数分片和 gather,配合 auto wrap policy 可以比较灵活地控制切分边界。ZeRO-3 更强调状态分片和训练系统整体管理,在配合 CPU offload、NVMe offload、pipeline parallel 时工程能力更完整。实际落地时,如果团队偏 PyTorch 原生、希望代码侵入小一些,FSDP 更自然;如果是超大模型训练、要叠加很多并行策略,DeepSpeed 生态通常更成熟。
7. 强化学习在大模型对齐里一般是什么框架
大模型对齐里最常见的是 RLHF,也就是先监督微调,再偏好建模,再强化学习优化。典型链路是 SFT 得到一个可用策略模型,然后收集偏好数据训练奖励模型,最后用 PPO 之类的算法让策略模型朝高奖励方向更新。
这套框架本质上不是让模型在环境里探索动作,而是把文本生成视作一个序列决策过程,每生成一个 token 都是在做动作选择。奖励信号通常不是即时给每个 token,而是对整段回答或者回答片段打分,所以要把最终奖励回传到生成轨迹里。难点在于奖励稀疏、训练不稳定、模型容易为了讨好奖励模型而偏离原分布,因此实际训练时都会加 KL 约束,把策略模型限制在参考模型附近。
8. PPO、DPO、GRPO 的区别是什么
PPO 是强化学习方法,依赖策略模型、参考模型、奖励模型,训练时还会引入 value/critic 去估计回报。它的好处是灵活,可以接复杂奖励,但工程链路长、训练不稳、成本高。PPO 的典型目标会带一个裁剪项,避免新旧策略差太远。
DPO 不显式训练奖励模型再跑 RL,而是直接利用 chosen/rejected 偏好对优化策略模型。它把偏好学习转成一个分类式目标,本质上在提升 chosen 相对 rejected 的概率,同时参考模型提供锚点。相比 PPO,它更简单、更稳定,代价是适用前提更依赖高质量偏好对。
GRPO 更强调组内相对比较。不是只比较一个 chosen 和一个 rejected,而是在一组候选里根据相对优劣优化策略。它适合推理、数学、代码这类可以对多候选进行相对打分的场景,尤其是当绝对奖励难定义,但组内排序信号比较可靠时更有优势。
9. PPO 里的 critic model 起什么作用
critic 的作用是估计 value,也就是当前状态下未来预期回报。因为直接用整段回答的最终奖励更新每个 token,方差会非常大,训练不稳定。critic 提供一个 baseline,用来计算 advantage:

这样策略梯度更新的信号会更稳。简单理解,critic 不是告诉模型“什么答案更好”,而是在告诉模型“当前这一步的实际收益,相对预期来说是超了还是没达到”。如果没有 critic,PPO 仍然能做,但方差会高很多,尤其在长序列生成里更明显。
10. 如果 PPO 训练里 KL 发散了,通常怎么处理
KL 发散说明当前策略偏离参考模型太快,常见原因是学习率过大、奖励尺度过强、采样温度过高、reward hacking,或者优势估计不稳。处理上通常先从最直接的地方下手:降学习率、增大 KL 系数、做 reward
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
本专栏聚焦 AI-Agent 面试高频考点,内容来自真实面试与项目实践。系统覆盖大模型基础、Prompt工程、RAG、Agent架构、工具调用、多Agent协作、记忆机制、评测、安全与部署优化等核心模块。以“原理+场景+实战”为主线,提供高频题解析、标准答题思路与工程落地方法,帮助你高效查漏补缺.
查看7道真题和解析