AI数据切片


AI数据切片


AI全场景数据切片(切分)完整指南

一、先搞懂:数据切片是什么

数据切片 = 按照固定规则把完整数据集分割成多份独立子集,是训练、推理、RAG、微调、评估全链路必备操作,核心目的:

  1. 防止过拟合、精准评估模型泛化能力
  2. 适配模型上下文窗口限制(长文本截断切块)
  3. 分布式训练拆分负载、批量推理
  4. 数据集分层,保证各类别分布均衡

二、AI各大场景切片用途 + 实操切分方案

场景1:大模型微调(SFT/RLHF)数据集划分(最常用)

  1. 传统强化学习方法,如RLHF(Reinforcement Learning from Human Feedback,基于人类反馈的强化学习)和RLAF(Reinforcement Learning from AI Feedback,基于人工智能反馈的强化学习)。这些方法需要训练一个奖励模型,并涉及复杂且通常不稳定的过程,使用算法如近端策略优化(PPO)来优化策略模型。
  2. 简化方法,如DPO和RPO。这些方法摒弃了奖励模型,提供了一个稳定、高效且计算效率高的解决方案。从监督微调到偏好优化当下最流行的LLMs训练流程大概可以分为以下三步:预训练(Pre-Training,PT)、监督微调(Supervised Fine-Tuning,SFT)和偏好优 (PreferenceOptimization,PO).

用途:把标注好的 instruction/input/output 完整数据集切分,训练集、验证集、测试集三分离,避免用训练数据评估,判断过拟合。

标准切分规则:

  1. 固定比例通用方案
    • 训练集 Train:80%(模型学习参数)
    • 验证集 Val:10%(训练中途监控loss、调超参)
    • 测试集 Test:10%(训练完成后最终效果评估,全程不参与训练)
  2. 分层切分 Stratified Split(推荐)
    • 若数据有多类任务(比如你有「周报优化」「接口汇报优化」两类样本),切分时保证三类子集里两类样本占比和原数据集一致,避免子集分布失衡。
  3. 代码示例(Python)
from sklearn.model_selection import train_test_split
import json

data = json.load(open("train.json"))
# 先切出测试集
train_val, test = train_test_split(data, test_size=0.1, random_state=42)
# 再切训练、验证
train, val = train_test_split(train_val, test_size=0.11, random_state=42)
# 保存三份独立文件
json.dump(train, open("train_split.json", "w", encoding="utf-8"))
json.dump(val, open("val_split.json", "w", encoding="utf-8"))
json.dump(test, open("test_split.json", "w", encoding="utf-8"))

特殊:交叉验证 K-Fold 切片

小数据集(样本<1000)用:将全集切k份,轮流1份做验证、剩余做训练,消除切分随机性误差。


场景2:RAG知识库长文本切块(Chunk切片,你正在做的周报知识库)

核心痛点:大模型上下文窗口有限(如8k/32k),PDF/长文档完整文本无法直接送入Embedding,必须切片。

4种主流切分方式:

  1. 固定长度滑动窗口切分(最通用)
    • 规则:设定块长度(如512token)+ 重叠区间(overlap=60~120token)
    • 作用:重叠防止语义被截断、上下文断裂;适合无明显分段的纯流水账文档
    • 示例:文本总长1000token,块长500,重叠100 → 块1[0-500]、块2[400-900]、块3[800-1000]
  2. 语义分割(高级,LangChain/LlamaIndex)
    • 通过Embedding判断句子语义相似度,语义断层处自动切分,不会把完整一句话拆两半,适合规范报告、合同、技术文档。
  3. 结构化分层切分
    • 按文档天然标记切割:标题#、段落换行、分页符、Markdown层级,优先保证完整章节为一块,适配你的周报知识库。
  4. 递归字符切分
    • 优先级拆分:换行→句号→逗号→空格,优先保留完整语义单元,再控制最大token长度。

实操参数参考(业务文档):

  • 块大小 chunk_size:400~800 token
  • 重叠 chunk_overlap:块长的10%~20%
  • 工具:LangChain RecursiveCharacterTextSplitter
from langchain.text_splitter import RecursiveCharacterTextSplitter

splitter = RecursiveCharacterTextSplitter(
    chunk_size=600,
    chunk_overlap=80,
    separators=["\n\n", "\n", "。", ",", " "]
)
chunks = splitter.split_text(long_report_text)

场景3:训练推理时的Batch批量切片

用途:显存不足以一次性加载全部数据,把数据集切成小批次送入模型前向传播。

切分逻辑:

  1. 设定 batch_size(如8/16/32),自动按顺序切片;
  2. 每个epoch开始前打乱数据集,再切片,避免模型记住固定批次顺序;
  3. 分布式训练:额外做分片切片,不同GPU分配独立数据子集。
from torch.utils.data import DataLoader, Dataset

class ReportDataset(Dataset):
    def __getitem__(self, idx):
        return self.data[idx]
    def __len__(self):
        return len(self.data)

loader = DataLoader(dataset, batch_size=16, shuffle=True) # 自动切片batch

场景4:计算机视觉CV领域图像切片

  1. 大图分割:遥感图、医疗影像超大图,切成固定尺寸小图训练推理;
  2. 滑动窗口切块推理:检测大图中小目标,重叠切片避免边缘物体漏检;
  3. 数据集划分:和NLP微调一致,train/val/test分层切分。

场景5:向量数据库切片(向量分片存储)

海量百万/亿级向量无法单表存储,按规则切片分库:

  1. 哈希分片:文本hash取模,均匀分到多个向量库;
  2. 业务分片:按文档类型、时间、业务模块切片(周报/接口文档分开存);
  3. 范围分片:向量ID区间切片。

场景6:数据预处理清洗切片

  1. 流式大数据切片:日志、业务数据流按时间窗口切片(每小时/每日切片);
  2. 脏数据隔离切片:把异常样本单独切分,不混入训练集;
  3. 多模态对齐切片:图文配对数据,成对切片保证图文一一对应。

三、切片核心通用原则(避坑)

  1. 信息不丢失 RAG切块必须加overlap重叠;微调数据集切分不能打乱样本配对(instruction-output不能拆分)。
  2. 分布一致 分层切分 Stratified,训练/验证/测试集任务、类别占比和原数据相同,否则评估失真。
  3. 边界适配模型 RAG块长度必须小于Embedding、LLM上下文上限;Batch大小匹配显卡显存。
  4. 不可数据泄露 验证/测试集绝对不能出现在训练切片中;RAG检索文档不能混入测试集样本。

四、结合你当前业务的切片落地总结

  1. 微调周报数据集:8:1:1分层切分 train/val/test;
  2. 周报知识库RAG:递归滑动窗口切块,chunk_size=600,overlap=80;
  3. 模型训练:Dataloader自动batch切片,shuffle打乱;
  4. 多Agent流水线:上游输出长文本,先切片再送入Embedding检索。

针对上面第四点展开

结合你的「周报优化AI代理+RAG+大模型微调」业务,数据切片全流程详细落地讲解

你的完整业务链路分为三块核心场景,每一块都有专属切片逻辑、参数、代码、避坑要点,全部贴合你之前做的口语周报转专业报告项目:

  1. 微调SFT数据集切片(训练模型用)
  2. RAG知识库长文档Chunk切块(智能代理检索用)
  3. 模型训练/推理Batch切片(训练阶段显存分片)

一、场景1:周报优化微调数据集切片(Alpaca格式 instruction/input/output

1. 业务场景说明

你批量生成了大量训练样本,每条结构: {"instruction":"优化报告","input":"口语化工作记录","output":"<thinking>推理过程</thinking>完整专业周报"} 总样本量几百~上万条,需要切分训练集、验证集、测试集,用来微调大模型、评估模型优化效果。

2. 切分目标

  1. 训练集:80%,模型学习周报优化逻辑、CoT思维链、专业行文风格;
  2. 验证集:10%,训练过程实时监控loss,调整学习率、epoch等超参数;
  3. 测试集:10%,训练完全结束后做最终效果打分,全程不能参与训练,防止数据泄露、评估虚高。

3. 切分方案:分层随机切分 Stratified Split

分层依据

你的样本分两类,必须保证三份子集内两类样本比例和原始全集一致:

  • 类别A:通用项目周报样本(会议、数据模型、接口综合场景)
  • 类别B:专项接口开发周报样本(接口联调、测试环境问题场景) 如果简单随机切分,可能出现验证集全是接口样本、训练集全是通用周报,模型评估结果失真。

标准切分比例与流程

  1. 全集 → 先切出10%作为固定测试集(永久封存,不参与任何训练调参)
  2. 剩余90% → 再切10%作为验证集(占总数据9%),剩下81%为训练集,比例换算:train:val:test = 8:1:1

完整可运行Python代码

import json
from sklearn.model_selection import train_test_split

# 1. 读取你生成的完整周报微调数据集
with open("full_report_dataset.json", "r", encoding="utf-8") as f:
    all_data = json.load(f)

# 2. 给每条样本打分类标签,用于分层切分
labels = []
for item in all_data:
    raw_input = item["input"]
    if "接口" in raw_input and "联调" in raw_input:
        labels.append("interface")  # B类:接口专项样本
    else:
        labels.append("general")    # A类:通用项目周报样本

# 3. 第一层切分:分出10%测试集
train_val_data, test_data, train_val_label, test_label = train_test_split(
    all_data, labels, test_size=0.1, random_state=42, stratify=labels
)

# 4. 第二层切分:剩余90%里分出10%验证集(相对全集10%)
train_data, val_data, train_label, val_label = train_test_split(
    train_val_data, train_val_label, test_size=0.11, random_state=42, stratify=train_val_label
)

# 5. 保存三份独立文件,分别用于训练、验证、测试
def save_json(data, path):
    with open(path, "w", encoding="utf-8") as f:
        json.dump(data, f, ensure_ascii=False, indent=2)

save_json(train_data, "train.json")
save_json(val_data, "val.json")
save_json(test_data, "test.json")

print(f"训练集:{len(train_data)} 条")
print(f"验证集:{len(val_data)} 条")
print(f"测试集:{len(test_data)} 条")

4. 业务专属避坑规则

  1. 禁止样本割裂:每条样本instruction/input/output必须整体切片,不能单独把output/input拆开;
  2. 测试集严禁复用:调Prompt、调超参时不能读取test.json,只能用val.json,否则会造成数据泄露,上线后真实效果暴跌;
  3. 固定随机种子random_state=42:每次切分结果完全一致,方便复现实验、对比不同模型效果;
  4. 小样本(总样本<500)升级方案:改用5折K-Fold交叉切片,消除单次切分带来的偶然性误差。

二、场景2:RAG知识库长文本Chunk切块(AI代理检索核心切片)

1. 业务场景说明

你的AI代理支持调取知识库,知识库存储两类长文档:

  1. 历史优质周报范文(完整Markdown长文档,几千字)
  2. 企业汇报规范、项目文档标准(制度类长文本)

大模型/Embedding存在token长度上限(如bge嵌入模型上限512token,LLM窗口8k),完整长文本无法直接向量化入库,必须切片分块。

2. 切分目标

  1. 单块长度适配Embedding模型上限,不截断语义;
  2. 块之间设置重叠,避免段落边界的信息丢失;
  3. 优先按照周报天然层级(标题、分段)切割,不把完整一段汇报拆碎。

3. 切分方案:递归字符滑动窗口切分(适配Markdown周报)

核心参数(专为你的周报业务调试)

  • chunk_size = 600 token(单块最大长度,适配BGE嵌入模型)
  • chunk_overlap = 80 token(重叠占块长13%,防止上下文断裂)
  • 切割分隔符优先级(从高到低):\n\n(大段落换行)> #(Markdown标题)> \n(单行换行)> (句号)> (逗号)

完整可运行代码(LangChain)

from langchain.text_splitter import RecursiveCharacterTextSplitter

# 初始化适配周报文档的切片器
report_splitter = RecursiveCharacterTextSplitter(
    chunk_size=600,
    chunk_overlap=80,
    separators=[
        "\n\n",
        "## ",
        "# ",
        "\n",
        "。",
        ","
    ],
    length_function=len
)

# 示例:读取一份完整历史周报长文本
long_report_doc = """
# 【XX项目】启动阶段工作周报
## 一、本周工作核心概要
本周,我们围绕【XX项目】的启动阶段,重点开展了需求深度对齐、技术方案初步设计及跨部门协同工作。
## 二、重点工作进展与成果
1. 需求共识达成,规避项目风险
   - 本周组织召开了3场跨部门需求评审会...
......(省略数千字长文本)
"""

# 执行切片,生成可入库的文本块
chunk_list = report_splitter.split_text(long_report_doc)

# 遍历打印每一块,查看切片效果
for idx, chunk in enumerate(chunk_list):
    print(f"===== 切片块{idx+1} =====")
    print(chunk)
    print("字符长度:", len(chunk))

4. 业务专属切分优势

  1. 优先按标题切割:周报的一级、二级标题会作为分割边界,不会把「本周工作概要」和「下一步计划」强行切到同一块;
  2. 重叠80token解决边界丢失问题:比如一块末尾写到“接口联调进度80%”,下一块开头重复这段内容,检索时不会丢失关键信息;
  3. 适配RAG检索逻辑:用户提问“接口开发进展”时,向量库只会召回包含接口相关的小块,不会传入整篇几千字周报,节省上下文窗口、减少模型幻觉。

5. 避坑要点

  1. 不要设置chunk_size超过Embedding最大输入长度(BGE最大512token,建议块长控制在600字符以内);
  2. overlap不能过大(超过块长20%会造成向量库大量重复数据,检索冗余);
  3. 不要使用纯固定字符切割(仅按500字符硬切),会把完整一句话、完整工作模块拆成两半,检索精度大幅下降。

三、场景3:模型训练/推理Batch批量切片(微调训练阶段)

1. 业务场景说明

微调大模型时,train.json动辄几千条样本,显卡显存无法一次性加载全部数据,需要把数据集切成小批次(Batch)循环送入模型做前向传播、反向梯度更新。 同时AI代理在线推理时,批量用户请求也会做Batch切片,提升并发吞吐量。

2. 切分目标

  1. 单批次数据量匹配显卡显存,避免OOM显存溢出;
  2. 每个训练轮次(epoch)开始前打乱样本顺序,防止模型记住固定批次顺序;
  3. 分布式多卡训练时,额外做数据分片切片,每张GPU分配独立子集。

3. 切分方案:DataLoader自动Batch切片(PyTorch微调通用)

适配你的周报数据集完整代码
import json
from torch.utils.data import Dataset, DataLoader

# 自定义周报微调数据集
class ReportSFTDataSet(Dataset):
    def __init__(self, data_path):
        with open(data_path, "r", encoding="utf-8") as f:
            self.data = json.load(f)

    def __len__(self):
        return len(self.data)

    def __getitem__(self, idx):
        # 读取单条样本,拼接成模型输入prompt
        item = self.data[idx]
        prompt = f"""
# Role:资深项目汇报秘书
# Task:优化口语化工作记录为专业周报
# Input:{item["input"]}
# Output:{item["output"]}
"""
        return prompt

# 加载训练集
train_dataset = ReportSFTDataSet("train.json")

# 自动批量切片:batch_size=8,每轮训练前打乱数据
train_loader = DataLoader(
    train_dataset,
    batch_size=8,    # 每批次8条样本,根据显存调整
    shuffle=True,    # 每个epoch自动打乱数据集再切片
    drop_last=False  # 不足一个batch的剩余样本保留,不丢弃
)

# 训练循环,逐批次读取切片后的数据
for batch_idx, batch_texts in enumerate(train_loader):
    # batch_texts 就是切片后的一批样本,送入模型编码、计算loss
    print(f"批次{batch_idx},当前批次样本数:{len(batch_texts)}")
    # model.train_step(batch_texts)
业务参数适配
  • 单卡16G显存:batch_size=8
  • 单卡24G/40G显存:batch_size=16/32

4. 在线推理切片(AI代理并发场景)

当多用户同时调用你的周报优化Agent,请求队列会做批量切片:

  1. 收集N条用户提问,切成batch=4/8批量送入LLM推理;
  2. 相比单条串行推理,大幅提升QPS并发能力;
  3. 同样限制单batch总token长度,防止超出模型上下文窗口。

5. 避坑要点

  1. 训练集必须开启shuffle=True,验证/测试集关闭shuffle,保证评估稳定;
  2. 微调时batch过大会出现梯度爆炸,过小会训练速度慢,需要根据显存平衡;
  3. 分布式训练不能直接全局打乱切片,需要先按GPU数量分片,再分片内打乱。

四、三大切片场景串联你的完整业务流程(端到端链路)

1. 原始口语记录 → 批量生成带CoT的周报样本 → 【数据集切片】train/val/test.json
        ↓
2. train.json送入微调框架 → DataLoader【Batch切片】分批训练大模型
        ↓
3. 历史优质周报、企业规范文档 → 【RAG文本Chunk切片】分块向量化存入向量库
        ↓
4. 用户使用AI代理输入口语记录
    ① 意图Agent判断需要RAG检索 → 向量库匹配切片后的文档块
    ② 检索块+用户原文送入微调后的大模型
    ③ 模型生成带CoT的专业周报
    ④ 校验Agent输出最终结果

五、三类切片核心差异总结(业务区分)

切片类型 作用对象 核心目的 你的业务核心参数
数据集分层切片 完整微调样本集 划分训练/验证/测试,精准评估模型泛化能力 8:1:1分层切分,random_state=42
RAG文本Chunk切块 长文档(周报/规范) 适配Embedding、LLM上下文长度,提升检索精度 chunk_size=600,overlap=80,按Markdown标题优先切割
Batch批量切片 训练/推理数据流 适配显卡显存,提升训练、并发推理效率 batch_size=8/16,训练集开启shuffle






参考资料

LLaMA-Factory 模型微调 https://ibaiyang.github.io/blog/ai人工智能/2026/07/01/LLaMA-Factory模型微调.html

Prompt 工程 https://ibaiyang.github.io/blog/ai人工智能/2025/03/01/Prompt工程.html


返回