登录
推荐 文章 Go 技术 课程 下载 专题 AI
首页 >  科技周边 >  人工智能

Datasets streaming 怎样流式读取大数据集

来源:17golang原创

时间:2026-10-25 12:07:41 313浏览 收藏

Hugging Face Datasets 读取大数据集时,在 load_dataset 中传入 streaming=True,再用 for 或 take 消费返回的 IterableDataset。这样无需先把整个数据集转换并加载成可随机访问的表;但后续若调用 list(stream) 收集全部样本,仍然可能耗尽内存。

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

先把读取任务拆成加载与消费

“先看几条是否可用”和“把全部文本交给训练任务”应使用不同的消费上限。前者限定预览数量、截断长文本并显示空结果;后者逐条处理,避免在应用层保留完整历史。流式对象提供迭代能力,不代表数据已经全部读取成功。

本文用自己准备的 JSONL 分片说明,文件放在 data 目录,命名如 articles-part-a.jsonl,每行是一个带 text 字符串字段的独立对象。代码为未执行的教学示例,未给出虚构下载速度、内存曲线或运行输出。远端数据集也可采用同样的 streaming 参数,但仓库名称、配置、split 和访问授权须按其数据集卡填写。

用 JSONL 文件建立流式读取组件

下面把文件选择、流对象和预览函数分开。load_dataset 的 json 构建器接收 data_files,train 表示本例的分片名;split="train" 取出单个可迭代对象。创建成功后,真正的文件内容与字段问题仍可能在迭代阶段暴露,因此异常处理要包住消费部分。

from datasets import load_dataset

# 使用你自己的 JSONL 分片;每行一个对象,并含有 text 字段
source_files = {"train": "data/articles-*.jsonl"}
stream = load_dataset(
    "json",
    data_files=source_files,
    split="train",
    streaming=True,  # 创建可迭代数据集,读取发生在消费样本时
)


def preview_text(dataset, limit=5):
    # 只保留受限预览,不将整个流转成列表
    rows = []
    for row in dataset.take(limit):
        text = row.get("text")
        if not isinstance(text, str):
            raise ValueError("样本的 text 字段必须是字符串")
        rows.append(text[:120].replace("\n", " "))
    return rows


try:
    preview = preview_text(stream)
    if not preview:
        print("没有可预览的记录")
    for position, snippet in enumerate(preview, start=1):
        # 序号与文本共同输出,便于识别记录,不只依靠颜色状态
        print(f"记录 {position}: {snippet}")
except Exception as exc:
    # 入口示例统一报告失败;批处理服务应记录异常类型并交给调用方处理
    raise RuntimeError("读取预览失败,请检查文件、格式与字段") from exc
流式读取结构图:JSONL分片、加载配置与IterableDataset的静态依赖
图1:静态结构图。左侧是源文件,中间是加载配置,右侧是可迭代对象;连线表示依赖,不代表运行顺序或真实结果。

图中的 JSONL分片、data_files、split、streaming=True、load_dataset 与 IterableDataset 分属源文件、加载配置、迭代对象三个边界。data_files 指定文件,split 选择分片,streaming=True 选择读取模式,load_dataset 据此创建 IterableDataset。

只预览少量样本并给出明确状态

preview_text 限定最多读取5条,并把每条预览截成120个字符。这个小列表保存的是展示内容,而不是把全部数据留在内存中。若只想持续处理记录,可以直接在 for 循环里调用业务函数,处理完当前记录就交给下一条。

给数据预览工具接界面时,应区分“尚未读取”“读取中”“没有记录”和“读取失败”。错误提示要保留可定位的字段或文件信息,同时避免把令牌写入页面。状态应有可读文字,样本应有记录序号,不让读者仅凭红绿颜色判断成败;长文本截断后也应说明截断发生在展示层。

take(5) 是有界查看,不等于随机抽样。原始文件前几条可能来自同一个来源,因此不能仅凭这个预览断言整个数据集的分布、质量或类别比例符合训练要求。

用缓冲区控制打乱与内存开销

需要让预览不总是从文件开头取样时,可以先 shuffle 再 take。流式 shuffle 使用有限缓冲区,buffer_size 的单位是样本数量,并非字节。下面的512只是教学起点,不是适用于所有机器的推荐值。

# stream 来自上一个例子;先打乱,再限定预览条数
mixed = stream.shuffle(seed=73, buffer_size=512)
for row in mixed.take(8):
    # 逐条使用,避免 list(mixed) 累积全部记录
    text = row.get("text", "")
    if not isinstance(text, str):
        continue  # 此处明确跳过异常字段;实际业务可改为记录或报错
    print(text[:80])
消费预算结构图:shuffle缓冲区、take上限与预览文本的关系
图2:静态结构图。区分样本缓冲预算与展示预算;没有表示实测内存占用或全局随机性。

IterableDataset、shuffle、buffer_size、seed、take 与预览文本组成图中的六个节点。IterableDataset 是 shuffle 的来源,buffer_size 配置缓冲容量,seed 配置随机种子,take 约束预览条数,预览文本绑定有限的展示结果。这些限制控制不同层面的资源,不能互相替代。

缓冲区越大,可能保留的样本越多;单条文本的体积、解码后的对象和下游批大小也会影响内存。固定 seed 便于在相同输入与设置下复查抽样,不能让变化的远端数据自动保持一致。有限缓冲打乱也不等于对全体记录进行完整随机排列。

空数据、坏字段和随机访问怎样处理

现象或需求原因或限制处理方式
创建对象后读取才报错内容读取是惰性的在实际迭代处处理异常
内存仍持续增长应用可能累积样本或缓冲过大检查列表、缓存和批大小
text字段不是字符串输入与消费函数约定不一致选择报错、转换或跳过并记录
想直接取第百万条IterableDataset不适合按行随机访问评估普通Dataset及索引需求

streaming=True 是否完全不下载任何内容?不是。远端迭代仍需传输数据、读取元数据或进行预读;它主要避免先完成整个数据文件的下载与表转换,不能承诺零网络、零缓存或固定内存。

本地流式文件需要联网吗?本例的数据来自自己的本地 JSONL 文件,源文件本身不需要从 Hub 获取。安装依赖、远端数据源和认证是另外的事项,不能从“使用本地路径”推导所有环境都绝对离线。

可以把大 JSON 数组直接当 JSONL 吗?不可以。JSONL 是逐行独立对象。格式与压缩方式会影响流式支持,有些 JSON 文件可能需要整体读取;选择格式时要查构建器说明,而不是只改文件扩展名。

开始接训练前,先让有限预览明确显示可读字段,再逐步接入消费函数与错误记录。保留清晰的记录上限和缓冲预算,才能避免在展示或处理层重新把大数据集全部攒进内存。

流式使用文档:https://huggingface.co/docs/datasets/stream

对象差异文档:https://huggingface.co/docs/datasets/about_mapstyle_vs_iterable

加载参数文档:https://huggingface.co/docs/datasets/package_reference/loading_methods

声明:本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>