DuckDB 与 Hugging Face:直接查询数据集
有效阅读仅保存在当前浏览器,用于「为你」推荐;暂停或清除记录。
DataHot 速览
DuckDB 与 Hugging Face 合作推出 hf:// 路径方案,自 DuckDB v0.10.3(2024年5月22日发布)起,用户可用 SELECT 直接查询 Hugging Face Hub 上的数据集,无需先下载。Hugging Face 数据集以 git 仓库形式存储,常见格式包括 CSV、JSONL 和 Parquet,DuckDB 通过 httpfs 扩展解析 hf://datasets/... 路径并读取文件。文章介绍了该集成的工作方式、示例查询和适用场景,例如直接分析 cais/mmlu 等数据集。
原收录理由(待核验):数据从业者可直接在 DuckDB 中查询 Hugging Face 上的 CSV、JSONL 和 Parquet 数据集,减少数据搬运,适合机器学习数据集分析与复用。
译文
AI 逐段翻译Hugging Face是大部分机器学习社区发布和查找其数据集的地方,而 DuckDB 是一种进程内分析型数据库,可以直接查询 CSV 和 Parquet 等文件,无需安装或运行服务器或数据仓库。
你是否知道,自 DuckDB v0.10.3(2024 年 5 月 22 日发布)起,你可以将 SELECT 指向 Hugging Face Hub 上的数据集,使用 DuckDB 的 hf:// 协议,直接进行查询,而无需先下载它?本文将介绍该集成的工作方式及其适用的用例。
背景
在 Hugging Face Hub 上,每个数据集都是一个 git 仓库,其数据以普通文件形式保存,通常是 CSV、JSONL 或 Parquet。cais/mmlu 基准测试以及本文后面使用的 datasets-examples/doc-formats-csv-1 仓库就是两个这样的例子:你可以在浏览器中浏览它们的文件和提交历史,就像浏览任何 git 仓库一样。
在 Hugging Face 集成之前,要从 DuckDB 获取这些数据,必须先下载文件,或者先用 Hugging Face 的 datasets 库加载它们,然后才能读取和分析。无论哪种方式,数据都必须先从 Hugging Face Hub 复制出来,然后才能查询。
DuckDB 之前已经能够通过其 httpfs 扩展读取 HTTP 上的远程文件,因此直接读取 URL 并不是什么新鲜事。Hugging Face 数据集也越来越多地以 Parquet 格式发布,这是 DuckDB 原生读取的列式格式,可以在不将所有内容都加载到内存的情况下进行扫描。
DuckDB 和 Hugging Face 合作在 hf:// 路径方案之上添加了该功能,基于 httpfs,于 2024 年 5 月宣布,随 DuckDB v0.10.3 一同发布。因此,DuckDB 可以将数据集仓库解析为其内部的文件,这样查询就可以直接在文件所在位置读取和分析它们,而不是通过下载的副本。
直接读取 Hugging Face 数据集
下面的示例涵盖了常见情况。DuckDB 的 Hugging Face 文档 是完整参考。该方案将 Hugging Face 数据集仓库映射为 DuckDB 可以读取的路径:
hf://datasets/my_username/my_dataset/path_to_file读取文件就只是一个查询。以下从 datasets-examples/doc-formats-csv-1 仓库读取该 CSV 文件:
SELECT*FROM'hf://datasets/datasets-examples/doc-formats-csv-1/data.csv';| kind | sound |
|---|---|
| dog | woof |
| cat | meow |
| pokemon | pika |
| human | hello |
这里 datasets-examples 是用户或组织,doc-formats-csv-1 是数据集仓库,而 data.csv 是其中的文件。相同的示例数据也发布在 doc-formats-jsonl-1 和 doc-formats-parquet-1 仓库中,因此这些查询返回相同的四行:
SELECT*FROM'hf://datasets/datasets-examples/doc-formats-jsonl-1/data.jsonl';SELECT*FROM'hf://datasets/datasets-examples/doc-formats-parquet-1/data/train-00000-of-00001.parquet';DuckDB 会根据文件推断格式,并且只读取查询实际需要的列。而且,不会先下载到本地副本。
一次查询多个文件
数据集通常分散在许多文件中。glob 模式 可以让你将整个目录视为一张表。cais/mmlu 基准测试将其 astronomy 任务存储在三个 Parquet 文件(dev、test 和 validation)中,以下查询统计所有这些文件中的行数:
SELECTcount(*)AScountFROM'hf://datasets/cais/mmlu/astronomy/*.parquet';| count |
|---|
| 173 |
由于 DuckDB 按列读取 Parquet,你可以在不将所有行拉入内存的情况下对这些文件进行过滤:
SELECTcount(*)AScountFROM'hf://datasets/cais/mmlu/astronomy/*.parquet'WHEREquestionLIKE'%planet%';| count |
|---|
| 21 |
版本与 ~parquet 分支
每个 Hugging Face 数据集都是一个 git 仓库,因此它包含分支和修订版本。你可以使用 @ 后缀将查询固定到特定的版本:
SELECT*FROM'hf://datasets/datasets-examples/doc-formats-csv-1@~parquet/**/*.parquet';| kind | sound |
|---|---|
| dog | woof |
| cat | meow |
| pokemon | pika |
| human | hello |
Hugging Face 会自动将每个数据集转换为此特殊 ~parquet 分支上的 Parquet 格式,以便高效扫描。因此,即使是以 CSV 或 JSONL 发布的数据集通常也有现成的列式版本,这正是 DuckDB 读取最快的格式。
保存本地副本
如果你要反复查询相同的数据,请将其物化一次,这样就不必每次都访问远程端点:
CREATETABLEdataASSELECT*FROM'hf://datasets/datasets-examples/doc-formats-csv-1/data.csv';之后,数据就存储在本地表中,查询不再访问 Hugging Face Hub:
SELECT*FROMdata;| kind | sound |
|---|---|
| dog | woof |
| cat | meow |
| pokemon | pika |
| human | hello |
私有和门控数据集
公共数据集无需任何设置。对于私有或门控数据集,请将 Hugging Face token 存储在 DuckDB 的 Secrets Manager 中。你可以直接传入 token:
CREATESECREThf_token(TYPEhuggingface,TOKEN'your_hf_token');或者让 DuckDB 从 ~/.cache/huggingface/token 中获取它,Hugging Face 工具会将 token 存储在那里:
CREATESECREThf_token(TYPEhuggingface,PROVIDERcredential_chain);典型用例
当你想要查看 Hugging Face Hub 上的数据,而不必承诺进行下载或构建管道时,该集成非常合适。
SELECT
count(*) AS questions,
count(DISTINCT question) AS distinct_questions,
avg(len(choices)) AS avg_choices
FROM 'hf://datasets/cais/mmlu/astronomy/*.parquet';
| questions | distinct_questions | avg_choices |
|---|---|---|
| 173 | 166 | 4.0 |
COPY (
SELECT question, choices, answer
FROM 'hf://datasets/cais/mmlu/astronomy/*.parquet'
WHERE question LIKE '%planet%'
) TO 'astronomy_planets.parquet';
SELECT subject, count(*) AS questions
FROM read_parquet([
'hf://datasets/cais/mmlu/astronomy/test-00000-of-00001.parquet',
'hf://datasets/cais/mmlu/anatomy/test-00000-of-00001.parquet'
])
GROUP BY subject
ORDER BY subject;
| subject | questions |
|---|---|
| anatomy | 135 |
| astronomy | 152 |
SELECT l.letter AS correct_choice, count(*) AS n
FROM 'hf://datasets/cais/mmlu/astronomy/*.parquet' AS m
JOIN (VALUES (0, 'A'), (1, 'B'), (2, 'C'), (3, 'D')) AS l(idx, letter)
ON m.answer = l.idx
GROUP BY l.letter
ORDER BY l.letter;
| correct_choice | n |
|---|---|
| A | 35 |
| B | 32 |
| C | 48 |
| D | 58 |
SELECT count(*) AS count
FROM 'hf://datasets/cais/mmlu@c30699e8356da336a370243923dbaf21066bb9fe/astronomy/*.parquet';
| count |
|---|
| 173 |
- 在使用数据集之前先探索它。在训练或微调数据集之前,你通常想了解其中有什么:行数、有多少唯一行,以及各列是什么样子。对
hf://路径执行一次查询即可回答这些问题,并且只读取你请求的列: - 为训练进行过滤和采样。大型数据集通常需要缩小为子集,比如单一语言或高于某个质量阈值的行,然后才有用。将其表示为
WHERE子句,并使用COPY将结果直接写入本地 Parquet 文件: 这将远程数据集转换为聚焦的本地文件,这里是 21 个提到行星的天文学问题。 - 使用基准测试和评估集。像 MMLU 这样的基准测试以按任务分组的许多小文件形式提供。你可以将多个任务读取为一张表,并计算每个任务的统计信息:
- 将 Hugging Face Hub 数据与你自己的数据连接。由于
hf://路径的行为与任何其他表源一样,你可以将公共数据集与你自己的表连接。这里有一个小的查找表,将每个数字答案映射到一个选项字母: - 可复现的分析。将查询固定到特定提交意味着它每次运行时都读取相同的数据,这对于任何你需要以后复现的内容都很重要。使用
@后缀添加修订版本:
结论
通过将数据集在 hf:// 协议中的路径放入 Hugging Face Hub 的 SELECT 中,你无需下载步骤、无需运行服务器即可查询它。
如果你要处理 Hugging Face Hub 上的数据集,这覆盖了许多日常工作,从检查新数据集到从较大的数据集中创建训练子集。
如需进一步阅读,请参阅原始公告帖,DuckDB 的 Hugging Face 文档,以及 Hugging Face 自己的DuckDB 指南。
这篇内容对你有用吗?
反馈只用于改善内容筛选,不等同于收藏