Shard 与 Tar Streaming 训练:知识点总结

本文总结了在大规模模型(尤其是 LLM)训练中,为什么要用 shard、shard 是什么、tar shard 如何工作、以及 RNG / shuffle / 内存 / IO 的整体机制


1. 什么是 Shard(核心定义)

Shard 不是一种固定文件格式,而是一种存储组织方式。

Shard = 一个较大的存储单元,里面顺序存放大量样本,用于高吞吐顺序 IO。

  • sample:一条训练样本
  • batch:一次送进 GPU 的一组 sample
  • shard:磁盘上的一个“大文件”,包含很多 sample

Shard 的目标只有一个:

把“大量随机小读” → 变成“少量顺序大读”


2. 为什么 Shard 能显著加快读取速度

2.1 不用 shard 的问题

  • 一个样本一个文件(.npy / .json / .jpg
  • 大量 open / stat / close
  • 随机 seek,IOPS 被打爆
  • GPU 等数据

2.2 shard 的本质优化

无 shard 有 shard
随机小 IO 顺序大 IO
IOPS 受限 带宽受限
CPU/元数据重 OS 预读友好

GPU 不怕数据大,怕数据碎。


3. 常见的 Shard 形式(不是“唯一格式”)

3.1 tar shard(最常见)

shard-00000.tar
shard-00001.tar
  • tar 内是大量 sample 文件
  • 完全线性结构
  • 天然支持 streaming
  • WebDataset 即此思路

3.2 bin + idx(工业级 LLM)

data.bin  # 连续存储
Data.idx  # offset / length / shape
  • 支持 mmap
  • 支持按 index 精确访问

3.3 其他

  • .mds(Mosaic Streaming)
  • .npz(能用但吞吐一般)
  • .zarr / hdf5(chunk ≈ shard)

Shard 是 IO 策略,不是文件后缀。


4. Tar Shard Streaming 的完整内存 / IO 机制

4.1 总体路径

磁盘 / S3
   ↓ 顺序 read
OS Page Cache(readahead)
   ↓
DataLoader Worker
   ↓
Tar Stream Parser
   ↓
Shuffle Buffer(内存)
   ↓
Batch / Prefetch
   ↓
GPU

4.2 关键事实

  • open() 不会读数据
  • tar 是 边读边解析,不会整包进内存
  • OS 自动 readahead,提高顺序读吞吐
  • 真正吃内存的是 shuffle buffer,而不是 shard 文件

5. Shard 会不会被整体加载进内存?

不会(默认情况下)。

Shard 训练是:

  • 打开文件描述符
  • 小块 read()
  • 顺序向前推进

内存中只存在:

  1. OS page cache(透明、可回收)
  2. 当前 sample
  3. shard 内 shuffle buffer
  4. 少量预取 batch

6. Shard 内 Shuffle 的正确理解

6.1 两层随机

  • Shard 级 shuffle:打乱 shard 顺序
  • Shard 内 buffer shuffle:在内存 buffer 中近似随机

随机发生在 内存,而不是磁盘。

6.2 为什么不全局随机

  • 全局随机 = 随机磁盘 IO
  • shard shuffle = 性能与随机性的平衡点

7. RNG(Random Number Generator)在训练中的角色

7.1 RNG 全称

RNG = Random Number Generator(随机数生成器)

7.2 数据侧 RNG 控制

  • shard 顺序 shuffle
  • shard 内 buffer shuffle
  • 分布式 rank 切分

7.3 训练侧 RNG 控制

  • dropout
  • 数据增强
  • CUDA 随机

7.4 工程原则

不要把“样本身份”绑定到读取顺序,而要用 sample_id。


8. 逻辑 Shard vs 物理(IO)Shard

8.1 逻辑 shard(index 切分)

  • GPU0: [0,200)
  • GPU1: [200,400)

解决的是:

  • 谁读哪些样本
  • DDP 不重复

8.2 物理 shard(文件合并)

解决的是:

  • 读得快不快
  • IO 吞吐

逻辑 shard ≠ IO shard


9. 一个判断口诀(工程经验)

谁读哪些数据 → sampler / index
数据读得快不快 → shard / IO 格式


10. 一句话总总结

Shard 训练 = 用大文件顺序读 + 内存中近似随机 + IO 与 GPU 并行流水线。

这是大规模模型能把 GPU 吃满的关键前提。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐