当前位置: 首页 > ds >正文

NLP核心技术解析:大模型与分词工具的协同工作原理

文章目录

    • 一、核心关系概述
    • 二、分词工具的核心作用
    • 三、未登录词(OOV)问题
      • 3.1 问题本质分析
      • 3.2 解决方案
        • 3.2.1 预对齐词汇表(最优解)
        • 3.2.2 子词回退策略
        • 3.2.3 词汇表扩展(适合专业领域)
      • 3.3 技术选型建议
      • 3.4 关键验证方法
      • 3.5 总结
    • 四、分词工具与Tokenizer的区别
    • 五、NLP 中的特殊标记
      • 5.1 特殊标记解释
      • 5.2 示例
    • 六、大模型输入的核心组成部分
      • 6.1 名词解释
      • 6.2 输入示例
      • 6.3 关键总结

一、核心关系概述

分词工具(如Jieba、SentencePiece)与 AI大模型(如GPT、BERT)的关系可总结为:

  • 分词工具是AI大模型的“前处理引擎”,为大模型提供数据预处理支持
  • 大模型是任务的“智能大脑”,它利用分词结果可以进行更高级的语言理解和生成任务

二、分词工具的核心作用

  1. 文本标准化处理
    • 中文分词示例:"深度学习" → ["深度", "学习"]
    • 解决英文子词问题:"unhappiness" → ["un", "happiness"]
  2. 降低计算复杂度
    • 长文本分割为词/子词单元,减少模型计算量
  3. 跨语言适配
    • 针对不同语言特性设计(如中文需分词,英文需处理子词)

三、未登录词(OOV)问题

3.1 问题本质分析

分词工具(如 Jieba)分出的词汇后续由 Tokenizer(如 BERT)转换为词汇表中的索引时,若词汇表中不包含某些词,则会出现 OOV(Out-of-Vocabulary)问题,这会导致:

  • 稀有词/专业术语被拆解为 <UNK>(未知标记)
  • 语义信息丢失(如 “量子计算” → [UNK]
  • 模型性能下降

3.2 解决方案

3.2.1 预对齐词汇表(最优解)

原理:强制分词工具只输出 Tokenizer 词汇表中存在的词汇

from transformers import BertTokenizer
import jieba# 加载Tokenizer并提取词汇表
tokenizer = BertTokenizer.from_pretrained("bert-base-chinese")
vocab = set(tokenizer.get_vocab().keys())  # 获取所有合法token# 定制化分词函数
def aligned_cut(text):words = []for word in jieba.lcut(text):# 检查词汇是否存在(处理子词情况)if word in vocab:words.append(word)else:# 递归拆解未登录词(直到字符级)for char in word:if char in vocab:words.append(char)else:words.append("[UNK]")return words# 测试
text = "量子计算是未来趋势"
print(aligned_cut(text))  # 输出保证在vocab中的分词
3.2.2 子词回退策略

原理:利用 Tokenizer 的子词分解能力处理未登录词

from transformers import AutoTokenizertokenizer = AutoTokenizer.from_pretrained("bert-base-chinese")def safe_tokenize(text):# 先用分词工具粗分words = jieba.lcut(text)  # 再用Tokenizer的子词处理tokens = []for word in words:tokens.extend(tokenizer.tokenize(word))  # 自动处理OOVreturn tokens# 测试
print(safe_tokenize("区块链技术"))  # ['区', '块', '链', '技术']
3.2.3 词汇表扩展(适合专业领域)

步骤

  1. 收集领域专有词汇(如医疗术语)

  2. 添加到分词工具用户词典

    jieba.load_userdict("medical_terms.txt")  # 每行格式: `术语 词频 词性`
    
  3. 微调 Tokenizer(需重新训练模型)

    new_tokens = ["COVID-19", "mRNA疫苗"]
    tokenizer.add_tokens(new_tokens)  # 扩展词汇表
    model.resize_token_embeddings(len(tokenizer))  # 调整模型嵌入层
    

3.3 技术选型建议

场景推荐方案优点缺点
通用领域子词回退策略无需额外资源可能拆解专业术语
专业领域(如医疗/法律)词汇表扩展+预对齐保持术语完整性需要领域词典和模型微调
多语言混合文本使用SentencePiece分词统一处理多种语言需替换原有分词工具

3.4 关键验证方法

  1. 覆盖率测试

    def check_coverage(texts):vocab = set(tokenizer.get_vocab().keys())oov_rate = 0for text in texts:words = jieba.lcut(text)oov_rate += sum(1 for w in words if w not in vocab) / len(words)print(f"OOV率: {oov_rate/len(texts):.2%}")check_coverage(["量子物理", "临床试验"])  # 示例输出: OOV率: 15.00%
    
  2. 可视化调试

    from transformers import pipeline
    nlp = pipeline("ner", model="bert-base-chinese")text = "患者有COVID-19症状"
    print(nlp(text))  # 检查专业术语是否被正确识别
    

3.5 总结

通过 词汇表预对齐 + 子词回退 + 领域适配扩展 的组合策略,可确保:
✅ 分词结果 100% 被 Tokenizer 接受
✅ 专业术语完整性保留
✅ 避免 <UNK> 导致的语义损失

最终效果取决于分词工具与 Tokenizer 的协同设计,建议在预处理阶段加入 OOV检测模块 进行质量监控。

四、分词工具与Tokenizer的区别

特性jieba(传统分词工具)大模型Tokenizer(如BERT/GPT)
设计目标针对特定语言(如中文)的词汇级分割将文本转换为模型可处理的子词/字符级ID
输出单元词语(如[“深度学习”, “是”, “未来”])子词(如[“深”, “度”, “学习”, “是”, “未”, “来”])
语言适应性需针对不同语言训练专用模型通过统一算法(如BPE/WordPiece)支持多语言
典型应用场景搜索引擎、文本分析等传统NLP任务大模型的输入预处理

问题:为什么大模型仍需自研Tokenizer?

  • 子词平衡:Tokenizer通过算法(如BPE)解决OOV(未登录词)问题,而 jieba 无法动态生成子词。
  • 多语言统一:大模型需处理混合语言文本(如中英混杂),jieba 仅支持中文。
  • 端到端训练:Tokenizer的分词方式与模型架构强相关(如BERT的WordPiece需与预训练一致)。

五、NLP 中的特殊标记

在自然语言处理(NLP)任务中,特殊标记(Special Tokens)用于处理文本输入和输出的特定需求。以下是常见的特殊标记及其作用:

5.1 特殊标记解释

  1. [CLS] (Classification Token)

    • 作用:用于分类任务的特殊标记。
    • 位置:通常添加到输入文本的开头。
    • 用途
      • 在 BERT 等模型中,[CLS] 标记的最终隐藏状态(即模型输出的对应向量)通常用作整个输入序列的聚合表示,用于分类任务(如情感分析、文本分类)。
      • 例如,在句子分类任务中,模型会根据 [CLS] 标记的向量输出分类结果。
  2. [SEP] (Separator Token)

    • 作用:用于分隔不同句子或文本段的特殊标记。
    • 位置
      • 在单句任务中,通常添加到句子末尾。
      • 在双句任务(如句子对分类、问答任务)中,用于分隔两个句子。
    • 用途
      • 帮助模型区分不同的句子或文本段。
      • 例如,在问答任务中,[SEP] 标记用于分隔问题和上下文。
  3. [MASK] (Mask Token)

    • 作用:用于掩码语言模型(Masked Language Model, MLM)任务。
    • 位置:替换输入文本中的某些词(通常随机选择)。
    • 用途
      • 在 BERT 等模型的预训练过程中,[MASK] 标记用于掩盖部分输入词,模型需要预测被掩盖的词。
      • 例如,输入 "I love [MASK] learning.",模型需要预测 [MASK] 位置的实际词(如 "deep")。
  4. [PAD] (Padding Token)

    • 作用:用于填充输入序列,使其达到固定长度。
    • 位置:添加到输入序列的末尾。
    • 用途
      • 在批处理(Batching)过程中,不同序列的长度可能不同,[PAD] 标记用于将短序列填充到相同长度。
      • 模型通常会忽略 [PAD] 标记的计算(通过注意力掩码实现)。
  5. [UNK] (Unknown Token)

    • 作用:用于表示词汇表中未包含的词(即未知词)。
    • 位置:替换输入文本中的未知词。
    • 用途
      • 当输入文本中的词不在模型的词汇表中时,模型会将其替换为 [UNK] 标记。
      • 例如,如果词汇表中没有 "ChatGPT",输入 "I use ChatGPT." 可能会被转换为 "I use [UNK]."

5.2 示例

以下是一个包含特殊标记的输入示例(以 BERT 为例):

[CLS] I love deep learning . [SEP] It is a fascinating field . [SEP] [PAD] [PAD]

六、大模型输入的核心组成部分

在自然语言处理(NLP)和大模型(如BERT、GPT等)中,input_idsattention_masktoken_type_ids 是模型输入的核心组成部分,用于将原始文本转换为模型可处理的数值化格式。以下是它们的详细解释和实际示例:

6.1 名词解释

  1. input_ids(文本的数值化表示)

    • 作用:将分词后的文本(Tokens)转换为模型词汇表中对应的整数ID。

    • 生成方式

      • 分词器(Tokenizer)先将文本拆分为词/子词(如"深度学习"["深", "度", "学", "习"])。
      • 然后查询词汇表,将每个Token映射为对应的ID(如"深"3918)。
    • 示例

      from transformers import AutoTokenizer
      tokenizer = AutoTokenizer.from_pretrained("bert-base-chinese")
      text = "深度学习很重要"
      inputs = tokenizer(text)
      print(inputs["input_ids"])  # 输出如:[101, 3918, 2428, 2110, 739, 2523, 7028, 6206, 102]
      
      • 101102 是BERT的[CLS][SEP]特殊标记的ID。
  2. attention_mask(注意力掩码)

    • 作用:标识哪些Token是有效输入,哪些是填充(Padding)部分。

      • 1:真实Token(模型需处理)。
      • 0:填充Token(模型忽略)。
    • 为什么需要:批量训练时,不同文本长度不同,需填充到相同长度。

    • 示例

      print(inputs["attention_mask"])  # 输出如:[1, 1, 1, 1, 1, 1, 1](无填充)
      

      如果填充到长度10:

      padded_inputs = tokenizer(text, padding="max_length", max_length=10)
      print(padded_inputs["attention_mask"])  # 输出如:[1, 1, 1, 1, 1, 1, 1, 0, 0, 0]
      
  3. token_type_ids(或 segment_ids,句子分段标识):

    • 作用:区分输入中的不同句子(如问答任务中的问题和上下文)。

      • 0:第一个句子。
      • 1:第二个句子。
    • 适用场景:BERT等模型处理句子对任务(如文本相似度、问答)。

    • 示例

      text_pair = ("深度学习是什么?", "它是AI的一个分支")
      inputs = tokenizer(*text_pair)
      print(inputs["token_type_ids"])  # 输出如:[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1]
      

6.2 输入示例

from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("bert-base-chinese")# 处理单句
single_text = "你好,世界!"
inputs = tokenizer(single_text, return_tensors="pt")
print("单句输入:")
print(f"input_ids: {inputs['input_ids']}") # 输出 input_ids: tensor([[ 101,  872, 1962, 8024,  686, 4518, 8013,  102]])
print(f"attention_mask: {inputs['attention_mask']}") # 输出 attention_mask: tensor([[1, 1, 1, 1, 1, 1, 1, 1]])
print(f"token_type_ids: {inputs['token_type_ids']}")  # 输出 token_type_ids: tensor([[0, 0, 0, 0, 0, 0, 0, 0]])# 处理句子对
text_pair = ("今天天气如何?", "今天下雨了。")
inputs_pair = tokenizer(*text_pair, return_tensors="pt")
print("\n句子对输入:")
print(f"input_ids: {inputs_pair['input_ids']}") # 输出 input_ids: tensor([[ 101,  791, 1921, 1921, 3698, 1963,  862, 8043,  102,  791, 1921,  678,7433,  749,  511,  102]])
print(f"attention_mask: {inputs_pair['attention_mask']}") # 输出 attention_mask: tensor([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]])
print(f"token_type_ids: {inputs_pair['token_type_ids']}")  # 输出 token_type_ids: tensor([[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1]])

6.3 关键总结

  • input_ids:文本的数字身份证,决定模型“看到”什么内容。
  • attention_mask:告诉模型“哪些部分需要关注”,优化计算效率。
  • token_type_ids:为模型标注“句子边界”,解决上下文依赖问题。

这些输入张量共同构成了大模型理解文本的基础,类似于人类阅读时需要的“文字+上下文+注意力焦点”。

http://www.xdnf.cn/news/4637.html

相关文章:

  • 排序算法——桶排序
  • 注意力机制(Attention)
  • 【关于ESP8266下载固件库的问题】
  • C++ 析构函数
  • 【Ollama】docker离线部署Ollama+deepseek
  • 从机器人到调度平台:超低延迟RTMP|RTSP播放器系统级部署之道
  • DeepSeek 入门:从注册到首轮对话全流程
  • Mysql如何完成数据的增删改查(详解从0到1)
  • 打造个人知识库,wsl+ollama部署deepseek与vscode集成
  • NetBox Docker 全功能部署方案(Ubuntu 22.04 + Docker)
  • k8s 中 deployment 管理的多个 pod 构成集群吗
  • PostgreSQL 查询历史最大进程数方法
  • 商汤科技前端面试题及参考答案
  • 服务器上机用到的设备
  • .net在DB First模式使用pgsql
  • K8s节点宕机自愈全流程解析
  • 【数据结构入门训练DAY-28】蓝桥杯算法提高VIP-产生数
  • 【前端基础】7、CSS的字体属性(font相关)
  • React Router Vs Vue Router
  • AGV智能搬运机器人:富唯智能引领工业物流高效变革
  • DeepSeek架构解析:从神经动力学视角解构万亿参数模型的认知涌现机制
  • 企业该如何选择合适的DDOS防护?
  • C++代码随想录刷题知识分享-----判断两个字符串是否为字母异位词(Anagram)【LeetCode 242】
  • 【论文阅读】Reconstructive Neuron Pruning for Backdoor Defense
  • C++类对象的隐式类型转换和编译器返回值优化
  • idea左侧项目资源管理器不见了处理
  • Python+深度学习:如何精准评估食品过敏风险?
  • 代码随想录Day20
  • Canal mysql to mysql 增加 online 库同步配置指南
  • MATLAB技巧——命令行输入的绘图,中文是正常的,到了脚本(m文件)里面就变成乱码的解决方法