BERT代码简单笔记

 参考视频:BERT代码(源码)从零解读【Pytorch-手把手教你从零实现一个BERT源码模型】_哔哩哔哩_bilibili


一、BertTokenizer

BertTokenizer 是基于 WordPiece 算法的 BERT 分词器,继承自 PreTrainedTokenizer。

继承的PretrainedTokenizer,具体操作的实现是在PretrainedTokenizer中的__call__执行。

1. 初始化 __init__

  • 加载词汇表文件
  • 创建 token 到 ID 的映射
  • 初始化基础分词器和 WordPiece 分词器
# 加载词汇表
self.vocab = load_vocab(vocab_file)
# 创建反向映射 (ID -> token)
self.ids_to_tokens = collections.OrderedDict([(ids, tok) for tok, ids in self.vocab.items()])# 初始化两个分词器
if do_basic_tokenize:self.basic_tokenizer = BasicTokenizer(...)  # 基础分词
self.wordpiece_tokenizer = WordpieceTokenizer(...)  # WordPiece分词

 

1.1 加载词汇

Vocabvocabulary(词汇表)的缩写,指的是模型能够理解和处理的所有词汇的集合。

有不同类型的vocab:

 

在BERT中,有几个特殊token:

special_tokens = {"[PAD]": "填充短序列","[UNK]": "未知词汇","[CLS]": "分类任务的开始符","[SEP]": "句子分隔符","[MASK]": "掩码语言模型的掩码符"
}
1.2 BasicTokenizer 基础分词

BasicTokenizer 负责将原始文本转换为基础的 token 序列。

主要参数:

def __init__(self,do_lower_case=True,        # 是否转换为小写never_split=None,          # 永不分割的词汇集合tokenize_chinese_chars=True, # 是否处理中文字符strip_accents=None,        # 是否去除重音符号do_split_on_punc=True,     # 是否在标点符号处分割
):

主要分词方法:

1. 清理文本:清除无效字符和空白字符

2. 处理中文字符(在字符周围添加空格)

3. unicode 标准化

Unicode 标准化有四种形式:NFC,NFKC,NFD,NFKD:

unicode_normalized_text = unicodedata.normalize("NFC", text)

NFC:规范分解后再组合,将字符分解后重新组合成最紧凑的形式;

NFD:规范分解,将组合字符分解为基础字符 + 组合标记;

NFKC:兼容性分解后再组合,更激进的标准化,会转换兼容性字符;

NFKD:兼容性分解,最彻底的分解形式。

4. 按空格分割成token

5. 对分割后的token做小写化和去重音

6. 再通过标点分割

def tokenize(self, text, never_split=None):# 处理流程:# 1. 清理文本text = self._clean_text(text)# 2. 处理中文字符(在字符周围添加空格)if self.tokenize_chinese_chars:text = self._tokenize_chinese_chars(text)# 3. Unicode 标准化unicode_normalized_text = unicodedata.normalize("NFC", text)# 4. 按空格分割orig_tokens = whitespace_tokenize(unicode_normalized_text)# 5. 处理每个 tokensplit_tokens = []for token in orig_tokens:if token not in never_split:# 小写化和去重音if self.do_lower_case:token = token.lower()if self.strip_accents is not False:token = self._run_strip_accents(token)elif self.strip_accents:token = self._run_strip_accents(token)# 6. 标点符号分割split_tokens.extend(self._run_split_on_punc(token, never_split))# 7. 最终清理output_tokens = whitespace_tokenize(" ".join(split_tokens))return output_tokens
 1.3 WordPiece子词分词

WordPiece 是一种子词分词算法,它将单词分解为更小的、有意义的片段,以解决:

  • 词汇表大小限制
  • 未登录词(OOV)问题
  • 词汇的组合性表示

主要参数:

def __init__(self, vocab, unk_token, max_input_chars_per_word=100):self.vocab = vocab                          # 词汇表(字典)self.unk_token = unk_token                  # 未知词标记,通常是 "[UNK]"self.max_input_chars_per_word = 100         # 单词最大字符数限制

核心算法:最长贪心匹配

def tokenize(self, text):output_tokens = []# 1. 按空格分割文本(假设已经过 BasicTokenizer 处理)for token in whitespace_tokenize(text):chars = list(token)# 2. 检查单词长度限制if len(chars) > self.max_input_chars_per_word:output_tokens.append(self.unk_token)continue# 3. 执行 WordPiece 分词is_bad = Falsestart = 0sub_tokens = []while start < len(chars):end = len(chars)cur_substr = None# 4. 贪心最长匹配while start < end:substr = "".join(chars[start:end])# 5. 非首个子词添加 "##" 前缀if start > 0:substr = "##" + substr# 6. 检查是否在词汇表中if substr in self.vocab:cur_substr = substrbreakend -= 1# 7. 如果没找到匹配,标记为失败if cur_substr is None:is_bad = Truebreaksub_tokens.append(cur_substr)start = end# 8. 根据结果添加到输出if is_bad:output_tokens.append(self.unk_token)else:output_tokens.extend(sub_tokens)return output_tokens

2. 核心分词方法 tokenize

分两种情况,第一种do_basic_tokenize: 先基础分词在wordpiece;第二种直接wordpiece。

3. Token与ID转换

def _convert_token_to_id(self, token):"""Token -> ID"""return self.vocab.get(token, self.vocab.get(self.unk_token))def _convert_id_to_token(self, index):"""ID -> Token"""return self.ids_to_tokens.get(index, self.unk_token)

 4. 特殊Token处理

def build_inputs_with_special_tokens(self, token_ids_0, token_ids_1=None):"""构建BERT输入格式"""if token_ids_1 is None:# 单句:[CLS] X [SEP]return [self.cls_token_id] + token_ids_0 + [self.sep_token_id]else:# 句对:[CLS] A [SEP] B [SEP]cls = [self.cls_token_id]sep = [self.sep_token_id]return cls + token_ids_0 + sep + token_ids_1 + sep

5. 特殊Token掩码

def get_special_tokens_mask(self, token_ids_0, token_ids_1=None, already_has_special_tokens=False):"""生成特殊token掩码:1表示特殊token,0表示普通token"""if token_ids_1 is not None:# 句对:[1] + [0]*len(A) + [1] + [0]*len(B) + [1]return [1] + ([0] * len(token_ids_0)) + [1] + ([0] * len(token_ids_1)) + [1]# 单句:[1] + [0]*len(X) + [1]return [1] + ([0] * len(token_ids_0)) + [1]

二、DataFrame

Parquet文件

是一种列式存储文件格式,专为大数据分析和处理设计。

 dfs 从数据集的单个文件读取内容;

df concat合并dfs读取到的两个文件内容;

三、Dataset

 

dataset.map()流程

 

set_format()

作用
指定数据集返回的数据格式为 PyTorch 张量(torch.Tensor),并筛选需要保留的列(如 input_idsattention_mask

关键参数

  • type:目标格式(支持 "torch""numpy""pandas" 等)。

  • columns:保留的字段列表(其他字段将被隐藏,但不会删除)。

  • output_all_columns:若为 True,即使未在 columns 中指定,也会保留所有字段(默认为 False)。

为什么要这一步:

(1) 适配 PyTorch 训练

  • PyTorch 的 DataLoader 和模型输入要求张量格式,直接使用 NumPy/列表会报错。

  • 自动转换省去手动调用 torch.tensor() 的麻烦。

(2) 减少内存占用

  • 隐藏不需要的字段(如未使用的 token_type_ids),避免数据加载时的冗余传输。

(3) 灵活性

  • 可随时切换格式(例如从 "torch" 改为 "numpy")或重置为默认状态:

# 重置为原始格式(Arrow)
tokenized_dataset.reset_format()

 DataCollatorForLanguageModeling

DataCollatorForLanguageModeling 是 HuggingFace Transformers 库中专门为语言模型(如 BERT)训练设计的数据整理器,主要用于 动态生成掩码语言模型(MLM)任务所需的输入

核心功能

(1) 动态掩码(Dynamic Masking)

mlm=True:启用掩码语言模型任务,随机遮盖输入 Token(如 BERT 的预训练方式)。

mlm_probability=0.15:每个 Token 有 15% 的概率被遮盖(原始 BERT 论文的设置)。

其中:

        80% 替换为 [MASK](如 "hello" → "[MASK]"

        10% 替换为随机 Token(如 "hello" → "apple"

        10% 保持原 Token(如 "hello" → "hello"

(2) 批量填充(Padding)

自动将一批样本填充到相同长度(根据 tokenizer.pad_token_id)。

生成 attention_mask 标记有效 Token。

(3) 标签生成(Labels)

自动生成与 input_ids 长度相同的 labels,其中:

被遮盖的 Token 位置:标注原始 Token ID(用于计算损失)。

未被遮盖的位置:标注为 -100(PyTorch 中忽略损失计算)。

 默认都是-100,在损失计算中设置忽略labels=-100的位置:

为什么需要DataCollatorForLanguageModeling

 关键参数:

def __init__(self,tokenizer,                # 必须传入的分词器实例mlm=True,                 # 是否启用MLM任务mlm_probability=0.15,     # 单Token被掩码的概率mask_replace_prob=0.8,    # 掩码Token替换为[MASK]的比例random_replace_prob=0.1,  # 掩码Token替换为随机词的比例pad_to_multiple_of=None,  # 填充长度对齐(如8的倍数优化GPU显存)return_tensors="pt",      # 输出格式(pt/tf/np)seed=None                 # 随机种子
):

 

训练

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/914150.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/914150.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PID控制算法理论学习基础——单级PID控制

这是一篇我在学习PID控制算法的过程中的学习记录。在一开始学习PID的时候&#xff0c;我也看了市面上许多的资料&#xff0c;好的资料固然有&#xff0c;但是更多的是不知所云。&#xff08;有的是写的太过深奥&#xff0c;有的则是照搬挪用&#xff0c;对原理则一问三不知&…

【Elasticsearch】function_score与rescore

它们俩都是用来“**干涉评分**”的&#xff0c;但**工作阶段不同、性能开销不同、能做的事也不同**。一句话总结&#xff1a;> **function_score** 在 **第一次算分** 时就动手脚&#xff1b; > **rescore** 在 **拿到 Top-N 结果后** 再“重新打分”。下面把“能干嘛”…

无广告纯净体验 WPS2016 精简版:移除联网模块 + 非核心组件,古董电脑也能跑

各位办公小能手们&#xff01;今天给你们介绍一款超神的办公软件——WPS2016精简版&#xff01;它有多小呢&#xff1f;才33MB&#xff0c;简直就是软件界的小不点儿&#xff01;别看它个头小&#xff0c;功能可一点儿都不含糊&#xff0c;文字、表格、演示这三大功能它全都有。…

《PyWin32:Python与Windows的桥梁,解锁系统自动化新姿势》

什么是 PyWin32在 Windows 平台的 Python 开发领域中&#xff0c;PyWin32 是一个举足轻重的库&#xff0c;它为 Python 开发者打开了一扇直接通往 Windows 操作系统底层功能的大门。简单来说&#xff0c;PyWin32 是用于 Python 访问 Windows API&#xff08;Application Progra…

vite如何生成gzip,并在服务器上如何设置开启

1. 安装插件npm install vite-plugin-compression -D2. 在 vite.config.ts 中配置TypeScriptimport { defineConfig } from vite import compression from vite-plugin-compressionexport default defineConfig({plugins: [compression({algorithm: gzip,ext: .gz,threshold: 1…

1068万预算!中国足协大模型项目招标,用AI技术驱动足球革命

中国足协启动国际足联“前进计划”下的大数据模型项目&#xff0c;预算1068万元。该项目将建立足球大数据分析平台&#xff0c;利用AI技术为国家队、青少年足球、业余球员及教练员裁判员提供精准数据分析服务&#xff0c;旨在通过科技手段提升中国足球竞技水平。 中国足球迎来数…

AI产品经理面试宝典第12天:AI产品经理的思维与转型路径面试题与答法

多样化思维:如何跳出单一框架解题? 面试官:AI产品常面临复杂场景,请举例说明你如何运用多样化思维解决问题? 你的回答:我会从三个维度展开:多角度拆解需求本质,多层级融合思维模式,多变量寻找最优解。比如设计儿童教育机器人时,不仅考虑功能实现(技术层),还融入情…

vscode.window对象讲解

一、vscode.window 核心架构图 #mermaid-svg-fyCxPz1vVhkf96nE {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-fyCxPz1vVhkf96nE .error-icon{fill:#552222;}#mermaid-svg-fyCxPz1vVhkf96nE .error-text{fill:#5522…

为什么一个 @Transactional 注解就能开启事务?揭秘 Spring AOP 的底层魔法

你是否也曾深陷在各种“额外”逻辑的泥潭&#xff0c;为了给一个核心业务方法增加日志、权限校验或缓存&#xff0c;而不得不将这些非核心代码硬塞进业务类中&#xff0c;导致代码臃肿、职责不清&#xff1f;是时候用代理设计模式 (Proxy Design Pattern) 来解脱了&#xff01;…

《Spring 中上下文传递的那些事儿》Part 8:构建统一上下文框架设计与实现(实战篇)

&#x1f4dd; Part 8&#xff1a;构建统一上下文框架设计与实现&#xff08;实战篇&#xff09; 在实际项目中&#xff0c;我们往往需要处理多种上下文来源&#xff0c;例如&#xff1a; Web 请求上下文&#xff08;RequestContextHolder&#xff09;日志追踪上下文&#xf…

配置驱动开发:初探零代码构建嵌入式软件配置工具

前言在嵌入式软件开发中&#xff0c;硬件初始化与寄存器配置长期依赖人工编写重复代码。以STM32外设初始化为例&#xff0c;开发者需手动完成时钟使能、引脚模式设置、参数配置等步骤&#xff0c;不仅耗时易错&#xff08;如位掩码写反、模式枚举值混淆&#xff09;&#xff0c…

Elasticsearch混合搜索深度解析(下):执行机制与完整流程

引言 在上篇中&#xff0c;我们发现了KNN结果通过SubSearch机制被保留的关键事实。本篇将继续深入分析混合搜索的执行机制&#xff0c;揭示完整的处理流程&#xff0c;并解答之前的所有疑惑。 深入源码分析 1. SubSearch的执行机制 1.1 KnnScoreDocQueryBuilder的实现 KNN结果被…

Apache HTTP Server 从安装到配置

一、Apache 是什么&#xff1f;Apache&#xff08;全称 Apache HTTP Server&#xff09;是当前最流行的开源Web服务器软件之一&#xff0c;由Apache软件基金会维护。它以稳定性高、模块化设计和灵活的配置著称&#xff0c;支持Linux、Windows等多平台&#xff0c;是搭建个人博客…

php中调用对象的方法可以使用array($object, ‘methodName‘)?

是的&#xff0c;在PHP中&#xff0c;array($object, methodName) 是一种标准的回调语法&#xff0c;用于表示“调用某个对象的特定方法”。这种语法可以被许多函数&#xff08;如 call_user_func()、call_user_func_array()、usort() 等&#xff09;识别并执行。 语法原理 在P…

【设计模式】单例模式 饿汉式单例与懒汉式单例

单例模式&#xff08;Singleton Pattern&#xff09;详解一、单例模式简介 单例模式&#xff08;Singleton Pattern&#xff09; 是一种 创建型设计模式&#xff0c;它确保一个类只有一个实例&#xff0c;并提供一个全局访问点来获取这个实例。&#xff08;对象创建型模式&…

vue3 el-table 行数据沾满格自动换行

在使用 Vue 3 结合 Element Plus 的 <el-table> 组件时&#xff0c;如果你希望当表格中的行数据文本过长时能够自动换行&#xff0c;而不是溢出到其他单元格或简单地截断&#xff0c;你可以通过以下几种方式来实现&#xff1a;方法 1&#xff1a;使用 CSS最简单的方法是通…

windows电脑远程win系统服务器上的wsl2

情况 我自己使用win11笔记本电脑&#xff0c;想要远程win11服务器上的wsl2 我这里只有服务器安装了wsl2&#xff0c;win11笔记本没有安装 因此下面提到的Ubuntu终端指的是win服务器上的wsl2终端 一定要区分是在哪里输入命令&#xff01;&#xff01; 安装SSH 在服务器上&#x…

神经辐射场 (NeRF):重构三维世界的AI新视角

神经辐射场 (NeRF)&#xff1a;重构三维世界的AI新视角 旧金山蜿蜒起伏的街道上&#xff0c;一辆装备12个摄像头的Waymo自动驾驶测试车缓缓驶过。它记录的280万张街景图像并未被简单地拼接成平面地图&#xff0c;而是被输入一个名为Block-NeRF的神经网络。数周后&#xff0c;一…

Kubernetes自动扩缩容方案对比与实践指南

Kubernetes自动扩缩容方案对比与实践指南 随着微服务架构和容器化的广泛采用&#xff0c;Kubernetes 自动扩缩容&#xff08;Autoscaling&#xff09;成为保障生产环境性能稳定与资源高效利用的关键技术。面对水平 Pod 扩缩容、垂直资源调整、集群节点扩缩容以及事件驱动扩缩容…

【CVPR2025】计算机视觉|SIREN: 元学习赋能!突破INR高分辨率图像分类难题

论文地址&#xff1a;https://arxiv.org/pdf/2503.18123v1 代码地址&#xff1a;https://github.com/SanderGielisse/MWT 关注UP CV缝合怪&#xff0c;分享最计算机视觉新即插即用模块&#xff0c;并提供配套的论文资料与代码。 https://space.bilibili.com/473764881 摘要 …