nanochat 数据处理完全指南 本文档详细介绍 nanochat 项目的数据处理流程,适合初学者阅读。 数据源说明 本项目针对不同地区用户提供了优化的数据访问方案: 国内版(推荐) 预训练数据:使用 ModelScope 平台的 FineWeb-Edu 数据集(ModelScope) 优势:国内访问速度快、稳定性高、无需特殊网络配置 配置:项目已默认使用国内源,无需额外设置 国际版 预训练数据:使用 HuggingFace 原始数据集 FineWeb-Edu 原始数据集 适用:海外用户或需要访问原始数据源 配置:需要修改 中的数据源配置 目录 数据处理概览 数据类型与来源 数据处理流程 详细操作步骤 数据处理技术细节 数据检查工具集 数据格式说明 数据量计算 常见问题解答 数据处理概览
本文档详细介绍 nanochat 项目的数据处理流程,适合初学者阅读。
本项目针对不同地区用户提供了优化的数据访问方案:
nanochat/dataset.py 中的数据源配置nanochat 项目训练一个完整的 ChatGPT 风格的语言模型,需要经历三个主要阶段,每个阶段使用不同的数据:
数据来源:FineWeb-Edu 数据集
Datawhale/fineweb-edu-100b-shuffleHuggingFaceFW/fineweb-edunanochat/dataset.py 中的数据源配置数据特点:
下载方式:
# 下载 8 个分片用于训练分词器(约 800MB) python -m nanochat.dataset -n 8 # 下载 240 个分片用于预训练(约 24GB) python -m nanochat.dataset -n 240
数据来源:SmolTalk 对话数据集
HuggingFaceTB/smoltalk如果下载速度慢,可以设置 HuggingFace 镜像:
export HF_ENDPOINT=https://hf-mirror.com
数据结构示例:
{ "messages": [ { "role": "user", "content": "你好,请介绍一下自己" }, { "role": "assistant", "content": "你好!我是一个AI助手..." } ] }
数据来源:多个任务数据集的混合
总计:约 21.4K 条训练样本
所有微调数据集来自 HuggingFace,会在训练时自动下载。国内用户建议设置镜像:
export HF_ENDPOINT=https://hf-mirror.com
或在 Python 代码中设置:
import os os.environ['HF_ENDPOINT'] = 'https://hf-mirror.com'
目的:使用已经处理好的、适合流式加载的数据集
数据集特点:
已完成的预处理
数据集来源
HuggingFaceFW/fineweb-edu(sample-100BT)Datawhale/fineweb-edu-100b-shuffle(ModelScope)下载方式
# 项目已自动配置为从 ModelScope 下载 python -m nanochat.dataset -n 8
目的:将文本转换为模型可以处理的数字序列
过程(参考 scripts/tok_train.py):
准备训练数据
# 使用前 2B(20亿)字符训练分词器 python -m scripts.tok_train --max_chars=2000000000
训练 BPE 分词器
保存分词器
~/.cache/nanochat/tokenizer/什么是分词器?
分词器就像一个"翻译官",把人类的文字转换成模型能理解的数字:
目的:将文本转换为 token 序列,并按需加载
特点:
数据加载器工作原理:
代码实现:
# 伪代码示例 def tokenizing_distributed_data_loader(batch_size, seq_len, split): """ batch_size: 每个GPU的批次大小 seq_len: 序列长度(上下文窗口) split: "train" 或 "val" """ while True: # 1. 从磁盘读取一个 parquet 分片 shard = load_next_shard() # 2. 遍历分片中的文档 for doc in shard: text = doc['text'] # 3. 使用分词器转换文本 tokens = tokenizer.encode(text) # 4. 切分成固定长度的序列 for i in range(0, len(tokens) - seq_len, seq_len): inputs = tokens[i:i+seq_len] targets = tokens[i+1:i+seq_len+1] # 目标是输入向右偏移1位 # 5. 组装成批次 batch_inputs.append(inputs) batch_targets.append(targets) if len(batch_inputs) == batch_size: yield (batch_inputs, batch_targets) batch_inputs = [] batch_targets = []
为什么使用这种方式?
前提条件:
步骤:
# 1. 下载初始数据(用于训练分词器) python -m nanochat.dataset -n 8 # 2. 后台下载完整训练数据 python -m nanochat.dataset -n 240 & # 3. 训练分词器 python -m scripts.tok_train --max_chars=2000000000 # 4. 评估分词器 python -m scripts.tok_eval # 5. 开始预训练 torchrun --standalone --nproc_per_node=8 -m scripts.base_train --depth=20 # 6. 评估模型 torchrun --standalone --nproc_per_node=8 -m scripts.base_eval
或者直接运行一键脚本:
bash speedrun.sh
步骤 1:准备中文数据
创建数据下载脚本:
# download_chinese_data.py from datasets import load_dataset, concatenate_datasets import os print("下载中文数据集...") # 1. 中文维基百科 wiki = load_dataset("wikipedia", "20220301.zh", split="train[:100000]") print(f"维基百科: {len(wiki)} 条") # 2. 百度百科 baike = load_dataset("xusenlin/baidubaike-563w", split="train[:200000]") print(f"百度百科: {len(baike)} 条") # 3. 新闻数据 news = load_dataset("THUDM/LongBench", "news", split="train[:50000]") print(f"新闻数据: {len(news)} 条") # 合并数据集 combined = concatenate_datasets([wiki, baike, news]) # 数据清洗 import re def clean_text(example): text = example.get('text', example.get('content', '')) # 去除特殊字符,只保留中文、英文、数字和标点 text = re.sub(r'[^\u4e00-\u9fa5a-zA-Z0-9,。!?、;:""''()【】《》\s]', '', text) if len(text) < 50: # 过滤太短的文本 return None return {'text': text} combined = combined.map(clean_text) combined = combined.filter(lambda x: x is not None) print(f"\n清洗后数据量: {len(combined)} 条") # 保存为 parquet 格式 output_dir = os.path.expanduser("~/.cache/nanochat/chinese_data") os.makedirs(output_dir, exist_ok=True) # 分割成多个分片(每个约 10 万条) shard_size = 100000 num_shards = (len(combined) + shard_size - 1) // shard_size for i in range(num_shards): start = i * shard_size end = min(start + shard_size, len(combined)) shard = combined.select(range(start, end)) shard_path = f"{output_dir}/shard_{i:05d}.parquet" shard.to_parquet(shard_path, compression='zstd', compression_level=3) print(f"已保存 {shard_path}: {len(shard)} 条") print("\n中文数据准备完成!")
运行:
python download_chinese_data.py
验证中文数据质量:
# 1. 检查数据完整性 python -m data_check.check_data ~/.cache/nanochat/chinese_data # 2. 检查字符分布(验证中文比例) python -m data_check.check_char_distribution ~/.cache/nanochat/chinese_data/shard_00000.parquet # 3. 检查文本长度分布 python -m data_check.check_length_distribution ~/.cache/nanochat/chinese_data/shard_00000.parquet # 4. 抽样检查内容质量 python -m data_check.check_content_quality ~/.cache/nanochat/chinese_data/shard_00000.parquet 20
步骤 2:训练中文分词器
中文分词器需要更大的词汇表(因为中文字符更多):
# 修改 tok_train.py 中的 vocab_size 参数 python -m scripts.tok_train --max_chars=2000000000 --vocab_size=80000
步骤 3:修改训练配置
使用 configs/chinese_d20.yaml 配置文件,或手动指定参数:
torchrun --standalone --nproc_per_node=8 -m scripts.base_train \ --depth=20 \ --vocab_size=80000 \ --device_batch_size=16 # 中文模型可能需要调整批次大小
完整流程可参考:scripts/train_chinese.sh
数据格式要求:
每条数据是一个包含多轮对话的 JSON 对象:
{ "messages": [ { "role": "user", "content": "如何做番茄炒蛋?" }, { "role": "assistant", "content": "做番茄炒蛋的步骤如下:\n1. 准备材料:鸡蛋3个,番茄2个...\n2. 将鸡蛋打散..." }, { "role": "user", "content": "需要放糖吗?" }, { "role": "assistant", "content": "可以放一点点糖,能让番茄的酸味更柔和..." } ] }
准备数据步骤:
例如,使用 Belle 中文对话数据集:
from datasets import load_dataset # 下载 Belle 数据集 belle = load_dataset("BelleGroup/train_1M_CN", split="train[:100000]") # 转换为对话格式 def convert_format(example): instruction = example['instruction'] input_text = example.get('input', '') output = example['output'] if input_text: user_content = f"{instruction}\n\n{input_text}" else: user_content = instruction return { "messages": [ {"role": "user", "content": user_content}, {"role": "assistant", "content": output} ] } converted = belle.map(convert_format) # 保存为 JSONL 格式 output_dir = os.path.expanduser("~/.cache/nanochat/chinese_sft") os.makedirs(output_dir, exist_ok=True) converted.to_json(f"{output_dir}/belle_100k.jsonl")
参考 tasks/smoltalk.py 创建自定义数据加载器:
# tasks/my_chinese_chat.py from tasks.common import Task class MyChineseChat(Task): def __init__(self, split, stop=None): from datasets import load_dataset # 从本地 JSONL 文件加载 data_path = "~/.cache/nanochat/chinese_sft/belle_100k.jsonl" ds = load_dataset("json", data_files=data_path, split="train") # 分割训练/验证集 ds = ds.train_test_split(test_size=0.1, seed=42) self.data = ds[split] if stop is not None: self.data = self.data.select(range(min(stop, len(self.data)))) def __len__(self): return len(self.data) def __getitem__(self, idx): return self.data[idx]
修改 scripts/chat_sft.py:
from tasks.my_chinese_chat import MyChineseChat train_ds = TaskMixture([ MyChineseChat(split="train", stop=10_000), # 可以混合其他任务... ])
为什么要分片?
分片大小的选择:
默认比例:99% 训练,1% 验证
实现方式:
# 伪代码 total_shards = 240 train_shards = int(total_shards * 0.99) # 237 val_shards = total_shards - train_shards # 3 if split == "train": shard_indices = range(0, train_shards) else: # "val" shard_indices = range(train_shards, total_shards)
为什么验证集这么小?
问题:文档长度不一,如何高效利用?
解决方案:连续拼接
示例:
文档1: "The cat sat on" (5 tokens) 文档2: "Hello world" (2 tokens) 文档3: "Machine learning is" (3 tokens) 拼接后(假设 seq_len=8): ["The", "cat", "sat", "on", "Hello", "world", "Machine", "learning"]
优点:
注意事项:
为什么要混洗?
两级混洗:
多 GPU 场景:
代码实现:
# GPU 0 加载分片 0, 8, 16, 24... # GPU 1 加载分片 1, 9, 17, 25... # GPU 2 加载分片 2, 10, 18, 26... # ... shard_idx = (global_shard_count + ddp_rank) % total_shards
好处:
项目提供了完整的数据检查和处理工具集(位于 data_check/ 目录),帮助您验证数据质量、分析数据特征,并转换自定义数据。
| 工具 | 功能 | 适用场景 |
|---|---|---|
check_data |
检查 Parquet 文件完整性 | 验证数据下载是否完整、检测损坏文件 |
check_length_distribution |
分析文本长度分布 | 评估数据长度分布,识别过短或过长文本 |
check_content_quality |
随机抽样检查内容质量 | 手动检查样本质量,自动检测重复和乱码 |
check_char_distribution |
统计字符分布 | 分析中英文比例,评估数据语言组成 |
convert_custom_data |
转换自定义文本数据 | 将文本文件转换为标准 Parquet 格式 |
check_data)作用:验证 Parquet 数据文件的完整性,检测损坏或空文件
用法:
# 检查默认数据目录 python -m data_check.check_data # 检查指定目录 python -m data_check.check_data ~/.cache/nanochat/base_data # 检查自定义数据目录 python -m data_check.check_data ~/.cache/nanochat/my_data
输出示例:
============================================================ 数据完整性检查工具 ============================================================ 找到 240 个 Parquet 文件 位置: ~/.cache/nanochat/base_data ============================================================ 检查进度: ============================================================ [ 1/240] shard_00000.parquet: 12,345 条数据 [ 2/240] shard_00001.parquet: 12,356 条数据 ... [240/240] shard_00239.parquet: 12,389 条数据 ============================================================ 检查结果: ============================================================ 所有文件完整! 统计信息: 文件数量: 240 总数据量: 2,967,840 条 平均每文件: 12,366 条
使用场景:
check_length_distribution)作用:分析文本长度分布,识别过短或过长的文本,评估数据质量
用法:
# 检查单个文件 python -m data_check.check_length_distribution ~/.cache/nanochat/base_data/shard_00000.parquet # 检查自定义数据 python -m data_check.check_length_distribution ~/.cache/nanochat/my_data/shard_00000.parquet
输出示例:
正在分析: ~/.cache/nanochat/base_data/shard_00000.parquet 长度统计: 总样本数: 12,345 平均长度: 1,234 字符 最短: 156 字符 最长: 8,932 字符 长度分布: < 50 字符: █ 2.3% (284) 50-100 字符: ██ 5.1% (629) 100-500 字符: ████████████████████ 45.2% (5,579) 500-1000 字符: ████████████████ 32.1% (3,963) 1000-2000 字符: ████████ 12.5% (1,543) 2000-5000 字符: ███ 2.6% (321) > 5000 字符: █ 0.2% (25) 数据质量评估: 平均长度合理 (500-2000 字符) 超短文本比例正常 超长文本比例正常
使用场景:
check_content_quality)作用:随机抽取样本进行内容质量检查,自动检测重复文本和乱码
用法:
# 默认抽样 10 条 python -m data_check.check_content_quality ~/.cache/nanochat/base_data/shard_00000.parquet # 指定抽样数量 python -m data_check.check_content_quality ~/.cache/nanochat/base_data/shard_00000.parquet 20
输出示例:
正在从 ~/.cache/nanochat/base_data/shard_00000.parquet 抽样... ============================================================ 随机抽样检查 (共 10 条) ============================================================ ──────────────────────────────────────────────────────────── 样本 1/10 ──────────────────────────────────────────────────────────── 长度: 1,234 字符 The quick brown fox jumps over the lazy dog... ============================================================ 内容质量检查清单: ============================================================ 请手动检查以上样本,确认: 句子完整,语法正确 没有大量乱码 没有大量重复内容 内容有意义,信息量足够 自动检测结果: 无完全重复的文本 无极短文本 无明显乱码
使用场景:
check_char_distribution)作用:统计中英文、数字、标点等字符的分布比例,评估数据语言组成(特别适用于中文数据)
用法:
# 检查字符分布 python -m data_check.check_char_distribution ~/.cache/nanochat/base_data/shard_00000.parquet # 检查中文数据 python -m data_check.check_char_distribution ~/.cache/nanochat/chinese_data/shard_00000.parquet
输出示例:
正在分析: ~/.cache/nanochat/chinese_data/shard_00000.parquet ============================================================ 字符分布统计 ============================================================ 总字符数: 1,234,567 中文字符: ████████████████████████████████████████ 78.5% (968,635) 英文字符: ████ 6.2% (76,543) 数字: █ 1.8% (22,222) 空白字符: ████ 8.1% (99,999) 标点符号: ████ 4.2% (51,852) 其他字符: █ 1.2% (14,816) ============================================================ 数据质量评估 (针对中文数据) ============================================================ 中文字符比例正常 (70-90%) 英文字符比例正常 (5-20%) 数字比例正常 (1-5%) ============================================================ 最常见的20个字符 ============================================================ 1. '的' : 45,678 (3.70%) 2. '是' : 23,456 (1.90%) 3. ' ' : 18,765 (1.52%) ...
使用场景:
convert_custom_data)作用:将文本文件转换为标准 Parquet 格式,方便用于训练
用法:
data_check/convert_custom_data.py 中的参数:# 方法1: 从单个文件读取 input_file = "my_data.txt" # 方法2: 从目录读取多个文件 input_dir = "my_texts" # 输出目录 output_dir = os.path.expanduser("~/.cache/nanochat/my_data") # 最小文本长度(过滤过短文本) min_length = 50 # 每个分片的文本数量 shard_size = 100
python -m data_check.convert_custom_data
工具功能:
输出示例:
============================================================ 自定义数据转换工具 ============================================================ 从 my_texts 读取 1,234 条文本 保存: ~/.cache/nanochat/my_data/shard_00000.parquet (100 条) 保存: ~/.cache/nanochat/my_data/shard_00001.parquet (100 条) ... 保存: ~/.cache/nanochat/my_data/shard_00012.parquet (34 条) 转换完成! 数据保存在: ~/.cache/nanochat/my_data
使用场景:
数据验证流程:
# 1. 下载数据后,检查完整性 python -m data_check.check_data # 2. 检查数据长度分布 python -m data_check.check_length_distribution ~/.cache/nanochat/base_data/shard_00000.parquet # 3. 抽样检查内容质量 python -m data_check.check_content_quality ~/.cache/nanochat/base_data/shard_00000.parquet 20 # 4. 如果是中文数据,检查字符分布 python -m data_check.check_char_distribution ~/.cache/nanochat/base_data/shard_00000.parquet
自定义数据处理流程:
# 1. 转换自定义数据 python -m data_check.convert_custom_data # 2. 验证转换后的数据 python -m data_check.check_data ~/.cache/nanochat/my_data # 3. 检查数据质量 python -m data_check.check_length_distribution ~/.cache/nanochat/my_data/shard_00000.parquet python -m data_check.check_content_quality ~/.cache/nanochat/my_data/shard_00000.parquet
什么是 Parquet?
文件结构:
读取方式:
import pyarrow.parquet as pq # 读取整个文件 table = pq.read_table("shard_00000.parquet") texts = table["text"].to_pylist() # 只读取部分行(高效) table = pq.read_table("shard_00000.parquet", columns=["text"], filters=[("row_id", ">=", 0), ("row_id", "<", 1000)])
什么是 JSONL?
示例文件:
{"messages": [{"role": "user", "content": "你好"}, {"role": "assistant", "content": "你好!"}]} {"messages": [{"role": "user", "content": "天气怎么样?"}, {"role": "assistant", "content": "今天天气不错。"}]}
读取方式:
import json with open("data.jsonl", "r", encoding="utf-8") as f: for line in f: data = json.loads(line) print(data["messages"])
Chinchilla 原则:数据量 = 模型参数量 × 20
计算示例:
以默认的 d20 模型为例:
| 模型 | 参数量 | Token 数 | 字符数 | 分片数 | 磁盘空间 |
|---|---|---|---|---|---|
| d12 | 123M | 2.5B | 12B | 48 | 4.8GB |
| d20 | 561M | 11.2B | 54B | 240 | 24GB |
| d26 | 1.2B | 24B | 115B | 450 | 45GB |
| d32 | 2.1B | 42B | 200B | 800 | 80GB |
A1: 项目已优化为使用 ModelScope
项目已经默认配置为从 ModelScope 下载数据,国内用户可以直接享受高速下载:
Datawhale/fineweb-edu-100b-shuffle (ModelScope)对于其他 HuggingFace 数据集(如 SmolTalk 等):
# 方法1: 设置环境变量 export HF_ENDPOINT=https://hf-mirror.com # 方法2: 使用 setup_china.sh 脚本(如果提供) bash scripts/setup_china.sh
参考配置:configs/chinese_d20.yaml
mirrors: huggingface: "https://hf-mirror.com" pip: "https://pypi.tuna.tsinghua.edu.cn/simple"
A2: 减少数据量
训练更小的模型:
# d12 模型只需要 48 个分片(约 5GB) python -m nanochat.dataset -n 48 python -m scripts.base_train --depth=12
或者:使用更多 epoch(重复使用数据)
# 修改 base_train.py target_param_data_ratio = 10 # 从 20 降到 10
注意:数据量减少会影响模型性能!
A3: 使用数据检查工具
项目提供了专门的数据检查工具来验证数据完整性:
# 方法1: 使用数据完整性检查工具(推荐) python -m data_check.check_data # 检查指定目录的数据 python -m data_check.check_data ~/.cache/nanochat/base_data
工具功能:
手动检查方法(备选):
# 查看已下载的分片 ls -lh ~/.cache/nanochat/base_data/ # 统计分片数量 ls ~/.cache/nanochat/base_data/*.parquet | wc -l # 检查某个分片的内容 python -c " import pyarrow.parquet as pq table = pq.read_table('~/.cache/nanochat/base_data/shard_00000.parquet') print(f'Rows: {len(table)}') print(f'Columns: {table.column_names}') print(f'First text: {table[\"text\"][0]}') "
A4: 可以!
步骤:
准备数据:整理成文本文件或 JSONL 格式
转换为 Parquet 格式:
方法1: 使用数据转换工具(推荐)
项目提供了便捷的数据转换工具 data_check.convert_custom_data:
# 修改 convert_custom_data.py 中的配置 # - input_file: 单个文本文件路径,或 # - input_dir: 包含多个 .txt 文件的目录 # - output_dir: 输出 Parquet 文件的目录 # - min_length: 最小文本长度(默认50字符) # - shard_size: 每个分片的文本数量(默认100) # 运行转换工具 python -m data_check.convert_custom_data
工具功能:
方法2: 手动转换(高级用户)
import pyarrow.parquet as pq import pyarrow as pa # 你的文本数据 texts = ["text1", "text2", "text3", ...] # 转换为 Parquet table = pa.Table.from_pydict({"text": texts}) pq.write_table( table, "~/.cache/nanochat/my_data/shard_00000.parquet", row_group_size=1024, compression="zstd", compression_level=3 )
# 使用数据检查工具验证 python -m data_check.check_data ~/.cache/nanochat/my_data # 检查数据质量 python -m data_check.check_content_quality ~/.cache/nanochat/my_data/shard_00000.parquet
# 在 nanochat/dataloader.py 中修改 base_dir base_dir = "~/.cache/nanochat/my_data"
A5: 看情况
默认数据(FineWeb-Edu):
自定义数据:
建议进行:
使用数据质量检查工具:
项目提供了多个数据质量检查工具,帮助您评估和验证数据:
# 1. 检查文本长度分布 # 作用:分析文本长度分布,识别过短或过长的文本 python -m data_check.check_length_distribution ~/.cache/nanochat/my_data/shard_00000.parquet # 2. 随机抽样检查内容质量 # 作用:随机抽取样本,手动检查内容质量,自动检测重复和乱码 python -m data_check.check_content_quality ~/.cache/nanochat/my_data/shard_00000.parquet 20 # 3. 检查字符分布(适用于中文数据) # 作用:统计中英文、数字、标点等字符的分布比例,评估数据语言组成 python -m data_check.check_char_distribution ~/.cache/nanochat/my_data/shard_00000.parquet
清洗脚本示例:
import re def clean_text(text): # 去除多余空白 text = re.sub(r'\s+', ' ', text) # 去除特殊字符(可选) text = re.sub(r'[^\w\s\u4e00-\u9fa5,。!?、;:""''()]', '', text) # 去除太短的文本 if len(text) < 50: return None # 去除重复字符 text = re.sub(r'(.)\1{10,}', r'\1\1\1', text) # 连续重复超过10次 return text # 应用清洗 cleaned_texts = [clean_text(t) for t in texts] cleaned_texts = [t for t in cleaned_texts if t is not None]
A6: 使用权重混合
在微调阶段,可以混合多个数据集:
from tasks.common import TaskMixture from tasks.arc import ARC from tasks.gsm8k import GSM8K from tasks.smoltalk import SmolTalk # 方法1: 按数量混合(默认) train_ds = TaskMixture([ ARC(split="train"), # 2.3K GSM8K(split="train"), # 8K SmolTalk(split="train"), # 10K ]) # 总共 20.3K,会循环较小的数据集 # 方法2: 手动控制比例 train_ds = TaskMixture([ ARC(split="train", stop=10_000), # 取10K(会重复) GSM8K(split="train", stop=10_000), # 取10K(会重复) SmolTalk(split="train", stop=10_000), # 取10K ]) # 每个数据集贡献相同数量 # 方法3: 在数据生成器中控制 def weighted_data_generator(datasets, weights): """ datasets: 数据集列表 weights: 权重列表(和为1) """ import random while True: # 按权重随机选择数据集 dataset = random.choices(datasets, weights=weights)[0] # 随机选择该数据集中的一个样本 idx = random.randint(0, len(dataset) - 1) yield dataset[idx] # 使用:70% SmolTalk, 20% GSM8K, 10% ARC gen = weighted_data_generator( [smoltalk_ds, gsm8k_ds, arc_ds], [0.7, 0.2, 0.1] )
A7: 可以,但不推荐
理论上可以:
风险:
最佳实践:
A8: 使用性能分析工具
import time # 在训练脚本中添加计时 t0 = time.time() x, y = next(train_loader) t1 = time.time() data_loading_time = t1 - t0 # 计算数据加载占比 if data_loading_time > step_time * 0.1: print(f"警告: 数据加载慢:{data_loading_time:.2f}s / {step_time:.2f}s")
优化建议:
num_workers(多进程加载)训练后,数据会保存在以下位置:
~/.cache/nanochat/base_data/ - 预训练数据(shard_00000.parquet, shard_00001.parquet, ...)~/.cache/nanochat/tokenizer/ - 分词器文件(tokenizer.json, merges.txt)~/.cache/nanochat/tokenized_data/ - 分词后的数据(可选)
train/ - 训练数据(tokens_00000.bin, ...)val/ - 验证数据(tokens_00000.bin)~/.cache/nanochat/base_checkpoints/ - 预训练检查点(d20/model.pt, optimizer.pt, meta.json)~/.cache/nanochat/mid_checkpoints/ - 中期训练检查点(d20/)~/.cache/nanochat/sft_checkpoints/ - 微调检查点(d20/)~/.cache/nanochat/eval_bundle/ - 评估数据(arc/, gsm8k/, ...)磁盘空间规划:
使用官方数据集开始
speedrun.sh逐步扩大规模
监控数据质量
充分利用缓存
文档记录
不要跳过数据验证
不要过度清洗
不要忽视版权
不要盲目增加数据
对于小数据集,可以考虑:
逐步增加数据难度:
未来可以加入:
本项目已针对不同地区用户进行优化:
Datawhale/fineweb-edu-100b-shuffle,国内访问速度快python -m nanochat.dataset -n 8 即可开始下载export HF_ENDPOINT=https://hf-mirror.comHuggingFaceFW/fineweb-edunanochat/dataset.py 中的数据源配置nanochat 的数据处理流程设计精巧:
理解数据处理是训练好模型的关键第一步!
有问题?
dev/repackage_data_reference.pybash speedrun.sh快乐训练!‘