当前位置:首页 > 文章列表 > 科技周边 > 人工智能 > Datasets流式读取与内存数据集的shuffle有什么区别

Datasets流式读取与内存数据集的shuffle有什么区别

来源:17golang原创 2026-10-13 20:39:08 0浏览 收藏

如果数据集能完整落到本地,Dataset.shuffle() 更接近全量随机排列;如果数据太大、只想边读边训练,streaming=True 得到的 IterableDataset 只能在分片和有限缓冲区内做近似打乱。两者都叫 shuffle,但访问模型、内存代价和随机范围并不相同。

官方地址:https://huggingface.co/docs/datasets/

先按“是否需要随机访问”选对象,再按“能接受多大的缓冲区”设置流式 shuffle。不要把流式数据的局部随机当成整个数据集的严格随机排列。

先看数据对象:能不能随机访问

普通 Dataset 是面向索引的对象,常见操作是 dataset[100] 或按列读取。它可以把数据组织成连续的 Arrow 存储,并在调用 shuffle 后维护一套行索引映射。索引映射带来随机访问能力,但读取不再天然保持连续,数据量很大时可能增加访问成本。

load_dataset(..., streaming=True) 返回的是 IterableDataset。它按迭代器消费数据,数据可以来自远端或本地文件分片,过滤、映射等处理通常在真正迭代时发生。它适合训练循环和快速抽样,却不适合通过下标直接定位第 N 条样本。

Dataset 与 IterableDataset 的索引访问和顺序迭代关系说明图
图1:对象关系说明图,重点看 Dataset 的索引访问与 IterableDataset 的顺序迭代边界。

内存数据集的 shuffle 是全量索引排列

对内存数据集调用 ds.shuffle(seed=42),可以理解为生成一套覆盖所有行的随机索引顺序。随机种子相同,输入数据和库行为保持一致时,得到的排列便于复现;但原始数据规模越大,重排索引和后续非连续读取的代价越明显。

from datasets import load_dataset

# 先加载成普通 Dataset,后续可以按下标访问。
dataset = load_dataset("cornell-movie-review-data/rotten_tomatoes", split="train")

# seed 固定排列,适合需要可复现的训练或离线切分。
shuffled = dataset.shuffle(seed=42)

# 这里是随机访问:可以直接取指定位置的样本。
sample = shuffled[100]
print(sample["label"], sample["text"][:40])

这种模式适合数据规模可控、需要多次随机访问、需要精确切分或希望对完整样本集合做离线处理的任务。若 shuffle 后读写变慢,通常不是“随机失效”,而是索引映射让底层读取失去了连续性。

流式数据集的 shuffle 是 shard 加 buffer 的近似随机

流式对象的 shuffle 不会先把全部样本收进内存。它会先调整数据分片的顺序,再填充一个由 buffer_size 控制的缓冲区;每次从缓冲区抽取样本,并用后续样本补位。因此,缓冲区越大,局部随机范围通常越宽,但启动等待和内存占用也会上升。

例如数据总量是一百万条而 buffer_size=10000,开始阶段只会在缓冲区覆盖的范围内抽样,之后随着新样本补入继续前进。它的目标是以较小内存维持吞吐,而不是构造一份全量随机索引表。

Dataset.shuffle 全量排列与 IterableDataset.shuffle 缓冲区抽样关系说明图
图2:随机范围说明图,区分全量索引排列、有限 buffer 抽样与每轮 epoch 的种子变化。
from datasets import load_dataset

# streaming 模式只在迭代时读取,避免先下载完整数据集。
streamed = load_dataset("HuggingFaceFW/fineweb", split="train", streaming=True)

# buffer_size 决定局部随机范围;seed 让分片和抽样顺序可复现。
shuffled = streamed.shuffle(seed=42, buffer_size=10_000)

# take 只取前几条用于观察,真实训练可以直接交给训练循环。
for row in shuffled.take(3):
    print(row["text"][:80])

训练时怎样选 buffer_size、seed 和 epoch

如果训练只需要持续消费样本,流式模式通常更合适。先给出一个能容纳的 buffer_size,再观察吞吐、启动延迟和样本混合程度:显存不是唯一约束,shuffle buffer 本身也会占用主机内存。

多轮训练时,可以在每轮开始调用 set_epoch()。官方文档把有效种子理解为初始 seed 加当前 epoch,这样每轮会重新打乱分片和缓冲区抽样顺序。

from datasets import load_dataset

# 分片数量有助于多 worker 或分布式读取时分配工作。
dataset = load_dataset("ethz/food101", split="train")
streamed = dataset.to_iterable_dataset(num_shards=64)
streamed = streamed.shuffle(seed=42, buffer_size=10_000)

for epoch in range(3):
    # 改变 epoch 后,流式 shuffle 使用新的有效种子。
    streamed.set_epoch(epoch)
    for row in streamed:
        # 这里放 tokenizer、batch 组装或模型训练逻辑。
        consume(row)
        break

还要注意调用顺序:如果已经用 take() 或 skip() 固定了分片顺序,后续再调用 shuffle 可能无法重新改变分片顺序。要切分流式数据,通常先 shuffle,再 take 或 skip。

一张表记住两种模式

比较项DatasetIterableDataset
读取方式索引访问,可随机定位顺序迭代,惰性读取
shuffle 核心全量行的索引排列分片顺序 + 有限 buffer 抽样
随机程度可接近完整数据集随机近似随机,受 buffer 大小影响
适合场景离线处理、精确切分、随机访问超大数据、远端数据、训练流水线

所以,“内存数据集还是流式数据集”不是 API 写法偏好,而是访问契约:需要第 N 条样本、完整重排和精确切分时选 Dataset;只需按批次向前消费、数据规模超出本地资源时选 IterableDataset,并把 buffer_size 当作随机性与资源之间的调节旋钮。

常见问题

流式 shuffle 能保证每个 epoch 都完全随机吗?

不能把它当成严格全量随机。它通过 shard 顺序和有限 buffer 提供近似随机;增大 buffer、设置固定 seed,并在每轮调用 set_epoch(),可以让训练顺序更充分且可复现。

为什么 shuffle 后 take 要放在后面?

take() 和 skip() 会固定部分分片顺序。若先切分再 shuffle,后续 shuffle 的可调整范围会受限,因此想抽取随机样本时应先 shuffle,再 take。

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
PEFT合并LoRA前怎样区分适配器与基础模型权重PEFT合并LoRA前怎样区分适配器与基础模型权重
上一篇
PEFT合并LoRA前怎样区分适配器与基础模型权重
Accelerate prepare为什么要同时接收模型与优化器
下一篇
Accelerate prepare为什么要同时接收模型与优化器
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • PubMedQA数据集详解:生物医学问答基准、功能与应用指南
    PubMedQA
    深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
    463次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    526次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    543次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    492次使用
  • MMBench详解:多模态大模型基准测试、功能特点与使用指南
    MMBench
    MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
    311次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议 和 隐私政策
返回登录
  • 重置密码