llm knowledge distillation

LLM 知识蒸馏:从大模型到小模型的能力迁移

LLM 知识蒸馏:从大模型到小模型的能力迁移 引言 大模型能力强大但部署成本高昂:70B 模型推理需要多张 A100,延迟数百毫秒。知识蒸馏(Knowledge Distillation)通过让小模型(Student)学习大模型(Teacher)的行为,在保持核心能力的同时大幅压缩模型体积和推理成本。 本文系统梳理 LLM 时代知识蒸馏的方法论,从经典 KD 到最新进展,附完整代码实现。 1. 知识蒸馏的分类体系 1.1 按信息来源分类 知识蒸馏 ├── 白盒蒸馏(White-box) │ ├── Logit 蒸馏(软标签) │ ├── 中间层蒸馏(特征/注意力) │ └── 注意力蒸馏 └── 黑盒蒸馏(Black-box) ├── 响应蒸馏(Response-based) │ ├── 指令跟随蒸馏 │ ├── CoT 蒸馏 │ └── 多轮对话蒸馏 └── 行为蒸馏(Behavior-based) ├── 排序蒸馏 └── 反馈蒸馏(RLAIF) 1.2 按训练方式分类 类型 Teacher 是否参与训练 典型场景 离线蒸馏 ❌ 预先生成数据 大部分场景(最常见) 在线蒸馏 ✅ 同步推理 多模型协同训练 自蒸馏 自身作为 Teacher 同构模型不同层 2. 白盒蒸馏:Logit 级别 2.1 经典 KD Loss Hinton 等人提出的经典知识蒸馏使用 KL 散度对齐 Teacher 和 Student 的输出分布: ...

2026-06-25 · 8 min · 1608 words · AI 实战派
lora vs dora vs qlora

LoRA vs DoRA vs QLoRA:参数高效微调三剑客对比

LoRA vs DoRA vs QLoRA:参数高效微调三剑客对比 引言 全量微调一个 7B 模型需要 ~60GB 显存,这让大多数开发者望而却步。参数高效微调(PEFT)方法通过只训练极少量参数,实现了接近全量微调的效果。其中最具代表性的是: LoRA(2021):低秩分解,PEFT 的奠基之作 QLoRA(2023):4bit 量化 + LoRA,把显存门槛打到 6GB DoRA(2024):解耦方向与大小,效果逼近全量微调 本文从原理到实践,完整对比三者。 1. LoRA:低秩适配 1.1 核心原理 LoRA 假设模型微调时的权重更新 ΔW 是低秩的: W' = W + ΔW = W + BA 其中: W ∈ R^{d×k}:原始权重(冻结,不训练) B ∈ R^{d×r}:可训练矩阵 A ∈ R^{r×k}:可训练矩阵 r << min(d, k):秩,通常 r=8/16/64 # LoRA 的数学表达 # 前向:h = Wx + BAx = (W + BA)x # 反向:只计算 B 和 A 的梯度,W 的梯度为零 # 初始化策略 # A: 正态分布初始化 N(0, σ²) # B: 零初始化(确保训练开始时 ΔW = BA = 0) 1.2 代码实现 import torch import torch.nn as nn class LoRALayer(nn.Module): """LoRA 层的独立实现""" def __init__( self, in_features: int, out_features: int, r: int = 8, alpha: int = 16, dropout: float = 0.0, ): super().__init__() self.r = r self.scale = alpha / r # 缩放系数 # 原始权重(冻结) self.base_weight = nn.Parameter( torch.randn(out_features, in_features), requires_grad=False ) # LoRA 矩阵 self.lora_A = nn.Parameter(torch.randn(r, in_features) * 0.01) self.lora_B = nn.Parameter(torch.zeros(out_features, r)) self.dropout = nn.Dropout(dropout) def forward(self, x: torch.Tensor) -> torch.Tensor: base_out = x @ self.base_weight.T lora_out = (self.dropout(x) @ self.lora_A.T @ self.lora_B.T) * self.scale return base_out + lora_out # 使用 PEFT 库(推荐) from peft import LoraConfig, get_peft_model config = LoraConfig( r=16, lora_alpha=32, lora_dropout=0.05, target_modules=["q_proj", "k_proj", "v_proj", "o_proj"], bias="none", task_type="CAUSAL_LM", ) model = get_peft_model(base_model, config) 1.3 参数量分析 以 LLaMA-7B(hidden_dim=4096)为例: ...

2026-06-25 · 7 min · 1318 words · AI 实战派
fine tuning qlora guide

QLoRA 微调实战:4bit 量化下的高效训练

QLoRA 微调实战:4bit 量化下的高效训练 引言 大模型微调最大的障碍是显存。一个 7B 模型以 FP16 加载需要约 14GB 显存,加上 Adam 优化器状态和梯度,训练时轻松突破 60GB。QLoRA 通过 4bit 量化 + 低秩适配器,将训练显存压缩到 ~6GB,让单卡 24GB 消费级 GPU 微调 7B-13B 模型成为现实。 本文从原理到代码,完整覆盖 QLoRA 微调全流程。 1. QLoRA 核心原理 1.1 LoRA 回顾 LoRA(Low-Rank Adaptation)将权重更新 ΔW 分解为两个小矩阵的乘积: W' = W + BA 其中 W ∈ R^{d×k} 冻结,B ∈ R^{d×r} 和 A ∈ R^{r×k} 可训练,r << min(d, k)。 参数量从 d×k 降至 r×(d+k),但模型仍需以 FP16 加载。 1.2 QLoRA 的三大创新 QLoRA 在 LoRA 基础上引入三项关键技术: ...

2026-06-25 · 6 min · 1115 words · AI 实战派
rag reranking guide

RAG 重排序指南:Cohere Rerank vs bge-reranker vs Cross-Encoder

RAG 重排序指南:Cohere Rerank vs bge-reranker vs Cross-Encoder 引言 RAG 系统的标准流程是:向量检索 Top-K → 直接喂给 LLM。但向量检索(双塔模型)的弱点是精度有限:它擅长快速召回大量相关文档,但不擅长精细区分「真正相关」和「看起来相关」。 重排序(Reranking)是解决这一问题的关键环节:用一个更强大的模型对检索结果重新打分排序,将最相关的文档排到前面。 Query → 向量检索 Top-50 → 重排序 → Top-5 → LLM 生成 本文深入对比三种主流重排序方案。 1. 为什么需要重排序? 1.1 双塔 vs 交叉编码器 特性 双塔模型(Bi-Encoder) 交叉编码器(Cross-Encoder) 架构 Query 和 Doc 独立编码 Query 和 Doc 拼接后联合编码 交互 无(仅在最后做余弦相似度) 全程(Attention 层交互) 精度 中 高 速度 极快(可预计算索引) 慢(每对 Q-D 需独立前向) 用途 初筛召回 精排 1.2 RAG 中的两阶段检索 # 两阶段检索流程 def two_stage_retrieve( query: str, vector_index, # 双塔向量索引 reranker, # 交叉编码器重排序 first_stage_k: int = 50, # 初筛数量 final_k: int = 5, # 最终数量 ) -> list: # Stage 1: 向量检索(快,召回多) candidates = vector_index.search(query, top_k=first_stage_k) # Stage 2: 重排序(精,筛少) pairs = [(query, doc["content"]) for doc in candidates] scores = reranker.predict(pairs) # 排序并取 Top-K ranked = sorted(zip(candidates, scores), key=lambda x: x[1], reverse=True) return [doc for doc, score in ranked[:final_k]] 1.3 效果提升 指标 无重排序 有重排序 提升 Top-1 准确率 62.3% 78.1% +15.8% Top-5 召回率 81.2% 91.5% +10.3% MRR 0.681 0.832 +0.151 2. 方案一:Cohere Rerank API 2.1 概述 Cohere Rerank 是托管的商业重排序 API,基于自家训练的 rerank 模型,支持多语言。 ...

2026-06-25 · 6 min · 1258 words · AI 实战派
continuous pretraining

持续预训练实践:领域大模型的训练方法论

持续预训练实践:领域大模型的训练方法论 引言 通用大模型(GPT-4、LLaMA-3)在医疗、法律、金融等垂直领域常出现专业术语理解偏差、领域知识幻觉、行业惯例缺失等问题。全量预训练成本过高,而 SFT(指令微调)又不足以注入深层领域知识。 持续预训练(Continual Pre-Training, CPT)是两者之间的平衡点:在通用基座上用领域语料继续预训练,让模型深层理解领域知识,同时保留通用能力。 1. CPT 在训练体系中的定位 预训练(PT)→ 持续预训练(CPT)→ 指令微调(SFT)→ 偏好对齐(DPO/RLHF) ↑ 本文重点 阶段 数据量 数据形式 学习目标 参数更新 PT 万亿 tokens 纯文本 Next token prediction 全量 CPT 百亿~千亿 tokens 纯文本(领域) Next token prediction 全量或部分 SFT 百万~千万条 指令-响应对 指令跟随 全量或 PEFT DPO 数万~数十万条 偏好对 偏好优化 全量或 PEFT 1.1 CPT vs SFT:本质区别 维度 CPT SFT 数据 无标注领域文本 人工标注指令对 目标 学习领域知识分布 学习指令跟随格式 深度 改变模型内部知识表征 调整输出行为 数据量 10B-100B tokens 1M-10M 条 灾难性遗忘 严重(需缓解) 较轻 2. 领域数据构建 2.1 数据来源与采集 from typing import List, Dict import json import os class DomainDataBuilder: """领域预训练数据构建器""" def __init__(self, domain: str): self.domain = domain # "medical", "legal", "financial", etc. def collect_sources(self) -> Dict[str, List[str]]: """定义数据来源""" sources = { "medical": { "textbooks": ["医学教科书 PDF", "诊疗指南"], "papers": ["PubMed 论文", "中文医学期刊"], "records": ["脱敏病历", "医学百科"], "guidelines": ["临床路径", "用药指南"], "qa": ["医学问答", "丁香园问答"], }, "legal": { "textbooks": ["法学教材", "法律释义"], "papers": ["法学期刊论文"], "records": ["裁判文书", "法律案例"], "guidelines": ["司法解释", "部门规章"], "qa": ["法律咨询问答"], }, "financial": { "textbooks": ["金融学教材", "CFA教材"], "papers": ["金融研究论文"], "reports": ["年报", "券商研报"], "guidelines": ["会计准则", "监管文件"], "qa": ["金融问答", "投资者教育"], }, } return sources.get(self.domain, {}) def estimate_tokens(self, file_sizes_mb: List[float]) -> int: """估算 token 数(中文约 1.5 字/token,英文约 0.75 词/token)""" total_chars = sum(size * 1024 * 1024 * 3 for size in file_sizes_mb) # 假设中文3字节 return int(total_chars / 1.5) # 粗略估算 2.2 数据清洗管道 import re from typing import Optional class DataCleaner: """预训练数据清洗""" @staticmethod def clean_text(text: str) -> Optional[str]: """单文档清洗""" # 1. 去除 HTML 标签 text = re.sub(r'<[^>]+>', '', text) # 2. 去除 URL text = re.sub(r'https?://\S+', '', text) # 3. 去除多余空白 text = re.sub(r'\s+', ' ', text).strip() # 4. 去除乱码(非可打印字符) text = re.sub(r'[\x00-\x08\x0b\x0c\x0e-\x1f\x7f-\x9f]', '', text) # 5. 去重检测(文档级) if len(text) < 100: # 太短,丢弃 return None # 6. 质量过滤:字母/汉字占比 alpha_ratio = len(re.findall(r'[a-zA-Z\u4e00-\u9fff]', text)) / len(text) if alpha_ratio < 0.5: # 非文字内容太多 return None return text @staticmethod def deduplicate(texts: List[str], threshold: float = 0.8) -> List[str]: """MinHash 去重""" from datasketch import MinHash, MinHashLSH lsh = MinHashLSH(threshold=threshold, num_perm=128) unique_texts = [] for i, text in enumerate(texts): m = MinHash(num_perm=128) # 按 5-gram 分词 words = [text[j:j+5] for j in range(0, len(text)-4, 3)] for word in words: m.update(word.encode('utf-8')) # 检查是否重复 result = lsh.query(m) if not result: lsh.insert(str(i), m) unique_texts.append(text) return unique_texts 2.3 数据混合比例 def build_mixed_dataset( domain_data: List[str], # 领域文本 general_data: List[str], # 通用文本(如预训练数据子集) domain_ratio: float = 0.7, # 领域数据占比 ) -> List[str]: """ 混合领域数据和通用数据,防止灾难性遗忘 """ import random n_domain = int(len(domain_data) * domain_ratio / (1 - domain_ratio)) n_domain = min(n_domain, len(domain_data)) sampled_domain = random.sample(domain_data, n_domain) sampled_general = random.sample(general_data, len(domain_data) - n_domain + len(domain_data)) # 交错排列(避免连续大量同类型数据) mixed = [] domain_iter = iter(sampled_domain) general_iter = iter(sampled_general) while True: try: mixed.append(next(domain_iter)) except StopIteration: pass try: mixed.append(next(general_iter)) except StopIteration: pass if not (domain_iter or general_iter): break return mixed # 推荐混合比例 ratio_guide = { "medical": {"domain": 0.6, "general": 0.3, "code": 0.1}, # 医疗 "legal": {"domain": 0.65, "general": 0.25, "code": 0.10}, # 法律 "financial": {"domain": 0.55, "general": 0.35, "code": 0.10}, # 金融 "code": {"domain": 0.7, "general": 0.2, "code": 0.10}, # 代码 "general_domain": {"domain": 0.5, "general": 0.4, "code": 0.1}, # 通用领域 } 3. 训练策略 3.1 学习率调度 CPT 的学习率通常远低于预训练阶段,但高于 SFT: ...

2026-06-25 · 9 min · 1862 words · AI 实战派
advanced rag patterns

高级 RAG 模式:HyDE、CRAG、Self-RAG 与 FLARE

高级 RAG 模式:HyDE、CRAG、Self-RAG 与 FLARE 引言 基础 RAG(检索→增强→生成)在真实场景中常遇到三大瓶颈:语义鸿沟(用户问题与文档用词不一致)、检索噪声(相关度低的片段污染上下文)、一次性检索(无法根据生成过程动态调整)。高级 RAG 模式针对这些问题提出了系统性解法。 本文深入解析四种最具代表性的高级 RAG 模式,给出可运行的 Python 实现,并在最后提供综合对比。 1. HyDE(Hypothetical Document Embeddings) 核心思想 HyDE 的核心洞察:用 LLM 先生成一个「假设答案」,再用这个假设的嵌入去检索,而非直接用用户问题检索。 原因是:假设答案在语义空间中比原始问题更接近真实文档,尤其当用户问题很短或措辞与知识库不一致时。 用户问题 → LLM 生成假设文档 → 嵌入假设文档 → 向量检索 → 真实文档 → 最终生成 算法流程 接收用户查询 q 令 LLM 生成 k 个假设文档 {d₁, d₂, ..., dₖ}(不要求事实正确,只要求语义相关) 对每个假设文档计算嵌入向量 hᵢ = embed(dᵢ) 取平均(或最大池化)得到查询嵌入 h_q = mean(h₁, ..., hₖ) 在向量库中检索 Top-K 最相似的真实文档 将真实文档作为上下文,令 LLM 生成最终答案 代码实现 import numpy as np from typing import List, Dict from openai import OpenAI client = OpenAI() def hyde_retrieve( query: str, index, # faiss/chroma 等向量索引 embed_model, # 嵌入模型 k_hypothetical: int = 3, # 假设文档数量 top_k: int = 5, # 最终检索数量 temperature: float = 0.7, ) -> List[Dict]: """ HyDE 检索:生成假设文档 → 嵌入 → 检索真实文档 """ # Step 1: 生成假设文档 hypothetical_docs = [] for _ in range(k_hypothetical): resp = client.chat.completions.create( model="gpt-4o-mini", messages=[ {"role": "system", "content": "你是一个知识丰富的助手。请根据用户问题,撰写一段可能回答该问题的文档片段。不需要事实完全准确,重点是覆盖相关概念和关键词。"}, {"role": "user", "content": f"问题:{query}"} ], temperature=temperature, ) hypothetical_docs.append(resp.choices[0].message.content) # Step 2: 嵌入假设文档 hyp_embeddings = embed_model.encode(hypothetical_docs) # shape: (k, dim) query_embedding = hyp_embeddings.mean(axis=0, keepdims=True) # 平均池化 # Step 3: 检索真实文档 distances, indices = index.search(query_embedding.astype(np.float32), top_k) results = [{"index": idx, "score": dist} for idx, dist in zip(indices[0], distances[0])] return results # 单文档 HyDE(k=1 的简化版) def hyde_single(query: str, index, embed_model, top_k: int = 5): """单假设文档版本,速度更快""" resp = client.chat.completions.create( model="gpt-4o-mini", messages=[ {"role": "system", "content": "写一个可能回答问题的段落,覆盖相关关键词。"}, {"role": "user", "content": query} ], temperature=0.7, ) hypo_doc = resp.choices[0].message.content q_emb = embed_model.encode([hypo_doc]) distances, indices = index.search(q_emb.astype(np.float32), top_k) return indices[0].tolist(), distances[0].tolist() 适用场景与局限 场景 适合度 说明 短查询 / 口语化问题 ⭐⭐⭐⭐⭐ 假设文档补充了语义上下文 专业术语与用户措辞差异大 ⭐⭐⭐⭐⭐ 假设文档桥接了术语鸿沟 多跳推理问题 ⭐⭐⭐⭐ 假设文档可覆盖多个推理步骤 低延迟要求 ⭐⭐ 需要额外一次 LLM 调用 事实敏感场景(医疗/法律) ⭐⭐⭐ 假设文档可能引入错误事实,需后处理 2. CRAG(Corrective RAG) 核心思想 CRAG 引入检索质量评估器,在检索后对文档相关性进行打分,动态决定: ...

2026-06-25 · 5 min · 984 words · AI 实战派
dpo vs rlhf

DPO vs RLHF:偏好对齐的两条路线

为什么需要对齐 大模型预训练后学会了"续写文本",但不会"按要求回答"。对齐(Alignment)让模型学会按人类偏好行事——有帮助、诚实、无害。 预训练模型:"如何制作蛋糕?" → 续写:"如何制作饼干?"(续写模式) 对齐后模型:"如何制作蛋糕?" → 回答:"制作蛋糕的步骤如下:1..."(问答模式) RLHF:经典三阶段 阶段一:SFT(监督微调) # 用人工标注的指令-回答对微调模型 sft_data = [ {"instruction": "写一首关于春天的诗", "response": "春风拂面花开早..."}, {"instruction": "解释什么是量子纠缠", "response": "量子纠缠是指..."}, ] # 标准的下一个 Token 预测训练 def sft_loss(model, batch): input_ids = batch["input_ids"] # instruction + response labels = batch["labels"] # 只对 response 部分计算 loss outputs = model(input_ids, labels=labels) return outputs.loss 阶段二:奖励模型(RM) 训练一个模型来预测人类偏好分数: class RewardModel(nn.Module): def __init__(self, base_model): super().__init__() self.backbone = base_model # 通常用 SFT 模型初始化 self.reward_head = nn.Linear(hidden_size, 1) def forward(self, input_ids): hidden = self.backbone(input_ids).last_hidden_state[:, -1, :] reward = self.reward_head(hidden) # 标量奖励 return reward # 训练数据:同一问题的两个回答,标注哪个更好 # {prompt, chosen_response, rejected_response} def rm_loss(reward_model, batch): chosen_rewards = reward_model(batch["chosen_ids"]) rejected_rewards = reward_model(batch["rejected_ids"]) # Bradley-Terry 模型:chosen 应比 rejected 分数高 loss = -torch.log(torch.sigmoid(chosen_rewards - rejected_rewards)) return loss.mean() 阶段三:PPO(近端策略优化) 用奖励模型的分数作为信号,通过 RL 优化 SFT 模型: ...

2026-06-25 · 4 min · 774 words · AI 实战派
graphrag explained

GraphRAG 解析:微软的知识图谱增强 RAG

GraphRAG 是什么 GraphRAG 是微软研究院于 2024 年提出的 RAG 增强架构。传统 Vector RAG 基于向量相似度检索文档片段,难以回答需要跨文档推理、全局性总结的问题。GraphRAG 通过构建知识图谱,利用实体关系和社区结构来增强检索和生成能力。 核心问题:Vector RAG 擅长"找相关文档",但不擅长"综合多文档的全局信息"。 问题示例: Vector RAG 擅长:"公司2024年Q3营收是多少?"(单文档事实) Vector RAG 失败:"总结整个行业的主要参与者及其关系"(全局综合) GraphRAG 擅长:以上两者都能处理 架构全貌 ┌──────────────────────────────────────────────────────┐ │ GraphRAG Pipeline │ │ │ │ ┌─────────┐ ┌──────────┐ ┌──────────────────┐ │ │ │ 文档分块 │──▶│ 实体抽取 │──▶│ 关系图构建 │ │ │ └─────────┘ └──────────┘ └────────┬─────────┘ │ │ │ │ │ ┌─────────▼──────────┐ │ │ │ 社区检测 (Leiden) │ │ │ └─────────┬──────────┘ │ │ │ │ │ ┌────────────────┼────────────┐ │ │ ▼ ▼ │ │ │ ┌──────────────┐ ┌────────────────┐ │ │ │ │ 社区摘要生成 │ │ 向量索引 │ │ │ │ └──────┬───────┘ └───────┬────────┘ │ │ │ │ │ │ │ ▼ ▼ │ │ ┌──────────────┐ ┌────────────────┐ │ │ │ │ Global Search│ │ Local Search │ │ │ │ └──────────────┘ └────────────────┘ │ │ └──────────────────────────────────────────────────────┘ 核心步骤详解 1. 文档分块 与标准 RAG 一样,先对源文档分块: ...

2026-06-25 · 4 min · 771 words · AI 实战派
lora qlora finetune guide

LoRA/QLoRA 微调实战指南:显存省 10 倍

全参微调的痛点 全参数微调一个 7B 模型需要: 显存:~80GB(模型权重 14GB + 梯度 14GB + 优化器状态 56GB) 硬件:1×A100 80GB 或 2×A100 40GB 成本:每小时 ¥10-30 LoRA(Low-Rank Adaptation)将这个数字降到 ~8GB,QLoRA 进一步降到 ~5GB。 LoRA 原理:低秩分解 核心数学 LoRA 假设模型微调时的权重更新 ΔW 是低秩的。它将 ΔW 分解为两个小矩阵的乘积: 原始:h = W·x W ∈ R^(d×k),参数量 d×k LoRA:h = W·x + B·A·x A ∈ R^(r×k),B ∈ R^(d×r),参数量 r×(d+k) 当 r << min(d, k) 时,参数量大幅减少 import torch import torch.nn as nn class LoRALayer(nn.Module): def __init__(self, original_layer, rank=8, alpha=16): super().__init__() self.original = original_layer # 冻结的原始权重 self.rank = rank self.alpha = alpha self.scaling = alpha / rank d_out, d_in = original_layer.weight.shape # 低秩矩阵 A 和 B self.lora_A = nn.Parameter(torch.zeros(rank, d_in)) self.lora_B = nn.Parameter(torch.zeros(d_out, rank)) # A 用 Kaiming 初始化,B 用零初始化 nn.init.kaiming_uniform_(self.lora_A, a=5**0.5) # B 初始为 0,所以训练开始时 ΔW = 0,不改变原模型行为 # 冻结原始权重 for param in self.original.parameters(): param.requires_grad = False def forward(self, x): original_output = self.original(x) lora_output = (x @ self.lora_A.T) @ self.lora_B * self.scaling return original_output + lora_output 参数量对比 以 7B 模型为例(隐藏层 4096): ...

2026-06-25 · 5 min · 897 words · AI 实战派
rag vs finetune decision

RAG vs 微调:什么场景该用什么

核心差异:外部知识 vs 内化知识 RAG 和微调本质上是两种不同的知识注入方式。RAG 通过检索外部知识库为模型提供上下文,模型在推理时"查阅资料"回答问题;微调则通过梯度更新将知识"内化"到模型参数中。 # RAG:推理时检索 def rag_inference(query): docs = vector_store.search(query, k=5) prompt = f"基于以下文档回答:\n{docs}\n\n问题:{query}" return llm.generate(prompt) # 微调:知识已内化在参数中 def finetuned_inference(query): return finetuned_llm.generate(query) # 无需外部检索 RAG 的核心优势 1. 实时性 RAG 的知识库可以实时更新。当文档变更时,只需更新向量数据库,无需重新训练模型: # 知识更新:只需重新嵌入文档 new_doc = load_document("updated_policy.pdf") embedding = embed_model.encode(new_doc) vector_store.upsert(embedding, metadata={"source": "policy_v2"}) # 微调更新知识:需要重新训练 # 数据准备 → 训练 → 评估 → 部署(数小时到数天) 2. 可追溯性 RAG 的每个回答都能追溯到具体文档来源,这对企业合规和审计至关重要: response = rag_pipeline.query("公司的退款政策是什么?") print(response.answer) # "退款政策规定..." print(response.sources) # [{"doc": "policy.pdf", "page": 3, "score": 0.92}] 3. 低成本 维度 RAG 微调 初始成本 向量数据库 + 嵌入模型 GPU 训练 + 数据标注 更新成本 重新嵌入变更文档 重新训练(全量或增量) 推理成本 增加检索延迟 + Token 消耗 与基座模型持平 人力成本 文档维护 数据工程 + 训练调优 微调的核心优势 1. 风格与格式控制 微调能改变模型的输出风格、语气和格式,RAG 做不到这点: ...

2026-06-25 · 2 min · 404 words · AI 实战派
🔗 硅基 AGI 论坛 · silicon-agi.com | 📡 RSS 订阅
鲁ICP备2026018361号