大模型算法工程师-面试题库大全¶
1 百亿级预训练语料清洗与去重¶
1.1 基于MinHash的大规模文本去重算法¶
1.1.1 MinHash签名长度如何影响百亿级语料的召回率与计算成本?¶
解读:¶
面试官想验证三件事:
-
你是否真正跑过百亿级去重/召回链路,而不是停留在论文公式;
-
能否把签名长度k、Jaccard阈值 $ \tau $、分桶策略 $ b \times r $、 $ \underline{\text{分布式计算}} $成本四者同时放进一个量化框架;
-
能否给出可落地的调参路径,而不是“越长越好”或“越短越快”这种学生答案。
在国内大厂的真实场景里,存储成本 $ \approx10\times $计算成本,所以回答必须同时算“钱”和“效果”。
知识点:¶
-
MinHash概率保证:两文档Jaccard≥τ时,至少一次碰撞概率 $ P=1-(1-\tau^r)^b $,其中签名长度 $ k=b\times r $。
-
百亿级去重经验 $ \tau $:中文网页 $ \tau=0.85\cdot UGC $文本 $ \tau=0.9\cdot 代码文本\tau=0.9 $
5; $ \tau $ 每升高0.01,签名长度需 $ * $+15% $ * $才能维持同等召回。
-
存储-计算换算:在阿里云PAI-Spark 10 TB级任务里,每增加1 bit签名,Shuffle量+1.2 PB/epoch,费用≈2400元;而漏召回一条重复样本,下游训练去重后浪费A100卡时≈6元;二者需要拉平。
-
分层签名:短签名k1=64 bit做全局初筛,长签名k2=256 bit做精准二次比对,可把总计算量压到单签方案的35%而不掉召回。
-
GPU加速:把签名当uint64向量搬上GPU,用Hamming距离≤3的Warp级位运算,吞吐可达2亿 doc/s/卡,此时签名长度必须是64整数倍,否则需要padding,浪费12%显存带宽。
答案:¶
“我会把问题拆成三步:
第一步,用业务τ倒推最小k。以国内搜索去重为例,τ = 0.85,要求召回≥99%,代入概率公式得k≥192 bit;如果τ提到0.9,k需要256 bit才能维持同样召回。
第二步,算经济账。在512节点Spark集群上跑192 bit签名,每天新增80亿文档·Shuffle量≈15 PB · 成本3万元;若k降到128 bit · Shuffle降到10 PB · 成本2万元,但召回掉到97% · 漏召2.4亿条重复,下游训练要多耗14.4万元的A100
卡时,显然128 bit更贵。因此192 bit是盈亏平衡点。
第三步・工程折中。线上采用分层签名+GPU二次校验:先存64 bit粗签名・把候选集压到1%;再对候选搬上GPU算192 bit精准签名・整体P99延迟18 ms・单卡QPS1.2万・满足搜索近线链路50 ms的SLA。这样签名长度虽然理论用192 bit・但平均计算量等效于86 bit・存储成本也降40%。
总结:在百亿级语料场景,签名长度不是越大越好,而是让“边际存储成本=边际漏召成本”;通过 $ \tau $-概率公式+分层签名+GPU Warp位运算,可以把最优k精确到 $ \star\pm8 $ bit $ \star\star $以内,并给出可量化的ROI。”
拓展思考:¶
如果面试官继续追问“万亿token预训练语料,重复模式随时间漂移,如何在线自适应k?”,可以回答:
“我会把签名长度做成可微变量,在每轮数据配比重训时,用验证集困惑度反弹作为信号,把k的梯度近似成‘漏召样本带来的额外训练步数×单次步成本’,用1D
网格搜索在128–320 bit区间每8 bit采样一次 · 15分钟即可收敛到新的最优k;同时把b×r做成热插拔参数 · 通过ZooKeeper推送到Flink实时去重节点 · 实现零停机调参。这样即使节日热点导致UGC文本分布突变 · 也能在2小时内完成k的在线自适应 · 保证召回波动<0.3%。”
1.1.2 在Spark分布式环境下如何设置MinHash band数以避免shuffle倾斜?
解读:¶
面试官问的是“百亿级参数预训练模型”落地时常见的去重/近似连接子问题。MinHash-LSH 在 Spark 上跑 · band 数 b 与 row 数 r 直接决定签名切割方式 · 进而决定 shuffle key 的分布。若 b 设置过大 · 同一 band 内 key 空间爆炸 · 导致数据倾斜 · 若 b 设置过小 · 召回率下降 · 漏召回相似 doc · 影响预训练语料质量。因此考点是:在保证召回率≥业务阈值的前提下 · 让 shuffle key 分布最均匀 · 从而消除 straggler。
知识点:¶
-
MinHash-LSH 原理:k 个 hash 函数生成签名向量,按 b×r 划分,同一 band 内完全相等即候选对。
-
shuffle key = bandId + hash(signature_slice) · key 的基数 ≈ b × |D| · |D| 为文档数。
-
倾斜根因:高频 bandId(如全 0 向量)或签名 slice 碰撞 · 导致某些 key 热得离谱。
-
Spark 诊断:利用 spark.sql.adaptive.enabled=true + spark.sql.adaptive.skewJoin.enabled=true 看 shuffle read skew ratio或在 accumulator 里统计每个 key 的频次。
-
国内大厂经验:
○ 先固定 $ \mathbf{r} = [k / b] \cdot k $ 通常取 128~256;
用泊松近似估算候选对数 $ E[\text{candidates}] \approx \Sigma_{{s \in (0,1)}} |D|^2 \cdot (1 - (1 - s^r)^b) \cdot \text{其中} s \text{为 Jaccard 均值}; $
○ 设业务要求召回率 ≥ 0.95 · 则 b 下限由 $ (1 - (1 - s^r)^b) \geq 0.95 $ 反推;
◦ 上限由 key 分布 99 分位 ≤ 3×中位数 决定,否则加随机盐或二次拆分。
答案:¶
步骤一:记录召回 20/702 步长4
步骤二:选满足召回率 $ \geq0.95 $的最小 $ b $,记为 $ b_0 $;若最大key频次 $ \geq $平均频次 $ \times3 $,则把该band内热key加盐二次哈希,盐值范围2-4,保证子key均匀。
步骤三:在百亿级全量任务中,打开 Spark AQE,设置
spark.sql.adaptive.advisoryPartitionSizeInBytes=128m
spark.sql.shuffle.partitions=20000
并在代码里用 repartition(col("band_salt_key")) 强制重新分区 · 彻
底打散。
步骤四:上线后通过 Spark History Server 观察shuffle read 时间分布,若仍有 stage 长尾,再微调 b 下调 2~4,或把 r 提高 8,用更窄的 band 换取更均匀的 key。
最终交付的b值既满足召回率红线,又让最大task处理数据量≤中位数×1。5 · 从而消除倾斜。
拓展思考:¶
-
如果签名维度 k 继续放大到 512 · 是否仍用固定 b×r?可以引入分层 LS H:先做 256 维粗 band 去重 · 再对候选对做 512 维精排 · 减少单次 shuffle 量。
-
在流式预训练场景,Flink 实时去重如何用 MinHash?可把 band 状态放在RockDBMapState · key 设计为 bandId+salt · 用 TTL 控制内存;倾斜时动态扩容 salt 位。
-
当业务允许近似去重率 98% 即可,可直接用b=16 + 布隆过滤器二次验证,把 shuffle 量再降 40%,节省 GPU 训练前的数据准备时间。
1.1.3 当文档长度差异极大时,如何调整MinHash的n-gram粒度以保证去重效果?
解读:¶
面试官想验证三件事:
-
你是否真正理解MinHash对短文档过哈希、对长文档欠哈希的本质缺陷;
-
能否给出可工程落地的动态粒度策略,而非只背公式;
-
是否具备百亿级语料、离线+在线混合链路的实操经验,能兼顾召回率、精准度与计算成本。
国内大厂在预训练数据清洗环节,短文本(≤100字)与长文本(≥10k字)并存是常态,若粒度固定,短文本容易“误杀”导致可用语料骤降,长文本则“漏杀”造成重复知识污染,最终影响大模型收敛速度与效果。
知识点:¶
-
n-gram粒度与Jaccard相似度的单调关系:粒度越细,签名维度越高,短文档区分度提升;粒度越粗,长文档噪声被平滑,重复片段更易被捕获。
-
长度分桶(Length Bucketing):按字符数或token数将文档划分为超短、短、中、长、超长五档,每档独立训练最优粒度,国内主流做法是64、128、256、512、1024字符滑动窗口。
-
动态k-gram:在签名生成阶段,对同一文档使用多组(k, w)并行签名,再按长度桶加权融合,兼顾局部与全局重复;工程上通过SIMD指令+GPU哈希将额外开销控制在5%以内。
-
阈值校准:每个桶单独采样10万对人工标注的“重复/不重复”样本,用PR曲线挑F1最大点,短桶阈值0.85、长桶阈值0.75是经验值,可直接复现。
-
在线粗排+离线精排:百亿级场景先跑12-bit最小哈希做粗排,把候选集压到万级别,再在该集合内用64-bit精细签名二次验证,整体P99延迟<20ms。
答案:¶
步骤一:长度分桶
把语料按Unicode字符长度划为五档:
超短: $ \leq64 $
短:65-256
中:257-1024
☑ 长:1025-4096
超长:>4096
步骤二:桶内网格搜索¶
对每一档随机采样100万文档对,用5-gram到20-gram滑动窗口扫一遍,计算签名128维,绘F1-阈值曲线,取峰值对应的粒度作为该桶最优k。
实验结论:¶
超短:k=5
短:k=8
中:k=12
☑ 长:k=16
超长:k=20
步骤三:动态签名生成¶
线上推理时,先按长度选桶,再按桶内k值生成签名;若文档长度处于桶边界±10%,同时取相邻两桶签名,做“或”合并防止边界抖动。
步骤四:阈值回退策略
当两个文档长度跨桶时,采用加权Jaccard:
sim = $ \alpha \cdot \text{sim_short} + (1 - \alpha) \cdot \text{sim_long} $
$ \alpha = len_short / (len_short + len_long) $
经验证 · a动态权重比单一阈值提升F1约3.7%。
步骤五:工程落地¶
离线MapReduce:每天全量清洗2.3 PB文本,5小时跑完,通过RocksDB存签名,内存压缩比1:8。
- 在线流式:Kafka实时接入・Flink CEP调用c++ minhash库・单核QPS 2.3万・CPU占用<15%。
结果:在100 B token的预训练语料上,重复率从11.4%压到2.1%,下游模型验证loss下降4.8%,训练步数减少12%,完全符合国内GPU预算考核要求。
拓展思考:¶
-
多语言场景:中文无空格 · n-gram需字符级;英文需子词级(BPE 8k vo ca b)。可在同一链路里按语言标签路由不同 tokenizer · 再复用上述分桶框架。
-
段落级去重:对超长文档,先按\n\n切段落,段落内再用局部敏感哈希(LSH)二次签名,避免整篇文档因一小段重复被整体过滤。
-
增量更新:每天新增5 T文本,采用布谷鸟过滤器存储昨日签名,内存占用降低至1/10,误判率<0.3%,满足小时级增量清洗。
-
与模型训练联动:把去重后的重复度分数作为sample weight喂给Traine r,重复度越低权重越高,实验显示GLUE平均分提升0.9,训练时间再省8%。
1.2.1 如何用FastText子词信息解决中文方言与简繁混合问题?¶
解读:¶
面试官想验证三件事:
-
你是否理解FastText子词机制的本质——用n-gram粒度而非整词粒度表示,天然适合形态变化丰富的语言;
-
你是否能把这一机制迁移到中文场景,解决“字/词边界模糊+方言同义异形+简繁异体”三重耦合难题;
-
你是否具备工业级落地视角,在百亿级大模型预训练管线里把FastText子词当作可插拔组件,而不是单独跑个小模型。
回答时务必体现“中文子词构造→方言对齐→简繁统一→大模型注入”四步闭环,并给出可验证的量化指标。
知识点:¶
-
中文子词构造:基于字符级n-gram(如 $ 3 \leq n \leq 5 $)+部首级n-gram(Unicode IDS序列)+拼音n-gram(带声调数字),形成多视图子词表;
-
方言对齐:利用同音映射表(《汉语方音字汇》)+人工构造的方言-普通话平行语料(粤语、吴语、闽南语各100万句),把方言词转写为共享子词序列·实现弱对齐;
-
简繁统一:在子词表层面做OpenCC风格的繁简转换,但保留一对多映射的多个子词id,让模型自动学习使用频率;
-
大模型注入:把上述子词Embedding作为增量词表插入到百亿级Transformer的Embedding层,采用warm-start策略:先冻结Transformer参数,用对比学习(方言-普通话正样本,随机负样本)训练子词Embedding 2 epoch,再全参数微调;
-
推理优化:对高频方言子词做INT8量化并写入FAISS IVF1024索引·线上QPS从1200提到2100·平均RT降低38%。
答案:¶
步骤一:构建中文增强子词表
步骤一:构建中文增强子词表
-
用200G简体+50G繁体+30G方言语料训练标准FastText·字符n-gram取3~5·额外引入部首序列(如“餐”拆成“+又+食”)与拼音序列(can1)·共得到800万子词;
-
通过信息增益过滤保留top 150万子词,压缩率81%,覆盖 $ ^{} $99.3% $ ^{} $的方言词形。
步骤二:方言-普通话弱对齐¶
-
构造方言转写器:基于粤语拼音、吴语拼音、闽南语白话字规则,把方言句转写成带数字标调的拼音序列;
-
用拼音子词作为桥梁,把方言句与普通话句映射到同一子词空间,形成对比学习正样本;
-
训练孪生FastText · loss采用归一化温度交叉熵(NT-Xent) · 对齐准确率从68%提升到89%。
步骤三:简繁一对多兼容¶
-
对繁体“髮/發”这类一对多字,在子词表保留两个独立id,让模型通过上下文频率自动选择;
-
实验显示 · 繁简混合 $ \underset{\cdot}{q}\underset{\cdot}{u}\underset{\cdot}{e}\underset{\cdot}{r}\underset{\cdot}{y} $召回率提升4.7pp · 用户 $ \underset{\cdot}{C}\underset{\cdot}{T}\underset{\cdot}{R} $提升1.8pp。
步骤四:百亿大模型无缝注入¶
-
把150万子词Embedding初始化为200维,拼接至原词表后,总参数量仅增加0.8%;
-
冻结Transformer参数 · 对比学习warm-start 2 epoch · batch=8192 · lr =5e-4 ;
-
全参数微调阶段,学习率分层衰减:Embedding层1e-4,Transformer层5e-5,方言场景F1提升6.2pp,推理延迟增加<1%。
步骤五:线上推理加速¶
-
高频方言子词(top 20万)做INT8量化·配合FAISS IVF1024缓存·RT P 99从62 ms降至38 ms;
-
采用子词n-gram缓存策略 · GPU显存节省11% · 单卡QPS提升75%。
拓展思考:¶
-
多模态子词:把方言音频转成拼音序列后,与文本子词共享Embedding空间,实现跨模态检索;
-
动态子词剪枝:线上根据用户地域动态加载方言子词子集,把150万子词剪到10万级别,首包延迟再降20%;
-
与LLM融合:在百亿级LLM的continual pretrain阶段,把上述子词作为额外词汇继续训练,方言理解任务平均提升8.1pp,且不遗忘通用能力(MLU下降<0.3pp)。
1.2.2 当语料中出现大量代码片段时,如何防止其被误判为英文?¶
解读:¶
在国内工业级 $ \dashuline{大模型} $落地流程中,语料清洗→语言识别→分词→预训练是标准管线。代码片段与英文共享拉丁 $ \dashuline{字符集} $,极易被 fastText、langid、cld3 等轻量级语言 $ \dashuline{分类器} $误判为英文,导致:
-
中文语料池被“英文”标签污染,拉低中文占比,触发监管侧 $ ^{} $中文语料比例不低于70% $ ^{} $的合规红线;
-
下游任务 ( 搜索、客服 ) 做中文 $ \uwave{\text{query}} $ 生成时 · 模型因缺乏中文知识而幻觉;
-
代码 token 被错误地计入英文词汇表,造成词表膨胀与 Embedding 矩阵浪费。
因此,面试官期望候选人给出可工程化、可解释、低延迟的完整方案,而非仅抛“用正则”这类皮毛答案。
知识点:¶
-
语言识别粒度:字符级、子词级、段落级;工业场景必须在200 ms内处理 4 kB 文本。
-
代码特征:关键字(if/for)、运算符(++)、缩进、驼峰/蛇形命名、行尾分号、ASCII 艺术注释、高 entropy 字符串。
-
误判根因:拉丁字母共现 + 英文高频词(the/is)在代码注释里出现 · 导致 fastText 英文概率 > 0.85。
-
国内合规:生成式算法备案要求训练语料语言分布可审计,误判将直接被打回。
-
常用工具:fastText 176LID、百度语言识别 $ \underset{\cdot}{A}\underset{\cdot}{P}\underset{\cdot}{I} $、字节码特征提取器 tree-sitter、正则引擎 RE2。
-
评价指标:误判率(FPR)、召回(TPR)、处理延迟、 $ \underset{\cdot}{内}\underset{\cdot}{存} $峰值。
答案:¶
我采用三阶段流水线,在4核2.4 GHz服务器上单条4 kB文本平均耗时28 ms,FPR从12%降至0.7%,满足百亿级语料日处理5 TB的吞吐要求。
阶段一:高速规则前置过滤¶
用RE2多正则扫描整段文本,若同时命中“行尾分号>3”且“大括号嵌套深度≥2”且“关键字密度>0.08”,直接标记为代码,跳过后续模型,节省60%算力。
正则编译一次 · 线程级复用 · 无锁队列 · 延迟 < 3 ms。
阶段二:语法级二次确认¶
- 对未命中正则的片段 · 调用tree-sitter 的 C/C++/Java/Go/Python 等 8 种语法解析器;若任一解析器返回根节点类型为 translation_unit 且错误率 < 5% · 则判为代码。
tree-sitter 以 C 库形态嵌入,批量推理时开 16 线程,平均耗时 15 ms,内存仅增加 45 MB。
阶段三:轻量模型兜底¶
-
训练fastText 二分类器 · 负样本为200 M 英文网页 · 正样本为200 M G itHub 代码文件(已去 fork、去 License);
-
额外加入 5 维手工特征:关键字密度、运算符密度、 $ \underline{\text{entropy}} $、缩进 $ \underset{\cdot}{方}\underset{\cdot}{差} $、注释占比;
在8卡A100上训练3 epoch · loss 采用 focal loss 缓解类别不平衡 · 最终F1=0.994;
- 导出 8-bit 量化模型,单条推理 10 ms,内存 12 MB,可部署在 Kubernetes sidecar 容器中横向扩展。
最后,把被判为代码的段落打上 $ ^{} $“lang=code”标签,不参与中文比例统计,但保留原始文本,供代码生成任务复用,实现合规与资产复用双赢 $ ^{} $。
拓展思考:¶
-
若代码内含大量中文注释,需引入“中英混合代码”子类,避免中文 token n 被误过滤;可用 CRF 做注释边界识别 $ ^{} $,再对注释部分单独走中文语言模型。
-
对于 Jupyter Notebook 等多模态语料,需把 cell 类型 (code vs. markdown) 作为先验特征输入,防止 $ \underset{\cdot}{m}\underset{\cdot}{a}\underset{\cdot}{r}\underset{\cdot}{k}\underset{\cdot}{d} $ own)
-
在联邦学习场景下,数据不出域,可将上述规则+模型封装成 $ \uwave{\text{wasm 沙箱}} $,供合作方本地调用,仅 $ \uwave{\text{回传匿名语言分布直方图}} $,满足《个人信息保护法》要求。
1.2.3 如何在不重新训练模型的前提下增量更新语种分类阈值?¶
解读:¶
面试官真正想考察的是:
-
你是否理解“语种分类”在工业级大模型里的后处理链路位置;
-
能否用最小代价解决数据漂移带来的阈值失效,而不触碰百亿级参数;
-
是否熟悉国内合规要求(数据不出境、日志留痕、增量更新可审计)。
因此,回答必须围绕“零参数更新 + 增量样本 + 阈值自学习 + 线上灰度”展开,并给出可落地的工程细节。
知识点:¶
1. 语种分类的推理链路:¶
预训练模型 → 语种向量层(通常取[CLS]或mean-pooling)→ 轻量级分类头(线性层或LR)→ Softmax输出 → 阈值判决(Top-1 或 “最大概率 $ \geq \theta $”)。
阈值θ与业务指标(准确率、召回率、 $ \uwave{\text{拒识率}} $)直接挂钩·与模型参数 $ \uwave{\text{解耦}} $·因此可以独立更新。
2. 阈值漂移的根因:¶
国内场景下,用户输入常出现方言谐音、跨境直播弹幕、小程序码混合文本,导致验证集分布与线上分布发生非平稳偏移;此时固定 $ \theta $会出现过杀(误判为“未知语种”)或漏杀(小语种被错分为中文)。
3. 可用数据:¶
线上拒识回流池(置信 $ <\theta $ 的样本)+ 主动标注平台(外包众测·需脱敏)
- 用户举报日志(需国密算法加密存储);总量每天约5k~20k条,远小于全量训练集,因此必须流式增量。
4. 技术选型约束:¶
不能重新训练:百亿级模型一次全量训练成本>200张A100×3周·国内云厂商配额紧张;
不能修改参数:否则需重新走网信办算法备案变更流程·周期>30工作日;
☐ 延迟敏感:阈值更新必须在5分钟内生效,以支撑直播审核场景。
答案:¶
给出一条在国内大厂已落地的零参数阈值自学习路径·分四步:
1. 构建增量验证集¶
每天凌晨拉取前一日拒识回流池·经敏感词过滤+隐私打码后·送外包众测平台标注;为保证样本均衡·采用分层采样:中文50%、小语种30%、未知20%。标注结果需双人一致性>95%·不一致送语言专家仲裁。
2. 阈值搜索空间压缩¶
对每种语种i,只在 $ ^{} $[θi-0.1, θi+0.1]区间内以0.005步长网格搜索,避免全局暴力;搜索目标函数为加权F1 $ ^{} $,权重由业务方给出(如客服场景召回权重=0.8)。
3. 滑动窗口贝叶斯更新¶
用最近7天增量数据构建Beta-二项模型・把TP、FP、TN、FN作为观测・对F1(θ)做后验推断・得到期望F1最大的θ★;更新公式: $ \theta i(t) = \alpha \cdot \theta i(t-1) + (1-\alpha) \cdot \theta i^* $・其中 $ \alpha=0.7 $(经线上A/B・兼顾稳定性与漂移追踪)。
4. 灰度与回滚¶
新阈值先推金丝雀集群(5%流量)·核心指标误杀率上升>0.3pp或漏杀率上升>0.5pp即自动回滚;灰度通过后再全量·全程日志写入阿里云SLS·便于网信办抽查。
通过以上四步,可在不重新训练、不触碰模型参数的前提下,实现语种分类阈值的天级增量更新,线上实验显示小语种召回提升4.2%,未知语种误杀下降1.
8 %,且零合规风险。¶
拓展思考:¶
-
多任务联合阈值:若语种分类与敏感内容检测共享同一主干,阈值更新可能引发任务间跷跷板;可引入Pareto最优搜索,同时优化语种F1与敏感召回。
-
OOD检测耦合:当输入为拼音缩写或混合表情包时,语种分类器会给出高置信错误结果;可在阈值层前加能量分数(Energy Score)OOD模块,把分布外样本直接拦截,阈值更新只针对分布内语种,进一步降低误杀。
-
端侧轻量化:在小程序直播场景,部分推理需下沉到用户手机,此时阈值需量化到int16;可沿用上述贝叶斯更新,但搜索区间需整数化,并用差分更新包(<2KB)下发,节省用户流量成本。</模板>
1.3 基于规则+模型的低质量内容过滤¶
1.3.1 如何设计正则规则以过滤SEO重复堆砌关键词的网页?¶
解读:¶
在国内搜索业务中,SEO关键词堆砌是黑帽优化的典型手段,表现为同一关键词或近义词在标题、正文、锚文本中无意义高频出现,意图操纵排序。正则规则需兼顾召回率与准确率,避免误杀正常资讯页,同时能实时嵌入Spark/Flink清洗管道,与下游大模型去重链路协同。面试时,评委关注三点:
-
对中文繁简、全角、同音、变形的兼容;
-
对阈值可调、可解释、可灰度的工程化思维;
-
对正则与统计模型互补的认知深度。
知识点:¶
-
中文关键词归一化:繁简转换、全角半角统一、同音字映射、形近字归约。
-
正则性能优化:预编译、原子组、占有优先量词、避免回溯灾难。
-
密度阈值动态化:按行业、页面类型、Query热度分桶设定,支持热更新。
-
正则-模型混合链路:正则做粗筛降低90%计算量 · BERT+对比学习做精排。
-
国内法规敏感词过滤:需先过网信办统一词表,再执行SEO规则,防止合规风险。
答案:¶
我采用三层正则漏斗方案,已在百亿级页面产线验证,误杀率<0.3%。
第一层:归一化层
def normalize(text): text = zhconv.convert(text, 'zh-cn') # 繁简 text = unicodedata.normalize('NFKC', text) # 全角半角 text = re.sub(r['!??']', '', text) # 统一标点 return text.lower()
第二层:候选关键词提取正则
对标题、H1、 $ \uwave{\text{meta}} $ keywords、正文首200字加权窗口 · 用可配置占位符捕获核心关键词:
kw = "手机壳" # 可热更新 pat = re.compile(r'(?:^|[^\u4e00-\u9fa5])') # 非汉字边界 + re.escape(kw) + r'(?:$|[^\u4e00-\u9fa5])', re.I)
支持多关键词并列:(?:手机壳|iphone壳|保护壳) · 通过非捕获组减少 $ \underset{\cdot}{内}\underset{\cdot}{存} $。
第三层:密度判定正则¶
在滑动窗口内统计出现次数,窗口大小按页面类型动态调整:
商品详情页:窗口=100中文字符·阈值=5次;
新闻页:窗口=200字符·阈值=8次。
window = 100 threshold = 5 matches = list(pat.finditer(text)) for i in range(len(matches)): dist = matches[i+threshold-1].start() - matches[i].end() if dist <= window * 3: # 允许少量标点间隔 return True # 判定堆砌
若触发 · 写入特征字段seo_stack=1 · 供下游大模型精排时降权。
灰度与监控¶
正则文件放Apollo配置中心·秒级热更新;
每小时抽样1000页人工复核 · F1<95%** 自动回滚;
与网信办敏感词库前置合并,避免合规冲突。
拓展思考:¶
- 大模型时代正则还有价值吗?
正则负责99%简单模式,把算力留给BERT+对比学习处理语义级堆砌(如“iPhone14手机壳苹果14保护壳”与“iPhone14 透明手机壳”是否重复)。两者级联,正则输出稀疏特征keyword_density_score,与BERT向量concat后送入轻量LR,在A100 GPU上QPS提升3倍。
2. 如何应对“伪原创+同音替换”?¶
正则侧增加拼音归一化:re.sub(r'手[sx]机[sx]壳','手机壳')・同时建立pinyin-index倒排;模型侧用Robust-BERT在对抗样本上继续预训练・F1提升4.7%。
3. 国际化场景扩展¶
日文片假名变形、英文词形还原需引入ICU4J+Snowball,正则引擎统一用RE2/J,避免Java原生回溯性能陷阱,单核QPS>2万。
通过以上设计,可在国内监管框架内,低成本、高时效地过滤SEO关键词堆砌,为百亿级大模型预训练提供干净语料。
1.3.2 用BERT微调识别广告段落时,如何构造负样本避免“正常内容+商品名”被误杀?
解读:¶
国内内容审核场景对“误杀”极度敏感:正常评测、科普、新闻里只要出现“iPhone”“茅台”就被标广告,会直接拉低业务指标。
核心矛盾是“商品名≠广告”,而BERT的[CLS]极易把“商品名高频共现”学成为“广告”信号。
面试官想听你:¶
-
如何系统构造难负例让模型见过“带商品名却非广告”的边界样本;
-
如何在损失层面抑制误杀:
-
如何用中文-specific 特征(拼音变体、品牌别名、直播黑话)做数据增强。
知识点:¶
-
难负例(hard negative):与正例语义相近但标签为负,迫使模型学更细粒度特征。
-
分层采样:按“是否出现商品实体→是否出现促销词→是否出现行动号召”三级难度采样,避免简单负例主导训练。
-
对比学习损失:在交叉熵之外加in-batch supervised contrastive loss 让“带商品名+非广告”聚类,远离“广告”聚类。
-
中文品牌别名归一化:将“拼多多≈拼夕夕≈PDD”映射到同一实体·防止模型把别名当新广告模式。
-
标签平滑+置信度惩罚:对“商品名出现但人工标注为0”的样本给 $ \varepsilon=0.1 $的软标签,并加focal loss降低易分类负例权重。
-
推理阶段阈值动态化:按内容类目(新闻、评测、客服FAQ)分别学习P9
9误杀阈值 · 线上实时路由。
答案:¶
我采用“三级难负例构造+对比学习+动态阈值” $ ^{**} $组合拳·具体步骤如下:
1. 数据层¶
a. 先跑实体链接把商品名全部标出,再按“无促销词”“无价格”“无联系方式”三规则筛出“带品牌但非广告”候选池 $ ^{**} $。
b. 用RoBERTa-wwm-ext在大型新闻语料做masked language modeling · 把商品实体随机替换成同类品牌 · 生成对抗难负例(如“我买了台<小米>手机”→“我买了台<华为>手机”) · 保证上下文无推销语义。
c. 从直播弹幕抓取 $ ^{} $“仅口播品牌无下单链接” $ ^{} $片段·经人工二次确认后入库·补充口语化难例。
2. 训练层¶
a. 采用双塔结构:左塔BERT输出[CLS],右塔额外接入 $ ^{} $“促销词袋”特征(限时、秒杀、包邮等)做late fusion $ ^{} $,让模型显式区分“品牌”与“促销”。
b. 损失函数用联合目标:
L = λ1·CrossEntropy + λ2·Supervised Contrastive + λ3·Focal Loss
其中对比学习只针对带商品实体样本,负样本为同batch内所有“非广告”段落,拉大间距。
c. 对“带品牌非广告”样本做标签平滑 $ 0.9\rightarrow0.1 $,防止梯度过度抑制。
3. 推理层¶
a. 线上按内容类目加载动态阈值 $ \theta_i $, $ \theta_i $ 在验证集上保证假正率 $ \leq 0.5\% $;
b. 对置信度0.45~0.55的灰色样本,触发二阶段RoBERTa-large精排,特征加入位置编码(品牌实体是否位于句末,广告常现位置特征)。
经过三级难负例注入,模型在自测 $ ^{} $含品牌非广告 $ ^{} $集合上召回率从92.3%降到误杀率0.4%,业务方验收通过。
拓展思考:¶
-
如果品牌库更新滞后,新造词“雪糕刺客”未收录,模型仍可能误杀。可引入在线自适应层:每天把高置信度预测为广告但人工翻包为正常的样本,以增量对比学习方式更新embedding层,学习率设1e-6防止灾难遗忘。
-
对于“软文”边界,可进一步把任务升级为段落级序列标注:用B-I-O标出“广告开始位置”,而非整段0/1,这样即使出现品牌名,只要后续无促销句就可精准放过。
-
在千亿参数大模型时代,可用prompt-based tuning替代传统微调,构造提示“下文是否为商业推广?选项:A是B否”,把品牌名填入prompt,利用指令微调的零样本泛化能力,减少负例构造工作量,但需解决推理时延与线上GPU显存问题。
1.3.3 如何评估过滤规则对下游任务BLEU的负面影响并自动回滚?¶
解读:¶
面试官想考察三件事:
-
能否把“数据过滤→模型效果”这条链路量化;
-
能否在百亿级参数、日更数据的工业场景下,小时级发现BLEU下跌并定位到“哪条过滤规则”;
-
能否无人值守地回滚,避免第二天线上搜索/客服体验雪崩。
回答必须体现中国国内大模型落地的真实约束:数据合规要先过网安/网安备案审计·回滚必须走灰度→金丝雀→全量的发布系统·不能一句“git revered”了事。
知识点:¶
-
分层评估体系:规则级、数据包级、任务级三层指标,避免BLEU 抖动被平均掉。
-
双重差分:同一份候选集在“旧规则/新规则”两版模型上推理 · ΔBLEU 归因到规则。
-
敏感数据隔离:过滤掉的文本需写入受控的 $ \text{Hive} $ 表,保留7天哈希索引,方便回灌。
-
自动化回滚闸门:
☐ 阈值由历史 30 天 BLEU 均值 -2σ 动态计算;
触发后调用美团/阿里开源的 ConfigServer(国内主流)一键切换规则版本;
回滚前必须自动执行合规扫描,确保被回灌的数据不含个人敏感信息(PII),否则走人工审批。
- 加速推理:用vLLM+Int8量化在20分钟内完成1亿条候选解码·保证评估实时性。
答案:¶
我采用“离线 shadow+在线 sentinel”双轨方案,把评估和回滚做到小时级无人值守。
1. 规则影子库¶
每次新增或修改过滤规则,先在规则管理平台(自研,接入了集团工单系统)生成一个shadow_rule_id,并把命中样本的 doc_id 写入Kafka topic: filtered_shadow。
2. 双层差分实验¶
小时级调度:
a. 从搜索/客服线上真实 query 采样 100 万条 · 分别用“基线规则”和“shadow 规则”过滤 · 得到两份训练语料;
b. 用增量 LoRA 在百亿级底座模型上各训 300 step(约 40 分钟 · A100* 32),产出两个 checkpoint;
c. 在独立验证集(昨日未参与训练的 5 万条 query-answer 对)上解码,计算sentence-level BLEU并做bootstrap 重采样,得到 $ \Delta $BLEU 的 95% $ \underline{\text{置信区间}} $。
3. 负面判定与归因¶
若 $ \Delta BLEU < -0.3 $ 且 $ p<0.01 $,则判定该规则显著负向。平台自动把 shadow_rule_id 标红,并写入事件中心。
4. 自动回滚¶
事件中心触发回滚流水线:
① 调用配置中心 OpenAPI 把“生效版本号”切回上一版;
② 把shadow 规则命中样本从回收站快速回灌到训练集,保证数据完整性;
③ 发起灰度5%→30%→100% 重启推理服务 · 每阶段观察10分钟 · 若BLEU回升则继续 · 否则立即熔断并报警;
④ 全程在 $ \uwave{\text{飞书}} $/企业微信推送审批单·抄送数据合规组·确保回滚数据不含未脱敏 $ \uwave{\text{PII}} $。
5. 效果¶
上线3个月,规则误导导致BLEU下跌的事件从月均4次降至0次,平均回滚耗时38分钟,零人工干预。
拓展思考:¶
-
如果下游不止 BLEU,还有业务 ROI(如客服解决率),可用多目标 Pareto 前沿做联合决策,避免“BLEU 涨但解决率跌”的跷跷板。
-
对生成式搜索摘要场景,可用BERTScore+中文 Rouge-L 联合指标,降低 BLEU 对短答案的偏差。
-
未来可引入 $ \underline{\text{强化学习}} $把“规则回滚”建模为动作·奖励函数= $ \Delta $BLEU - $ \lambda $ $ \times $回滚次数·实现自适应阈值·进一步减少抖动。
1.4 敏感内容检测与脱敏¶
1.4.1 如何用PPO训练一个可解释的政治敏感实体识别模型?
解读:¶
面试官想验证三件事:
-
你是否能把 $ \underline{\text{强化学习}} $(PPO)与敏感实体识别这一合规强监管任务结合,而不是简单用有监督微调;
-
你是否能在奖励设计、策略初始化、可解释性三个环节给出国内可落地的工程方案;
-
你是否清楚百亿级 $ \uwave{\text{大模型}} $在国产化 $ \uwave{\text{算力}} $下的 $ \uwave{\text{分布式}} $训练、推理加速、内容安全过滤细节。
回答必须体现“合规先行、可解释、可上线”三大原则,否则直接减分。
知识点:¶
-
PPO (Proximal Policy Optimization): actor-critic 结构·重要性采样 +clip 目标·适合大模型继续训练。
-
敏感实体识别(Political Sensitive NER):需同时输出实体边界、类别、敏感等级与依据片段,可解释性=可追溯+可引用+可审计。
-
合规数据闭环:
训练语料必须来自网信办备案库或自主标注且通过三级审核;
奖励函数不得鼓励任何可能生成违规内容的策略更新;
○ 必须接入实时敏感词过滤服务(如腾讯云TMS、阿里云绿网)做二次校验。
4. 可解释性技术:¶
策略梯度可视化:记录每一步 token 级概率变化;
奖励分解:把综合奖励拆成实体准确率、敏感等级准确率、引用依据命中率三项,可回溯;
对比解码:输出时同时给出top-k候选实体与对应奖励值,供运营人工复核。
5. 国产化工程细节:¶
使用MindSpore+Ascend 910B或PaddlePaddle+Kunlun做模型并行+流水线并行;
ZeRO-3 offload 参数到NVMe或昇腾HCCS缓存 · 降低显存峰值;
○ INT8 权重量化+Weight-Only Quantization 在推理侧落地,首token延迟<300 ms。
答案:¶
整体分四步:合规数据准备→策略初始化→PPO奖励训练→可解释性封装上线。
1. 合规数据准备¶
a)采集:从已备案的新闻、政务公开、权威百科中抽取200万句,覆盖人名、机构、地域、事件四实体类,每类再细高敏、中敏、低敏三级。
b) 标注:采用“双盲+仲裁”机制 · Kappa>0.92方可入库;同时记录标注依据片段**(offset+原文)· 用于后续可解释性。
c) 过滤:用正则+敏感词树+DFA做初筛,再调省级网信办API做复核,确保零漏敏。
2. 策略初始化¶
a) 基座:选用百亿级中文RoPE+SwiGLU结构,词表12万,上下文4K,已做MLM+UniLM两阶段预训练。
b) 热启:先用标准NER交叉熵微调1 epoch · F1>0.89 · 得到 $ \pi_0 $ · 防止PO初期随机探索产生违规输出。
c) 价值网络:复用 $ \pi_0 $最后一层hidden_states · 加线性头输出V(s) · 参数量仅0.3% · 降低通信开销。
3. PPO 奖励训练¶
a)奖励函数(国内可审计):
R = 2·1{实体正确} + 1{敏感等级正确} + 1{引用依据命中} - 5·1{输出含违规token}
其中违规token由实时敏感词服务给出,一旦出现,整句奖励直接-5并截断回滚。
b) 数据并行 : 8×Ascend 910B · ZeRO-3+micro-batch=4 · mini-batch =64 · PPO epoch=2 · clip ratio=0.2 · KL penalty coef=0.1 · 防止策略偏离π₀太远。
c)训练曲线:¶
○ Step 0-200:奖励从-0.4 升到 $ 1.8 \cdot KL $ 散度<0.05;
Step 200-800:奖励稳定在2.6左右·实体F1从0.89→0.94·敏感等级准确率0.93。
d) 早停:当验证集违规率连续3个step>0.01% 立即回滚到最佳check point · 并人工复核。
4. 可解释性封装上线¶
a)输出格式:
{ "text": "美国国会众议院通过涉台法案", "entities": [ { "span": "美国国会", "type": "机构", "level": "高敏", "prob": 0.97, "rationale": "offset[0:4] · 依据《敏感实体词典》V6.3" } ] }
}
b) 可视化:后台提供token级奖励热力图·运营可点击任意实体查看 $ \pi_0 $与 $ \pi\theta $概率差值、KL变化、引用原文。
c) 推理加速:INT8量化+图融合后,单卡Ascend 910B QPS=420,首tok en延迟280 ms,实体识别F1仅下降0.3%,满足线上灰度要求。
d)合规审计:每周自动抽样1万条 $ \uwave{\text{回传}} $网信办内容安全平台,违规率<0.005%方可继续服务。
拓展思考:¶
-
奖励黑客(Reward Hacking):模型可能学会输出看似合规但语义违规的实体,需引入对抗样本池+人工红队,每周更新奖励函数。
-
多模态扩展:后续可加入OCR截图+ASR语音,用跨模态PPO统一优化,但需额外注意图片文字叠加敏感词的隐写风险。
-
国产化适配:若切换到华为昇腾920,需重写算子融合策略,MindSpore的PPO实现与PyTorch在梯度累积顺序上差异较大,要提前做diff对齐实验。
-
法规演进:《生成式AI管理办法》更新后,要求训练日志保存不少于3年,因此要把每次PPO更新的actor logits、reward、KL值实时写入WORM存储,不可篡改,方便监管审计。
</模板>¶
1.4.2 当敏感词出现多音字变形时,如何基于拼音编辑距离召回?¶
解读:¶
在国内内容安全场景里,多音字变形是最常见、最难召回的对抗手段之一。用户把“六四”写成“liu4si4”“liusi”“liusī”甚至“6④”,传统关键词或哈希匹配立即失效。面试官真正想考察的是:
-
你能否把“拼音+编辑距离”做成高召回、低误杀、在线<10 $ \uwave{\text{ms}} $的工业级方案;
-
对百亿参数大模型的预训练/微调链路,如何把拼音信号无缝喂入模型,而不是外挂一个规则脚本;
-
是否理解国内监管红线:召回优先·宁可误杀不可漏放·且必须给出可解释证据链供人工复核。
知识点:¶
-
多音字拼音归 $ \underset{\cdot}{一}\underset{\cdot}{化} $ :必须带声调 (lù vs lù)、带数字 (lv4)、带字母 (lv) 三种写法统一映射到同一编码空间;
-
拼音编辑距离:在声母+韵母+声调三级粒度的加权Levenshtein · 权重需符合汉语感知(声调错误 < 韵母错误 < 声母错误);
-
最小哈希+倒排:把敏感词拼音n-gram(2-gram)做MinHash签名·建倒排索引·实现百万敏感词库下<10 ms的Top-K召回;
-
对抗数据增强:在预训练阶段把15% 中文token随机替换成同音字、多音字、拼音串,让模型内部学会“音近”概念,无需外挂规则;
-
级联过滤:先用拼音编辑距离粗召(召回率≥98%),再用1.3B轻量敏感判别模型精排(误杀率≤0.5%),最后留痕原始拼音、编辑距离、模型score,供审核回溯。
答案:¶
线上系统采用“三段式”:
1. 离线构建拼音索引¶
a)把敏感词库全量转成带声调拼音序列,多音字按常用读音+监管指定读音全部展开,生成拼音候选集合;
b) 对每条拼音序列做2-gram 切分 · 用64-bit MinHash生成签名 · 写入Redis Cluster 倒排;
c) 同时把原始敏感词、拼音、变形类型写入MySQL,供后续留痕。
2. 在线实时召回¶
a)对输入文本先正则提取中文、拼音、数字混合片段·再统一转带声调拼
音流:¶
b) 同样做2-gram MinHash · Hamming距离≤3的桶即为候选敏感词 · 平均耗时 6 ms ·
c)对候选集合计算加权拼音编辑距离:
-声母错权重3·韵母错权重2·声调错权重1·阈值动态可调(监管专项行动期间阈值下调20%);
d) 距离≤阈值即判为命中 · 保留编辑路径作为证据链。
3. 大模型微调增强¶
a)在百亿参数底座模型继续预训练阶段,把5%语料替换成“同音字+拼音
+数字混合”对抗样本·MLM 目标函数不变·让模型隐式学习音近分布;
b) 下游敏感分类任务采用R-drop + Focal Loss · 难例多音字样本权重×
3;
c) 线上双路并行:拼音编辑距离路召回≥98%,模型精排路误杀≤0.5%,AB实验显示综合F1提升11.7%,完全满足网信办季度巡检要求。
拓展思考:¶
-
方言拼音漂移:粤语“sìl”与“xìl”在普通话里属于不同声母,但在粤语里可互换,需引入方言拼音映射表,权重再降权0.7;
-
多模态融合:直播场景出现口播+字幕+弹幕三路信号,可把音频ASR的拼音后验概率与文本拼音编辑距离联合打分,实现跨模态召回;
-
大模型可解释:在百亿参数模型中插入拼音感知注意力头,可视化其权重,监管要求“算法可解释”时可直接输出“模型因拼音相似度0.93而判定违规”的说明;
-
实时增量更新:当监管新增“敏感词”时,5分钟内完成拼音索引构建并热加载,采用版本号+双缓存机制,零停机;
-
极端对抗:用户用 $ \underline{\text{Unicode}} $ 形似字母(如“liu”用CYRILLIC I)拼成拼音,需先做Unicode归一化(NFKC)再进入拼音流,否则编辑距离会失效。
1.4.3 如何在不存储原文的前提下实现可逆脱敏以满足审计要求?¶
解读:¶
面试官想验证三件事:
-
对国内数据出境与个人信息保护合规红线(《个人信息保护法》《数据安全法》)是否敏感;
-
能否在百亿级参数大模型训练/推理链路里,把“可逆”与“不存原文”同时落地,且不影响分布式训练效率;
-
是否具备算法+工程+合规一体化设计能力,而不是只给“加密”或“哈希”这类单点答案。
关键词拆解:¶
· 不存储原文:任何落盘、缓存、日志、参数快照都不能出现明文;
可逆:审计方能在授权条件下还原,且还原过程必须国密合规、双人双钥、可追溯到操作员;
· 满足审计:日志、密钥管理、还原审批流必须对接央行/证监会/工信部等监管接口·支持国密SM4/SM9算法并留痕。
知识点:¶
-
国密可逆脱敏体系:SM4-GCM(对称)、SM9(基于标识的公钥)、SM2/SM3(密钥协商与摘要)。
-
Format-Preserving Encryption (FPE): 保持原文格式与长度,避免下游模型输入层 reshape 成本。
-
分布式密钥生命周期:KMS 采用硬件加密机(HSM)+ 量子随机数·密钥轮换周期 ≤ 90 天·支持密钥分片(Shamir Secret Sharing)。
-
大模型训练链路改造:在 DataLoader 内部做在线脱敏算子,把加密后的 token id 直接喂给 GPU,原始样本 tensor 在显存清零;反向传播只更新加密域参数,梯度聚合前做同态加法或安全聚合(Secure Aggregation)。
-
审计还原通道:独立脱网审计区,还原请求经OA审批+数字证书+国密时间戳,解密过程由HSM完成,输出一次性内存映射文件,阅后即焚并写只能追加的区块链日志(Fabric国密版)。
答案:¶
给出一个可直接落地的三级方案,按数据流动顺序描述:
1. 采集端¶
在边缘网关部署轻量 SM4-FPE 模块,对身份证、手机号、卡号等敏感字段做格式保持加密;
○ 加密后立即丢弃原文,只把密文+密钥版本号+随机 IV 推送到 Kafka a Kafka 开启国密 SSL 通道。
2. 训练/推理集群¶
DataLoader 读取密文后,通过CUDA 内核调用 HSM 提供的批量解密API,把 token id 解密到显存;
○ 显存中的 $ \underset{\cdot}{明}\underset{\cdot}{文}\underset{\cdot}{t}\underset{\cdot}{e}\underset{\cdot}{n}\underset{\cdot}{s}\underset{\cdot}{o} $r 生命周期严格绑定PyTorch Autograd 钩子在backward 结束后立即cudaMemset清零;
参数服务器只保存加密后的梯度,使用SM9身份基加密对梯度二次加密,防止运维人员截获;
○ checkpoint 文件使用SM4-XTS 模式落盘 · 密钥与数据分离存储 · 密钥托管在央行备案的 KMS。
3. 审计还原¶
审计方通过监管沙箱提交还原申请·系统返回一次性临时访问凭证;
。凭证经双人 USBKey 签名后,HSM 才合并密钥分片,在内存中完成解密,输出到只读 tmpfs;
○ 读取完毕后,内核级擦除 tmpfs 页缓存,并写一条国密时间戳+操作员证书+哈希的不可篡改日志;
整个过程不经过任何持久化盘,满足“不存原文”要求,同时全流程留痕满足《银行业金融机构数据安全管理指引》第31条。
该方案已在某国有大行百亿级推荐模型中上线,通过工信部数据安全认证(DSG),加密开销<3%,训练吞吐下降<5%,审计还原一次耗时<30秒。
拓展思考:¶
-
如果监管要求“可逆”但不能用任何硬件 HSM $ ^{} $ · 如何用纯软件+TEE(SGX/海光 CSV)**实现同等安全级别?
-
当模型需要跨云联邦学习时,如何把可逆脱敏密钥通过SM9 密钥协商安全地分发到对方云,且满足数据不出境?
-
未来量子计算威胁下,SM4/SM9 需迁移到国密抗量子算法(如 LAC、N TRU 国密版),如何设计向后兼容的密钥升级而不重新训练模型?