行业知识库长文本数据处理方法

1. 文本切分策略

基于语义的切分

  • 段落/章节切分:按自然段落或章节边界切分
  • 语义单元切分:确保每个切分包含完整的语义信息
  • 使用工具:如NLTK、SpaCy等进行句子和段落识别
import spacy
nlp = spacy.load("zh_core_web_sm")  # 加载中文模型

def semantic_split(long_text, max_tokens=2048):
    doc = nlp(long_text)
    chunks = []
    current_chunk = []
    current_length = 0
    
    for sent in doc.sents:
        sent_tokens = len(sent.text.split())
        if current_length + sent_tokens > max_tokens and current_chunk:
            chunks.append(" ".join(current_chunk))
            current_chunk = [sent.text]
            current_length = sent_tokens
        else:
            current_chunk.append(sent.text)
            current_length += sent_tokens
    
    if current_chunk:
        chunks.append(" ".join(current_chunk))
    
    return chunks

2. 重叠窗口处理

  • 固定窗口大小:如4096 tokens,但保留一定重叠
  • 重叠比例:通常10-30%,确保上下文连贯性
  • 避免切断关键信息:在句子或段落边界处切分
def create_overlapping_chunks(text, tokenizer, chunk_size=4000, overlap=400):
    tokens = tokenizer.encode(text)
    total_length = len(tokens)
    
    chunks = []
    for i in range(0, total_length, chunk_size - overlap):
        end = min(i + chunk_size, total_length)
        if end - i < 100:  # 太小的块不处理
            continue
        chunk_tokens = tokens[i:end]
        chunk_text = tokenizer.decode(chunk_tokens)
        chunks.append(chunk_text)
        
        if end == total_length:
            break
            
    return chunks

3. 构建训练样本格式

指令微调格式

<系统>您是一个专业的行业助手</系统>
<用户>这个行业中[问题]</用户>
<助手>[从切分后的知识库内容构建回答]</助手>

QA对构建

  • 从长文本中提取关键信息点
  • 为每个信息点构建问答对
  • 使用模板生成多样化问题
def generate_qa_pairs(text_chunk):
    # 可以使用大模型API来生成问答对
    prompt = f"""
    基于以下内容生成5个高质量的问答对:
    {text_chunk}
    
    格式:
    Q1: [问题1]
    A1: [答案1]
    ...
    """
    qa_pairs = call_llm_api(prompt)  # 调用大模型API
    return parse_qa_pairs(qa_pairs)  # 解析结果

4. 处理超长文档

检索增强方法

  • 建立文档索引(如用Faiss, Elasticsearch)
  • 微调时结合检索结果
  • 使用"检索然后阅读"的范式
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.vectorstores import FAISS
from langchain.embeddings import HuggingFaceEmbeddings

def build_retrieval_system(documents):
    # 1. 切分文档
    text_splitter = RecursiveCharacterTextSplitter(
        chunk_size=1000,
        chunk_overlap=200
    )
    chunks = text_splitter.split_documents(documents)
    
    # 2. 创建向量存储
    embeddings = HuggingFaceEmbeddings(model_name="multilingual-e5-large")
    vectorstore = FAISS.from_documents(chunks, embeddings)
    
    return vectorstore

5. 数据清洗与标准化

  • 去除无关内容:表格中的特殊字符、页码、页眉页脚
  • 格式标准化:统一换行符、空格处理
  • 去重处理:删除重复内容,特别是在切分后可能产生的重复
def clean_text(text):
    # 移除特殊字符和格式
    text = re.sub(r'\n{3,}', '\n\n', text)  # 多余换行符
    text = re.sub(r'\s{2,}', ' ', text)     # 多余空格
    
    # 移除页眉页脚模式
    text = re.sub(r'第\d+页', '', text)     # 页码
    text = re.sub(r'页码:\d+', '', text)   # 页码
    
    # 其他清洗规则...
    
    return text.strip()

6. 微调数据混合策略

  • 长短文本混合:维持80%短文本(2K以内)和20%长文本
  • 梯度累积:处理长文本时使用更小的batch_size配合梯度累积
  • 课程学习:先用短文本微调,再逐步引入长文本
# 微调配置示例
training_args = TrainingArguments(
    per_device_train_batch_size=4,
    gradient_accumulation_steps=8,  # 累积8步梯度再更新,等效batch_size=32
    max_steps=10000,
    learning_rate=2e-5,
    fp16=True,
    logging_steps=10,
    output_dir="./results",
    save_strategy="steps",
    save_steps=500,
)

实施建议

  1. 分析知识库文档类型:不同类型文档可能需要不同切分策略
  2. 做好质量控制:随机抽查切分后的文本,确保语义完整
  3. 长文本样本降采样:防止长文本在训练中占比过大
  4. 评估指标监控:特别关注模型在长文本上的表现变化
Logo

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

更多推荐