快手 大模型开发 一面
1. 全参数微调的显存一般怎么估算
全参数微调的显存不能只看模型参数本身,真正上线训练时至少要把参数、梯度、优化器状态和激活值都算进去。最粗略的估算方式是:如果模型参数量是 N,训练精度是 bf16,那么参数大约占 2N 字节,梯度再来一份 2N,如果用 Adam,还要额外保存两组一阶和二阶矩,通常再加 4N + 4N 字节。也就是说,不考虑激活值时,单参数相关内存大致可以按 12N ~ 16N 字节估。真正把 batch size、sequence length、checkpointing、并行策略加进去后,激活值往往才是大头。
所以面试里如果只答“参数量乘 2”基本不够。更稳的答法是先给出静态显存估算,再补充训练时还要考虑 activation、ZeRO、gradient checkpoint、tensor parallel、optimizer offload 这些因素。这样会更像真的做过训练。
def estimate_full_ft_memory(params_billion, bytes_param=2, adam_state_bytes=8):
n = params_billion * 1e9
param_mem = n * bytes_param
grad_mem = n * bytes_param
opt_mem = n * adam_state_bytes
total = param_mem + grad_mem + opt_mem
return total / (1024 ** 3)
print(f"{estimate_full_ft_memory(7):.2f} GB")
2. MoE 模型微调时显存怎么估,不是参数量大就一定更吃显存
MoE 的关键在于“总参数量”和“激活参数量”不是一回事。一个 8x7B 的 MoE 模型总参数很多,但每个 token 实际只会激活其中一部分 expert,比如 top-2 路由时,真正参与前向和反向的参数远小于总量。所以算训练显存时,参数存储确实还是要考虑全部权重,但算激活值和计算量时,更应该看每个 token 实际经过的 expert 数量。
这也是为什么很多人看到 MoE 总参数量很大,就误以为训练一定更贵。实际上它在吞吐和计算效率上的表现,经常和 dense 模型不一样。真正麻烦的地方反而是专家并行、路由不均衡、通信开销和 load balancing,而不只是静态显存账面数字。
3. 从数学上解释为什么 attention 里要除以 sqrt(d_k)
缩放点积注意力里,q 和 k 的点积会随着维度 d_k 增大而变大。如果 q 和 k 的各维分量是独立、均值为 0、方差为 1 的随机变量,那么它们点积的方差大约和 d_k 成正比。也就是说,维度越高,点积的绝对值波动越大。这个值一旦直接送进 softmax,就会让 softmax 非常尖锐,梯度也会更容易饱和。
除以 sqrt(d_k) 的作用,本质上是把点积的尺度重新拉回一个更稳定的范围,让不同 head、不同维度下的数值分布别差太多。这样 softmax 不至于一上来就接近 one-hot,训练会稳很多。
import torch, math q = torch.randn(2, 4, 64) k = torch.randn(2, 4, 64) raw = torch.matmul(q, k.transpose(-2, -1)) scaled = raw / math.sqrt(64) print(raw.std().item(), scaled.std().item())
4. 如果 attention 不除 sqrt(d_k),会发生什么,有没有别的办法
如果不做缩放,最直接的问题就是 softmax 输入值容易过大,分布变得特别尖。这样模型会过早把注意力压到极少数位置上,梯度更新变差,尤其在深层网络和大维度下更明显。训练初期可能就会出现不稳定、收敛慢,甚至局部数值爆炸的问题。
当然也不是说只能用 sqrt(d_k) 这一种办法。比如有些变体会用 learnable temperature,或者在 Q/K 上做归一化,让点积本身更稳定。但标准 Transformer 里这个缩放足够简单,也足够有效,所以成了默认做法。
5. 多模态大模型的主流架构一般有哪些
现在常见的多模态大模型大致可以分几类。第一类是“视觉编码器 + 投影层 + 语言模型”,也就是先用 ViT 这类视觉 backbone 提特征,再通过 MLP、Q-Former 或 projector 映射到语言模型能接的 token 空间,这类方案工程上最常见。第二类是原生统一建模,把不同模态都转成统一 token 再一起训练,这种理论上更优雅,但训练成本很高。第三类是 encoder-decoder 风格,用 encoder 处理多模态输入,decoder 负责生成,更适合结构化输出或长生成任务。
面试里如果继续往下聊,我一般会说实际业务里最常用的还是第一类,因为改造成本低、复用现有 LLM 方便、迭代快。真正难点不在“接上去”,而在跨模态 token 设计、细粒度对齐和长上下文下的信息保真。
6. 为什么很多多模态系统都要加一个 connector,而不是把视觉特征直接塞给 LLM
因为视觉编码器输出的表征空间和语言模型的 token 表征空间本来就不是同一个分布,直接硬塞进去,语言模型很难稳定理解。connector 的作用就是做一个跨模态接口层,把视觉特征投影成语言模型更容易消费的表示,有时候还承担压缩、重采样、信息筛选的作用。
如果更细一点讲,connector 不只是“对齐维度”,更是在做语义桥接。像简单线性层、MLP projector、Q-Former,本质上代表的是不同复杂度的对齐方式。任务越细粒度,对 connector 的设计要求通常越高。
7. 为什么多模态模型经常要做视觉 token 压缩,不压缩会怎样
视觉 token 的数量通常远大于文本 token,尤其输入分辨率一高,patch 数量就会很快膨胀。如果不压缩,首先推理成本会非常高,其次语言模型的上下文预算会被视觉信息迅速吃掉,最后还会造成注意力
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
本专栏聚焦 AI-Agent 面试高频考点,内容来自真实面试与项目实践。系统覆盖大模型基础、Prompt工程、RAG、Agent架构、工具调用、多Agent协作、记忆机制、评测、安全与部署优化等核心模块。以“原理+场景+实战”为主线,提供高频题解析、标准答题思路与工程落地方法,帮助你高效查漏补缺.