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

《从零构建大语言模型》学习笔记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.dtcms.com/a/320591.html

相关文章:

  • 【lucene】PostingsEnum.freq()
  • CVRF 是什么?微软弃用 MS 编号后,网络安全的下一个标准
  • C/C++与JavaScript的WebAssembly协作开发指南
  • 电脑定时开关机终极指南
  • 2025小程序怎么快速接入美团核销,实现自动化核销
  • PeiQi网络安全知识文库PeiQi-WIKI-Book保姆式搭建部署教程
  • sqli-labs通关笔记-第38关 GET字符型堆叠注入(单引号闭合 手工注入+脚本注入两种方法)
  • 欧拉角、四元数与旋转矩阵的C语言转换实现
  • 《论文阅读》传统CoT方法和提出的CoT Prompting的区分
  • 手搓MCP全流程指南:从本地开发部署到PyPI公开发布
  • 自由学习记录(79)
  • 深入解析 Seaborn:数据可视化的优雅利器
  • 智慧社区(九)——事务加持下的小区删除操作
  • Azure OpenAI gpt5和AWS Secrets Manager构建智能对话系统
  • 智能云探索:基于Amazon Bedrock与MCP Server的AWS资源AI运维实践
  • AWS 云小白学习指南 (一)
  • 跟着尚硅谷学vue-day7
  • 【华为机试】55. 跳跃游戏
  • LeetCode有效三角形的个数
  • 借助Rclone快速从阿里云OSS迁移到AWS S3
  • 基于UDP的代理协议的Tuic怎么样?
  • 破解 Django N+1 查询困境:使用 select_related 与 prefetch_related 实践指南
  • 五十六、【Linux系统nginx服务】nginx虚拟主机实现
  • [linux] Linux:一条指令更新DDNS
  • GPT-OSS重磅开源:当OpenAI重拾“开放”初心
  • 面试题:bable,plugin,loader,还有在打包过程中.vue/.react文件是如何转化为.js文件的
  • linux mysql 8.X主从复制
  • 聚焦2025世界机器人大会:全尺寸人形交互陪伴机器人GR-3有哪些亮点值得关注?
  • React 原生部落的生存现状:观察“Hooks 猎人“如何用useEffect设陷阱反被依赖项追杀
  • vscode EIDE 无法编译,提示 “文件名、目录名或卷标语法不正确;