《从零构建大语言模型》学习笔记2,文本数据处理1(以及tiktoken库无法下载gpt2参数,调用get_encoding时SSL超时的解决方法)

《从零构建大语言模型》学习笔记2,文本数据处理1

文章目录

  • 《从零构建大语言模型》学习笔记2,文本数据处理1
    • 前言
    • 1、分词
    • 2.将把提取出来的词元转换为数字ID
    • 3.添加特殊上下文标记
    • 4. 字节对编码(以及tiktoken库无法下载gpt2参数,调用get_encoding时SSL超时的解决方法)


前言

本书原项目地址:https://github.com/rasbt/LLMs-from-scratch
接下来就开始学习代码了,在训练我们的LLM模型之前,我们先要准备好学习的文本数据,所以第一步是把文本转成计算机能运算的向量,这个过程也叫做embedding,如果有自己部署过开源大模型的小伙伴,就会知道除了要下载大预言模型,在这之前还有个embedding模型,我个人理解应该就是这个过程。其实就是建立一个把所有的文字或者词句映射成方便计算机运算的一些向量库。

这里就引用原作者的图片来介绍了

当然不止是文本数据有这个过程,音视频和图片文件都有这个过程。
当然embedding 需要收集庞大的数据来构造,我们自己收集是比较麻烦的,所以我们后面会用开源的gpt2来进行映射。
有了这个向量库之后,我们需要对我们自己的语料进行转换,把普通的文字根据向量库转成数字。所有第一步要把我们的语料进行分词,把一整句完整的句子拆分为单个的单词和符号。

1、分词

这一步前面的代码还是比较好理解的,原作者用来一本小说的所有文字举例来说明如何简单的对语料进行分词。关于代码我就贴一些关键代码进行解读。
下面我就贴代码了

with open("the-verdict.txt", "r", encoding="utf-8") as f:raw_text = f.read() ##读入文件按照utf-8
print("Total number of character:", len(raw_text))##先输出总长度
print(raw_text[:99])##输出前一百个内容
preprocessed = re.split(r'([,.:;?_!"()\']|--|\s)', raw_text) ##按照符号继续把原文件给分割了
preprocessed = [item.strip() for item in preprocessed if item.strip()]##去掉两端的空白字符 也是去掉了空字符串和仅包含空白字符的项
print(preprocessed[:30])

以上代码是为了把小说中的所有词语和标点符号拆分为一个列表,后续好进行处理和索引。主要用的正则表达式来进行拆分。


2.将把提取出来的词元转换为数字ID

上一步提取出来的词元列表,我们去重后编排一个数字ID列表,过程如下图:

代码如下:

all_words = sorted(set(preprocessed))#从去掉重复的字符
vocab_size = len(all_words)#计总的单词书print(vocab_size)
print(all_words[:50])vocab = {token:integer for integer,token in enumerate(all_words)}##先把word进行编号,再按照单词或者标点为索引(有HashList那味道了)class SimpleTokenizerV1:#一个实例的名字创立def __init__(self, vocab): ## 初始化一个字符串self.str_to_int = vocab #单词到整数的映射self.int_to_str = {i:s for s,i in vocab.items()} #方便解码,进行整数到词汇的反向映射def encode(self, text):preprocessed = re.split(r'([,.:;?_!"()\']|--|\s)', text)##正则化分词标点符号preprocessed = [item.strip() for item in preprocessed if item.strip()## 去掉两端空格与全部的空句]ids = [self.str_to_int[s] for s in preprocessed]##整理完的额字符串列表对应到id,从字典出来return idsdef decode(self, ids):text = " ".join([self.int_to_str[i] for i in ids]) #映射整数id到字符串。join是用前面那个(“ ”)联结成一个完整的字符串# Replace spaces before the specified punctuationstext = re.sub(r'\s+([,.?!"()\'])', r'\1', text) #使用正则表达式,去除标点符号前的多余空格# \s+匹配一个或者多个空白  \1 替换到匹配return texttokenizer = SimpleTokenizerV1(vocab) #用vocab创造一个实例
text = """"It's the last he painted, you know," Mrs. Gisburn said with pardonable pride."""
ids = tokenizer.encode(text) #按照这个例子里的encode函数处理text
print(ids)

all_words 是词元去重排序后的一个字典。然后定义了一个SimpleTokenizerV1类,这个类里面定义了两个函数,一个encode函数能把任意段话转为数字ID列表,decode函数能把数字ID列表解码为对应的文字段落。


3.添加特殊上下文标记

上面的SimpleTokenizerV1类还有些缺陷,就是all_words这个字典太小了,可能会有很多没有收录的词语,这时候就要对SimpleTokenizerV1类进行改进了,通过判断来添加"<|endoftext|>", “<|unk|>” 这两个标签,一个是段落结束标志,一个是没有对应词元时的标志。


代码如下:

class SimpleTokenizerV2:##版本2.0,启动!def __init__(self, vocab):self.str_to_int = vocabself.int_to_str = { i:s for s,i in vocab.items()}#s为单词,i是keydef encode(self, text):preprocessed = re.split(r'([,.:;?_!"()\']|--|\s)', text)#正则化按照标点分类preprocessed = [item.strip() for item in preprocessed if item.strip()]#去掉两头与所有空余句preprocessed = [item if item in self.str_to_int else "<|unk|>" for item in preprocessed#遍历 preprocessed 中的每个 item,如果 item 存在于 self.str_to_int(即词汇表)中,就保留 item#如果不存在(即该单词或符号未定义在词汇表中),就替换为特殊标记 <|unk|>。#拓展:推导式(如列表推导式)是一种紧凑的语法,专门用于生成新列表(或其他容器)#与普通 for 循环相比,它更加简洁和高效,但逻辑复杂时可能会降低可读性。]ids = [self.str_to_int[s] for s in preprocessed]#单词或标点映射为整数列表return idsdef decode(self, ids):text = " ".join([self.int_to_str[i] for i in ids])# Replace spaces before the specified punctuationstext = re.sub(r'\s+([,.:;?!"()\'])', r'\1', text)return texttokenizer = SimpleTokenizerV2(vocab)text1 = "Hello, do you like tea?"
text2 = "In the sunlit terraces of the palace."text = " <|endoftext|> ".join((text1, text2))#用句子分隔符链接两个句子print(text) #跟第一个一样,但不会报错了
tokenizer.decode(tokenizer.encode(text))

主要是编码的时候做了一次未知词元的判断

4. 字节对编码(以及tiktoken库无法下载gpt2参数,调用get_encoding时SSL超时的解决方法)

以上提到的分词方式是比较简单的,主要是方便大家理解。接下来使用一种基于字节对编码(BPE)概念的更复杂的分词方案。BPE分词器被用于训练诸如GPT-2、GPT-3以及ChatGPT最初使用的模型等大型语言模型。那具体怎么实现的我这里也不深究了,我们直接拿过来用就好,下面需要使用到tiktoken这个库。

import importlib
import tiktoken
print("tiktoken version:", importlib.metadata.version("tiktoken"))#验证下载并输出版本信息
tokenizer = tiktoken.get_encoding("gpt2")#初始化GPT2!

到这里需要注意一下,因为这里需要下载gpt2的参数,但是大部分人的网络应该下载不下来,根据错误提示可以手动下载vocab.bpe和encoder.json这两个文件,下载后在当前路径创建一个文件夹 .tiktoken,把文件放在这里面。然后还需要把缓存路径设置为该路径,同时手动修改vocab.bpe文件名为6d1cbeee0f20b3d9449abfede4726ed8212e3aee,修改encoder.json文件名为6c7ea1a7e38e3a7f062df639a5b80947f075ffe6。
vocab.bpe下载地址:https://openaipublic.blob.core.windows.net/gpt-2/encodings/main/vocab.bpe
encoder.json下载地址:https://openaipublic.blob.core.windows.net/gpt-2/encodings/main/encoder.json
修改后的代码如下:

import importlib
import tiktoken
print("tiktoken version:", importlib.metadata.version("tiktoken"))#验证下载并输出版本信息import hashlib
blobpath = "https://openaipublic.blob.core.windows.net/gpt-2/encodings/main/vocab.bpe"
vocab_key = hashlib.sha1(blobpath.encode()).hexdigest()
print(vocab_key)
blobpath = "https://openaipublic.blob.core.windows.net/gpt-2/encodings/main/encoder.json"
encoder_key = hashlib.sha1(blobpath.encode()).hexdigest()
print(encoder_key)import os
tiktoken_cache_dir = ".tiktoken"
os.environ["TIKTOKEN_CACHE_DIR"] = tiktoken_cache_dir
# validate
assert os.path.exists(os.path.join(tiktoken_cache_dir, vocab_key))
assert os.path.exists(os.path.join(tiktoken_cache_dir, encoder_key))tokenizer = tiktoken.get_encoding("gpt2")#初始化GPT2!

完整的解决思路可以参考下面两个链接:
how to use tiktoken in offline mode computer
SSLError: HTTPSConnectionPool(host=‘openaipublic.blob.core.windows.net’, port=443)

后面的代码就是使用gpt2的参数对本地语料进行加解码了。

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

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

相关文章

【AI工具】解放双手,操控浏览器的工具对比,来了

&#x1f4d2;前言在github上面&#xff0c;有几个操作浏览器的mcp工具&#xff1a;browser-use / browser-usemicrosoft / playwright-mcpAgentDeskAI / browser-tools-mcphangwin / mcp-chrome想知道他们的区别吗&#xff0c;想知道那个更适合你吗&#xff0c;想。。。&#…

Linux 操作系统基础知识总结

1、操作系统总体介绍 CPU&#xff1a; 就像人的大脑&#xff0c;主要负责相关事情的判断以及实际处理的机制。 查询指令&#xff1a; cat /proc/cpuinfo 内存&#xff1a; 大脑中的记忆区块&#xff0c;将皮肤、眼睛等所收集到的信息记录起来的地方&#xff0c;以供CPU进行判断…

cudagraph 本质详解

理解 CUDA Graph 的本质,关键在于理解它解决了什么问题,以及它通过什么机制来解决这个问题。 一、 核心问题:传统 CUDA 编程的“CPU 瓶颈” 在 CUDA Graph 出现之前,我们通常使用 CUDA Stream 来向 GPU 提交任务。这是一个动态的过程: CPU 作为指挥官:CPU 循环地、逐条…

Spring MVC 父子容器深度解析:原理、实战与优化

1. 父子容器的定义与设计初衷一句话总结&#xff1a;父子容器的核心价值在于解耦 Web 层与业务层&#xff0c;实现职责分离与上下文隔离。1.1 父子容器的层次关系在 Spring MVC 中&#xff0c;容器分为两类&#xff1a;父容器&#xff08;Root ApplicationContext&#xff09;&…

AI赋能SEO关键词优化策略

内容概要 人工智能&#xff08;AI&#xff09;技术正深刻改变着搜索引擎优化&#xff08;SEO&#xff09;的实践方式&#xff0c;尤其在关键词研究这一核心领域带来了革命性的影响。本文聚焦于AI如何赋能SEO关键词优化策略&#xff0c;系统性地探讨其核心价值与应用路径。我们将…

虚拟机Ubuntu图形化界面root用户登录错误

当在 Ubuntu 图形界面登录 root 用户出现错误无法进入时 1. 检查 PAM 配置文件 PAM&#xff08;Pluggable Authentication Modules&#xff0c;可插拔认证模块&#xff09;负责管理用户认证相关的策略。图形登录界面的 PAM 配置文件通常是 /etc/pam.d/gdm-password 。以管理员权…

【杂谈】-逆缩放悖论:为何更多思考会让AI变“笨“?

逆缩放悖论&#xff1a;为何更多思考会让AI变"笨"&#xff1f; 文章目录逆缩放悖论&#xff1a;为何更多思考会让AI变"笨"&#xff1f;1、解码逆缩放现象2、AI 推理失效的五大症结3、AI 推理应对复杂度的策略图谱4、人工智能评估体系的反思5、人工智能推理…

强制用户更改WordPress密码的重要性及实现方法

确保 WordPress 网站的安全性是每位网站管理者的重要任务。在网络安全日益受到关注的今天&#xff0c;为用户提供安全、稳定的网络环境至关重要。而一个有效的方法就是强制用户定期更改密码。这篇文章将介绍为什么要强制用户更改密码以及如何在 WordPress 中实现这一功能。同时…

计算机基础速通--数据结构·串的应用

如有问题大概率是我的理解比较片面&#xff0c;欢迎评论区或者私信指正。 友友们&#xff0c;我遇到了一个大问题&#xff0c;技术类的英文面&#xff08;ai应用开发/java后端偏金融方向&#xff09;该如何准备&#xff1f;本人英语就过了个六级&#xff0c;脑阔疼额。友友们有…

05--STL认识(了解)

1. STL概念——标准模板库 STL(standard template libaray-标准模板库)&#xff1a;是C标准库的重要组成部分&#xff0c;不仅是一个可复用的组件库&#xff0c;而且是一个包罗数据结构与算法的软件框架。 STL与CPP标准库的关系&#xff1a; 2. STL的版本 3. STL的组成 4. STL…

VBA经典应用69例应用9:ReDim语句的语法

《VBA经典应用69例》&#xff08;版权10178981&#xff09;&#xff0c;是我推出的第九套教程&#xff0c;教程是专门针对初级、中级学员在学习VBA过程中可能遇到的案例展开&#xff0c;这套教程案例众多&#xff0c;紧贴“实战”&#xff0c;并做“战术总结”&#xff0c;以便…

连锁店管理系统的库存跟踪功能:数字化转型下的零售运营核心

在连锁零售行业&#xff0c;库存管理的效率直接决定着运营成败。传统人工库存管理模式早已难以应对全渠道销售时代的复杂需求&#xff0c;而连锁店管理系统的库存跟踪功能&#xff0c;正成为解决库存难题、提升客户体验的关键武器。本文将深入解析施易德&#xff08;cegid&…

Nestjs框架: 接口安全与响应脱敏实践 --- 从拦截器到自定义序列化装饰器

接口安全问题&#xff1a;敏感数据脱敏的必要性 在用户注册成功后&#xff0c;若直接将用户数据&#xff08;如密码、ID 等&#xff09;返回给前端&#xff0c;存在严重的安全风险 为此&#xff0c;需要在接口响应前对数据进行脱敏处理 关键点&#xff1a; 敏感字段&#xff…

Python包与虚拟环境工具全景对比:从virtualenv到uv的演进

Python 的开发环境管理一直是综合性的工程问题。随着工具和规范的不断进化&#xff0c;我们看到了从 virtualenv / pip 开始&#xff0c;到 pipenv 和 poetry 的环境一体化&#xff0c;再到 uv 和 hatch 这样的一体化、高性能新生代工具。 本文将对比这些工具的特点、优势和选型…

期货和期权对冲后能盈利吗?

本文主要介绍期货和期权对冲后能盈利吗&#xff1f;期货和期权作为金融衍生品的两大核心工具&#xff0c;其组合对冲策略的盈利性取决于市场走势、策略设计、成本管控及风险对冲效果。对冲的本质是降低风险&#xff0c;但通过合理设计&#xff0c;部分策略可在对冲风险的同时创…

【其他分类】Showrunner AI版的Netflix 互动故事创作平台 进行动画生成与微调、角色场景创建

Showrunner是一个AI 驱动的角色场景动画。视觉风格较为统一&#xff0c;偏向 3D Q 版卡通风格&#xff0c;支持语音对白修改、镜头相机切换、动画角色和场景设置等功能。 论文原文中文翻译官方地址pdf版 、网页版pdf版https://www.showrunner.xyz/ 当前的2D 动画软件&#xff…

K8s 常见故障案例分析

#作者&#xff1a;程宏斌 文章目录一、节点故障&#xff08;一&#xff09;节点 NotReady 状态排查步骤解决方案二、Pod 故障&#xff08;一&#xff09;Pod 一直处于 Pending 状态排查步骤解决方案&#xff08;二&#xff09;Pod 频繁重启故障现象排查步骤解决方案三、控制器故…

半精度权重 及 Phi-3线性层的权重分布

半精度权重 我们可以使用张量的 to() 方法以及适当的类型 torch.float16,将权重转换为 FP16: torch.manual_seed(11) weights = torch.randn(1000) * .07 weights.min(),

Linux怎么安装Docker?环境怎么搭建?步骤是什么?如何配置?有哪些注意事项?出现问题怎么排除?

一、Docker简介与环境准备 1.1 什么是Docker Docker是一个开源的容器化平台&#xff0c;它使用Linux内核的cgroup&#xff0c;namespace以及OverlayFS类的UnionFS等技术&#xff0c;对进程进行封装隔离&#xff0c;属于操作系统层面的虚拟化技术。Docker能够自动执行重复性任务…

apiSQL网关调优:释放单节点的最大潜能

前言 在构建高性能、高可用的API服务时&#xff0c;apiSQL 提供了强大的集群部署模式&#xff0c;通过横向扩展来分散负载、提高吞吐量。然而&#xff0c;在某些场景下&#xff0c;我们同样需要关注并最大化单个节点的处理能力。当单个 apiSQL 网关节点需要处理高并发请求或承载…