OA0
OA0 是一个探索 AI 的社区
现在注册
已注册用户请  登录
OA0  ›  代码  ›  LitData — 为大规模 AI 训练提供高效数据流处理能力

LitData — 为大规模 AI 训练提供高效数据流处理能力

 
  repository ·  2026-07-12 11:00:21 · 1 次点击  · 0 条评论  

通过优化数据加载加速模型训练

LitData    
转换                              优化

✅ 并行化数据处理                  ✅ 流式加载大型云端数据集
✅ 创建向量嵌入                    ✅ 将训练加速高达20倍
✅ 运行分布式推理                  ✅ 暂停/恢复数据流
✅ 大规模网页抓取                  ✅ 无需本地加载,直接使用远程数据
--- ![PyPI](https://img.shields.io/pypi/v/litdata) ![Downloads](https://img.shields.io/pypi/dm/litdata) ![License](https://img.shields.io/github/license/Lightning-AI/litdata) [![Discord](https://img.shields.io/discord/1077906959069626439?label=在Discord上获取帮助)](https://discord.gg/VptPCZkGNa)

Lightning AI快速开始优化数据转换数据功能基准测试模板社区

  开始使用

 

为什么选择 LitData?

加速模型训练不仅仅是内核调优。数据加载常常是训练过程的瓶颈,因为数据集太大而无法放入磁盘,由数百万个小文件组成,或者从云端流式加载缓慢。

LitData 提供了预处理和优化数据集的工具,将其转换为能够高效地从任何云端或本地源流式加载的格式。它还包含一个用于在优化前进行分布式数据处理的映射算子。这使得数据流水线更快、与云端无关,并可以将训练吞吐量提升高达 20 倍。

 

寻找 GPU?

超过 340,000 名开发者使用 Lightning Cloud —— 专为 PyTorch 和 PyTorch Lightning 构建。
- GPU 从 $0.19 起。
- 集群:前沿级的训练/推理集群。
- AI Studio(氛围训练):AI 帮助您调试、调优和氛围训练的工作空间。
- AI Studio(氛围部署):AI 帮助您优化和部署模型的工作空间。
- 笔记本:持久的 GPU 工作空间,AI 帮助您编码和分析。
- 推理:将模型部署为推理 API。

快速开始

首先,安装 LitData:

pip install litdata

选择您的工作流程:

🚀 加速模型训练
🚀 转换数据集

 

高级安装 安装所有额外组件
pip install 'litdata[extras]'

 


加速模型训练

直接从云端存储流式加载数据集,无需本地下载。选择适合您工作流程的方法:

选项 1:立即使用现有数据 ⚡⚡

直接从云端存储流式加载原始文件——无需预先优化。

from litdata import StreamingRawDataset
from torch.utils.data import DataLoader

# 指向您现有的云端数据
dataset = StreamingRawDataset("s3://my-bucket/raw-data/")
dataloader = DataLoader(dataset, batch_size=32)

for batch in dataloader:
    # 即时处理原始字节
    pass

主要优势:

即时访问: 无需预处理,立即开始流式加载。
零启动时间: 无需数据转换或优化。
原生格式: 直接使用原始文件格式(图片、文本等)。
灵活处理: 在流式加载过程中即时应用转换。
云端原生: 直接从 S3、GCS 或 Azure 存储流式加载。

选项 2:优化以获得最大性能 ⚡⚡⚡

通过优化数据集以便直接从云端存储流式加载,加速模型训练(速度提升 20 倍)。无需本地下载即可使用远程数据,支持加载数据子集、访问单个样本和可恢复的流式加载。

步骤 1:优化您的数据(一次性设置)

将原始数据转换为优化的分块格式,以获得最大流式加载速度。
此步骤通过将数据写入高效的分块二进制格式来格式化数据集,以实现快速加载。

import numpy as np
from PIL import Image
import litdata as ld

def random_images(index):
    # 在此处替换为您的实际图片加载逻辑(例如 .jpg、.png 等)
    # 建议:使用像 JPEG 这样的压缩格式以获得更好的存储和优化的流式加载速度
    # 您还可以应用调整大小或降低图像质量以进一步提高流式加载速度并节省空间
    fake_images = Image.fromarray(np.random.randint(0, 256, (32, 32, 3), dtype=np.uint8))
    fake_labels = np.random.randint(10)

    # 您可以使用任何键:值对。请注意,样本之间的类型不能改变,Python 列表必须
    # 始终包含相同数量的元素且类型相同
    data = {"index": index, "image": fake_images, "class": fake_labels}

    return data

if __name__ == "__main__":
    # optimize 函数将数据写入优化后的格式
    ld.optimize(
        fn=random_images,                   # 应用于每个输入的函数
        inputs=list(range(1000)),           # 函数的输入(这里是一个数字列表)
        output_dir="fast_data",             # 优化后的数据存储于此
        num_workers=4,                      # 同一台机器上的工作进程数
        chunk_bytes="64MB"                  # 每个数据块的大小
    )

步骤 2:将数据上传到云端

将数据上传到 Lightning Studio(由 S3 支持)或您自己的 S3 存储桶:

aws s3 cp --recursive fast_data s3://my-bucket/fast_data

步骤 3:在训练期间流式加载数据

通过将 PyTorch DataSet 和 DataLoader 替换为 StreamingDataset 和 StreamingDataLoader 来加载数据。

import litdata as ld

dataset = ld.StreamingDataset('s3://my-bucket/fast_data', shuffle=True, drop_last=True)

# 自定义 collate 函数以处理批次(可选)
def collate_fn(batch):
    return {
        "image": [sample["image"] for sample in batch],
        "class": [sample["class"] for sample in batch],
    }

dataloader = ld.StreamingDataLoader(dataset, collate_fn=collate_fn)
for sample in dataloader:
    img, cls = sample["image"], sample["class"]

主要优势:

加速训练: 优化后的数据集加载速度提升 20 倍。
流式加载云端数据集: 无需下载即可使用云端数据。
PyTorch 优先: 与 PyTorch 库(如 PyTorch Lightning、Lightning Fabric、Hugging Face)兼容。
轻松协作: 在云端共享和访问数据集,简化团队项目。
跨 GPU 扩展: 流式数据自动扩展到所有 GPU。
灵活存储: 使用 S3、GCS、Azure 或您自己的云账户进行数据存储。
压缩: 使用高级压缩算法减少数据占用空间。
本地或云端运行: 在您自己的机器上运行,或通过 Lightning Studios 自动扩展到数千个云端 GPU。
企业级安全: 通过 Lightning Studios 自行托管或在您的云账户上处理数据。

 


转换数据集

通过跨多台机器并行化(映射)工作,加速数据处理任务(数据抓取、图像调整大小、嵌入创建、分布式推理)。

以下是一个调整大小和裁剪大型图像数据集的示例:

from PIL import Image
import litdata as ld

# 使用本地或 S3 文件夹
input_dir = "my_large_images"     # 或 "s3://my-bucket/my_large_images"
output_dir = "my_resized_images"  # 或 "s3://my-bucket/my_resized_images"

inputs = [os.path.join(input_dir, f) for f in os.listdir(input_dir)]

# 调整输入图像大小
def resize_image(image_path, output_dir):
  output_image_path = os.path.join(output_dir, os.path.basename(image_path))
  Image.open(image_path).resize((224, 224)).save(output_image_path)

ld.map(
    fn=resize_image,
    inputs=inputs,
    output_dir="output_dir",
)

主要优势:

✅ 并行化处理: 通过跨多台机器同时转换数据来减少处理时间。
✅ 扩展到大数据: 增加您可以有效处理的数据集大小。
✅ 灵活用例: 调整图像大小、创建嵌入、抓取互联网等。
✅ 本地或云端: 在您自己的机器上运行,或通过 Lightning Studios 自动扩展到数千个云端 GPU。
✅ 企业级安全: 通过 Lightning Studios 自行托管或在您的云账户上处理数据。

 


关键特性

用于优化和流式加载数据集以进行模型训练的功能

✅ 流式加载原始云端数据集(测试版) 🔗   无需任何优化或转换,即可直接从 S3、GCS 和 Azure 云端存储轻松流式加载原始文件(图像、文本等)。非常适合需要即时访问原生格式原始数据的工作流程。 **前提条件:** 安装从 **Amazon S3** 或 **Google Cloud Storage** 等云端存储流式加载原始数据集所需的依赖项:
# 对于 aws s3
pip install "litdata[extra]" s3fs

# 对于 gcloud storage
pip install "litdata[extra]" gcsfs
**使用示例:**
from torch.utils.data import DataLoader
from litdata import StreamingRawDataset

dataset = StreamingRawDataset("s3://bucket/files/")

# 配合 PyTorch DataLoader 使用
loader = DataLoader(dataset, batch_size=32)
for batch in loader:
    # 每个元素都是原始字节
    pass
> 使用 `StreamingRawDataset` 按原样流式加载数据。如果要获得最快的流式加载速度,请在优化数据后使用 `StreamingDataset`。 您还可以通过继承 `StreamingRawDataset` 并重写 `setup` 方法来自定义文件的分组方式。这对于配对相关文件(例如图像和掩码、音频和转录)或任何自定义分组逻辑非常有用。
from typing import Union
from torch.utils.data import DataLoader
from litdata import StreamingRawDataset
from litdata.raw.indexer import FileMetadata

class SegmentationRawDataset(StreamingRawDataset):
    def setup(self, files: list[FileMetadata]) -> Union[list[FileMetadata], list[list[FileMetadata]]]:
        # TODO:在此处实现您的自定义分组逻辑。
        # 例如,按前缀、扩展名或任何您需要的规则对文件进行分组。
        # 返回一个组列表,其中每个组都是 FileMetadata 的列表。
        # 示例:
        #   return [[image, mask], ...]
        pass

# 初始化自定义数据集
dataset = SegmentationRawDataset("s3://bucket/files/")
loader = DataLoader(dataset, batch_size=32)
for item in loader:
    # 批次中的每个项目都是一对:[image_bytes, mask_bytes]
    pass
**智能索引缓存** `StreamingRawDataset` 会自动缓存文件索引以实现即时启动。初始扫描会构建并缓存索引,后续运行即可立即加载。 **两级缓存:** - **本地:** 存储在您的缓存目录中,以实现即时访问 - **远程:** 自动保存到云端存储(例如 `s3://bucket/files/index.json.zstd`)以备重用 **强制重建:**
# 当数据集文件发生变化时
dataset = StreamingRawDataset("s3://bucket/files/", recompute_index=True)
✅ 流式加载大型云端数据集 🔗   使用存储在云端的数据,无需全部下载到本地,节省时间和空间。 想象一下,您正在处理一个包含大量在线存储数据的项目。您无需等待数小时将其全部下载,而是可以通过流式加载几乎立即开始处理数据。 使用 LitData 优化数据集后,按如下方式流式加载:
from litdata import StreamingDataset, StreamingDataLoader

dataset = StreamingDataset('s3://my-bucket/my-data', shuffle=True)
dataloader = StreamingDataLoader(dataset, batch_size=64)

for batch in dataloader:
    process(batch)  # 替换为您的数据处理逻辑

此外,您可以在初始化数据集时为 [S3](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/core/session.html#boto3.session.Session.client) 或 GCP 注入客户端连接设置。这对于为每个数据集指定自定义端点和凭据非常有用。
from litdata import StreamingDataset

# 适用于自定义 S3 兼容端点的 boto3 兼容存储选项
storage_options = {
    "endpoint_url": "your_endpoint_url",
    "aws_access_key_id": "your_access_key_id",
    "aws_secret_access_key": "your_secret_access_key",
}

dataset = StreamingDataset('s3://my-bucket/my-data', storage_options=storage_options)

dataset = StreamingDataset('s3://my-bucket/my-data', storage_options=storage_options)
此外,您可以在初始化数据集时指定自定义缓存目录。当您希望将缓存存储在特定位置时,这非常有用。
from litdata import StreamingDataset

# 使用自定义缓存目录初始化 StreamingDataset
dataset = StreamingDataset('s3://my-bucket/my-data', cache_dir="/path/to/cache")
✅ 流式加载 Hugging Face 🤗 数据集 🔗   要使用您喜爱的 Hugging Face 数据集与 LitData,只需将其 URL 传递给 `StreamingDataset`。
如何获取 HF 数据集 URI? https://github.com/user-attachments/assets/3ba9e2ef-bf6b-41fc-a578-e4b4113a0e72
**前提条件:** 安装流式加载 Hugging Face 数据集所需的依赖项:
pip install "litdata[extra]" huggingface_hub

# 可选:加速高带宽网络上的下载
pip install hf_transfer
export HF_HUB_ENABLE_HF_TRANSFER=1
**流式加载 Hugging Face 数据集:**
import litdata as ld

# 定义 Hugging Face 数据集 URI
hf_dataset_uri = "hf://datasets/leonardPKU/clevr_cogen_a_train/data"

# 创建流式加载数据集
dataset = ld.StreamingDataset(hf_dataset_uri)

# 打印第一个样本
print("Sample", dataset[0])

# 使用 StreamingDataLoader 流式加载数据集
dataloader = ld.StreamingDataLoader(dataset, batch_size=4)
for sample in dataloader:
    pass
您无需担心索引数据集或任何其他设置。**LitData** 将**自动处理所有必要步骤**并`缓存` `index.json` 文件,这样您就不必再次索引。 这确保了下次流式加载数据集时,将跳过索引步骤。   ### 索引 HF 数据集(可选) 如果 Hugging Face 数据集尚未索引,您可以先使用 `index_hf_dataset` 方法对其进行索引,然后使用上面的代码进行流式加载。
import litdata as ld

hf_dataset_uri = "hf://datasets/leonardPKU/clevr_cogen_a_train/data"

ld.index_hf_dataset(hf_dataset_uri)
- 提前索引 Hugging Face 数据集将使流式加载稍微快一些,因为它避免了在流式加载期间进行实时索引。 - 要使用 `HF 受限数据集`,请确保设置了 `HF_TOKEN` 环境变量。 **注意**:对于 HuggingFace 数据集,仅支持 **`Parquet 格式`** 的数据集的 `索引` 和 `流式加载`。   ### Hugging Face 数据集的完整工作流程 为了完全控制缓存路径(`index.json 文件的存储位置`)和其他配置,请遵循以下步骤: 1. 首先索引 Hugging Face 数据集:
import litdata as ld

hf_dataset_uri = "hf://datasets/open-thoughts/OpenThoughts-114k/data"

ld.index_parquet_dataset(hf_dataset_uri, "hf-index-dir")
2. 现在要流式加载 HF 数据集,将 `HF 数据集 URI`、`index.json` 文件存储的路径以及 `ParquetLoader` 作为 `item_loader` 传递给 **`StreamingDataset`**:
import litdata as ld
from litdata.streaming.item_loader import ParquetLoader

hf_dataset_uri = "hf://datasets/open-thoughts/OpenThoughts-114k/data"

dataset = ld.StreamingDataset(hf_dataset_uri, item_loader=ParquetLoader(), index_path="hf-index-dir")

for batch in ld.StreamingDataLoader(dataset, batch_size=4):
  pass
  ### LitData `Optimize` 与 `Parquet` 对比 以下是 `Imagenet 数据集(155 GB)` 的基准测试,表明 **`使用 LitData 优化数据集比使用原始 Parquet 文件更快,且输出大小更小`**。 | **操作** | **大小 (GB)** | **时间 (秒)** | **吞吐量 (图像/秒)** | |-----------------------------------|---------------|---------------------|-----------------------------| | LitData 优化数据集 | 45 | 283.17 | 4000-4700 | | Parquet 优化数据集 | 51 | 465.96 | 3600-3900 | | 索引 Parquet 数据集(开销) | N/A | 6 | N/A |
✅ 在多 GPU、多节点上流式加载 🔗   使用 Lightning 优化和加载的数据会自动在分布式训练中跨 GPU 或多节点高效流式加载。 `StreamingDataset` 和 `StreamingDataLoader` 会自动确保每个 rank 接收到相同数量的多样化批数据,因此它可以开箱即用地与您最喜爱的框架([PyTorch Lightning](https://lightning.ai/docs/pytorch/stable/)、[Lightning Fabric](https://lightning.ai/docs/fabric/stable/) 或 [PyTorch](https://pytorch.org/docs/stable/index.html))配合进行分布式训练。 以下是一个说明 Streaming Dataset 在多节点/多 GPU 下工作原理的图示。
from litdata import StreamingDataset, StreamingDataLoader

# 对于训练数据集,不要忘记启用 shuffle 和 drop_last !!!
train_dataset = StreamingDataset('s3://my-bucket/my-train-data', shuffle=True, drop_last=True)
train_dataloader = StreamingDataLoader(train_dataset, batch_size=64)

for batch in train_dataloader:
    process(batch)  # 替换为您的数据处理逻辑

val_dataset = StreamingDataset('s3://my-bucket/my-val-data', shuffle=False, drop_last=False)
val_dataloader = StreamingDataLoader(val_dataset, batch_size=64)

for batch in val_dataloader:
    process(batch)  # 替换为您的数据处理逻辑
![一个说明 Streaming Dataset 如何与多节点配合工作的图示。](https://pl-flash-data.s3.amazonaws.com/streaming_dataset.gif)
✅ 从多个云服务提供商流式加载 🔗   `StreamingDataset` 支持从常见的云存储提供商(如 AWS S3、Google Cloud Storage (GCS) 和 Azure Blob Storage)读取优化后的数据集。以下是使用每个云提供商使用 StreamingDataset 的示例。
import os
import litdata as ld

# 使用 boto3 从 AWS S3 读取数据
aws_storage_options={
    "aws_access_key_id": os.environ['AWS_ACCESS_KEY_ID'],
    "aws_secret_access_key": os.environ['AWS_SECRET_ACCESS_KEY'],
}
# 您也可以传递会话选项。(仅适用于 boto3)
aws_session_options = {
  "profile_name": os.environ['AWS_PROFILE_NAME'],  # 仅自定义配置文件需要
  "region_name": os.environ['AWS_REGION_NAME'],    # 仅自定义区域需要
}
dataset = ld.StreamingDataset("s3://my-bucket/my-data", storage_options=aws_storage_options, session_options=aws_session_options)

# 使用未签名请求从 AWS S3 读取数据(使用 boto3)
aws_storage_options={
  "config": botocore.config.Config(
        retries={"max_attempts": 1000, "mode": "adaptive"}, # 配置 S3 操作的重试
        signature_version=botocore.UNSIGNED, # 使用未签名请求
  )
}
dataset = ld.StreamingDataset("s3://my-bucket/my-data", storage_options=aws_storage_options)

aws_storage_options={
    "AWS_ACCESS_KEY_ID": os.environ['AWS_ACCESS_KEY_ID'],
    "AWS_SECRET_ACCESS_KEY": os.environ['AWS_SECRET_ACCESS_KEY'],
    "S3_ENDPOINT_URL": os.environ['AWS_ENDPOINT_URL'],  # 仅自定义端点需要
}
dataset = ld.StreamingDataset("s3://my-bucket/my-data", storage_options=aws_storage_options)

dataset = ld.StreamingDataset("s3://my-bucket/my-data", storage_options=aws_storage_options)

# 从 GCS 读取数据
gcp_storage_options={
    "project": os.environ['PROJECT_ID'],
}
dataset = ld.StreamingDataset("gs://my-bucket/my-data", storage_options=gcp_storage_options)

# 从 Azure 读取数据
azure_storage_options={
    "account_url": f"https://{os.environ['AZURE_ACCOUNT_NAME']}.blob.core.windows.net",
    "credential": os.environ['AZURE_ACCOUNT_ACCESS_KEY']
}
dataset = ld.StreamingDataset("azure://my-bucket/my-data", storage_options=azure_storage_options)
✅ 暂停、恢复数据流 🔗   在长时间训练期间流式加载数据,如果中断,可以无缝地从中断处继续。 LitData 提供了一个有状态的 `Streaming DataLoader`,例如,您可以随时 `暂停` 和 `恢复` 训练。 信息:`Streaming DataLoader` 被 [Lit-GPT](https://github.com/Lightning-AI/litgpt/blob/main/tutorials/pretrain_tinyllama.md) 用于预训练 LLM。由于多次失败(网络、CUDA 错误等),从较早的检查点重新启动对于预训练完整模型至关重要。
import os
import torch
from litdata import StreamingDataset, StreamingDataLoader

dataset = StreamingDataset("s3://my-bucket/my-data", shuffle=True)
dataloader = StreamingDataLoader(dataset, num_workers=os.cpu_count(), batch_size=64)

# 恢复 dataLoader 状态(如果存在)
if os.path.isfile("dataloader_state.pt"):
    state_dict = torch.load("dataloader_state.pt")
    dataloader.load_state_dict(state_dict)

# 迭代数据
for batch_idx, batch in enumerate(dataloader):

    # 每 1000 个批次存储一次状态
    if batch_idx % 1000 == 0:
        torch.save(dataloader.state_dict(), "dataloader_state.pt")
✅ 在优化时使用共享队列 🔗   如果您使用多个工作进程来优化数据集,您可以使用共享队列来加速该过程。 这在并行优化大型数据集时特别有用,因为某些工作进程可能比其他进程慢。 当工作进程因内存不足 (OOM) 错误而失败时,它还可以提高容错能力。
import numpy as np
from PIL import Image
import litdata as ld

def random_images(index):
    fake_images = Image.fromarray(np.random.randint(0, 256, (32, 32, 3), dtype=np.uint8))
    fake_labels = np.random.randint(10)

    data = {"index": index, "image": fake_images, "class": fake_labels}

    return data

if __name__ == "__main__":
    # optimize 函数将数据写入优化后的格式。
    ld.optimize(
        fn=random_images,                   # 应用于每个输入的函数
        inputs=list(range(1000)),           # 函数的输入(这里是一个数字列表)
        output_dir="fast_data",             # 优化后的数据存储于此
        num_workers=4,                      # 同一台机器上的工作进程数
        chunk_bytes="64MB",                 # 每个数据块的大小
        keep_data_ordered=False,            # 使用共享队列来加速过程
    )
### 使用与不使用共享队列的性能差异: **注意**:以下基准测试是使用 ImageNet 数据集在具有 16 个工作进程的 A10G 机器上收集的。 | 配置 | 优化时间 (秒) | 流式加载 1 (图像/秒) | 流式加载 2 (图像/秒) | |------------------|---------------------|---------------------|---------------------| | 共享队列 (`keep_data_ordered=False`) | 1281 | 5392 | 5732 | | 无共享队列 (`keep_data_ordered=True (默认)`) | 1187 | 5257 | 5746 | 📌 注意:**shared_queue** 选项影响优化时间,而不是流式加载速度。 > 虽然流式加载数字可能看起来略有不同,但这是偶然的,并非由 shared_queue 引起。 > > 流式加载发生在优化之后,不涉及 shared_queue 所作用的进程间通信。 - 📄 使用共享队列有助于在工作进程之间平衡负载,尽管由于在进程之间发送项目时进行序列化的开销,可能会略微增加优化时间。 - ⚡ 然而,当某些工作进程比其他进程慢时,它可以显著提高优化性能。
✅ 使用 `Queue` 作为优化数据的输入 🔗   有时您没有要优化的静态输入列表——相反,您获得的是随时间流入的数据流。在这种情况下,您可以使用 multiprocessing.Queue 将数据馈送到 optimize() 函数中。 - 这在使用远程源(如网页抓取器、套接字或 API)收集数据时特别有用。 - 您还可以使用此设置来存储强化学习期间的 `replay buffer` 数据,然后将其流式加载回来用于训练。
from multiprocessing import Process, Queue
from litdata.processing.data_processor import ALL_DONE
import litdata as ld
import time

def yield_numbers():
    for i in range(1000):
        time.sleep(0.01)
        yield (i, i**2)

def data_producer(q: Queue):
    for item in yield_numbers():
        q.put(item)

    q.put(ALL_DONE)  # 用于指示完成的哨兵值

def fn(index):
    return index  # 用于演示的恒等函数

if __name__ == "__main__":
    q = Queue(maxsize=100)

    producer = Process(target=data_producer, args=(q,))
    producer.start()

    ld.optimize(
        fn=fn,                   # 处理每个项目的函数
        queue=q,                 # 👈 从此队列流式加载数据
        output_dir="fast_data",  # 存储优化数据的位置
        num_workers=2,
        chunk_size=100,
        mode="overwrite",
    )

    producer.join()
📌 注意:使用队列来优化数据集会影响优化时间,而不是流式加载速度。 > 无论工作进程数量如何,您只需要放置一个哨兵值来表示完成。 > > LitData 会在内部处理它。
✅ LLM 预训练 🔗   LitData 针对 LLM 预训练进行了高度优化。首先,我们需要对整个数据集进行分词,然后才能消费它。
import json
from pathlib import Path
import zstandard as zstd
from litdata import optimize, TokensLoader
from tokenizer import Tokenizer
from functools import partial

# 1. 定义一个函数,将 jsonl 文件中的文本转换为 tokens
def tokenize_fn(filepath, tokenizer=None):
    with zstd.open(open(filepath, "rb"), "rt", encoding="utf-8") as f:
        for row in f:
            text = json.loads(row)["text"]
            if json.loads(row)["meta"]["redpajama_set_name"] == "RedPajamaGithub":
                continue  # 排除 GitHub 数据,因为它与 starcoder 重叠
            text_ids = tokenizer.encode(text, bos=False, eos=True)
            yield text_ids

if __name__ == "__main__":
    # 2. 生成输入(我们将优化来自 SlimPajama 数据集的所有压缩 json 文件)
    input_dir = "./slimpajama-raw"
    inputs = [str(file) for file in Path(f"{input_dir}/SlimPajama-627B/train").rglob("*.zst")]

    # 3. 将优化后的数据存储在您想要的任何位置 "/teamspace/datasets" 或 "/teamspace/s3_connections"
    outputs = optimize(
        fn=partial(tokenize_fn, tokenizer=Tokenizer(f"{input_dir}/checkpoints/Llama-2-7b-hf")), # 注意:您可以使用 HF tokenizer 或任何其他
        inputs=inputs,
        output_dir="./slimpajama-optimized",
        chunk_size=(2049 * 8012),
        # 这很重要,用于告知 LitData 我们正在编码连续的 1D 数组(tokens)。
        # LitData 会跳过为每个样本存储元数据,例如所有 tokens 连接形成一个大张量。
        item_loader=TokensLoader(),
    )
import os
from litdata import StreamingDataset, StreamingDataLoader, TokensLoader
from tqdm import tqdm

# 加一,因为我们还需要下一个词
dataset = StreamingDataset(
  input_dir=f"./slimpajama-optimized/train",
  item_loader=TokensLoader(block_size=2048 + 1),
  shuffle=True,
  drop_last=True,
)

train_dataloader = StreamingDataLoader(dataset, batch_size=8, pin_memory=True, num_workers=os.cpu_count())

# 迭代 SlimPajama 数据集
for batch in tqdm(train_dataloader):
    pass
✅ 过滤非法数据 🔗   有时,您有不希望包含在优化数据集中的坏数据。使用 LitData,仅生成要包含的好数据样本。
from litdata import optimize, StreamingDataset

def should_keep(index) -> bool:
  # 替换为您自己的逻辑
  return index % 2 == 0

def fn(data):
    if should_keep(data):
        yield data

if __name__ == "__main__":
    optimize(
        fn=fn,
        inputs=list(range(1000)),
        output_dir="only_even_index_optimized",
        chunk_bytes="64MB",
        num_workers=1
    )

    dataset = StreamingDataset("only_even_index_optimized")
    data = list(dataset)
    print(data)
    # [0, 2, 4, 6, 8, 10, ..., 992, 994, 996, 998]
您甚至可以使用 try/except。
from litdata import optimize, StreamingDataset

def fn(data):
    try:
        yield 1 / data
    except:
        pass

if __name__ == "__main__":
    optimize(
        fn=fn,
        inputs=[0, 0, 0, 1, 2, 4, 0],
        output_dir="only_defined_ratio_optimized",
        chunk_bytes="64MB",
        num_workers=1
    )

    dataset = StreamingDataset("only_defined_ratio_optimized")
    data = list(dataset)
    # 0 被过滤掉,因为它们会引发除零错误
    print(data)
    # [1.0, 0.5, 0.25]
✅ 合并数据集 🔗   混合搭配不同的数据集以进行实验并创建更好的模型。 使用 `CombinedStreamingDataset` 合并数据集。例如,[Slimpajama](https://huggingface.co/datasets/cerebras/SlimPajama-627B) 和 [StarCoder](https://huggingface.co/datasets/bigcode/starcoderdata) 的这个混合被用于 [TinyLLAMA](https://github.com/jzhang38/TinyLlama) 项目,以在 3 万亿个 tokens 上预训练一个 1.1B 的 Llama 模型。 ```python from litdata import StreamingDataset, CombinedStreamingDataset, StreamingDataLoader, TokensLoader from tqdm import tqdm import os train_datasets = [ StreamingDataset( input_dir="s3://tinyllama-template/slimpajama/train/", item_loader=TokensLoader(block_size=2048 + 1), # 针对 LLM 使用的 tokens 进行了优化的加载器 shuffle=True, drop_last=True, ), StreamingDataset( input_dir="s3://tinyllama-template/starcoder/", item_loader=TokensLoader(block_size=2048 + 1), # 针对 LLM 使用的 tokens 进行了优化的加载器 shuffle=True, drop_last=True, ), ] # 按以下比例混合 SlimPajama 数据和 Starcoder 数据: weights = (0.693584, 0.306416) combined_dataset
1 次点击  ∙  0 人收藏  
登录后收藏  
0 条回复
关于 ·  帮助 ·  PING ·  隐私 ·  条款   
OA0 - Omni AI 0 一个探索 AI 的社区
沪ICP备2024103595号-2
耗时 18 ms
Developed with Cursor