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

chapter2-处理文本数据

【README】

本文内容总结自《从零构建大模型》第二章,非常棒的一本书,墙裂推荐;

项目目录结构:


【1】在线使用BPE分词器

test0205_p29_bpe_tokenizer.py

from importlib.metadata import version
import tiktokenprint("tiktoken version=" , version("tiktoken"))print("\n\n=== 使用BPE分词器 ")
# 获取BPE分词器
bpeTokenizer = tiktoken.get_encoding("gpt2")
rawText = ("hello, do you like tea? <|endoftext|> in the sunlit terraces""of sumunknownPlace."
)tokenIds = bpeTokenizer.encode(rawText, allowed_special={"<|endoftext|>"})
print(tokenIds)


 

【打印效果】

=== 使用BPE分词器 
[31373, 11, 466, 345, 588, 8887, 30, 220, 50256, 287, 262, 4252, 18250, 8812, 2114, 1659, 2160, 34680, 27271, 13]

【2】离线使用bpe分词器

安装bpe分词器所需的词汇表文件与编码json文件;

【test0205_p29_diy_bpe_tokenizer.py】

import os
import tiktoken
from pathlib import Pathtiktoken_cache_dir = str(Path("..", "tiktoken", ".tiktoken"))
os.environ["TIKTOKEN_CACHE_DIR"] = tiktoken_cache_dirprint("\n\n=== 使用BPE分词器 ")
# 获取BPE分词器
bpeTokenizer = tiktoken.get_encoding("gpt2")
rawText = ("hello, do you like tea? <|endoftext|> in the sunlit terraces""of sumunknownPlace."
)tokenIds = bpeTokenizer.encode(rawText, allowed_special={"<|endoftext|>"})
print(tokenIds)# 把tokenId转为字符串 -- 解码
print("\n\n===把tokenId转为字符串 -- 解码")
decodeResult = bpeTokenizer.decode(tokenIds)
print(decodeResult)

解决tiktoken库调用get_encoding时SSL超时-CSDN博客


 


【3】使用滑动窗口进行数据采样

test0206_p31_slide_window_data_sample.py

import os
from pathlib import Pathimport tiktokenfrom src.utils import BusiIoUtilstiktoken_cache_dir = str(Path("..", "tiktoken", ".tiktoken"))
os.environ["TIKTOKEN_CACHE_DIR"] = tiktoken_cache_dirprint("\n\n=== 使用BPE分词器 ")
# 获取BPE分词器
bpeTokenizer = tiktoken.get_encoding("gpt2")# 读取verdict小说
print("\n\n=== 读取verdict小说,并用自定义分词器分词")
with open(Path(BusiIoUtils.get_root_dir(), "..", "file", "the-verdict.txt")) as f:raw_text = f.read()
encoded_text = bpeTokenizer.encode(raw_text)
print(len(encoded_text))# 截取前50个词元
encode_sample = encoded_text[50:]# 创建下一个单词预测任务的输入-目标对
context_size = 4  # 滑动窗口大小=4
x = encode_sample[:context_size]
y = encode_sample[1:context_size + 1]
print(f"x:{x}")
print(f"y:      {y}")# 处理多个预测任务
print("\n\n===处理多个预测任务,输出词元id")
for i in range(1, context_size + 1):context = encode_sample[:i]desired = encode_sample[i]print(context, "---->", desired)# 处理多个预测任务
print("\n\n===处理多个预测任务,输出词元id解码后的词元")
for i in range(1, context_size + 1):context = encode_sample[:i]desired = encode_sample[i]print(bpeTokenizer.decode(context), "---->", bpeTokenizer.decode([desired]))# 实现一个数据加载器
# 目标是: 返回两个张量, 一个包含大模型所见的文本输入的输入张量,另一个包含大模型需要预测的目标词元的目标张量
import torch

【打印效果】

=== 使用BPE分词器 === 读取verdict小说,并用自定义分词器分词
5145
x:[290, 4920, 2241, 287]
y:      [4920, 2241, 287, 257]===处理多个预测任务,输出词元id
[290] ----> 4920
[290, 4920] ----> 2241
[290, 4920, 2241] ----> 287
[290, 4920, 2241, 287] ----> 257===处理多个预测任务,输出词元id解码后的词元and ---->  establishedand established ---->  himselfand established himself ---->  inand established himself in ---->  a

【4】高效数据加载器

为实现高效数据加载器,引入PyTorch内置的Dataset类和DataLoader类;

在把词元token转为嵌入向量前,还需要实现一个高效的数据加载器 DataLoader。

这个数据加载器会遍历输入数据集,并将输入和目标以PyTorch张量的形式返回,这些PyTorch张量可以被视为多维数组。

具体来说,我们的目标是返回两个张量:一个是包含大语言模型所见的文本输入的输入张量,另一个是包含大语言模型需要预测的目标词元的目标张量


【4.1】定义数据集类GPTDatasetV1用于批处理输入和目标的数据集

【GPTDatasetV1.py】

import torch
from torch.utils.data import Dataset, DataLoaderclass GPTDatasetV1(Dataset):def __init__(self, txt, tokenizer, max_length, stride):self.input_ids = []self.target_ids = []# 对全部文本进行分词token_ids = tokenizer.encode(txt)# 使用滑动窗口把文本划分为长度为max_length的重叠序列for i in range(0, len(token_ids) - max_length, stride):input_chunk = token_ids[i:i + max_length]target_chunk = token_ids[i + 1: i + max_length + 1]self.input_ids.append(torch.tensor(input_chunk))self.target_ids.append(torch.tensor(target_chunk))# 返回数据集的总行数def __len__(self):return len(self.input_ids)# 返回数据集的指定行def __getitem__(self, idx):return self.input_ids[idx], self.target_ids[idx]

【5】用于批量生成输入-目标对的数据加载器

【test0206_p35_dataloader.py】

import os
from pathlib import Path
import tiktoken
from src.chapter02.GPTDatasetV1 import GPTDatasetV1 as Diy_GPTDatasetV1
from src.utils import BusiIoUtils
import torch
from torch.utils.data import Dataset, DataLoadertiktoken_cache_dir = str(Path("..", "tiktoken", ".tiktoken"))
os.environ["TIKTOKEN_CACHE_DIR"] = tiktoken_cache_dirprint("\n\n=== 使用BPE分词器 ")
# 获取BPE分词器
bpeTokenizer = tiktoken.get_encoding("gpt2")# 创建数据加载器
def create_data_loader(txt, batch_size=4, max_length=256, stride=128, shuffle=True, drop_last=True,num_workers=0):# 初始化分词器tokenizer = tiktoken.get_encoding("gpt2")# 创建数据集dataset = Diy_GPTDatasetV1(txt, tokenizer, max_length, stride)dataloader = DataLoader(dataset,batch_size=batch_size,shuffle=shuffle,# 如果drop_last为True,且批次大小小于指定的batch_size,则会删除最后一批,以防止在训练期间出现损失剧增drop_last=drop_last,# 用于预处理的cpu进程数num_workers=num_workers)return dataloader# 读取verdict小说
print("\n\n=== 读取verdict小说,并用自定义分词器分词")
with open(Path(BusiIoUtils.get_root_dir(), "..", "file", "the-verdict.txt")) as f:raw_text = f.read()print(raw_text[:10])data_loader = create_data_loader(raw_text, batch_size=1, max_length=4, stride=1, shuffle=False)
data_iter = iter(data_loader)
first_batch = next(data_iter)
print(first_batch)

【打印结果】

=== 使用BPE分词器 === 读取verdict小说,并用自定义分词器分词
I HAD alwa
[tensor([[  40,  367, 2885, 1464]]), tensor([[ 367, 2885, 1464, 1807]])]

【5.2】设置批次大小(超参数)等于8,查看效果

# 使用大于1的批次大小(批次大小是超参数,这里设置为8)
data_loader2 = create_data_loader_v1(raw_text, batch_size=8, max_length=4, stride=4, shuffle=False)
data_iter2 = iter(data_loader2)
inputs, targets = next(data_iter2)
print("inputs = \n", inputs)
print("targets = \n", targets)

【打印结果】

inputs = tensor([[   40,   367,  2885,  1464],[ 1807,  3619,   402,   271],[10899,  2138,   257,  7026],[15632,   438,  2016,   257],[  922,  5891,  1576,   438],[  568,   340,   373,   645],[ 1049,  5975,   284,   502],[  284,  3285,   326,    11]])
targets = tensor([[  367,  2885,  1464,  1807],[ 3619,   402,   271, 10899],[ 2138,   257,  7026, 15632],[  438,  2016,   257,   922],[ 5891,  1576,   438,   568],[  340,   373,   645,  1049],[ 5975,   284,   502,   284],[ 3285,   326,    11,   287]])

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

相关文章:

  • 使用dig查看dns递归查询过程
  • Python编程6——面向对象编程1
  • 在 WSL 中安装 JetBrains Toolbox:完整指南
  • Lua中table、模块、元表和元方法
  • VScode单双引号、分号格式
  • 基于ssm的商城系统(全套)
  • Metasploit工具使用详解(中)笔记
  • 生成式人工智能:R²AIN SUITE 助力零售业的效率革命
  • 贪心算法求解汽车加油问题
  • Typora中文直装版
  • VB.NET中Load事件问题解决方案
  • 工业手持PDA终端,有哪些作用?
  • Vue CLI创建vue项目,安装插件
  • Proguard代码混淆-springboot3
  • UART通信HAL库API
  • AI+行业全景图:医疗/教育/金融领域的应用现状
  • [C]基础16.数据在内存中的存储
  • 如何删除PC上除Windows10操作系统之外的所有内容
  • C++ 写单例的办法
  • 北京大学肖臻老师《区块链技术与应用》公开课:04-BTC-共识协议
  • Linux下基本指令的介绍
  • PINN是否需要对空间进行网格化
  • 挖o心得(4)
  • 【深度学习-pytorch篇】4. 正则化方法(Regularization Techniques)
  • 使用u盘重装银河麒麟操作系统
  • 【人工智能】微调革命:释放大模型的无限潜能
  • 【系统架构设计师】2025年上半年真题论文回忆版: 论软件测试方法及应用(包括解题思路和参考素材)
  • 社交类网站设计:经典feed流系统架构详细设计(小红书微博等)
  • window 显示驱动开发-处理 E_INVALIDARG 返回值
  • ArgoDB表类型及常用命令