ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

RAG系统嵌入模型微调实战:解决同义词语义鸿沟,提升检索准确率

RAG系统嵌入模型微调实战:解决同义词语义鸿沟,提升检索准确率 在实际检索增强生成RAG系统中一个常见的痛点在于语义鸿沟用户提问的表述与知识库中存储的文本表述不一致导致向量检索召回率低。例如用户问“如何解决程序崩溃”而知识库中存储的是“应用程序异常退出的处理方法”尽管两者语义高度相似但字面匹配度低传统嵌入模型可能无法将它们映射到相近的向量空间。解决这一问题的核心思路之一就是对嵌入模型进行微调使其能更好地理解特定领域或任务中的同义词、近义词及关联表述从而提升检索的准确性和鲁棒性。本文将深入探讨如何针对“同义词理解”这一具体目标对嵌入模型进行微调。我们将从理解微调的原理与价值开始逐步完成环境准备、数据构造、模型训练、效果评估及生产部署的全流程。无论你是希望优化现有RAG系统的开发者还是对嵌入模型微调感兴趣的研究者都能通过本文获得一套可复现的实战方案。最终你将掌握如何让嵌入模型更“懂”你的业务语言显著提升下游检索任务的效果。1. 理解嵌入模型微调为什么以及何时需要在标准的RAG流程中嵌入模型负责将查询和文档块转换为高维向量。检索的本质就是计算查询向量与所有文档向量之间的相似度如余弦相似度并返回最相似的Top-K个文档。这里隐含了一个关键假设语义相似的文本其向量表示也相似。然而预训练的通用嵌入模型如text-embedding-ada-002、bge-large-zh是在海量、多样化的公开数据上训练的。它们虽然具备强大的通用语义理解能力但对于特定领域如医疗、法律、金融的专业术语、行话、缩写及其同义词映射或者对于特定任务中独特的表述习惯其理解可能不够精准。微调嵌入模型的核心目的就是让模型在特定领域或任务的数据分布上重新校准其向量空间。具体到“同义词”场景我们希望模型学习到“程序崩溃” ≈ “应用程序异常退出”“购买” ≈ “下单” ≈ “订购”“CPU占用高” ≈ “处理器负载过大”通过微调模型会调整其参数使得这些语义相同但表述不同的文本对在向量空间中的距离更近同时使语义不相关的文本对距离更远。那么何时需要考虑微调嵌入模型呢你可以通过以下 checklist 进行判断检索召回率低人工判断相关的文档经常无法进入检索结果的Top-K。存在大量领域术语业务文档中包含大量通用模型可能不熟悉的专业词汇。用户查询与文档表述差异大用户习惯的口语化、简写表达与文档中严谨、完整的书面化表达不匹配。你有高质量的标注数据能够获取或构造一批查询相关文档不相关文档的三元组数据。通用模型性能达到瓶颈在尝试了更好的分块策略、重排序等技术后检索质量仍不理想。如果满足上述多条那么嵌入模型微调很可能带来显著的性能提升。接下来我们将进入实战环节。2. 环境准备与工具选型微调嵌入模型是一个典型的机器学习工程任务需要合适的软件环境、硬件资源以及核心库。2.1 硬件与软件环境要求微调对计算资源有一定要求尤其是显存。以下是一个参考配置表组件学习/实验环境生产微调环境说明GPUNVIDIA GPU (如 RTX 3090/4090, 24GB显存)NVIDIA A100/H100 (80GB显存)显存大小决定可微调的模型规模与批次大小。内存32 GB64 GB 或更高用于加载数据和模型参数。Python3.8 - 3.103.8 - 3.10推荐使用虚拟环境。CUDA11.7 或 11.8与GPU驱动匹配的版本必须与PyTorch版本兼容。对于实验一块24GB显存的消费级显卡足以微调像BAAI/bge-small-zh这类较小模型。如果只有CPU虽然可以运行但训练速度会非常慢仅建议用于理解流程。2.2 核心Python库安装我们将使用transformers、datasets、peft和trl等库。创建一个新的虚拟环境并安装依赖是推荐做法。# 创建并激活虚拟环境 (以conda为例) conda create -n rag-finetune python3.9 conda activate rag-finetune # 安装PyTorch (请根据你的CUDA版本访问 https://pytorch.org/ 获取对应命令) # 例如对于CUDA 11.8 pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118 # 安装核心机器学习库 pip install transformers datasets accelerate peft trl sentence-transformers # 安装训练循环和评估相关工具 pip install scikit-learn tqdm tensorboard2.3 模型选型从哪里开始微调选择一个合适的基座模型是成功的第一步。对于中文场景以下模型是很好的起点BGE (BAAI General Embedding) 系列由智源研究院发布在中文语义相似度任务上表现优异。例如BAAI/bge-small-zh: 小型模型速度快适合快速实验和部署资源受限的场景。BAAI/bge-base-zh: 基础模型在效果和速度间取得平衡。BAAI/bge-large-zh: 大型模型效果最好但需要更多显存和计算时间。M3E 系列专门为中文文本检索优化的模型。开源通用模型如thenlper/gte-baseintfloat/e5-large-v2等在多语言任务上表现良好。对于同义词微调实战我们选择BAAI/bge-base-zh作为基座模型。它在效果和资源消耗上是一个较好的折中且社区支持完善。注意在开始微调前务必记录下基座模型的原始性能例如在你的测试集上的检索召回率以便与微调后的模型进行对比量化提升效果。3. 构造微调数据关键在于正负样本微调嵌入模型通常采用对比学习范式其目标是让正样本对语义相似的文本的向量距离更近负样本对语义不相似的文本的向量距离更远。因此数据的质量直接决定了微调的效果。3.1 数据格式定义我们需要的核心数据是三元组(anchor, positive, negative)Anchor (查询): 通常代表用户的问题或搜索词。Positive (正例): 与Anchor语义高度相关的文本即我们希望检索到的目标文档片段。Negative (负例): 与Anchor语义不相关的文本。高质量的负例对于模型学会区分细微差异至关重要。数据可以组织成JSON Lines格式每行一个样本{anchor: 系统卡顿怎么办, positive: 解决应用程序响应缓慢的操作指南, negative: 如何安装最新的系统补丁} {anchor: 订单支付失败, positive: 交易处理未成功的排查步骤, negative: 查看历史订单记录的方法}3.2 数据来源与构造策略对于同义词微调我们需要构造大量(同义表述 同义表述 无关表述)的三元组。策略一利用现有业务日志推荐从搜索日志、客服问答对、用户反馈中提取真实的(query, clicked_doc)对作为(anchor, positive)。负例可以从同一批次中随机选择未被点击的文档困难负例或从其他不相关主题的文档中采样。策略二基于知识库文档人工构造或增强从知识库中提取关键句子或段落。人工或利用大语言模型LLM为每句话生成多种同义表述。例如原句“重启服务可以清除临时缓存。”同义表述“通过重新启动服务来释放临时缓存数据。”同义表述“执行服务重启操作以清空缓存。”将原句和它的一个同义表述作为anchor和positive。从其他毫不相关的文档中随机选取一句作为negative。策略三使用公开语义相似度数据集进行预热如STS-B、ATEC、BQ Corpus等中文语义匹配数据集可以用于模型的初步微调使其更好地适应对比学习任务。以下是一个模拟生成同义词微调数据的Python脚本示例演示了如何利用少量种子数据扩展import json import random # 种子同义词对 - 在实际项目中这部分可能来自业务数据或人工整理 seed_synonym_pairs [ ([程序崩溃, 应用闪退], [应用程序异常退出, 软件意外停止工作]), ([购买, 下单], [订购商品, 进行交易]), ([CPU占用高, 处理器负载大], [系统处理器使用率过高, CPU利用率飙升]), ([网络连接失败, 无法上网], [网络链路中断, 互联网访问故障]), ] # 无关句子池 - 模拟不相关的文档片段 unrelated_pool [ 如何配置数据库连接参数。, 用户权限管理的最佳实践。, 本周的团队会议安排在周三下午。, 项目代码仓库的Git工作流说明。, 年度预算报告的编写格式要求。, ] samples [] for anchor_group, positive_group in seed_synonym_pairs: # 在锚点词组和正例词组内部两两组合构造正样本对 for anchor in anchor_group: for positive in positive_group: if anchor ! positive: # 避免自己和自己组队 # 随机选择一个无关句子作为负例 negative random.choice(unrelated_pool) samples.append({ anchor: anchor, positive: positive, negative: negative }) # 保存为JSONL文件 with open(synonym_finetune_data.jsonl, w, encodingutf-8) as f: for sample in samples: f.write(json.dumps(sample, ensure_asciiFalse) \n) print(f生成了 {len(samples)} 个训练样本。) # 查看前3个样本 for i in range(3): print(json.dumps(samples[i], ensure_asciiFalse, indent2))3.3 数据划分与加载将构造好的数据按比例如8:1:1划分为训练集、验证集和测试集。使用datasets库可以方便地加载和处理。from datasets import Dataset, DatasetDict import json # 读取JSONL文件 data [] with open(synonym_finetune_data.jsonl, r, encodingutf-8) as f: for line in f: data.append(json.loads(line.strip())) # 转换为Dataset对象 raw_dataset Dataset.from_list(data) # 划分数据集 (这里简单按顺序划分实际应随机打乱) train_testvalid raw_dataset.train_test_split(test_size0.2, seed42) test_valid train_testvalid[test].train_test_split(test_size0.5, seed42) dataset_dict DatasetDict({ train: train_testvalid[train], validation: test_valid[train], test: test_valid[test] }) print(dataset_dict)4. 模型微调实战使用对比损失进行训练我们将使用transformers和peft库采用LoRA技术对模型进行高效微调。LoRA只训练模型的一小部分参数能大幅减少显存消耗并避免灾难性遗忘非常适合嵌入模型微调。4.1 模型与Tokenizer加载from transformers import AutoTokenizer, AutoModel import torch model_name BAAI/bge-base-zh tokenizer AutoTokenizer.from_pretrained(model_name) model AutoModel.from_pretrained(model_name) # 将模型设置为评估模式并移动到GPU model.eval() device torch.device(cuda if torch.cuda.is_available() else cpu) model.to(device)BGE模型在调用时需要在查询文本前添加指令前缀“为这个句子生成表示以用于检索相关文章”但在微调时我们通常直接使用原始文本因为指令信息已经内化在训练数据中。为了简化本例不添加指令前缀你也可以根据官方建议添加。4.2 实现对比损失函数我们将使用InfoNCE Loss也称为NT-Xent Loss它是对比学习中常用的损失函数。对于一个批次内的样本它鼓励正样本对的相似度远高于负样本对的相似度。import torch.nn.functional as F def contrastive_loss(anchor_emb, positive_emb, negative_emb, temperature0.05): 计算对比损失。 anchor_emb: [batch_size, hidden_dim] positive_emb: [batch_size, hidden_dim] negative_emb: [batch_size, hidden_dim] temperature: 温度参数用于缩放相似度。 # 计算锚点与正例的余弦相似度 pos_sim F.cosine_similarity(anchor_emb, positive_emb, dim-1) / temperature # [batch_size] # 计算锚点与负例的余弦相似度 neg_sim F.cosine_similarity(anchor_emb, negative_emb, dim-1) / temperature # [batch_size] # 对于每个锚点其正例相似度应高于负例相似度。 # 我们将它构造为一个二分类问题正例对的标签为1负例对的标签为0。 # 但更常见的InfoNCE形式是使用交叉熵其中分子是exp(pos_sim)分母是exp(pos_sim) exp(neg_sim) # 这里我们采用一种简化的形式最大化 pos_sim - neg_sim loss -torch.log(torch.exp(pos_sim) / (torch.exp(pos_sim) torch.exp(neg_sim))) return loss.mean() # 更标准、更稳定的InfoNCE实现推荐 def info_nce_loss(anchor_emb, positive_emb, temperature0.05): 计算InfoNCE损失。假设一个批次内第i个anchor与第i个positive是正样本对与其他所有样本包括其他anchor都是负样本。 这种实现更高效能利用批次内所有其他样本作为负例。 anchor_emb: [batch_size, hidden_dim] positive_emb: [batch_size, hidden_dim] batch_size anchor_emb.size(0) # 归一化向量使余弦相似度计算变为点积 anchor_norm F.normalize(anchor_emb, dim-1) positive_norm F.normalize(positive_emb, dim-1) # 计算相似度矩阵 [batch_size, batch_size] logits torch.matmul(anchor_norm, positive_norm.transpose(0, 1)) / temperature # 标签是单位矩阵表示每个位置i的正例是positive_emb[i] labels torch.arange(batch_size).to(logits.device) loss F.cross_entropy(logits, labels) return loss4.3 配置LoRA进行参数高效微调使用peft库为模型的注意力层添加LoRA适配器。from peft import LoraConfig, get_peft_model, TaskType # 定义LoRA配置 lora_config LoraConfig( task_typeTaskType.FEATURE_EXTRACTION, # 对于嵌入模型我们进行特征提取任务 r8, # LoRA的秩较小的r如4,8即可越大参数量越多 lora_alpha32, # 缩放因子 lora_dropout0.1, target_modules[query, key, value], # 在Transformer的Q,K,V投影层添加LoRA biasnone, ) # 将原模型转换为PEFT模型 peft_model get_peft_model(model, lora_config) peft_model.print_trainable_parameters() # 查看可训练参数占比通常不到1%4.4 构建训练循环我们将使用PyTorch原生方式编写训练循环以便更清晰地理解流程。在实际项目中也可以使用transformers.Trainer。from torch.utils.data import DataLoader from tqdm import tqdm import numpy as np def collate_fn(batch, tokenizer, max_length512): anchors [item[anchor] for item in batch] positives [item[positive] for item in batch] negatives [item[negative] for item in batch] # 对三组文本分别进行编码 anchor_enc tokenizer(anchors, paddingTrue, truncationTrue, max_lengthmax_length, return_tensorspt) positive_enc tokenizer(positives, paddingTrue, truncationTrue, max_lengthmax_length, return_tensorspt) negative_enc tokenizer(negatives, paddingTrue, truncationTrue, max_lengthmax_length, return_tensorspt) return anchor_enc, positive_enc, negative_enc # 准备数据加载器 train_dataloader DataLoader( dataset_dict[train], batch_size16, # 根据显存调整 shuffleTrue, collate_fnlambda b: collate_fn(b, tokenizer) ) # 定义优化器只优化可训练参数即LoRA参数 optimizer torch.optim.AdamW(peft_model.parameters(), lr1e-4) # 训练循环 num_epochs 3 peft_model.train() for epoch in range(num_epochs): total_loss 0 progress_bar tqdm(train_dataloader, descfEpoch {epoch1}) for anchor_enc, positive_enc, negative_enc in progress_bar: # 将数据移动到设备 anchor_enc {k: v.to(device) for k, v in anchor_enc.items()} positive_enc {k: v.to(device) for k, v in positive_enc.items()} negative_enc {k: v.to(device) for k, v in negative_enc.items()} # 前向传播获取句向量 # 通常取[CLS] token的表示作为句子向量BGE模型也采用此方式 anchor_outputs peft_model(**anchor_enc) positive_outputs peft_model(**positive_enc) negative_outputs peft_model(**negative_enc) anchor_embeddings anchor_outputs.last_hidden_state[:, 0, :] # [batch_size, hidden_dim] positive_embeddings positive_outputs.last_hidden_state[:, 0, :] negative_embeddings negative_outputs.last_hidden_state[:, 0, :] # 计算损失 - 使用简化对比损失 loss contrastive_loss(anchor_embeddings, positive_embeddings, negative_embeddings) # 反向传播 optimizer.zero_grad() loss.backward() optimizer.step() total_loss loss.item() progress_bar.set_postfix({loss: loss.item()}) avg_loss total_loss / len(train_dataloader) print(fEpoch {epoch1} finished. Average loss: {avg_loss:.4f}) # 保存微调后的模型包括基础模型和LoRA权重 peft_model.save_pretrained(./finetuned_bge_lora) tokenizer.save_pretrained(./finetuned_bge_lora)5. 效果评估与验证训练完成后必须对模型进行评估以确认微调是否真正提升了同义词场景下的检索能力。5.1 构建测试评估函数我们可以在测试集上计算一个关键指标正例相似度高于负例相似度的比例。理想情况下这个比例应为100%。from sklearn.metrics import accuracy_score import torch.nn.functional as F def evaluate_model(model, tokenizer, test_dataset, device): model.eval() correct 0 total 0 with torch.no_grad(): for item in test_dataset: anchor item[anchor] positive item[positive] negative item[negative] # 编码并获取向量 anchor_enc tokenizer(anchor, return_tensorspt, paddingTrue, truncationTrue, max_length512).to(device) pos_enc tokenizer(positive, return_tensorspt, paddingTrue, truncationTrue, max_length512).to(device) neg_enc tokenizer(negative, return_tensorspt, paddingTrue, truncationTrue, max_length512).to(device) anchor_out model(**anchor_enc) pos_out model(**pos_enc) neg_out model(**neg_enc) anchor_emb anchor_out.last_hidden_state[:, 0, :] pos_emb pos_out.last_hidden_state[:, 0, :] neg_emb neg_out.last_hidden_state[:, 0, :] # 计算余弦相似度 sim_pos F.cosine_similarity(anchor_emb, pos_emb).item() sim_neg F.cosine_similarity(anchor_emb, neg_emb).item() if sim_pos sim_neg: correct 1 total 1 accuracy correct / total return accuracy # 加载微调后的模型进行评估 from peft import PeftModel base_model AutoModel.from_pretrained(model_name).to(device) finetuned_model PeftModel.from_pretrained(base_model, ./finetuned_bge_lora).to(device) finetuned_model.eval() test_acc evaluate_model(finetuned_model, tokenizer, dataset_dict[test], device) print(f微调模型在测试集上的准确率正例相似度 负例相似度: {test_acc:.4f}) # 对比原始模型 original_model AutoModel.from_pretrained(model_name).to(device) original_model.eval() original_acc evaluate_model(original_model, tokenizer, dataset_dict[test], device) print(f原始模型在测试集上的准确率: {original_acc:.4f})5.2 在真实RAG流程中验证更可靠的验证是将其嵌入到你的RAG系统中使用一批真实的用户查询对比微调前后检索到的Top-K文档的相关性。构建测试查询集收集一批真实或模拟的用户查询。准备文档库使用你的知识库文档。生成向量并检索分别用原始模型和微调后的模型为所有文档和查询生成向量进行检索。人工或LLM评估对检索结果的相关性进行评分如0-5分计算平均分或NDCG等指标。# 伪代码对比检索结果示例 def test_retrieval(query, document_chunks, model, tokenizer, top_k3): # 为所有文档块生成向量 doc_embeddings [] for chunk in document_chunks: inputs tokenizer(chunk, return_tensorspt, paddingTrue, truncationTrue, max_length512).to(device) with torch.no_grad(): outputs model(**inputs) emb outputs.last_hidden_state[:, 0, :].cpu().numpy() doc_embeddings.append(emb[0]) doc_embeddings np.array(doc_embeddings) # 为查询生成向量 query_inputs tokenizer(query, return_tensorspt, paddingTrue, truncationTrue, max_length512).to(device) with torch.no_grad(): query_outputs model(**query_inputs) query_emb query_outputs.last_hidden_state[:, 0, :].cpu().numpy()[0] # 计算余弦相似度 similarities np.dot(doc_embeddings, query_emb) / (np.linalg.norm(doc_embeddings, axis1) * np.linalg.norm(query_emb) 1e-8) top_indices np.argsort(similarities)[-top_k:][::-1] return [(document_chunks[i], similarities[i]) for i in top_indices] # 分别用两个模型测试 query 软件老是闪退 # 假设doc_chunks是你的文档列表 # original_results test_retrieval(query, doc_chunks, original_model, tokenizer) # finetuned_results test_retrieval(query, doc_chunks, finetuned_model, tokenizer) # 比较两个结果列表的差异6. 部署与集成将微调模型用于生产RAG训练和评估完成后下一步是将模型集成到RAG系统中。6.1 模型合并与保存为了部署方便可以将LoRA权重合并到基础模型中得到一个完整的、独立的模型文件。# 合并LoRA权重到基础模型 finetuned_model finetuned_model.merge_and_unload() # PeftModel的方法 # 保存完整的模型 merged_model_save_path ./finetuned_bge_merged finetuned_model.save_pretrained(merged_model_save_path) tokenizer.save_pretrained(merged_model_save_path)6.2 使用Sentence-Transformers格式许多RAG框架如LangChain更倾向于使用sentence-transformers库加载模型。我们可以将模型转换为该格式。from sentence_transformers import SentenceTransformer # 方法1如果已经保存为 transformers 格式可以直接用 SentenceTransformer 加载需模型支持 # model_st SentenceTransformer(merged_model_save_path) # 方法2更可靠的方式是创建一个包装类但最简单的是直接使用保存的模型目录。 # 确保保存的目录下有 model.safetensors 或 pytorch_model.bin 以及 config.json 和 tokenizer 文件。 # 然后可以这样加载 model_st SentenceTransformer(merged_model_save_path, devicecuda) # 测试编码 sentences [程序崩溃了, 应用程序异常退出] embeddings model_st.encode(sentences, normalize_embeddingsTrue) # 通常建议归一化 print(embeddings.shape)6.3 集成到向量数据库与RAG服务以ChromaDB和FastAPI为例展示如何集成微调后的模型。# 安装 chromadb 和 fastapi # pip install chromadb fastapi uvicorn import chromadb from chromadb.config import Settings from sentence_transformers import SentenceTransformer import uvicorn from fastapi import FastAPI from pydantic import BaseModel from typing import List # 1. 初始化嵌入函数 embed_model SentenceTransformer(./finetuned_bge_merged, devicecuda) def my_embed_function(texts: List[str]) - List[List[float]]: embeddings embed_model.encode(texts, normalize_embeddingsTrue) return embeddings.tolist() # 2. 创建或连接ChromaDB集合 chroma_client chromadb.PersistentClient(path./chroma_db) collection chroma_client.get_or_create_collection( namemy_rag_knowledge, embedding_functionmy_embed_function # 关键使用自定义的微调模型 ) # 3. 假设已有文档块添加到集合中 document_chunks [文档1内容..., 文档2内容..., ...] # 你的知识库分块 metadatas [{source: doc1}, {source: doc2}, ...] ids [id1, id2, ...] collection.add( documentsdocument_chunks, metadatasmetadatas, idsids ) # 4. 创建FastAPI服务提供检索接口 app FastAPI() class QueryRequest(BaseModel): query: str top_k: int 5 app.post(/retrieve) async def retrieve(request: QueryRequest): results collection.query( query_texts[request.query], n_resultsrequest.top_k ) # 返回检索到的文档和元数据 return { documents: results[documents][0], metadatas: results[metadatas][0], distances: results[distances][0] } # 运行服务: uvicorn main:app --host 0.0.0.0 --port 80007. 常见问题、排查与最佳实践7.1 微调过程中的常见问题问题现象可能原因检查与解决方案Loss不下降或波动大学习率过高/过低批次大小不合适数据质量差如正负例区分不明显。尝试降低学习率如5e-5增大批次大小在显存允许范围内检查数据确保正例确实相关负例确实不相关。训练后效果变差过拟合灾难性遗忘LoRA通常可避免评估方式有误。增加验证集监控验证集loss尝试更小的LoRAr值确保测试集没有数据泄露在真实检索任务上评估。显存不足OOM模型太大批次太大序列长度太长。换用更小的基座模型如bge-small-zh减小batch_size在tokenizer中设置更小的max_length如256。相似度分数全部接近1或0向量未归一化温度参数temperature设置不当。在计算损失或相似度前对向量进行L2归一化调整temperature值通常设在0.01到0.2之间尝试。检索结果没有改善微调数据与真实业务查询分布不符模型容量不足RAG其他环节如分块、重排序是瓶颈。分析bad case针对性补充训练数据尝试更大的基座模型检查分块策略是否合理是否丢失了关键信息。7.2 同义词微调的最佳实践数据质量高于数据数量1000个高质量、标注准确的三元组远胜于10万个噪声大的数据。重点关注“困难负例”的构造即与查询有些相关但实际不相关的文档。领域聚焦如果你的RAG系统只服务于一个特定领域如IT运维那么微调数据应完全来自该领域避免引入无关的通用语义。持续迭代微调不是一劳永逸的。上线后收集新的用户查询和未被成功检索的日志构造新的训练数据定期进行增量微调。A/B测试在生产环境中对微调模型和原始模型的检索效果进行A/B测试用客观指标如点击率、问题解决率衡量提升。不要忽视基础工作微调嵌入模型是提升RAG效果的重要手段但它不能弥补糟糕的文档分块、贫乏的知识库内容或不合理的检索策略。确保这些基础环节都已优化。7.3 扩展方向结合知识图谱将实体、关系等结构化信息与文本向量结合实现混合检索。动态负采样在训练过程中从向量数据库中实时检索与查询最相似的“非正例”文档作为负例提升模型区分细微差异的能力。多任务学习除了对比损失可以同时加入MLM掩码语言模型损失帮助模型更好地理解领域文本。蒸馏将微调后的大模型知识蒸馏到更小的模型中以提升线上推理速度。嵌入模型微调是优化RAG系统检索层的一把利器尤其适用于解决领域术语和同义词映射问题。成功的核心在于构造贴近真实业务场景的高质量训练数据并采用LoRA等高效微调技术以降低成本和风险。通过本文的实战流程你可以系统地完成从数据准备、模型训练、评估到部署的全过程最终让你的RAG系统更精准地理解用户的真实意图。
返回列表