使用HuggingFace Datasets库高效处理大规模数据集

使用HuggingFace Datasets库高效处理大规模数据集

notebooks Notebooks using the Hugging Face libraries 🤗 notebooks 项目地址: https://gitcode.com/gh_mirrors/note/notebooks

引言:大数据处理的挑战

在自然语言处理(NLP)领域,研究人员和工程师经常需要处理海量文本数据。传统的数据加载方式往往需要将整个数据集一次性加载到内存中,这对于GB甚至TB级别的数据集来说几乎是不可能的任务。本文将介绍如何使用HuggingFace Datasets库来高效处理大规模数据集,而无需担心内存限制。

准备工作:安装必要库

在开始之前,我们需要安装一些必要的Python库:

pip install datasets evaluate transformers[sentencepiece]
pip install zstandard
pip install psutil

这些库包括:

  • datasets: HuggingFace提供的数据集处理库
  • transformers: HuggingFace的NLP模型库
  • zstandard: 用于处理压缩数据
  • psutil: 用于监控内存使用情况

加载大规模数据集

让我们从加载一个真实的医学文献数据集开始,这个数据集包含超过1500万篇PubMed文章的标题和摘要:

from datasets import load_dataset

data_files = "PUBMED_title_abstracts_2020_baseline.jsonl.zst"
pubmed_dataset = load_dataset("json", data_files=data_files, split="train")

查看数据集的基本信息:

pubmed_dataset

输出显示这个数据集包含15,518,009条记录,每条记录包含'meta'和'text'两个字段。我们可以查看第一条记录的内容:

pubmed_dataset[0]

内存使用分析

处理大数据时,内存管理至关重要。让我们看看加载这个数据集占用了多少内存:

import psutil

print(f"RAM used: {psutil.Process().memory_info().rss / (1024 * 1024):.2f} MB")

令人惊讶的是,尽管数据集原始大小约为19.5GB,但内存占用却远小于这个数字:

print(f"Number of files in dataset : {pubmed_dataset.dataset_size}")
size_gb = pubmed_dataset.dataset_size / (1024**3)
print(f"Dataset size (cache file) : {size_gb:.2f} GB")

这是因为Datasets库采用了智能的内存映射技术,不会一次性加载全部数据到内存中。

流式处理模式

对于真正的大规模数据集,我们可以使用流式处理模式(streaming mode),这种方式几乎不占用内存:

pubmed_dataset_streamed = load_dataset(
    "json", data_files=data_files, split="train", streaming=True
)

流式模式下,我们可以逐个访问数据样本:

next(iter(pubmed_dataset_streamed))

数据处理管道

在流式模式下,我们可以构建高效的数据处理管道:

  1. 分词处理:使用预训练的分词器处理文本
from transformers import AutoTokenizer

tokenizer = AutoTokenizer.from_pretrained("distilbert-base-uncased")
tokenized_dataset = pubmed_dataset_streamed.map(lambda x: tokenizer(x["text"]))
next(iter(tokenized_dataset))
  1. 数据洗牌:虽然数据是流式的,我们仍然可以进行洗牌操作
shuffled_dataset = pubmed_dataset_streamed.shuffle(buffer_size=10_000, seed=42)
next(iter(shuffled_dataset))
  1. 数据分割:获取数据集的前N个样本或跳过前N个样本
dataset_head = pubmed_dataset_streamed.take(5)
list(dataset_head)

# 创建训练集和验证集
train_dataset = shuffled_dataset.skip(1000)
validation_dataset = shuffled_dataset.take(1000)

多数据集混合处理

Datasets库还支持混合多个流式数据集:

law_dataset_streamed = load_dataset(
    "json",
    data_files="FreeLaw_Opinions.jsonl.zst",
    split="train",
    streaming=True,
)

from itertools import islice
from datasets import interleave_datasets

combined_dataset = interleave_datasets([pubmed_dataset_streamed, law_dataset_streamed])
list(islice(combined_dataset, 2))

处理更复杂的数据集结构

对于具有训练集、验证集和测试集分割的大型数据集,我们可以这样加载:

base_url = "https://the-eye.eu/public/AI/pile/"
data_files = {
    "train": [base_url + "train/" + f"{idx:02d}.jsonl.zst" for idx in range(30)],
    "validation": base_url + "val.jsonl.zst",
    "test": base_url + "test.jsonl.zst",
}
pile_dataset = load_dataset("json", data_files=data_files, streaming=True)
next(iter(pile_dataset["train"]))

性能优化技巧

  1. 批量处理:通过批量处理数据可以提高处理速度
import timeit

code_snippet = \"\"\"batch_size = 1000

for idx in range(0, len(pubmed_dataset), batch_size):
    _ = pubmed_dataset[idx:idx + batch_size]
\"\"\"

time = timeit.timeit(stmt=code_snippet, number=1, globals=globals())
print(
    f"Iterated over {len(pubmed_dataset)} examples (about {size_gb:.1f} GB) in "
    f"{time:.1f}s, i.e. {size_gb/time:.3f} GB/s"
)
  1. 合理设置缓冲区大小:在洗牌操作中,缓冲区大小会影响内存使用和随机性质量

实际应用建议

  1. 数据预处理:在流式模式下,所有数据预处理操作都应设计为逐样本或小批量进行
  2. 内存监控:在处理数据时持续监控内存使用情况
  3. 错误处理:为数据流管道添加适当的错误处理机制
  4. 缓存策略:合理利用Datasets库的缓存机制加速重复实验

总结

HuggingFace Datasets库提供了强大的工具来处理大规模数据集,特别是其流式处理功能使我们能够在有限的内存资源下处理GB甚至TB级别的数据。通过本文介绍的技术,研究人员和工程师可以更高效地开展大规模NLP实验和模型训练,而无需担心硬件限制。

关键要点:

  • 使用streaming=True参数启用流式处理模式
  • 利用map()shuffle()等方法构建数据处理管道
  • 通过take()skip()实现数据集分割
  • 使用interleave_datasets()混合多个数据集
  • 始终监控内存使用情况以确保高效处理

notebooks Notebooks using the Hugging Face libraries 🤗 notebooks 项目地址: https://gitcode.com/gh_mirrors/note/notebooks

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

幸愉旎Jasper

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值