Arrow 与 Parquet 格式详解
Hugging Face datasets 库主要涉及两种核心格式:Apache Arrow(本地缓存/运行时格式)和 Parquet(云端存储/压缩格式)。
它们都是二进制格式,不能像 JSONL 那样直接用记事本或文本编辑器打开阅读(会看到乱码),但通过工具可以非常方便地查看。
1. Hugging Face 的核心格式
Apache Arrow (.arrow) — 本地运行时之王
当你使用 save_to_disk() 或 load_dataset() 时,数据在本地主要是以 Arrow 格式存在的。
- 本质:一种高性能的内存数据格式
- 特点:
- 零拷贝 (Zero-copy):读取数据几乎不需要消耗 CPU 去解析(JSON 需要 parse,Arrow 不需要)
- 内存映射 (Memory Mapping):这是它的杀手锏。它允许你在 16GB 内存的电脑上瞬间"加载" 1TB 的数据集。它并不把数据真的全部读进内存,而是按需从硬盘读取,但操作系统觉得它已经在内存里了
- 能直接打开吗? ❌ 不能。它是二进制文件
Parquet (.parquet) — 云端存储与压缩之王
你在 Hugging Face 网页上浏览文件列表时,看到的通常是 Parquet 文件。
- 本质:一种列式存储的二进制文件格式
- 特点:
- 高压缩率:比 JSONL 小得多(通常只有 JSONL 体积的 40%-60%)
- 列式读取:如果你只需要数据集里的 "text" 这一列,它不需要扫描整个文件,读取速度极快
- 能直接打开吗? ❌ 不能。它是二进制文件
2. 与 JSONL 的全方位对比
| 特性 | JSONL (.jsonl) | Arrow / Parquet (HF 格式) |
|---|---|---|
| 可读性 | 高 (人类可读),可以用记事本、head、cat 查看 | 低 (二进制乱码),必须用专门工具或代码读取 |
| 体积 | 大 (纯文本,包含大量重复的 key 字符串) | 小 (Parquet 压缩率极高,Arrow 略大但高效) |
| 加载速度 | 慢,Python 需要逐行解析字符串,消耗 CPU | 极快,二进制直接映射,几乎无解析开销 |
| 内存占用 | 高,加载大文件容易内存溢出 (OOM) | 极低,支持内存映射,不占物理内存 |
| 适用场景 | 调试、小数据、数据清洗中间过程 | 大规模预训练数据、生产环境、高性能计算 |
3. 如何查看这些格式?
虽然不能用记事本,但有很方便的方法查看:
方法一:使用 VS Code 插件(推荐)
如果你用 VS Code 开发,不需要写代码就能看:
- Parquet: 安装
Parquet Viewer插件。点击.parquet文件,它会像 Excel 表格一样展示数据 - Arrow/Parquet: 安装
Data Wrangler插件,可以进行高级的数据查看和统计
方法二:使用 Pandas (Python)
这是最通用的方法,把它们当表格读进来:
查看 Parquet:
import pandas as pd
# 就像读 CSV 一样简单
df = pd.read_parquet("output_dir/part-00000.parquet")
print(df.head()) # 查看前5行
查看 Arrow (save_to_disk 的产物):
from datasets import load_from_disk
# 这里传入的是文件夹路径,不是单个文件
dataset = load_from_disk("/root/autodl-fs/cci3_hq_30b")
print(dataset[0]) # 查看第一条数据
4. 为什么云端用 Parquet 而不是 Arrow?
既然 Arrow 在本地跑得那么快(零拷贝、内存映射),为什么云端(如 Hugging Face Hub, S3, HDFS)不直接存 Arrow 格式,反而要多此一举存成 Parquet 呢?
核心原因是:Arrow 是为了"计算"设计的,而 Parquet 是为了"存储和传输"设计的。
宜家家具比喻
-
Arrow (本地运行) = 组装好的成品家具
- 优点:你坐下就能用(CPU 拿到数据就能算),不需要等待组装
- 缺点:体积巨大,里面有很多空隙(Padding),极占空间,不适合卡车运输
-
Parquet (云端存储) = 扁平包装的快递箱 (Flat-pack)
- 优点:体积极小,甚至能压缩到成品的 1/10,非常适合卡车运输(网络传输)和堆在仓库里(云存储)
- 缺点:你不能直接坐上去,必须先拆包组装(解压并转换为 Arrow 内存格式)才能用