LlamaIndex 模型微调实战指南:Embedding、LLM 与重排序器的端到端微调
【免费下载链接】llama_indexLlamaIndex is the document processing platform for AI项目地址: https://gitcode.com/GitHub_Trending/ll/llama_index
微调(Fine-tuning)是对模型本身在数据集上进行更新,使其在输出质量、幻觉抑制、数据记忆与延迟成本等方面得到改善的一种手段。本篇指南基于 LlamaIndex 框架的 Fine-tuning 使用场景文档(docs/src/content/docs/framework/use_cases/fine_tuning.md),系统梳理 Embedding 微调、LLM 蒸馏微调、评估器微调、Cross-Encoder 重排序微调与 Cohere 自定义 Reranker 五大方向,并结合仓库内 8 个可运行 Notebook 的完整代码链路,帮助你掌握"合成数据生成 → 模型微调 → 指标评估 → 接入 RAG 应用"的完整实战方案。
微调与检索增强:互补而非替代
LlamaIndex 的核心方法论是上下文学习 / 检索增强(in-context learning / retrieval augmentation),即让模型处于推理模式(inference mode),借助外部检索到的上下文回答问题,而不直接训练模型本身。微调则是另一条路径:直接更新模型权重。二者并非对立关系,微调可以从多个维度"增强"模型:
- Embedding 微调收益:在目标数据的训练分布上微调 Embedding 模型,可以得到更有意义的向量表示,进而带来更好的检索性能。
- LLM 微调收益:
- 学习给定数据集的输出风格(style);
- 学习训练数据中较少出现的领域专用语言(DSL),例如 SQL;
- 修正难以通过提示工程(prompt engineering)修复的幻觉与错误;
- 将一个更强的模型(如 GPT-4)蒸馏(distill)到更简单、更便宜的模型(如 gpt-3.5、Llama 2)中。
当前 LlamaIndex 与微调生态有三大核心集成方向:Embedding 微调以提升检索性能、Llama 2 微调以改进 text-to-SQL、gpt-3.5-turbo 微调以蒸馏 gpt-4。下文逐一展开。
Finetuning Embeddings:三步提升检索性能
LlamaIndex 提供了完整的 Embedding 微调指南,覆盖两条路径:直接微调模型本身(以bge系列为示例),或为任意黑盒 Embedding 训练一个适配层(adapter)。完整流程由三步构成:
- 使用 LlamaIndex 在任意非结构化语料上生成合成问答数据集;
- 微调模型;
- 评估模型。
根据官方文档所述,该流程通常能为检索评估指标带来5-10% 的提升。微调完成后,可以将模型直接接入基于 LlamaIndex 的 RAG 应用。
对应仓库中的可运行示例:
- Fine-tuning an Adapter(适配层微调)
- Embedding Fine-tuning Guide(Embedding 微调指南)
- Router Fine-tuning(路由微调)
第一步:合成问答数据集
以 finetune_embedding.ipynb 为例,先通过SimpleDirectoryReader加载 PDF 文档,再用SentenceSplitter切分为文本块:
from llama_index.core import SimpleDirectoryReader from llama_index.core.node_parser import SentenceSplitter def load_corpus(files, verbose=False): reader = SimpleDirectoryReader(input_files=files) docs = reader.load_data() parser = SentenceSplitter() nodes = parser.get_nodes_from_documents(docs, show_progress=verbose) return nodes train_nodes = load_corpus(["./data/10k/lyft_2021.pdf"], verbose=True) val_nodes = load_corpus(["./data/10k/uber_2021.pdf"], verbose=True)然后使用generate_qa_embedding_pairs,让 LLM(示例中为gpt-3.5-turbo)以每个文本块为上下文生成问题,形成(问题,文本块)的问答对数据集,并落盘为 JSON 供后续复用:
from llama_index.finetuning import generate_qa_embedding_pairs from llama_index.core.evaluation import EmbeddingQAFinetuneDataset from llama_index.llms.openai import OpenAI train_dataset = generate_qa_embedding_pairs( llm=OpenAI(model="gpt-3.5-turbo"), nodes=train_nodes, output_path="train_dataset.json", ) val_dataset = generate_qa_embedding_pairs( llm=OpenAI(model="gpt-3.5-turbo"), nodes=val_nodes, output_path="val_dataset.json", ) # 可选:从 JSON 重新加载 train_dataset = EmbeddingQAFinetuneDataset.from_json("train_dataset.json") val_dataset = EmbeddingQAFinetuneDataset.from_json("val_dataset.json")EmbeddingQAFinetuneDataset是 LlamaIndex core 中用于承载 Embedding 微调数据的标准数据结构(定义于 llama-index-core/llama_index/core/evaluation/),包含查询、语料与相关文档(question/corpus/relevant_docs)三张映射表。
第二步:微调模型
使用SentenceTransformersFinetuneEngine,以BAAI/bge-small-en作为基座模型(也可以指定model_id换成其他 sentence-transformers 兼容模型),model_output_path指定微调产物的输出目录,并可传入val_dataset在训练过程中进行验证:
from llama_index.finetuning import SentenceTransformersFinetuneEngine finetune_engine = SentenceTransformersFinetuneEngine( train_dataset, model_id="BAAI/bge-small-en", model_output_path="test_model", val_dataset=val_dataset, ) finetune_engine.finetune()训练完成后通过get_finetuned_model()拿到可直接被 LlamaIndex 使用的 Embedding 模型。从 Notebook 输出可以看到,它返回的是一个标准的HuggingFaceEmbedding对象(model_name='test_model'、embed_batch_size=10、max_length=512、pooling='cls'、normalize=True),因此可以无缝替换Settings.embed_model接入既有 RAG 管线。
第三步:评估
Notebook 的评估部分对比了三个模型:OpenAI 专有 Embedding、开源BAAI/bge-small-en、微调后的模型,采用两种评估手段:
- Hit-rate 指标:对每个(query, context)对,用 query 检索 top-k 文档,命中真实上下文即计为一次命中;
InformationRetrievalEvaluator:来自sentence-transformers的标准检索评估器。
评估结论是:在 LLM 生成的合成数据上微调,能显著提升开源 Embedding 模型的检索效果(对应代码见 finetune_embedding.ipynb 的 Evaluate 章节,以及 eval_utils.py 中的评估工具函数)。
变体一:黑盒 Embedding 的适配层微调
如果不想(或无法)直接更新 Embedding 模型权重,可以改用EmbeddingAdapterFinetuneEngine,在任意黑盒 Embedding(示例为local:BAAI/bge-small-en)之上训练一个轻量线性适配层,可配置bias、epochs、verbose,甚至自定义优化器:
from llama_index.finetuning import EmbeddingAdapterFinetuneEngine from llama_index.core.embeddings import resolve_embed_model base_embed_model = resolve_embed_model("local:BAAI/bge-small-en") finetune_engine = EmbeddingAdapterFinetuneEngine( train_dataset, base_embed_model, model_output_path="model_output_test", # bias=True, epochs=4, verbose=True, # optimizer_class=torch.optim.SGD, # optimizer_params={"lr": 0.01} ) finetune_engine.finetune() embed_model = finetune_engine.get_finetuned_model()微调产物同样可以离线加载:LinearAdapterEmbeddingModel(base_embed_model, "model_output_test"),完整示例见 finetune_embedding_adapter.ipynb。
变体二:Router 微调
路由(Router)是查询引擎中的一个关键环节:它决定当前查询应该派发给哪个下游工具/索引。在 router_finetune.ipynb 中,作者用同样的SentenceTransformersFinetuneEngine(epochs=30)对路由场景的 Embedding 进行微调,然后用微调后的模型驱动RouterQueryEngine(结合SummaryIndex、VectorStoreIndex与QueryEngineTool),并通过PydanticProgram输出结构化的路由决策,从而让路由选择更贴合私有数据分布。
Fine-tuning LLMs:用 GPT-4 蒸馏出更便宜的模型
用 GPT-3.5 蒸馏 GPT-4(OpenAI 微调端点)
这是文档重点介绍的集成方向之一:使用 OpenAI 的微调端点,将 gpt-3.5-turbo 微调为能够输出 GPT-4 级别回答的模型,用于 RAG/Agent 场景。整体思路:
- 用 GPT-4 从任意非结构化上下文自动生成问题,并通过 GPT-4 的 query engine 流程生成"标准答案"(ground-truth answers);
OpenAIFineTuningHandler回调自动把问答对记录到数据集(JSONL);- 启动微调任务,得到蒸馏模型;
- 用 Ragas 评估,与朴素的 GPT-3.5 流程进行基准对比。
对应仓库示例:GPT-3.5 Fine-tuning Notebook、Function Calling Fine-tuning(WIP)。
数据准备:DatasetGenerator 生成训练/评估问题
Notebook 下载一份 IPCC 报告 PDF 后,用DatasetGenerator.from_documents配合自定义的"出题人"提示词,在文档的不同分区上分别生成训练题与评估题(各 40 题),并保存为train_questions.txt与eval_questions.txt(仓库中已附带这两个文件:train_questions.txt、eval_questions.txt):
from llama_index.core import SimpleDirectoryReader from llama_index.llms.openai import OpenAI from llama_index.core.evaluation import DatasetGenerator documents = SimpleDirectoryReader(input_files=["IPCC_AR6_WGII_Chapter03.pdf"]).load_data() question_gen_query = ( "You are a Teacher/ Professor. Your task is to setup " "a quiz/examination. Using the provided context, formulate " "a single question that captures an important fact from the " "context. Restrict the question to the context information provided." ) dataset_generator = DatasetGenerator.from_documents( documents[:50], question_gen_query=question_gen_query, llm=gpt_35_llm ) questions = dataset_generator.generate_questions_from_nodes(num=40)用 OpenAIFineTuningHandler 收集训练数据
将OpenAIFineTuningHandler挂载到CallbackManager并绑定到 LLM 上,之后每次 query engine 的问答调用都会被自动记录为微调样本:
from llama_index.llms.openai import OpenAI from llama_index.finetuning.callbacks import OpenAIFineTuningHandler from llama_index.core.callbacks import CallbackManager finetuning_handler = OpenAIFineTuningHandler() callback_manager = CallbackManager([finetuning_handler]) llm = OpenAI(model="gpt-3.5-turbo", temperature=0.3) llm.callback_manager = callback_manager # 用绑定了 handler 的 LLM 构建 query engine 并逐题回答 index = VectorStoreIndex.from_documents(documents) query_engine = index.as_query_engine(similarity_top_k=2, llm=llm) for question in questions: response = query_engine.query(question) finetuning_handler.save_finetuning_events("finetuning_events.jsonl")生成的finetuning_events.jsonl每条记录是 OpenAI 微调所需的对话格式(system / user / assistant 消息),其中 user 消息包含"上下文 + 问题",assistant 消息是 GPT-4 生成的答案。仓库中已附带一份示例数据:finetuning_events.jsonl。
启动微调任务:OpenAIFinetuneEngine
OpenAIFinetuneEngine封装了"上传文件 → 启动微调 job → 获取微调模型"的全过程,也可以传入已有的start_job_id复用历史任务:
from llama_index.finetuning import OpenAIFinetuneEngine finetune_engine = OpenAIFinetuneEngine( "gpt-3.5-turbo", "finetuning_events.jsonl", # start_job_id="<start-job-id>" # 已有 job 时可指定 ) finetune_engine.finetune() finetune_engine.get_current_job() # 查看 job 状态(如 n_epochs=3) ft_llm = finetune_engine.get_finetuned_model(temperature=0.3)Notebook 的输出展示了 OpenAI 侧对训练数据的校验信息:Num examples: 61、0 examples may be over the 4096 token limit、By default, you'll train for 3 epochs等,说明引擎直接复用了 OpenAI Fine-tuning API 的数据检查与计费逻辑。另一种更简洁的写法是通过OpenAIFinetuneEngine.from_finetuning_handler(finetuning_handler, "gpt-3.5-turbo", "tmp.jsonl"),直接从 handler 构造引擎。
用 Ragas 评估蒸馏效果
微调完成后,把ft_llm塞回Settings.llm或 query engine 中,用同一份评估题重新走一遍 RAG 流程,再交给 Ragas 打分。Notebook 中使用了两个核心指标:
answer_relevancy:生成答案与问题的相关程度,取值范围 (0,1),越高越好;faithfulness:生成答案相对给定上下文的忠实度/事实一致性,取值范围 (0,1),越高越好。
from llama_index.core import Settings Settings.llm = ft_llm Settings.context_window = 2048 # 人为限制上下文窗口以触发 refine 流程 from datasets import Dataset from ragas import evaluate from ragas.metrics import answer_relevancy, faithfulness ds = Dataset.from_dict({"question": questions, "answer": answers, "contexts": contexts}) result = evaluate(ds, [answer_relevancy, faithfulness]) print(result)Notebook 中记录的真实运行结果:蒸馏前ragas_score: 0.8356(answer_relevancy 0.9725 / faithfulness 0.7325),蒸馏后ragas_score: 0.8680(answer_relevancy 0.9607 / faithfulness 0.7917)——faithfulness 有可见提升(0.7325 → 0.7917),直观验证了微调确实改变了模型行为。你也可以像 Notebook 那样手动逐题对比蒸馏前后模型的回答,确认差异。
微调以改进结构化输出(Function Calling)
微调的另一个典型用途是让模型更稳定地输出结构化数据。仓库中 openai_fine_tuning_functions.ipynb 展示了基于 OpenAI Function Calling 的微调流程,适用于需要 LLM 严格按函数签名/JSON Schema 输出的场景,文档注明该教程为 WIP(进行中)状态。
微调 Llama 2 以改进 Text-to-SQL
该教程演示如何在 text-to-SQL 数据集上微调 Llama 2,再用 LlamaIndex 的抽象对任意 SQL 数据库进行结构化分析。技术栈包括:
- 训练数据集:
sql-create-context; - 基座模型:OpenLLaMa;
- 微调框架:PEFT(Parameter-Efficient Fine-Tuning);
- 云端算力:Modal;
- 推理抽象:LlamaIndex(负责把微调模型接入 SQL 查询链路)。
这一方向的价值在于:SQL 这类 DSL 在通用模型的训练数据中占比有限,通过微调可以让开源模型在私有 schema 上生成更准确的查询。
微调评估器(LLM Judge):把 GPT-4 裁判蒸馏成 GPT-3.5
社区观察表明,GPT-4 作为裁判(judge/evaluator)与人类评估者能达到较高的一致性。因此,把 GPT-4 judge 蒸馏到 GPT-3.5 judge,有望以更低的成本获得接近 GPT-4 的评估水平。对应两个教程:
- Fine-tune LLM Correctness Judge(单维度正确性评分)
- Fine-tune LLM Judge(成对比较)
以 Correctness Judge 为例(finetune_llm_judge_single_grading_correctness.ipynb),流程为:
- 用
WikipediaReader加载语料、DatasetGenerator生成问题; - 让 Llama-2 生成待评估的回答;
- 实例化 GPT-4 裁判:
CorrectnessEvaluator(llm=gpt_4_llm),对"参考答案 vs 生成答案"打出 1-5 分;同时把OpenAIFineTuningHandler挂到 GPT-4 LLM 的CallbackManager上,自动收集每次评分调用的对话记录; - 用
OpenAIFinetuneEngine("gpt-3.5-turbo", "correction_finetuning_events.jsonl")启动蒸馏,把"用户查询 + 参考答案 + 生成答案 + GPT-4 评分"这套 prompt-response 模式教给 gpt-3.5-turbo; - 得到微调后的 GPT-3.5 judge,用于低成本的批量评估。
从 Notebook 输出可以看到,每条训练样本的 system 消息就是完整的评分准则(1-5 分、相关性/正确性判定规则、输出格式约束),assistant 消息是 GPT-4 的评分与理由——这正是"把评判标准固化进模型"的过程。
Fine-tuning Cross-Encoders for Re-Ranking
重排序(re-ranking)是高级检索流程中的关键步骤:先从多个来源检索出候选节点(retrieval),再用一个独立的模型对这些节点重新排序,把最相关的节点排到最前面。对 Cross-Encoder 进行微调,可以在自有私有数据上改善重排序性能。
Cross-Encoder Finetuning 示例 使用sentence-transformers包微调 cross-encoder 模型,训练数据集基于QASPER数据集生成:
from llama_index.finetuning.cross_encoders import CrossEncoderFinetuneEngine from llama_index.finetuning.cross_encoders.dataset_gen import ( generate_cross_encoder_dataset, ) finetuning_engine = CrossEncoderFinetuneEngine( dataset=finetuning_dataset, epochs=2, batch_size=8 ) finetuning_engine.finetune() # 推送到 HuggingFace Hub 供后续部署 finetuning_engine.push_to_hub(repo_id="bpHigh/Cross-Encoder-LLamaIndex-Demo-v2")Notebook 后续通过SentenceTransformerRerank将微调后的模型作为 node postprocessor 接入检索链路,并用PairwiseComparisonEvaluator对"微调前/微调后"的重排序结果进行成对对比评估,验证重排序质量是否提升。
Cohere Custom Reranker:训练领域专属重排序器
与 Cross-Encoder 思路类似,也可以直接利用 CohereAI 的自定义重排序器训练模块,在领域数据或私有数据集上训练专属 reranker,从而改进检索性能。完整示例见 Cohere Custom Reranker,其中:
- 用 OpenAI 生成合成数据集、用 CohereAI 训练自定义 reranker 并与基础 reranker 对比评估;
- 核心 API 包括
generate_cohere_reranker_finetuning_dataset(生成训练/验证数据)、CohereRerankerFinetuneEngine(训练引擎)与CohereRerank(推理期接入 RAG 管线的 postprocessor); - 注意训练数据量约束:Cohere 自定义 reranker 训练至少需要 256 个(查询 + 相关段落)对,可选附带 hard negatives;验证集至少 64 对(验证可选)。Notebook 中正是取 Lyft 2021 10-K 的前 256 个节点构造训练对,用 Uber 2021 10-K 构造验证集。
延伸:MistralAI 微调(同一套流程的另一实现)
仓库的 mistralai_fine_tuning.ipynb 展示了同一套"蒸馏式微调"流程在 Mistral 生态中的落地:用mistral-large-latest生成训练数据(并用mistral-small-latest生成合成训练/评估问题以避免对两个目标模型的偏向),通过MistraAIFinetuneEngine包装抽象微调open-mistral-7b。这也印证了 LlamaIndex 微调抽象(数据集生成、handler 收集、finetune engine 封装)的跨厂商可迁移性。
总结与实践建议
围绕 LlamaIndex 的微调体系,可以归纳出几条可复用的工程路径:
- 检索质量优先→ 微调 Embedding(
SentenceTransformersFinetuneEngine)或训练轻量适配层(EmbeddingAdapterFinetuneEngine),再用 hit-rate /InformationRetrievalEvaluator评估,官方文档称通常可获得 5-10% 的检索指标提升; - 回答质量与成本兼顾→ 用
OpenAIFineTuningHandler收集 GPT-4 的问答/评分轨迹,经OpenAIFinetuneEngine蒸馏到 gpt-3.5-turbo,并用 Ragas 的answer_relevancy、faithfulness等指标做前后对比; - 排序体验优化→ 微调 Cross-Encoder(
CrossEncoderFinetuneEngine+sentence-transformers)或训练 Cohere 自定义 reranker(CohereRerankerFinetuneEngine),通过 node postprocessor 接入重排序链路; - 评估降本→ 用
CorrectnessEvaluator/ 成对比较评估器把 GPT-4 judge 蒸馏成 GPT-3.5 judge。
所有流程遵循同一骨架:用 LLM 在非结构化语料上合成数据集 → 微调模型 → 在验证集上量化评估 → 通过Settings或 query engine 把微调产物插回 RAG 应用。各方向的可运行完整代码均位于 docs/examples/finetuning/ 目录下,建议在自有数据集上先小规模复现,再根据评估结果决定是否投入完整训练。
【免费下载链接】llama_indexLlamaIndex is the document processing platform for AI项目地址: https://gitcode.com/GitHub_Trending/ll/llama_index
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考