快手 大模型开发 一面

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)

缩放点积注意力里,qk 的点积会随着维度 d_k 增大而变大。如果 qk 的各维分量是独立、均值为 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面试实战专栏 文章被收录于专栏

本专栏聚焦 AI-Agent 面试高频考点,内容来自真实面试与项目实践。系统覆盖大模型基础、Prompt工程、RAG、Agent架构、工具调用、多Agent协作、记忆机制、评测、安全与部署优化等核心模块。以“原理+场景+实战”为主线,提供高频题解析、标准答题思路与工程落地方法,帮助你高效查漏补缺.

全部评论

相关推荐

今天 11:02
电子科技大学 C++
自我介绍 实习1. 具体实现了哪些功能?用户如何使用这些功能?2. 项目使用上的核心原则有哪些?3. 日志中标记的错误等级(如 fail、警告)有什么区别?升级逻辑是怎样的?项目没问手撕1. LeetCode1188 多生产者多消费者队列2. LeetCode46 全排列3. LeetCode146 LRU八股1. 讲一讲 Go 语言中的 WaitGroup 并发原语2. 讲一讲 GoRoutine闲聊1. 非科班为何选择软件方向?如何权衡课内学业与实习?2. 上一段实习地点在哪?上海 Base 是否能够接受?3. 参加字节跳动技术训练营主要是学了什么内容?a. 这里其实没有学到什么,随便说了一个消息队列的实现,然后平滑地过渡到到手撕环节4. 以后选择制造业还是互联网?对岗位要求有什么了解?能实习多久?5. 反问总结实习基本不问产出的...只是问问部门业务?不知道是不是不知道怎么问?项目一点没问...八股基本没问,问到的 Go 的基本没学过,Go 这一块还是很薄弱的。想了一下,还是打算专攻C++吧,原本觉得是C++后端太地狱了,但是发现补一个Go的简历也没有很轻松,还不如就学C++,然后Go的也投,能接受转语言我就去。手撕只撕出来LRU,其他两题都没调出来,LRU这里其实写了很多次了,其实应该快一点写完的...事实是真到面试的时候会很紧张。
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务