DuckDB 与 Hugging Face:直接查询数据集

Hugging Face 托管着数十万个数据集。借助 DuckDB 的 hf:// 协议,可以直接读取这些数据所在的远程文件,无须先把完整文件下载为本地副本。本文介绍这项集成的工作方式和适用场景。

Hugging Face 是机器学习社区发布、寻找数据集的重要平台;DuckDB 则是进程内的分析型数据库,可以直接查询 CSV、Parquet 等文件,无须安装或运行服务器、数据仓库。

从 2024 年 5 月 22 日发布的 DuckDB v0.10.3 起,就可以在 SELECT 中指定 Hugging Face Hub 上的数据集路径,通过 hf:// 协议查询,无须先下载文件。

背景

Hugging Face Hub 上的每个数据集都是一个 Git 仓库,其中的数据通常以 CSV、JSONL 或 Parquet 文件存储。后面使用的 cais/mmlu 基准和 datasets-examples/doc-formats-csv-1 都是这样的仓库,可以像浏览其他 Git 仓库一样查看文件和提交历史。

在集成 Hugging Face 之前,要用 DuckDB 分析这些数据,通常得先下载文件,或通过 Hugging Face 的 datasets 库 加载,再交给 DuckDB。两种方式都需要先把数据从 Hub 复制出来。

DuckDB 的 httpfs 扩展 原本就能读取 HTTP 远程文件,因此直接读取 URL 并非新功能。越来越多的 Hugging Face 数据集也以 Parquet 发布;这种列式格式由 DuckDB 原生读取,扫描时无须把全部数据装入内存。

DuckDB 与 Hugging Face 合作,在 httpfs 之上加入了 hf:// 路径格式,并随 v0.10.3 于 2024 年 5 月宣布。DuckDB 因而可以把数据集仓库解析为其中的文件,直接读取并分析远程数据。

直接读取 Hugging Face 数据集

下面介绍常见用法,完整参考见 DuckDB 的 Hugging Face 文档。路径格式把数据集仓库映射为 DuckDB 可读取的地址:

hf://datasets/⟨my_username⟩/⟨my_dataset⟩/⟨path_to_file⟩

读取文件只需要一条查询。下面读取示例仓库中的 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 是仓库内文件。同样的数据还发布在 JSONL 和 Parquet 示例仓库中,以下两条查询返回相同的四行:

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 模式可以把整个目录作为一张表。MMLU 的 astronomy 任务分别存放在 dev、test、validation 三个 Parquet 文件中,下面统计它们的总行数:

SELECT count(*) AS count
FROM 'hf://datasets/cais/mmlu/astronomy/*.parquet';
count
173

DuckDB 按列读取 Parquet,因此可以跨文件筛选,无须将每一行都拉入内存:

SELECT count(*) AS count
FROM 'hf://datasets/cais/mmlu/astronomy/*.parquet'
WHERE question LIKE '%planet%';
count
21

版本与 ~parquet 分支

每个数据集都是 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 分支上自动转换数据集,便于高效扫描。即使数据集原本以 CSV 或 JSONL 发布,通常也已有可用的列式版本,这也是 DuckDB 读取最快的格式。

保存本地副本

如果要反复查询同一份数据,可以先物化一次,避免每次访问远程端点:

CREATE TABLE data AS
    SELECT *
    FROM 'hf://datasets/datasets-examples/doc-formats-csv-1/data.csv';

此后,数据存放在本地表中,查询不再访问 Hub:

SELECT *
FROM data;
kind sound
dog woof
cat meow
pokemon pika
human hello

私有与受限数据集

公开数据集无须额外设置。对于私有或需申请访问的数据集,可以在 DuckDB 的 Secrets Manager 中保存 Hugging Face token,直接提供 token:

CREATE SECRET hf_token (
    TYPE huggingface,
    TOKEN 'your_hf_token'
);

也可以让 DuckDB 从 Hugging Face 工具保存 token 的 ~/.cache/huggingface/token 文件读取:

CREATE SECRET hf_token (
    TYPE huggingface,
    PROVIDER credential_chain
);

典型场景

当你想先看看 Hub 上的数据,而暂时不想下载完整数据或构建数据流水线时,这项集成尤其适用。

使用前探索数据集

训练或微调前,通常需要了解行数、唯一行数、列内容等。对 hf:// 路径执行一条查询即可得到答案,且只读取所需列:

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

筛选训练数据与抽取子集

大型数据集往往需要先缩小范围,比如只保留一种语言,或达到质量阈值的行。用 WHERE 表达筛选条件,再通过 COPY 将结果直接写为本地 Parquet:

COPY (
    SELECT question, choices, answer
    FROM 'hf://datasets/cais/mmlu/astronomy/*.parquet'
    WHERE question LIKE '%planet%'
) TO 'astronomy_planets.parquet';

这样就把远程数据集变成了聚焦需求的本地文件;本例中是提到 planet 的 21 道天文学题目。

分析基准与评测集

MMLU 等基准按任务组织大量小文件。可以把多个任务当作一张表读取,并计算各任务的统计值:

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

将 Hub 数据与自己的数据连接

hf:// 路径与其他表数据源一样,因此可以把公开数据集与自己的表连接。下面用一个小型查找表,把数字答案映射为选项字母:

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:// 协议让你只需在 SELECT 中指定路径,就能查询 Hub 上的数据集,无须预先下载完整文件,也无须运行服务器。对于日常使用 Hugging Face 数据集的人,这可以覆盖探索新数据集、从大数据集中生成训练子集等常见任务。

延伸阅读:最初的公告、DuckDB 文档、Hugging Face 的 DuckDB 指南。


原文:DuckDB and Hugging Face: Querying Datasets Directly,The DuckDB team,2026-09-25。本文为中文翻译。示例结果来自原文,未在本次准备中运行。文章源码位于 duckdb-web 仓库,按其 MIT 许可证使用,许可声明如下:

Copyright 2018-2025 Stichting DuckDB Foundation

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容