news 2026/4/25 22:35:08

【AI大模型春招面试题28】什么是“词表扩展”?大模型词表扩展的常见方法及注意事项?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【AI大模型春招面试题28】什么是“词表扩展”?大模型词表扩展的常见方法及注意事项?


🎪 摸鱼匠:个人主页

🎒 个人专栏:《大模型岗位面试题》

🥇 没有好的理念,只有脚踏实地!

文章目录

      • 一、面试官到底在考什么?(考点拆解)
      • 二、核心原理:为什么不能随便“加词”?
      • 三、标准答案与实操解析
        • 1. 什么是“词表扩展”?
        • 2. 常见方法(由浅入深)
        • 3. 注意事项(这是区分初级和高级的关键)
      • 四、易错点与深水区(面试官的“陷阱”)
      • 五、模拟面试现场
      • 总结(一句话记忆)

你好!咱们直接切入正题。这道题在现在的面试中(尤其是涉及垂直领域微调、多语言适配的岗位)出现频率极高,因为它不仅考察你对Tokenizer 原理的理解,更考察你是否有工程落地经验避坑意识

很多候选人只会背“加几个词就行”,但真正做过的人知道,改词表等于动模型的根基,处理不好模型直接“失语”或崩溃。

下面我按“考点拆解 -> 核心原理 -> 标准答案(含实操) -> 易错点/深水区 -> 模拟面试”的逻辑给你深度解析。


一、面试官到底在考什么?(考点拆解)

当面试官问“词表扩展”时,他其实想确认你三件事:

  1. 原理深度:你是否理解 Token ID 与 Embedding 层的映射关系?是否知道修改词表后,模型权重矩阵发生了什么变化?
  2. 工程能力:你会用transformers还是手写脚本?你是直接替换词表文件,还是走了标准的resize_token_embeddings流程?
  3. 风险意识:扩展后是否需要重训?只训新向量够不够?会不会破坏原有语义空间?

二、核心原理:为什么不能随便“加词”?

在回答之前,脑子里要有这张图:

  • Tokenizer:字典,负责把文字转成 ID(比如 “苹果” -> 1024)。
  • Embedding Layer:查找表(Lookup Table),形状是[Vocab_Size, Hidden_Dim]。ID 1024 对应这一行向量。

词表扩展的本质

  1. 字典变大:Tokenizer 能识别更多新词(如生僻字、医疗术语)。
  2. 矩阵扩容:模型的 Embedding 层和 Output (LM Head) 层必须从[V_old, D]扩容到[V_new, D]
  3. 初始化关键:新增的那部分行向量(新词的 Embedding)怎么初始化?随机?平均?这是影响收敛速度的核心。

三、标准答案与实操解析

1. 什么是“词表扩展”?

“简单来说,就是给大模型‘增补字典’。预训练模型的词表通常是通用的,遇到垂直领域(如医疗、法律)的生僻词、专业术语,或者特定语言的字符时,会被切分成很多细碎的子词(Subwords),导致序列变长、语义割裂。
词表扩展就是把这些高频的专业词或生僻字,作为一个完整的 Token 加入词表,并相应地扩大模型的 Embedding 矩阵,让模型能‘一口吃掉’这些概念,而不是‘嚼碎了再咽’。”

2. 常见方法(由浅入深)

这里要展示你知道不同的场景用不同的招:

方法 A:基于 Hugging Faceresize_token_embeddings(最常用、最标准)

  • 适用场景:绝大多数微调任务,增加几百到几千个新词。

  • 操作逻辑

    1. tokenizer.add_tokens(new_tokens)添加新词,返回新增数量。
    2. 调用model.resize_token_embeddings(len(tokenizer))
    3. 关键点:HF 底层会自动将新增加的 Embedding 向量初始化为均值为 0、方差为预设值的高斯分布(或者有时复用已有向量的平均,取决于具体实现配置,但默认通常是随机初始化)。
  • 代码示例(面试时能口述出这个很加分):

    fromtransformersimportAutoTokenizer,AutoModelForCausalLM tokenizer=AutoTokenizer.from_pretrained("base_model")model=AutoModelForCausalLM.from_pretrained("base_model")# 1. 准备新词列表 (例如医疗术语)new_tokens=["靶向药","免疫疗法","CAR-T"]num_added=tokenizer.add_tokens(new_tokens)ifnum_added>0:# 2. 扩容模型嵌入层model.resize_token_embeddings(len(tokenizer))# 3. (进阶) 此时新向量是随机的,通常需要针对新词表进行一段“预热训练”

方法 B:特殊符号占位符替换(Hack 法,不推荐但需知道)

  • 适用场景:无法修改模型结构,或者紧急修复某个特定词。
  • 逻辑:利用原词表中极少使用的特殊符号(如<unused0>)映射到新词。训练时强制模型学习该 ID 代表新含义。
  • 缺点:浪费原词表空间,语义不直观,难以维护。

方法 C:完全重训 Tokenizer + 从头映射(高成本,用于大改版)

  • 适用场景:跨语言迁移(如从纯英文模型改成中英混排),或原词表对目标语言支持极差(如中文被切成单字)。
  • 逻辑:在新语料上重新训练 BPE/Unigram 词表 -> 构建新旧词表映射 -> 尝试将旧 Embedding 投影到新空间(很难完美)-> 大量重训。
  • 注意:这通常等同于重新预训练,成本极高。
3. 注意事项(这是区分初级和高级的关键)

面试时一定要强调以下几点,这是血泪经验

  1. 必须同步扩容 LM Head

    • 很多新人只改了 Embedding 层,忘了输出层(LM Head /lm_head)。如果输出层没扩容,模型生成时遇到新词 ID 会直接报错或映射错误。resize_token_embeddings通常会自动处理这两层,但如果是自定义模型架构,务必检查。
  2. 新向量的初始化策略

    • 随机初始化是默认做法,但会导致训练初期新词梯度不稳定。
    • 高阶技巧:如果新词是由旧词组成的(例如 “人工智能” 原本被切分为 “人工” + “智能”),可以将新词的 Embedding 初始化为旧词向量的平均值。这能让新词在训练开始前就拥有合理的语义位置,显著加快收敛。
  3. 训练策略(两阶段法)

    • 不要直接全量微调!
    • Phase 1:冻结大部分主干参数,只训练 Embedding 层和 LM Head(或者加上少量 Layer),让新词向量先“融入”语义空间。
    • Phase 2:解锁全部参数进行正常 SFT(监督微调)。
    • 原因:新向量是随机的,如果直接参与深层计算,巨大的噪声会破坏预训练好的权重分布。
  4. 分词优先级的变化

    • 加入新词后,Tokenizer 的贪心匹配逻辑会变。要确保新加的长词不会被错误的短词优先匹配掉(通常add_tokens会自动处理优先级,但需验证)。
  5. 量化兼容性

    • 如果模型是 4-bit/8-bit 量化的(如 bitsandbytes),直接resize可能会报错或失效。通常需要先卸载量化,扩容后再重新量化,或者使用支持动态扩容的量化后端。

四、易错点与深水区(面试官的“陷阱”)

Q: 词表扩展后,原来的性能会下降吗?

  • 易错回答:不会,只是加了新词。
  • 专业回答有可能
    1. 优化器状态污染:如果使用 AdamW,新加入的参数会影响全局的梯度统计量(momentum/variance),可能导致旧知识遗忘加速。
    2. 语义空间挤压:如果扩充太大(比如从 32k 扩到 100k),而隐藏层维度不变,单个向量代表的语义密度可能变化,需要足够的训练数据来“校准”。
    3. 解决:控制学习率,对新旧参数使用不同的学习率(新词用大一点,旧词用小一点)。

Q: 为什么有时候加了词,模型还是输出乱码?

  • 原因
    1. 只加了词表,没改模型权重(最常见)。
    2. 训练数据不足:新词在微调数据里出现次数太少,向量没学好。
    3. 解码错误:生成的 Token ID 超出了原词表范围,但解码器还在用旧词表解,或者新词对应的字节序列非法。

五、模拟面试现场

面试官: “我们想在医疗场景下用 LLaMA-3,但它对很多药品名切分得很碎。你怎么做词表扩展?要注意什么?”

候选人(你)
“这个问题很典型。我会分三步走:

第一步,数据驱动的选词。
我不会拍脑袋加词。我会先拿一批医疗语料,用原生的 LLaMA-3 Tokenizer 跑一遍,统计那些被切分成 3 个以上 token 且高频出现的专有名词(比如具体的化学药名)。同时,结合医学词典,筛选出约 2000-5000 个核心术语作为候选集。

第二步,标准扩容与初始化。
利用transformers库,先tokenizer.add_tokens()把这些词加进去。然后关键一步,调用model.resize_token_embeddings()
这里有个细节,默认是新向量随机初始化。为了稳一点,我会写个小脚本,对于像‘阿司匹林肠溶片’这种由已知字组成的词,尝试用其子词向量的均值来初始化新向量,而不是纯随机。这样模型一开始就能大概猜到这词的意思。

第三步,差异化训练策略。
扩容后,我绝对不会直接全量微调。
我会先做一个Embedding Warm-up:冻结 Transformer 的主体层,只开放 Embedding 层和 LM Head,用医疗语料跑几个 epoch,让新词向量快速收敛到合理的语义空间。
然后再解冻所有层,用正常的学习率进行 SFT。
另外,因为引入了新参数,我会稍微调低一点整体学习率,防止破坏基座模型原有的通用能力。

最后还要注意一点,如果我们要部署量化版本,必须在扩容完成、训练好之后,再进行量化,不能在量化状态下直接改词表大小,否则容易出兼容性问题。”


总结(一句话记忆)

词表扩展不是简单的“加字典”,而是**“字典扩容 + 矩阵重塑 + 向量初始化 + 分层热身训练”**的系统工程。

这套回答既展示了你对 HF 工具的熟练度,又体现了对深度学习原理(初始化、优化器、语义空间)的深刻理解,绝对是资深程序员的水平。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/25 22:34:54

“月薪1.4万,测试干了四年,我该往哪走?”

一位成都测试同学的深夜迷茫&#xff0c;和一个面试700场的老兵给他的答案01 深夜咨询凌晨两点多&#xff0c;一位同学在群里发了一条消息。他说自己今年29岁&#xff0c;在成都做测试&#xff0c;培训入行&#xff0c;实际干了四年&#xff0c;简历上包装了六年。月薪1.4万&am…

作者头像 李华
网站建设 2026/4/25 22:33:26

李雅普诺夫吸引子驱动AI训练新范式

问题解构与方案推演 针对用户关于“2026年热力学AI方向是否已出现基于李雅普诺夫吸引子的训练范式”的查询&#xff0c;我们需要结合理论物理概念&#xff08;李雅普诺夫稳定性、热力学熵&#xff09;与人工智能工程实践&#xff08;训练范式、优化算法&#xff09;进行交叉验…

作者头像 李华
网站建设 2026/4/25 22:32:15

C#跨平台AI语音对话SDK:XiaoZhiSharp集成与实战指南

1. 项目概述与核心价值最近在折腾一些智能对话和语音交互相关的项目&#xff0c;发现市面上虽然有不少大模型API&#xff0c;但想要把它们无缝集成到自己的C#应用里&#xff0c;尤其是还得支持跨平台、实时语音这些功能&#xff0c;总感觉缺那么一个趁手的“轮子”。要么是封装…

作者头像 李华
网站建设 2026/4/25 22:26:30

轻量级代码生成器codeg:模板引擎在批量代码生成中的工程实践

1. 项目概述与核心价值最近在GitHub上看到一个挺有意思的项目&#xff0c;叫xintaofei/codeg。光看这个名字&#xff0c;可能有点摸不着头脑&#xff0c;“codeg”是啥意思&#xff1f;是“Code Generator”&#xff08;代码生成器&#xff09;的缩写吗&#xff1f;点进去一看仓…

作者头像 李华
网站建设 2026/4/25 22:24:23

​.NET 实战:Redis 缓存穿透、击穿与雪崩的原理剖析与解决方案

在 .NET 高并发系统中&#xff0c;Redis 作为核心缓存层&#xff0c;一旦出现“穿透、击穿、雪崩”&#xff0c;数据库将瞬间承受巨大压力&#xff0c;严重时甚至会导致整个服务雪崩。本文将深入剖析三者原理&#xff0c;并给出可直接落地的 .NET 解决方案。一、缓存穿透 1. 原…

作者头像 李华