Huggingface数据集采样之后得到的arrow文件无法用Dataset.load_from_disk加载解决方法

问题起源

我现在有数据集

在这里插入图片描述

我想要采样1/10构成一个新的数据集。起初我只是简单的使用save_to_disk保存,如下代码:

from datasets import Dataset
import os# 原数据集路径
source_dataset_path = "~/.cache/huggingface/datasets/allenai___tulu-3-sft-mixture-1024-test/train"
# 新数据集保存路径
output_dataset_path = "~/.cache/huggingface/datasets/allenai___tulu-3-sft-mixture-1024-73k/train"# 加载原数据集
dataset = Dataset.load_from_disk(source_dataset_path)# 设置随机种子,确保每次运行结果相同
seed = 123
dataset = dataset.shuffle(seed=seed)# 随机采样1/10的数据
sampled_dataset = dataset.select(range(len(dataset)//10))# 输出采样后的数据集大小
print(f"采样后的数据集包含 {len(sampled_dataset)} 条数据")# 保存采样后的数据集到新目录
sampled_dataset.save_to_disk(output_dataset_path)print(f"数据集已保存到: {output_dataset_path}") 

但是后面使用的时候遇到问题,当执行下面的代码,load_from_disk会报错:

from datasets import load_dataset, load_from_disk# 加载数据集
input_dir="~/.cache/huggingface/datasets/allenai___tulu-3-sft-mixture-1024-73k"
dataset = load_from_disk(input_dir)# 指定保存路径
output_dir = "xxxx/data/tulu-3-sft-mixture-seqlen-1024-json-73k"# 将数据集转换为 JSON 格式
for split in dataset.keys():  # 处理所有划分 (train, validation 等)dataset[split].to_json(f"{output_dir}/{split}.json", orient="records", lines=True)

报错如下:我里面有.arrow文件,却显示neither a Dataset directory nor a DatasetDict directory.

(base)@test:~$ python arrow2json.py 
Traceback (most recent call last):
lib/python3.10/site-packages/datasets/load.py", line 2218, in load_from_diskraise FileNotFoundError(
FileNotFoundError: Directory ~/.cache/huggingface/datasets/allenai___tulu-3-sft-mixture-1024-73k is neither a Dataset directory nor a DatasetDict directory.

提问GPT4o:

它是通过什么来判断不是Dataset directory nor a DatasetDict directory的,是通过~/.cache/huggingface/datasets/allenai___tulu-3-sft-mixture-1024-73k/dataset_dict.json这个嘛

是的,Hugging Face 的 datasets 库会通过检查目录中的特定文件来确定一个目录是否是一个有效的 DatasetDatasetDict 目录。主要通过以下几个文件来进行判断:

  1. dataset_dict.json:这个文件是用于 DatasetDict 类型的数据集。DatasetDict 是一个包含多个数据集分割(如 trainvalidation 等)的字典。如果这个文件存在,Hugging Face 会认为该目录是一个 DatasetDict

  2. dataset_info.json:这个文件存储了数据集的元数据,包括数据集的特征、版本信息等。如果这个文件存在,Hugging Face 会根据它来加载数据集的结构。

  3. state.json 指定arrow文件和split切分等。

这是上面截图中的state.json文件内容:看一下它的具体内容

{"_data_files": [{"filename": "data-00000-of-00005.arrow"},{"filename": "data-00001-of-00005.arrow"},{"filename": "data-00002-of-00005.arrow"},{"filename": "data-00003-of-00005.arrow"},{"filename": "data-00004-of-00005.arrow"}],"_fingerprint": "3f23ea1c8451dc7f","_format_columns": null,"_format_kwargs": {},"_format_type": null,"_output_all_columns": false,"_split": "train"
}

GPT4o继续回答:
错误原因:报错提示 FileNotFoundError: Directory ~/.cache/huggingface/datasets/allenai___tulu-3-sft-mixture-1024-73k is neither a Dataset directory nor a DatasetDict directory,这意味着该目录下缺少 dataset_dict.json 或其他标识该目录为有效 Hugging Face 数据集目录的文件。

继续debug:

sampled_dataset.save_to_disk(output_dataset_path)
为什么保存的文件中没有dataset_info.json等信息,如何做才能有

GPT4o的回答:

Dataset.save_to_disk() 方法仅会保存数据集的实际内容(即数据文件),但它不会自动保存 dataset_info.jsonstate.json 等元数据文件。为了确保在保存采样后的数据集时包括这些元数据,你需要手动创建并保存 dataset_info.jsonstate.json 文件。以下是如何做到这一点。

解决方案:手动生成并保存 dataset_info.jsonstate.json 文件

在你保存采样后的数据集时,你需要确保保存相关的元数据文件。你可以通过以下步骤:

  1. 创建 dataset_info.json 文件:这可以通过复制原始数据集的元数据并修改其中的一些信息(例如样本数和文件大小)来完成。
  2. 保存 state.json 文件:需要模仿样本的格式来完成。

你可以通过以下方式修改你的代码来保存这些元数据文件:(这里笔者和GPT反复对线,个中过程只有经历过的人才懂)

重新采样和保存 dataset_info.jsonstate.json的核心代码
import os
import json
from datasets import Dataset, DatasetInfo
from pathlib import Path# 原数据集路径
source_dataset_path = "~/.cache/huggingface/datasets/allenai___tulu-3-sft-mixture-1024/train"
# 新数据集保存路径
output_dataset_path = "~/.cache/huggingface/datasets/allenai___tulu-3-sft-mixture-1024-73k/train"# 加载原数据集
dataset = Dataset.load_from_disk(source_dataset_path)# 设置随机种子,确保每次运行结果相同
seed = 123
dataset = dataset.shuffle(seed=seed)# 随机采样1/10的数据
sampled_dataset = dataset.select(range(len(dataset)//10))# 输出采样后的数据集大小
print(f"采样后的数据集包含 {len(sampled_dataset)} 条数据")# 保存采样后的数据集到新目录
sampled_dataset.save_to_disk(output_dataset_path)# 获取原始数据集的信息
original_dataset_info = DatasetInfo.from_directory(source_dataset_path)# 创建dataset_info.json
dataset_info = {"builder_name": original_dataset_info.builder_name,"config_name": original_dataset_info.config_name,"dataset_name": original_dataset_info.dataset_name,"dataset_size": original_dataset_info.dataset_size,"description": original_dataset_info.description,"features": original_dataset_info.features.to_dict(),"size_in_bytes": os.path.getsize(output_dataset_path),"splits": {"train": {"name": "train","num_bytes": os.path.getsize(output_dataset_path),"num_examples": len(sampled_dataset),"shard_lengths": [len(sampled_dataset)],"dataset_name": original_dataset_info.dataset_name}},"version": {"version_str": f"{original_dataset_info.version.major}.{original_dataset_info.version.minor}.{original_dataset_info.version.patch}","major": original_dataset_info.version.major,"minor": original_dataset_info.version.minor,"patch": original_dataset_info.version.patch}
}# 保存dataset_info.json
dataset_info_path = os.path.join(output_dataset_path, "dataset_info.json")
with open(dataset_info_path, "w") as f:json.dump(dataset_info, f, indent=4)
print(f"dataset_info.json 已保存至: {dataset_info_path}")# 创建state.json文件
state_json = {"_data_files": [{"filename": os.path.basename(file)}for file in sorted(Path(output_dataset_path).glob("*.arrow"))],"_fingerprint": sampled_dataset._fingerprint,"_format_columns": None,"_format_kwargs": {},"_format_type": None,"_output_all_columns": False,"_split": "train"
}# 保存state.json
state_json_path = os.path.join(output_dataset_path, "state.json")
with open(state_json_path, "w") as f:json.dump(state_json, f, indent=4)
print(f"state.json 已保存至: {state_json_path}")
代码说明
  1. 加载原始数据集:首先,加载原始数据集并执行数据采样。

  2. 保存采样后的数据集:保存采样后的数据集内容到 output_dataset_path

  3. 获取原始数据集的元信息:使用 DatasetInfo.from_directory() 方法获取原始数据集的元信息。通过这个信息,你可以得到原始数据集的结构、特征、分割等。

  4. 创建并保存 dataset_info.json

    • 创建 dataset_info.json 文件并填写相关信息。
    • 其中包括数据集的 features(字段结构)、splits(分割信息)、dataset_size(文件大小)等信息。
  5. 创建并保存 state.json

    • 创建 state.json 文件并包含必要信息。
  6. 保存文件:将 dataset_info.jsonstate.json 文件保存到新数据集目录中。

重要注意事项
  • features:这部分来自原始数据集的 DatasetInfo 对象,保留了字段和类型的信息。
  • splits:你需要手动为采样后的数据集定义分割信息。采样了训练集,splits 部分需要包括 train 分割。
  • size_in_bytesnum_bytes:这些值应基于采样后的数据集大小和文件大小进行更新。

通过这些操作,你就能确保采样后的数据集包括了 dataset_info.jsonstate.json 文件,从而能够正常加载和使用。

创建state.json文件的代码解释
# 创建state.json文件
state_json = {"_data_files": [{"filename": os.path.basename(file)}for file in sorted(Path(output_dataset_path).glob("*.arrow"))],"_fingerprint": sampled_dataset._fingerprint,"_format_columns": None,"_format_kwargs": {},"_format_type": None,"_output_all_columns": False,"_split": "train"
}# 保存state.json
state_json_path = os.path.join(output_dataset_path, "state.json")
with open(state_json_path, "w") as f:json.dump(state_json, f, indent=4)
print(f"state.json 已保存至: {state_json_path}")
说明
  1. _data_files 字段

    • 使用 Path(output_dataset_path).glob("*.arrow") 遍历目标目录下的所有 .arrow 文件,并将其文件名作为 filename 的值填入。
    • 文件名需要用 os.path.basename(file) 获取,因为文件路径不应该包含绝对路径。
  2. _fingerprint 字段

    • 使用 sampled_dataset._fingerprint 获取数据集的唯一指纹值,确保其与实际数据内容匹配。
  3. _format_columns_format_kwargs_format_type 字段

    • 设置为 None,与 Hugging Face 数据集的默认值保持一致。
  4. _split 字段

    • 设置为 "train",因为你的数据集是训练集。
  5. 排序

    • 使用 sorted() 确保文件按照文件名顺序排列,避免 _data_files 顺序不一致。

运行上面的代码,可以得到想要的两个文件

state.json如下:

{"_data_files": [{"filename": "data-00000-of-00001.arrow"}],"_fingerprint": "fda1608541b4fb67","_format_columns": null,"_format_kwargs": {},"_format_type": null,"_output_all_columns": false,"_split": "train"
}

dataset_info.json如下:

{"builder_name": "arrow","config_name": "default","dataset_name": "55e9fd6d41c3cd1a98270dff07557bc2a1e1ba91","dataset_size": 2914253735,"description": "","features": {"id": {"dtype": "string","_type": "Value"},"messages": [{"content": {"dtype": "string","_type": "Value"},"role": {"dtype": "string","_type": "Value"}}],"source": {"dtype": "string","_type": "Value"}},"size_in_bytes": 4096,"splits": {"train": {"name": "train","num_bytes": 4096,"num_examples": 73752,"shard_lengths": [73752],"dataset_name": "55e9fd6d41c3cd1a98270dff07557bc2a1e1ba91"}},"version": {"version_str": "0.0.0","major": 0,"minor": 0,"patch": 0}
}

万事俱备,只欠东风

还需要如下图所示的dataset_dict.json文件,这个比较简单

在这里插入图片描述
对于我的情况,直接复制过来就行
dataset_dict.json内容如下:

{"splits": ["train"]}

重新load_from_disk正常运行

from datasets import load_dataset, load_from_disk# 加载数据集
input_dir="~/.cache/huggingface/datasets/allenai___tulu-3-sft-mixture-1024-73k"
dataset = load_from_disk(input_dir)# 指定保存路径
output_dir = "xxxx/data/tulu-3-sft-mixture-seqlen-1024-json-73k"# 将数据集转换为 JSON 格式
for split in dataset.keys():  # 处理所有划分 (train, validation 等)dataset[split].to_json(f"{output_dir}/{split}.json", orient="records", lines=True)

生成的结果如下:
在这里插入图片描述

成功解决数据集采样之后只得到.arrow文件,但是无法load_from_disk的问题。

后记

2024年12月29日22点08分于上海, 在GPT4o大模型辅助下完成。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/497450.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【畅购商城】购物车模块之查看购物车

目录 分析 接口 后端实现 前端实现:显示页面 前端实现:显示购物车信息 分析 用户如果没有登录,购物车存放在浏览器端的localStorage处,且以数组的方式进行存储。用户如果登录了,购物车存放在redis中&#xff0c…

html+css+js网页设计 美食 逛吃网7个页面

htmlcssjs网页设计 美食 逛吃网7个页面 网页作品代码简单,可使用任意HTML辑软件(如:Dreamweaver、HBuilder、Vscode 、Sublime 、Webstorm、Text 、Notepad 等任意html编辑软件进行运行及修改编辑等操作)。 该网站是美食菜谱社区…

记录C#知识点(三)41-60

目录 41.winform启动wpf程序 42.winform调用wpf 43.nuget安装包问题 41.winform启动wpf程序 winform启动wpf程序的时候 以下方式会导致winform界面有问题 WpfApp1.App.Main(); 使用下面的方式 可以解决 winform启动 new WindowsFormsApp1.Form1().Show(); wpf启动 new …

图解Modern Cpp内存序

文章目录 为什么需要内存序?内存序的分类内存序的作用指令重排序限制跨线程可见性 样例分析完全乱序: memory_order_relaxed读写同步: memory_order_acquire 和 memory_order_release一致性 memory_order_seq_cst6. 内存序的权衡总结 C 内存序(Memory Order)定义了多线程环境下…

MySQL第二弹----CRUD

笔上得来终觉浅,绝知此事要躬行 🔥 个人主页:星云爱编程 🔥 所属专栏:MySQL 🌷追光的人,终会万丈光芒 🎉欢迎大家点赞👍评论📝收藏⭐文章 ​ 一、修改表 使用ALTER …

Pytorch | 利用SMI-FGRM针对CIFAR10上的ResNet分类器进行对抗攻击

Pytorch | 利用I-FGSSM针对CIFAR10上的ResNet分类器进行对抗攻击 CIFAR数据集SMI-FGRM介绍SMI-FGRM算法流程 SMI-FGRM代码实现SMI-FGRM算法实现攻击效果 代码汇总smifgrm.pytrain.pyadvtest.py 之前已经针对CIFAR10训练了多种分类器: Pytorch | 从零构建AlexNet对CI…

AE Dressler CESAR 1312 Generator Model User Manual

AE Dressler CESAR 1312 Generator Model User Manual

每天40分玩转Django:Django类视图

Django类视图 一、知识要点概览表 类别知识点掌握程度要求基础视图View、TemplateView、RedirectView深入理解通用显示视图ListView、DetailView熟练应用通用编辑视图CreateView、UpdateView、DeleteView熟练应用Mixin机制ContextMixin、LoginRequiredMixin理解原理视图配置U…

建造者模式 Builder Pattern

在创建一个对象的时候,构造器参数有点多,而且有些参数还是可选的,再者还有不少同类型的,那就更应该使用 builder 模式了。 使用 Builder 模式的初衷是 把易变性(mutability)移动到Builder类,而…

OpenCV-Python实战(11)——边缘检测

一、Sobel 算子 通过 X 梯度核与 Y 梯度核求得图像在,水平与垂直方向的梯度。 img cv2.Sobel(src*,ddepth*,dx*,dy*,ksize*,scale*,delta*,borderType*)img:目标图像。 src:原始图像。 ddepth:目标图像深度,-1 代表…

Github优质项目推荐(第十期)

文章目录 Github优质项目推荐(第十期)一、【postiz-app】,14.6k stars - 您的终极 AI 社交媒体调度工具二、【lobe-chat】,50.1k stars - AI 聊天框架三、【cobalt】,22.1k stars - 媒体下载器四、【build-your-own-x】…

【Linux】:Linux网络编程基础

1 网络基础概念 计算机网络背景 网络发展 独立模式:计算机之间相互独立; 网络互联:多台计算机连接在一起,完成数据共享 局域网LAN:计算机数量更多了,通过交换机和路由器连接在一起 广域网WAN:将远隔千里的计算机都连在一起 所谓"局域网"和"广域网"只是…

基于Golang的博客系统的设计与实现

全文字数:6040 全文字符数:3753 正文字数:5296 正文字符数:3176 图片数:8 表格数:10 Abstract With the continuous development of the Internet, more and more internet developers will use blogs to…

Type-C接口的拍摄云台

在摄影与摄像的世界里,稳定性是确保画面流畅、清晰的关键因素之一。无论是专业摄影师还是摄影爱好者,都深知在拍摄过程中,任何微小的抖动都可能对最终作品产生不可忽视的影响。为了克服这一挑战,拍摄云台应运而生,成为…

【Go】:Sentinel 动态数据源配置指南

前言 在现代微服务架构中,流量控制是确保系统高可用性和稳定性的关键。Sentinel 是一款由阿里巴巴开源的流量控制组件,它不仅支持熔断降级和流量整形,还能通过动态数据源(如本地文件或 Nacos)加载规则,从而…

密钥登录服务器

1. 生成 SSH 密钥对 如果您还没有生成密钥对,可以使用以下命令生成: ssh-keygen 在 root 用户的家目录中生成了一个 .ssh 的隐藏目录,内含两个密钥文件:id_rsa 为私钥,id_rsa.pub 为公钥。 在提示时,您可…

Apriori关联规则算法 HNUST【数据分析技术】(2025)

1.理论知识 Apriori是一种常用的数据关联规则挖掘方法,它可以用来找出数据集中频繁出现的数据集合。该算法第一次实现在大数据集上的可行的关联规则提取,其核心思想是通过连接产生候选项及其支持度,然后通过剪枝生成频繁项集。 Apriori算法的…

2025最新版Java面试八股文大全

一、Java并发面试题 1、 ThreadLocal 1.1 谈谈你对ThreadLocal的理解? ThreadLocal的作用主要是做数据隔离,填充的数据只属于当前线程,变量的数据对别的线程而言是相对隔离的。它不是针对程序的全局变量,只是针对当前线程的全局…

tryhackme-Cyber Security 101-Cryptography-Cryptography Basics(加密基础)

目的:了解加密和对称加密的基础知识。 任务1:介绍 你有没有想过如何防止第三方阅读你的消息?您的应用程序 或 Web 浏览器如何与远程服务器建立安全通道?安全是指没有人可以读取或更改交换的数据;此外,我们可以确信我们…

40.2 预聚合和prometheus-record使用

本节重点介绍 : downsample降采样可以降低查询数据量 prometheus原生不支持downsample 实时查询/聚合 VS 预查询/聚合的优缺点 实时查询/聚合条件随意组合,性能差预查询/聚合 性能好,聚合条件需要提前定义 prometheus的预查询/聚合配置举例 downsample…