字节大模型算法秋招一面
- 轮次
- 一面
- 时间
- 2026-10
- 来源
- 牛客网
《面试题目》
- 项目选型基座模型时,选择该模型的理由是什么,是否评估过能力更强的备选模型?
- 项目的数据方案是如何确定的,有没有调研过公开数据集作为替代?
- 你接触过哪些 RL 算法,DAPO 对比 GRPO,主要解决了哪些痛点?
- 挑选强化学习算法时,你一般会重点考量哪些因素?
- 什么场景需要做上下文压缩,它和任务文本长度之间有什么关联?
- 模型标称上下文窗口与真实可用有效长度有什么差异,长上下文下模型效果下滑的原因?
- 如果要优化长程 Agent 框架,你会从哪几个方向入手?
- FlashAttention 加速的底层原理是什么,分块策略与显存读写之间有什么联系?
- vLLM 的 PagedAttention 是如何实现 KV Cache 管理的?
- 手撕:实现 Self-Attention。
《参考解析》
基座模型选型:不能只答「能力强」。合理的框架是四层筛选:① 硬约束先过一遍——许可证是否允许商用、能否私有化部署、上下文长度、需要的语言与模态、有没有函数调用与结构化输出这类必需能力;② 任务匹配——用自己业务的真实评测集(不是公开榜单)跑候选模型,看本任务上的准确率、格式遵从率、拒答率、幻觉率;③ 成本与性能——单位 token 价格、首 token 延迟与吞吐、高并发下的稳定性、量化后的精度损失,以及走 API 还是自部署;④ 工程与生态——微调工具链成熟度、社区活跃度、版本演进与弃用策略、有没有同级备选。最后一定要讲清切换方案:接口做一层适配、评测集常备,换模型时能快速验证并灰度,不被单一供应商锁死。面试官问「有没有评估过更强的备选」,考的就是你有没有留后路。
数据方案与公开数据集:确定顺序通常是「先对齐任务定义与标签口径 → 再定来源与规模 → 最后定清洗与配比」。来源上优先用业务真实数据(最贴分布),公开数据集的价值是冷启动、补长尾或当评测基线;直接拿来训练要过三关:许可证是否允许训练与商用、与业务分布差多少(论坛语料和客服话术不是一回事)、有没有和评测集重叠(污染会让指标虚高)。工程上要写清来源、清洗规则(去重、脱敏、格式统一、质量过滤)、配比与采样策略,并保留可复现的数据版本;上线前用同一份评测集做消融,确认增益真的来自数据。
DAPO 对比 GRPO:GRPO 去掉了价值网络,对同一个 prompt 采样一组回答,用组内奖励的均值与标准差作基线算优势,省了 critic 的显存、也少了训练不稳定的来源。它的问题是组内优势在「整组都对」或「整组都错」时方差趋近于 0,梯度被浪费,难样本尤其明显;另外存在长度偏置(按序列平均会让长回答的梯度被稀释),token 级权重处理也不够细。DAPO 是面向大规模 RL 的一批工程改进:动态采样把无效组丢掉并按需补采,保证每个 batch 都有有效梯度;放宽 KL 约束、允许更多探索;把 loss 改成 token 级归一化以缓解长度偏置;对超长截断样本做掩码。回答的落点应是「解决训练稳定性与样本效率」,也要能说出代价——动态采样抬高 rollout 成本,去掉 KL 约束需要更强的评测与回滚机制。
强化学习算法选什么,看哪些因素:① 奖励是否可靠——有没有可自动判定的 verifier(数学、代码),还是只能靠偏好模型或人工,奖励噪声大就选保守算法、调小学习率;② 算力与数据预算——PPO 要 critic 显存吃紧,GRPO 与 DPO 系更省,在线 rollout 的吞吐决定组能开多大;③ 任务形态——单步偏好对齐用 DPO 系,多步推理与可验证任务用 GRPO / DAPO 系,长程 Agent 还要考虑多轮环境与稀疏奖励;④ 稳定性与可观测性——KL 散度、熵、奖励曲线是否容易崩,有没有现成的回滚与 checkpoint 策略;⑤ 与现有基础设施的兼容(推理引擎、并行策略、采样吞吐)。最后一定要有「离线评测 + 小规模在线灰度」两道验证,不能只看训练奖励涨。
上下文压缩与有效长度:触发压缩的判据是「占用接近预算且历史里含大量冗余」,典型场景是多轮对话、长文档 RAG、以及 Agent 的长轨迹(工具返回占大头)。手段按代价排序:结构化裁剪(工具返回只留摘要与关键字段、去掉重复片段、按重要性丢弃早期轮次)、滚动摘要(把旧轮次压成要点并保留实体与结论)、检索式记忆(历史写进向量库按需召回)、以及训练侧的 token 压缩。它和文本长度的关系本质是预算分配:窗口是总预算,系统提示、检索片段、历史、当前输入都要分,文本越长越要提前规划,而不是等爆了再截断。压缩会丢信息,关键约束与数字要白名单式保留,压缩策略也要做 A/B,否则容易压掉决定性信息。
标称窗口与真实有效长度:标称窗口是位置编码与注意力机制能接受的 token 数(很多模型靠 RoPE 外推或插值扩出来),有效长度是在这个长度下模型仍能可靠利用信息的范围,两者通常差很多:超过训练长度一定倍率后,检索类任务的准确率就明显下滑,中段信息最容易被忽略。下滑原因有几层:训练数据里长文档本来就少、长距离注意力权重被稀释、位置编码外推造成分布偏移、注意力被大量无关 token 分散。工程对策是别依赖标称值:关键信息前置或重复、用分块检索代替整篇塞入、超长任务做分层摘要,并用自己的任务集测出「有效长度」再定预算。优化长程 Agent 框架可以往这几个方向入手:上下文与记忆的分层管理、工具返回的裁剪与结构化、状态持久化与断点续跑、给循环设步数与超时并做失败恢复、以及把可观测(每步轨迹、耗时、token)做扎实,否则调优没有依据。
FlashAttention 的分块与显存读写:标准注意力的瓶颈不在算力而在显存 IO:要显式写出 S×S 的注意力矩阵并反复读写 HBM,显存占用随序列长度平方增长。FlashAttention 用分块加在线 softmax 绕开它:把 Q、K、V 切成能放进 SRAM 的小块,外层遍历 Q 块、内层遍历 K/V 块,边算边用 running max 与 running sum 做在线归一化,全程不把完整注意力矩阵写回 HBM,只保留输出与统计量;反向传播用重算替代存储中间矩阵。收益是 HBM 访问量大幅下降、显存从平方降到线性、长序列上提速明显;代价是实现复杂(要手写 CUDA 或 Triton)以及需要处理因果掩码与非对齐分块边界。常见追问是「分块为什么能加速而不是增加计算」——因为计算量没变,变的是访存次数与显存占用。
PagedAttention 如何管理 KV Cache:它把 KV Cache 按固定大小的 block 切分,像操作系统的虚拟内存分页一样管理:逻辑上连续的序列通过 block table 映射到物理上不连续的显存块,于是不必再为每个序列预留最大长度的连续显存。三个直接好处:碎片与内部浪费大幅减少(原来按最大长度预留、实际用不满),显存利用率上去后并发 batch 能开更大、吞吐提升;共享前缀(同一 system prompt、few-shot、beam search 分支)只存一份,多个序列指向同一物理块,配合写时复制;块的分配与回收是常数级操作,省掉了昂贵的连续显存整理。它也是连续批处理能高效跑起来的基础——序列随时进出,按块增量分配即可。
手撕 Self-Attention:核心几行要能默写:Q = X @ Wq、K = X @ Wk、V = X @ Wv(形状 [B, L, d]),scores = Q @ K.transpose(-2, -1) / sqrt(d_k),因果掩码用上三角置负无穷再 masked_fill(注意 mask 形状要能广播到 [B, h, L, L]),attn = softmax(scores, dim=-1),out = attn @ V;多头则把 d_model 拆成 h × d_head,reshape 与 transpose 成 [B, h, L, d_head],算完合并再过输出投影。要主动说清的细节:sqrt(d_k) 缩放是防止点积过大让 softmax 饱和、梯度消失;掩码必须在 softmax 之前加;softmax 用 float32 计算更稳,并注意整行全被掩掉时的数值问题。追问通常是复杂度(时间与显存都是 O(L²))和优化方向(FlashAttention、KV Cache、MQA / GQA)。