24.1 LLM基础
24.1.1 数据处理
你在构造数据集的时候,需要注意什么?
-
数据质量问题
-
数据格式
-
数据安全性
-
数据去噪与清洗
你在构造数据集的时候,数据集的采集一般怎么做的?
-
公开数据集
-
使用已有的高质量开源数据集,如:
-
The Pile
-
Common Crawl
-
OpenWebText
-
Wikipedia
-
BookCorpus
-
C4 (Colossal Clean Crawled Corpus)
-
领域特定数据集:如医学(PubMed)、法律(CaseLaw)、代码(GitHub)、多语言(OPUS)等
-
-
-
网络爬虫 / 网页抓取
-
通过编写爬虫程序从互联网抓取相关网页内容,如新闻、博客、论坛、问答网站(如知乎、Stack Overflow)等
-
可使用工具:Scrapy、BeautifulSoup、Selenium 等
-
-
人工生成 / 众包平台
-
通过人工撰写、标注或审核来构造高质量数据,如:
-
使用 Amazon Mechanical Turk、Appen、Label Studio 等众包平台
-
内部团队或专家编写(适用于专业领域,如医疗、法律、金融)
-
-
-
合成数据(Synthetic Data)
-
利用已有模型(如 GPT、Hunyuan等)生成模拟数据,如对话、问答对、代码示例等
-
常用于冷启动、数据增强、特定场景构造
-
你在构造数据集的时候,数据集的采集如何保证质量?
-
明确采集目标:采集前明确用途:是用于预训练、SFT(监督微调)、RLHF,还是特定任务(如问答、摘要、翻译)。不同任务对数据类型要求不同。
-
选择可信来源:优先选择权威、高质量的公开数据源,如 Wikipedia、新闻站点、官方文档、开源代码库等。
-
制定采集策略:包括主题分布、语言种类、领域覆盖、时间范围等,避免数据过于集中或缺失重要维度。
-
初步筛选与过滤:在采集阶段就进行初步过滤,比如只抓取特定域名、文件类型、内容长度等,减少明显低质或无关内容。
你在构造数据集的时候,数据集的格式需要注意什么?
关键设计原则:
-
结构清晰:每个字段含义明确,如
instruction(指令)、input(输入)、output(输出)、source(来源)等。 -
字段一致:同一数据集内,所有样本应尽量保持相同字段结构。
-
支持多任务:比如同时支持问答、摘要、翻译,可通过字段区分任务类型。
-
可扩展性:可添加额外字段,如
id、domain、difficulty、language等,便于后续筛选和分析。
你在构造数据集的时候,数据集的去噪和清洗需要注意什么?
常见的噪声与问题:
| 类型 | 说明 | 示例 |
| 格式噪声 | HTML标签、特殊符号、乱码、BOM头等 | <p>你好</p>、\xa0、 |
| 内容噪声 | 广告、导航栏、版权声明、用户信息、脚本等 | “欢迎访问XXX网站”、“本站版权所有” |
| 低质内容 | 语句不通、语义模糊、拼写错误、语法错误 | “我明天去哪不知道去哪好” |
| 重复数据 | 完全重复或高度相似的样本 | 抓取多次的同一篇文章 |
| 有害/违规内容 | 暴力、色情、政治敏感、歧视性言论等 | 不适宜公开传播的内容 |
| 隐私信息 | 姓名、电话、地址、身份证、银行卡等 | “我的电话是138xxxx1234” |
去噪与清洗的关键步骤:
-
初步过滤
-
按来源、文件类型、文本长度、语言等做初步筛选
-
去除明显非目标内容(如导航、广告、版权页)
-
-
格式清洗
-
去除 HTML/XML 标签、特殊字符、多余空格、BOM 头等
-
统一编码(如 UTF-8)、规范化文本(如全角/半角、大小写)
-
-
内容筛选
-
去除无意义、不通顺、语法错误严重的句子/段落
-
可使用语言模型、规则或分类器辅助判断内容质量
-
-
去重
-
基于文本相似度(如 TF-IDF、MinHash、SimHash、BERT Embedding + 余弦相似度)去除重复或高度相似样本
-
可设定阈值,如相似度 > 0.9 则认为是重复
-
-
有害/敏感内容过滤
-
使用关键词黑名单、分类模型、敏感内容检测 API 过滤不当内容
-
检查并去除隐私信息(可用脱敏工具或正则匹配)
-
-
语言/领域过滤
-
保留在目标语言(如中文、英文)范围内的数据
-
按领域关键词筛选,确保与任务相关
-
你做数据增强怎么做?
数据增强 是指在不改变数据语义或任务目标的前提下,通过一定方法生成新的、多样的、有效的训练样本,从而提升模型的学习能力与泛化性能。
在自然语言处理(NLP)和 LLM 场景中,数据增强主要针对 文本数据,目的是生成“看起来不一样,但语义或意图一致”的新样本。
下面按技术难度、可控性、适用任务等维度,介绍常用的数据增强方法:
-
基于文本变换的增强(Rule-based / Simple NLP)
适用于大多数 NLP 任务,操作简单、可控性强。
-
同义替换(Synonym Replacement)
-
使用同义词库(如中文同义词词林、哈工大同义词词表、WordNet、中文近义词工具)将句子中的某些词语替换为其同义词。
-
例:
-
原句:这个产品质量很好 → 增强:这个商品品质不错
-
-
随机插入 / 删除 / 交换(EDA: Easy Data Augmentation)
-
EDA 提出四种简单操作,适用于文本分类等任务:
-
随机插入一个词的同义词
-
随机删除一个非关键单词
-
随机交换两个相邻词的位置
-
随机替换一个词为其同义词
-
-
-
回译(Back Translation)
-
将原始文本翻译成另一种语言(如英文),再翻译回原语言,得到语义相近但表达不同的句子。
-
例:中文 → 英文 → 中文,常用于分类、生成类任务的增强。
-
工具:Google Translate API、百度翻译、DeepL、Hunyuan翻译等
-
-
-
基于模板 / 指令改写的增强(Instruction-based / Prompt-based)
适用于对话、问答、指令跟随类任务(如 InstructGPT、ChatGLM 的微调任务)。
-
指令改写(Instruction Paraphrasing)
-
对同一个任务目标,使用不同的语言表达方式重写 prompt / instruction。
-
例:
-
原始指令:总结这段文字 → 增强指令:请用一句话概括以下内容 / 这段话的核心意思是什么?
-
-
输入改写(Input Rephrasing)
-
对输入内容(如问题、描述)进行同义改写、句式变换,但保持原意。
-
例:
-
原问题:北京故宫什么时候建成的?→ 增强:故宫始建于哪一年?/ 明朝紫禁城建于何时?
-
-
基于生成模型的增强(LLM / Generator-based)
利用语言模型(如 GPT、Hunyuan、T5、BART)生成新的样本,适合数据稀缺或需要高质量多样化数据的场景。
-
生成式扩增(Generative Augmentation)
-
使用 LLM 生成:
-
同任务的不同问法(如问答对的多种问法)
-
同一语义的多种表达(如摘要的多种写法)
-
对话中的不同用户 / 助手发言
-
不同风格的文本(正式、口语、幽默等)
-
-
-
基于混合法 / 对抗增强的方法(Advanced)
-
Mixup(较少用于文本,更多用于 CV,但有文本变种)
-
混合两个样本的部分信息生成新样本(如混合两段文本的摘要目标)
-
-
对抗样本增强(Adversarial Augmentation)
-
通过添加扰动(如同义词替换、字符级扰动)生成让模型容易出错的样本,再用于强化训练,提高鲁棒性
-
-
数据集一般怎么划分?训练集、验证集、测试集的比例是多少?
-
经典 ML 场景(数据量适中): 70% 训练 / 15% 验证 / 15% 测试
-
深度学习 / 大模型场景(数据量大): 90% 训练 / 5% 验证 / 5% 测试
-
超大数据场景(如百亿 token 预训练): 几乎全部用于训练,验证/测试只占极小比例(如 0.1% ~ 1%)
划分原则:
-
独立同分布(i.i.d.)假设: 训练/验证/测试集应来自同一分布,确保评估有效。
-
测试集必须“不可见”: 只用于最终评估,不能参与任何调参或模型选择。
-
验证集用于调优: 比如选择模型超参数、决定是否早停、模型 checkpoint 选择等。
-
可复现性与随机性控制: 划分时使用固定随机种子(random seed),确保结果可复现。
如何保证划分后的数据分布一致(如领域、难度、语言)?
解决方法:分层采样 / 分布感知的划分(Stratified Sampling)
-
什么是分层采样?
-
不是简单随机划分,而是按照某些关键属性(如类别、领域、语言等)先分组,然后在每个组内按比例划分,确保每个子集(训练/验证/测试)都包含相似的分布。
-
按什么维度做分层?
| 维度 | 说明 | 适用任务/场景 |
| 类别(Class) | 每个类别的样本按比例划分,防止某些类只在训练或测试集中出现 | 文本分类、情感分析、多标签任务 |
| 领域(Domain) | 比如医疗、法律、新闻等,确保每个领域的数据都出现在各个集合中 | 多领域对话、多文档摘要 |
| 语言(Language) | 比如中、英、日等,确保每种语言都均匀分布 | 多语言模型、翻译、跨语言检索 |
| 难度 / 长度 / 来源 | 比如问题难度、文本长度区间、数据来源站点 | 问答、推理、教育类任务 |
| 用户 / 会话 ID | 比如用户行为数据,同一用户的数据不要同时出现在训练和测试中 | 推荐系统、搜索、个性化任务 |
实际操作方法:
-
工具支持:
-
Python 中可使用
sklearn.model_selection.StratifiedShuffleSplit(适用于类别分布) -
自定义分层:按领域/语言等分组后,对各组分别做随机划分
-
多维度分层:可做多级分组(如先按领域,再按类别)
-
-
流程举例:
-
假设你有一个多领域分类数据集,包括“医疗、法律、金融”三个领域,每个领域样本数不均。你可以:
-
先按领域分组
-
在每个领域内部,按比例(如 8:1:1)划分训练/验证/测试
-
最后合并各领域的划分结果,形成整体数据集
-
-
这样可以保证每个领域都在训练/验证/测试集中有代表,避免评估时出现“某个领域从未见过”的情况。
如果数据有类别不平衡问题,怎么处理?
-
重采样(Resampling)
-
过采样(Oversampling):增加少数类样本
-
方法:随机复制、SMOTE(合成少数类样本,适用于数值型,文本类较少用)、数据增强(如改写少数类样本)
-
适用:小样本类别,但要小心过拟合
-
-
欠采样(Undersampling):减少多数类样本
-
方法:随机删除部分多数类样本
-
适用:数据量很大时,但可能丢失重要信息
-
-
-
类别加权(Class Weighting)
-
在损失函数中为不同类别设置不同的权重,让模型更关注少数类
-
例如:
loss = cross_entropy(..., weight=[w1, w2, ...]) -
适用于神经网络、分类模型(如 BERT、LLM 微调)
-
-
评估指标优化
-
不使用准确率(Accuracy),而是采用更合理的指标:
-
F1-score(尤其是宏平均 F1)
-
精确率 / 召回率(Precision / Recall)
-
AUC / ROC(适用于二分类)
-
混淆矩阵分析
-
-
-
分层评估(Stratified Evaluation)
-
在测试集划分时也按类别分层,确保每个类别都有样本参与评估,避免某些类“被忽略”
-
24.1.2 提示词工程
一个好的提示(Prompt)应该具备哪些特点?
-
清晰明确:任务目标、输入输出要求清晰,不含糊。
-
结构良好:比如使用指令(Instruction)、输入(Input)、输出格式(Output Format)等结构化元素。
-
有上下文:必要时提供背景信息、示例或上下文,帮助模型更好理解。
-
具有引导性:通过措辞引导模型生成你想要的风格、格式或内容。
-
简洁有效:避免冗长、复杂的表述,防止模型抓不住重点。
提示词工程 vs 微调(Fine-tuning)有什么区别?
-
提示词工程是通过优化输入提示来引导模型行为,无需修改模型参数,适用于快速迭代、灵活调整、多任务切换。
-
微调(Fine-tuning)是通过用特定任务的数据训练模型,调整模型参数使其更适合某一任务,适合任务非常固定、数据量较大的情况。
-
提示词工程更灵活、轻量,微调更定制化、成本更高。
常见的提示结构有哪些?
-
零样本提示(Zero-shot Prompt):直接提问或下达指令,不给示例。
-
例: “什么是机器学习?”
-
-
少样本提示(Few-shot Prompt):给出几个输入-输出示例,让模型模仿。
-
指令式提示(Instruction Prompt):明确告诉模型要做什么。
-
例: “请将以下句子翻译成英文:今天天气很好。”
-
-
角色扮演提示(Role-playing Prompt):让模型扮演某个角色,如医生、律师、客服。
-
例: “假设你是一名资深医生,请向患者解释高血压的危害。”
-
-
链式提示 / 思维链(Chain-of-Thought / CoT Prompt):引导模型逐步推理。
-
例: “让我们一步步思考:如果一个班级有 24 个学生,其中 12 个喜欢数学,那么不喜欢数学的有多少个?”
-
有关思维链,能详细说说吗?
思维链提示是指在提问时引导模型逐步推理、展示中间过程,而不是直接给出最终答案。它通过“让我们一步步思考”、“首先...其次...最后...”等句式,激发模型的逻辑推理能力。
作用: 显著提升模型在数学推理、逻辑分析、常识推理等复杂任务上的表现。
如何用提示控制输出格式(如JSON、列表、表格)?
可以在提示中明确要求输出格式,比如:
-
“请以 JSON 格式输出答案,包含字段:name, age, gender。”
-
“请将结果以表格形式呈现,包含序号、名称、价格三列。”
-
“请输出一个包含 3 个要点的列表,简洁明了。”
如何评估一个提示的好坏?
-
人工评估:看输出是否符合需求、格式是否正确、内容是否准确。
-
任务指标:比如准确率、召回率、F1(分类任务)、BLEU/ROUGE(生成任务)。
-
一致性 / 稳定性:相同提示多次生成的输出是否一致。
-
效率:是否能在尽量短的 Prompt 下达到较好效果。
24.1.3 LLM使用
你们用的是什么大语言模型?
OpenAI的、千问系列。
一般在项目开始前会多测几个,做技术选型。
模型参数Temperature有什么作用?
-
当 Temperature 设置较低(如 0.1 ~ 0.5)时:
-
模型倾向于选择概率最高的词,输出更加 确定、稳定、保守。
-
适用于对准确性、一致性要求高的任务,如 事实问答、代码生成、指令执行。
-
-
当 Temperature 设置较高(如 0.7 ~ 1.2 或更高)时:
-
模型会更多地考虑次优词,使输出更加 多样、有创意、富有变化。
-
适用于内容创作、头脑风暴、故事生成、诗歌等开放型任务。
-
-
Temperature = 0:相当于贪婪解码(Greedy Search),每次只选最可能的词,输出确定性最高,但可能过于机械。
你使用LLM怎么避免幻觉问题?
-
使用检索增强生成(RAG, Retrieval-Augmented Generation)
-
原理: 先通过检索系统(如向量数据库 + embedding 模型)从可靠的知识库中检索相关信息,再将这些信息作为上下文输入给 LLM,让它基于真实内容作答,而非“编造”。
-
优点: 显著提升回答的准确性和可追溯性,尤其适用于知识问答、文档助手、企业知识库等场景。
-
通过提示词工程约束模型
-
在提示中明确要求模型“基于事实回答”、“不要编造信息”、“若不确定请说明”等。
-
提供参考文档、上下文、来源信息,引导模型基于已知内容生成。
-
使用可信数据源进行微调或 SFT
-
通过监督微调(SFT)让模型在高质量、可靠的数据上进行学习,减少“胡说”的倾向。
-
适用于专业领域(如医疗、法律),用领域知识训练模型更“靠谱”。
你的产品的效率调优这块你们是怎么做的?
-
模型层面优化
-
选用合适的模型尺寸:比如用 7B、13B 参数模型 而非更大的 65B 或 175B,根据任务需求权衡效果与速度。
-
使用蒸馏模型(Distil-LLM)、量化模型(如 INT8 / GGUF / AWQ),减小模型体积,提升推理速度,适合部署在边缘设备或对延迟敏感的场景。
-
使用优化推理框架:如 vLLM、TensorRT-LLM、LLama.cpp、Text Generation Inference (TGI)、FastChat 等,支持高效批处理、KV Cache 优化、连续批处理等。
-
-
推理与部署优化
-
批处理(Batching):将多个请求合并为一个 batch 推理,提高 GPU 利用率和吞吐量。
-
流式输出(Streaming):支持逐字或逐句返回,提升用户交互体验,降低等待感。
-
缓存机制:对常见 Query 的结果或中间 Embedding 进行缓存,避免重复计算。
-
异步处理 & 队列系统:高并发场景下使用消息队列(如 Kafka、RabbitMQ)做请求调度,避免模型过载。
-
-
检索增强类任务优化(如 RAG)
-
优化向量检索速度:使用高效的 ANN 算法(如 HNSW、IVF),优化 embedding 模型(如 BGE-small、text2vec)。
-
限制检索返回的文档数量,只取 Top-k 最相关内容,减少输入 Token 数,加快生成速度。
-
对检索 + 生成 pipeline 做整体延迟优化,比如并行检索与模型预热。
-
-
成本控制
-
优先使用性价比高的模型(如开源模型本地部署 vs API 调用)。
-
对低价值或低频请求做降级处理,比如用规则引擎代替模型推理。
-
监控 GPU / TPU 使用率,动态扩缩容,避免资源浪费。
-
24.2 流程化
24.2.1 RAG
RAG是什么?
RAG 是 Retrieval-Augmented Generation 的缩写,中文通常翻译为 检索增强生成。它是近年来大语言模型(LLM, Large Language Model)应用中的一种重要技术架构,用于提升大模型在知识问答、信息检索等任务中的准确性和时效性。
大语言模型虽然具备强大的语言理解和生成能力,但其知识范围受限于训练数据的截止时间(例如,某个模型可能只训练到 2023 年底),并且它无法动态获取最新信息或访问特定领域的私有知识库。
RAG 的解决思路是:
不让大模型“凭空想象”答案,而是先从外部知识库中 检索出相关的文档或信息片段,再把这些信息作为上下文,提供给大模型,辅助它生成更准确、更有依据的回答。
简单来说就是:
-
检索(Retrieval):从知识库中找出与用户问题最相关的资料。
-
生成(Generation):将检索到的资料和用户问题一起输入大模型,让它基于这些信息生成回答。
【必问】说一下RAG的流程?
-
用户提问(User Query)
-
用户向系统提出一个问题,比如:“光合作用的具体过程是什么?”
-
-
检索模块(Retriever)
-
利用向量检索(如 Dense Retrieval)、关键词检索或混合检索方法,从知识库(通常是文档库、FAQ库、网页库等)中找出与用户问题最相关的几篇文档或文本片段。
-
常用的检索模型有:BM25(传统关键词匹配)、DPR(Dense Passage Retrieval,基于稠密向量)、FAISS、Milvus 等。
-
-
文档/片段准备
-
将检索到的相关文档进行整理,可能包括截断、拼接、格式化等处理,以便输入到 LLM 中。
-
-
生成模块(Generator,通常是大语言模型)
-
将 用户原始问题 + 检索到的相关文档内容 一同输入大语言模型(如 GPT、Hunyuan、LLaMA 等)。
-
大模型结合这些上下文信息,生成更加准确、有依据的回答。
-
MB25关键字检索的原理是什么?
BM25 是一种基于词频和逆文档频率的经典关键字检索算法,用于衡量一个文档与查询(Query)之间的相关性,它的核心思想是: 对查询中的每个关键词,计算其在当前文档中的重要性得分,然后将所有关键词的得分综合起来,得到文档与查询的整体相关性得分。
-
词频(TF, Term Frequency)部分:一个词在文档中出现的次数越多,通常说明它越相关 —— 但不是线性增长,而是有饱和效应。
-
逆文档频率(IDF, Inverse Document Frequency)部分:一个词如果在整个语料库中很少出现(比如专业词、关键词),那它对区分文档的相关性就更有价值。
你们用的是什么向量数据库?
在我们项目中,我们使用的是 Milvus 作为向量数据库,主要用于存储和高效检索高维向量数据,比如文本的嵌入向量。
-
高性能与高扩展性
-
支持多种索引类型,检索效率高
-
丰富的向量操作与灵活的元数据过滤
-
良好的生态与社区支持
-
生产就绪,支持云原生部署
【必问】RAG中retrieval你们是怎么实现的?你们在RAG中是怎么用Milvus的?
-
知识库预处理 & 文本切块(Chunking)
-
首先,我们将原始知识库(如文档、PDF、网页、FAQ、内部资料等)进行文本清洗、分段、切块,得到一系列较短的文本单元(通常 200~800 字符,视模型输入窗口而定)。
-
每个文本块会作为一个可检索的单元,后续会为它们生成 Embedding 向量并存储到向量数据库中。
-
-
文本向量化(Embedding)
✅ Embedding 模型是检索的基础,它决定了“语义相似度”的计算质量。
-
使用 Embedding 模型(我们用的是 BGE 系列模型,比如 BGE-base-zh),将每个文本块转化为高维向量(如 1024 维),用于后续的语义相似度计算。
-
同时,用户的问题(query)也会通过同一个 Embedding 模型转换成向量,确保与文档向量处于同一语义空间。
-
-
向量存储(Vector Storage)
-
将每个文本块的向量 + 元数据(如文档ID、标题、时间、来源等)存储进向量数据库(我们用的是 Milvus)。
-
Milvus 支持高效的向量存储与检索,并能基于向量相似度快速召回最相关的文档。
-
-
向量检索(Dense Retrieval)
🔍 这里我们用的索引通常是 HNSW 或 IVF 系列索引,以实现高效、快速的相似向量搜索。
✅ 这一步是典型的 Dense Retrieval(稠密检索 / 语义检索),它不依赖关键词,而是基于语义匹配,对表述多样、同义改写等情况更鲁棒。
-
当用户输入问题时,我们:
-
先用 BGE 模型将用户 query 转为向量;
-
然后通过 Milvus 向量数据库,基于向量相似度(如余弦相似度)检索出与 query 向量最相似的 Top-K 个文档片段(比如 Top 3~10)。
-
-
-
混合检索 / 关键词召回(增强召回)
-
除了向量检索,我们还可能结合 BM25 等关键词检索方法,召回一批基于关键词匹配的文档,再与向量检索结果做融合(如并集、加权排序),从而提高召回的全面性,避免漏召。
-
这属于 混合检索策略,我们根据实际效果选择是否启用。
-
-
检索结果返回
这些文档会被输入到 生成模块(大语言模型),与大模型一起生成最终回答。
-
最终检索模块会返回:
-
Top-K 个最相关的文档片段
-
通常还会附带一些元数据信息(如来源、时间等),用于后续展示或进一步过滤。
-
-
Milvus的原理你知道吗?
Milvus 采用分层架构设计,主要分为以下几个核心组件:
-
Client(客户端)
-
用户通过 SDK(如 Python、Java、Go 等)或 RESTful API 与 Milvus 交互,提交向量数据、创建索引、执行检索等操作。
-
Query Node(查询节点)
-
负责处理用户的向量相似性搜索请求,比如查找与某个 Query Vector 最相似的 Top-K 向量。
-
它会基于索引结构快速筛选候选向量,并计算相似度(如欧氏距离、内积、余弦相似度)进行排序,返回最相关的结果。
-
Data Node(数据节点)
-
负责向量数据与元数据的存储与管理,包括原始向量、标量字段(如文档 ID、时间戳等)的写入、读取与持久化。
-
Index Node(索引节点,部分版本中)
-
负责构建向量索引,比如 HNSW、IVF 等。它会从 Data Node 获取原始向量数据,构建索引后供 Query Node 高效检索使用。
Milvus 的核心原理,可以拆解为以下几个关键技术点:
-
向量数据的存储
-
Milvus 存储的是高维向量(通常是 768 维、1024 维等 Embedding 向量),这些向量一般是由文本、图片、音频等数据通过 Embedding 模型(如 BERT、Hunyuan Embedding、SBERT 等)转化而来。
-
每个向量通常还会附带一些标量字段(metadata),比如文档 ID、文本标题、时间等,用于辅助过滤和业务逻辑。
-
向量索引(Indexing)—— 核心原理之一
为了能在海量向量中快速找到与查询向量最相似的 Top-K 向量,Milvus 不为原始向量做线性扫描(那会非常慢),而是先为向量构建索引结构。
我们项目中通常使用的是 HNSW 或 IVF 系列索引,根据数据规模和查询延迟要求做选择。
-
相似性度量(Similarity Metric)
-
Milvus 支持多种向量相似度的计算方式,常见的有:
-
欧氏距离(L2)
-
内积(IP, Inner Product)
-
余弦相似度(Cosine)
-
-
在检索时,Milvus 会根据你选择的度量方式,对向量进行排序,返回最相似的 Top-K 条记录。
-
元数据过滤(Scalar Filtering)
-
除了向量相似性,Milvus 还支持基于标量字段(如时间、类别、标签等)进行过滤,比如:
“找出与 query 向量相似,且时间在 2024 年之后、类别为‘法律’的文档”
-
这种能力是通过在检索时结合 布尔表达式(Boolean Expression) 实现的,非常适用于实际业务系统中的精细化召回。
你们用的是什么向量模型(Embedding 模型)?
我们项目中使用的是 BGE(BAAI General Embedding)系列的 Embedding 模型,是由北京智源人工智能研究院(BAAI)推出的开源、高性能、多场景适用的文本嵌入模型。
BGE 是专为文本语义嵌入(Text Embedding)设计的模型系列,目标是提供更强的语义理解能力、更高的召回精度、更好的跨场景泛化性,相比传统的 Embedding 模型(如 SBERT、BERT-base 等)有显著提升。
我们主要使用了 BGE 系列中的某个具体模型,比如:
-
BGE-small-zh / BGE-base-zh(中文优化,轻量或平衡型)
-
BGE-large-zh(更大规模,效果更强)
-
BGE-M3-Embedding(多语言 / 多粒度 / 多场景,SOTA 级别)
我们根据实际场景的数据规模、响应速度、效果要求,选用了 BGE-base-zh 或 BGE-large-zh,在中文语义表征和召回效果上表现非常优秀。
混合检索的原理是什么?
混合检索(Hybrid Retrieval)是指将多种不同的检索策略或技术结合起来,共同完成信息召回的一种方法。常见的混合方式是「关键词检索(如 BM25)」与「向量语义检索(如 Dense Retrieval)」相结合,从而兼顾检索的精准性、召回率和语义理解能力。
混合检索的实现方式可以分为两大类:
方式 1:结果层面的融合(Post-merging,最常用)
-
分别使用 关键词检索(如 BM25) 和 向量检索(如 Dense) 对同一问题进行检索,各自返回一组 Top-K 文档。
-
然后将两组结果进行合并(如去重、排序、加权打分),最终输出综合得分最高的 Top-N 文档。
🔧 常见融合策略包括:
-
并集合并(Union):将两种方法召回的结果合并去重,再统一排序。
-
加权打分(Score Fusion):为每种检索方式设置一个权重,比如:
-
BM25 得分 × α + 向量相似度得分 × β,综合排序
-
-
重排序(Re-Ranking):先粗筛(如用 BM25 召回较多结果),再用向量模型或交叉编码器精排。
✅ 这种方式实现简单、灵活、易于上线,是我们项目中常用的方案。
方式 2:联合检索(Joint Retrieval,更复杂但更先进)
-
使用一个统一的模型或框架,同时考虑关键词信号与向量信号,在同一阶段完成检索。
-
比如使用 ColBERT、Uni-Retrieval、DETR 等模型,将词元级别的匹配信号与向量语义信号融合到一个相似度计算中。
-
或者使用 Cross-Encoder(交叉编码器),将 Query 和 Document 一起输入模型,直接输出相关性得分,但计算开销较大,通常用于精排阶段。
🔧 这类方法通常用于对效果要求极高、资源较充足的场景,但实时性要求较高的系统可能更偏向于“结果融合”。
Cross-Encoder的原理是什么?
Cross-Encoder 是一种特殊的文本匹配模型,它将 Query(用户问题)和 Document(候选文档/文本片段) 同时输入同一个模型,直接计算它们之间的相关性得分,而不是像 Dense Retrieval 那样分别计算向量再做相似度(如余弦相似度)。
工作原理(与传统 Dense 检索对比):
| 方法 | 输入 | 处理方式 | 输出 | 特点 |
| Dense Retrieval(如 DPR) | Query → 向量,Doc → 向量 | 分别 Embedding,计算向量相似度(如余弦) | 相似度分数 | 速度快,但语义理解有限 |
| Cross-Encoder | Query + Doc(拼接输入) | 两者一起输入模型,经过 Transformer 编码,直接输出相关性得分 | 相关性分数(如 0~1 或 logits) | 语义理解强,准,但慢 |
🔍 关键点:
-
Cross-Encoder 不生成向量表示,而是把 Query 和 Document 拼接在一起(如 [SEP] 分隔)输入一个 Transformer 模型(如 BERT、RoBERTa 等)。
-
模型通过自注意力机制,同时理解 Query 和 Document 的语义交互,最后通过一个线性层输出一个 相关性分数(score),表示两者有多相关。
-
例如:可以输出一个 0~1 的 score,越接近 1 表示越相关。
RAG中的Rerank是什么?Cross-Encoder重排是什么原理?
Cross-Encoder 重排(Cross-Encoder Re-Ranking),是指在召回阶段先用快速的方法(如 BM25 或 Dense Retrieval)召回一批候选文档(比如 Top 50~100),然后把这些候选文档与用户 Query 一起输入 Cross-Encoder,由它对每一个 Query-Doc 对计算一个相关性得分,最后按照得分高低排序,选出最终的 Top-K(如 Top 3~5)最相关文档。
-
召回阶段(第一阶段检索)
-
使用 快速检索方法(如 BM25、Dense Retrieval)召回一批可能相关的文档,比如 Top 50~100 个候选。
-
这一步追求的是“召回尽可能多的潜在相关文档”,速度快但可能不够精准。
-
-
重排阶段(第二阶段精排)
-
将用户 Query 与每一个召回的 Document 配对,输入到 Cross-Encoder 模型中,计算它们之间的相关性得分。
-
根据得分对所有候选文档重新排序(Re-Rank),选出 Top-K 最相关的文档(如 Top 3~5)。
-
-
生成阶段
-
将用户 Query + 精排后的高质量文档,输入大语言模型(如 Hunyuan、GPT),生成最终回答。
-
为什么用Cross-Encoder重排?
-
语义理解能力强
-
Cross-Encoder 能够理解 Query 和 Document 之间的复杂语义关系、上下文依赖、同义表达、逻辑关联,比单纯的向量相似度或关键词匹配更精准。
-
它考虑的是两者联合作用下的匹配信号,而不是独立的向量表示。
-
-
排序精度高
-
在召回后的小范围候选集上使用 Cross-Encoder 精排,可以大幅提升最终返回文档的相关性,从而提高 RAG 系统回答的准确性和可靠性。
-
实验证明,在很多检索评测任务中(如 MS MARCO、TREC),Cross-Encoder 重排能显著提高 NDCG@K、MAP、Recall@K 等指标。
-
-
灵活适配不同任务
-
可用于文档检索、问答匹配、语义相似度判断、多轮对话上下文选择等多种任务。
-
你做RAG的关键字检索和向量检索的比重是怎么调的?
在我们 RAG 系统中,关键字检索(如 BM25)和向量检索(如 Dense Retrieval)的比重调整,本质上是在 召回阶段如何平衡‘字面匹配’与‘语义匹配’,最终目标是召回既精准又全面的相关文档。 我们通常不会简单设定一个固定比例,而是通过实验、召回效果评估、线上 AB 测试等方式,动态调整两者的权重或组合策略。
方法 1:结果融合(Post-Merging)—— 最常用工程实践
🔹 不直接设定“比例”,而是:
-
分别用 BM25(关键字) 和 Dense(向量,如 BGE + Milvus) 召回 Top-K 候选文档(比如各召回 Top 30~50),
-
然后对两组结果进行 去重、合并、综合排序,最终选出 Top-N(如 Top 5~10)送入生成模块。
🔧 常见融合策略包括:
-
并集合并(Union Merge):简单合并两路召回结果,去重后统一排序(比如按时间、来源、或简单规则)。
-
加权打分(Score Fusion):为每路召回结果设定一个权重,比如:
-
BM25 得分 × α
-
向量相似度得分 × β
-
然后计算综合得分:
Score = α × BM25 + β × DenseScore,按总分排序 -
我们通过实验调整 α 和 β 的值(比如 α=0.4,β=0.6 或反之),找到最优组合
-
-
重排序(Re-Ranking):先召回较多结果,再使用 Cross-Encoder 或规则做最终排序
方法 2:路由策略(Routing Strategy)—— 按 Query 类型动态选择
-
对于某些明确包含关键词、专有名词、技术术语的 Query(如“BERT模型的损失函数是什么?”),我们可能更偏向向量检索或加强 Dense 权重;
-
对于表述清晰、包含明确关键词的 Query(如“2023年公司营收是多少?”),可能更依赖 BM25 或加大关键字权重。
🔹 我们可以基于规则、关键词匹配、或轻量级分类器,动态调整两路检索的权重或是否启用某路检索。
方法 3:AB 测试与效果评估 —— 数据驱动决策
-
我们通过离线指标(如 Recall@K、NDCG@K、命中率)和线上指标(如用户满意度、回答准确率、首答解决率),评估不同比重或组合策略的效果。
-
比如:
-
只用 Dense:召回语义相关但可能漏掉关键文档;
-
只用 BM25:召回精准但可能漏掉语义相似表述;
-
混合检索:两者结合,效果更优。
-
🔧 我们会调整:
-
各自召回的 Top-K 数量
-
融合时的权重参数(α / β)
-
是否做重排序、用什么模型做精排
RAG问答的时候,多模态是怎么实现的?
多模态 RAG = 多模态知识理解 + 多模态信息检索 + 多模态内容生成。
-
多模态信息的输入与预处理
-
用户可能输入:
-
纯文本问题
-
图片(如 JPG、PNG,含文字/图表)
-
PDF / 扫描件(含文字和布局)
-
PPT / Word / 截图等
-
🔹 预处理包括:
-
OCR(光学字符识别):提取图片、PDF、扫描件中的文字内容(常用模型如 PaddleOCR、Tesseract、TrOCR、Donut 等)
-
Layout Analysis(版面分析):识别文档中的文字区域、表格、标题、图表位置等(用于结构化信息提取)
-
多模态文档解析:将 PDF、PPT、图片等转换为文本 + 结构化信息,甚至保留图文对应关系
✅ 目标:把多模态内容转化为可检索、可理解、可嵌入的文本或结构化信息。
-
多模态 Embedding(嵌入)与向量化
-
为了让多模态内容(如图文混合、图表+说明文字)能被检索,我们需要将其转化为向量表示(Embedding),和传统文本一样存入向量数据库。
🔹 关键技术:
-
对于 纯文本部分,仍然使用文本 Embedding 模型(如 BGE、SBERT)
-
对于 图像/图表/多模态内容,使用 多模态 Embedding 模型,比如:
-
BLIP-2、BLIP、Flamingo、LLaVA、Otter、ImageBind、Multimodal-BERT
-
CLIP(用于图像+文本联合嵌入)
-
多模态文档模型(如 Donut、UniDoc、mPLUG-DocOwl、Minigpt4、Qwen-VL 等)
-
👉 这些模型能将 图像+文本、图文混排内容 映射到一个统一的 Embedding 空间,从而支持多模态语义检索。
-
多模态检索(Multimodal Retrieval)
-
用户的问题可能是纯文本(如“这个图里的趋势是什么?”),也可能是图文混合。
-
我们需要从多模态知识库中,检索出与该问题最相关的多模态内容(如图表页、图片、PDF 页面等)。
🔹 检索方式包括:
-
图文联合检索:将用户问题 + 图像内容同时 Embedding,进行相似度匹配
-
文本描述检索:如果多模态内容已被 OCR 或解析为文本,可走传统文本检索(Dense / BM25)
-
多模态向量数据库:使用支持多模态向量的数据库(如 Milvus、Weaviate、Pinecone、Qdrant(逐步支持)),存储多模态 Embedding,实现高效检索
✅ 核心:把多模态内容向量化后,通过相似度检索召回最相关的那部分信息,用于后续生成。
-
多模态生成(Multimodal Answering)
-
检索到的多模态内容(如图表、图片、PDF 页面等)会与用户问题一起,输入大模型,生成自然语言的回答。
🔹 如果使用的是多模态大模型(如 GPT-4V、Gemini、Qwen-VL、LLaVA、InternVL、Hunyuan-Vision 等),则:
-
可以直接理解图片/图表内容,并结合用户问题生成回答;
-
也可以将图文混合内容作为上下文,生成更精准的解释、分析、问答。
🔹 如果使用的是纯文本大模型(如 GPT-3.5、Hunyuan、LLaMA):
-
通常只能处理OCR 提取出的文本部分,无法直接理解原图,但依然能基于提取的文字内容 + 用户问题生成答案。
✅ 目标:让大模型基于检索到的多模态知识,生成准确、有依据的回答,必要时可附带图表、引用来源等。
24.2.2 工作流workflow
大模型的工作流workflow是什么?
大模型的工作流是指:为了完成某个具体任务,将大语言模型(LLM)与其他组件(如 Prompt、数据预处理、工具、知识库、记忆模块、Agent、外部 API 等)按照一定顺序组织与协调,所形成的处理流程。
一个典型的大模型工作流可能包括如下环节:
-
任务理解与输入处理
-
用户输入解析、意图识别、参数提取等。
-
-
上下文管理(Memory)
-
对于多轮对话或任务,需要维护上下文,比如对话历史、用户偏好等。
-
-
知识检索(可选,如 RAG 场景)
-
从向量数据库或文档中检索相关信息,与用户问题组合输入给 LLM。
-
-
Prompt 构造
-
动态或静态地构造输入给大模型的提示词,可能包括指令、上下文、示例等。
-
-
模型调用(LLM Inference)
-
将构造好的 Prompt 发送给大语言模型,获取生成结果。
-
-
后处理
-
对模型输出进行格式化、提取结构化信息、过滤噪音等。
-
-
工具/动作执行(可选,如 Agent 场景)
-
如果涉及到工具调用(如搜索、计算、API),则执行相应动作并可能反馈给模型二次处理。
-
-
结果返回与展示
-
最终结果返回给用户,可能伴随 UI 展示、导出等。
-
你是如何编排大模型工作流的?
编排大模型工作流,本质上是将多个步骤模块化,并按逻辑顺序组织起来,确保信息正确流转、模块间高效协作,最终完成目标任务。
在实际项目中,编排工作流通常会借助一些框架(如 LangChain、LlamaIndex、AutoGen、Semantic Kernel 等),但也可以手动设计和编排。
工作流编排的关键点:
-
模块化设计:每个步骤职责清晰,便于维护和替换;
-
数据流转:确保每一步的输出能正确作为下一步的输入;
-
可扩展性:方便插入新的模块(如新增一个检索源、工具等);
-
容错与日志:对关键步骤加入异常处理和调用监控;
-
灵活配置:支持不同任务使用不同的子工作流。
chain式的工作流有哪些优缺点?
优点:
-
模块化 & 可复用
-
每个 Chain 封装一段逻辑(如检索+Prompt+LLM),可以在多个地方复用。
-
-
逻辑清晰
-
通过链式调用(如
chain1 >> chain2或SequentialChain),流程顺序一目了然,便于理解和维护。
-
-
易于编排与组合
-
LangChain 提供多种 Chain 类型(如
SimpleChain、SequentialChain、RouterChain、TransformChain),支持灵活组合。
-
-
抽象层次高
-
开发者无需关心底层的 Prompt 如何传参、LLM 如何调用,Chain 已帮你封装好。
-
-
便于调试与监控
-
可以为每个 Chain 加入回调(Callback)机制,记录输入输出,方便排查问题。
-
缺点:
-
灵活性受限
-
Chain 通常是线性(顺序)执行,如果任务需要条件分支、循环、动态决策,纯 Chain 模型可能不够灵活(此时需要 Agent 或 Graph)。
-
-
错误处理较弱
-
如果中间某一步出错(如检索失败、Embedding 错误),可能缺乏细粒度的错误捕获与恢复机制,需要额外编码处理。
-
-
复杂流程编排较难
-
对于有多个输入来源、多工具协同、状态依赖等复杂场景,仅靠 Chain 很难清晰表达逻辑,可能需要引入 Agent、LangGraph 等更高级编排方式。
-
-
性能瓶颈
-
多个 Chain 串行执行时,若某一步耗时较长(如大文档检索、复杂 Prompt 构造),整体延迟会叠加,需优化各模块效率。
-
24.2.3 Agent
Agent是什么?
Agent(智能体)是由语言模型(LLM)驱动的、具有一定自主决策能力的流程控制器。它能根据任务目标,动态决定下一步该做什么,比如调用工具、执行动作、选择工具/步骤、拆解任务等。
简单来说:
Agent = LLM + 工具(Tools) + 决策逻辑(如 ReAct、Plan-and-Solve) + 状态管理(可选)
-
具备任务拆解与执行能力:Agent 可以将复杂任务分解为多个步骤,并决定每一步如何执行。
-
能调用外部工具/函数:比如搜索、计算器、API、数据库、代码执行环境等。
-
动态决策:不是固定流程(如 Chain),而是根据当前状态和目标,由 LLM 决定下一步做什么。
-
通常基于 Prompt 策略(如 ReAct、Plan-and-Solve)引导模型行为。
Agent vs chain式的工作流有什么区别?
| 维度 | Chain(链式工作流) | Agent(智能体) |
| 流程控制方式 | 固定、顺序执行(A → B → C) | 动态决策,由 LLM 决定下一步调用哪个工具/步骤 |
| 灵活性 | 低,适合明确、线性任务 | 高,适合开放性、多路径、需推理的任务 |
| 工具调用 | 一般不支持或需硬编码 | 原生支持工具调用(Tools),LLM 决定是否调用 |
| 适用场景 | 简单、流程固定的任务(如固定 Prompt → LLM → 输出) | 复杂、需推理和多步操作的任务(如订机票、自动 debug、多工具协作) |
| 代表实现 | LangChain 的 SequentialChain、SimpleChain | LangChain 的 Agent、ReActAgent、PlanAndSolveAgent |
| 典型 Prompt 策略 | 无特殊策略,直接拼接输入 | 使用 ReAct、Plan-and-Solve 等提示策略 引导模型决策 |
MCP是什么?
MCP(Model Context Protocol,模型上下文协议)是由 LangChain 提出的一个开放标准协议,目的是为 LLM 提供标准化的方式来发现和调用 本地或远程的工具、函数、数据源、服务。
可以把 MCP 理解为 LLM 的“插件市场/工具箱协议”。
-
标准化工具注册与发现机制:让 LLM 知道有哪些工具可用(比如计算器、日历、文件读写、数据库查询等)。
-
本地/云端工具集成:MCP Host 可以运行在本地,提供工具列表与调用接口,LLM 通过自然语言理解需要什么工具,然后安全调用。
-
与 Agent 配合使用:Agent 可以基于 MCP 提供的工具列表,进行工具选择与调用,实现更强大的能力。
MCP vs Function Calling有什么区别?
| 维度 | MCP(Model Context Protocol) | Function Calling(函数调用,如 OpenAI Function Call) |
| 提出方 | LangChain 主推的开放协议 | 由 OpenAI 等模型厂商原生支持(如 GPT 的 function_call 参数) |
| 定位 | 标准化工具发现与调用协议(生态级) | 模型原生支持的、直接调用函数的机制 |
| 工具注册方式 | 通过 MCP Server / Manifest 定义工具集,标准化描述 | 由开发者手动定义函数签名,传给模型 |
| 工具发现 | LLM 可通过 MCP 知道有哪些工具可用(类似插件) | 工具由开发者显式定义,模型不一定“知道”工具存在,只按 JSON 格式调用 |
| 适用范围 | 更通用、生态化,支持本地/远程工具集成 | 厂商限定(如 OpenAI、Azure OpenAI),通常云 API 调用 |
| 与 LLM 交互方式 | 通过自然语言 + 工具描述,让 LLM 自主选择 | 模型根据开发者提供的函数 schema,返回要调用的函数名与参数 |
| 典型使用场景 | LangChain 生态、本地智能体工具集成 | 直接与 OpenAI 等模型交互,快速实现工具调用 |
MCP和Agent有什么关系?
MCP 可以作为 Agent 的“工具箱”或“能力来源”。
-
Agent 要执行任务,往往需要调用各种工具(如搜索、数据库、代码执行等)。
-
MCP 提供了一种标准化方式来定义、注册和发现这些工具,使得 Agent 可以更智能、更安全地选择并调用它们。
-
在 LangChain 生态中,你可以构建一个 MCP Server,提供一组工具,然后让 Agent 在运行时发现并使用这些工具完成任务。
说几个Agent框架?
-
LangChain(Python)
-
提供多种 Agent 类型:
ReActAgent、ZeroShotAgent、PlanAndSolveAgent、SelfAskWithSearchAgent等。 -
支持 Tool 调用、Prompt 策略、多工具协同。
-
-
AutoGen(Microsoft,Python & TS)
-
支持多 Agent 协作、人机混合、复杂任务分解,非常适合构建多角色智能体系统。
-
-
Dify.AI / OpenAGI / Agent助手平台(国内/商业化)
-
提供低代码/无代码方式构建 Agent 应用,有些支持自定义 Agent Workflow。
-
Agent的ReAct模式是什么?
ReAct(Reason + Act,推理 + 行动)是一种提示策略,让 LLM 模拟人类的“思考 → 行动 → 观察”过程,从而在复杂任务中做出更好的决策,尤其适用于工具调用与推理任务。
典型流程:
-
思考(Thought):分析问题,决定接下来需要什么信息或动作。
-
行动(Action):执行一个工具调用或者逻辑步骤(如搜索、计算)。
-
观察(Observation):得到行动的结果,继续推理。
Agent的Plan-and-Solve模式是什么?
Plan-and-Solve(计划与解决)是另一种常见的 Agent 提示策略,它要求 LLM 先制定一个清晰的计划(Plan),然后一步步按照计划去执行(Solve),从而完成任务。
典型流程:
-
计划(Plan):先想清楚要分几步,每一步做什么。
-
执行(Solve / Act):按计划逐步执行,可能包括工具调用、逻辑推理等。
Multi-Agent如何做?
Multi-Agent 系统是由多个 Agent 协作或竞争,共同完成一个复杂任务。
常见方式:
-
角色分工:每个 Agent 扮演不同角色(如 Manager、Coder、Tester、Searcher)。
-
通信机制:Agent 之间通过消息、共享内存、对话等方式交互。
-
任务分配与调度:由主 Agent 协调,或基于规则/市场机制分配任务。
-
协作与冲突解决:多个 Agent 可能需协商、投票、合并结果。
框架支持:
-
AutoGen:原生支持多 Agent 对话与协作,非常适合构建客服、开发团队模拟等。
-
MetaGPT:模拟软件公司多个角色(产品经理、程序员、测试)协作开发软件。
-
LangChain + 自定义通信层:也可以自己实现 Agent 间消息传递。
Agent里幻觉怎么解决呢?
解决方法包括:
-
使用外部工具验证
-
不轻信 LLM“口说无凭”,而是让它调用搜索、数据库、API 获取真实信息。
-
例如:问“北京人口是多少?”→ 不直接回答,而是调用搜索工具查最新数据。
-
-
引入检索增强生成(RAG)
-
让 Agent 基于可靠的知识库/文档回答问题,而非自由发挥。
-
-
采用 ReAct / Plan-and-Solve 等结构化策略
-
引导模型先思考、再行动、再验证,减少胡编乱造。
-
-
提示工程(Prompt Engineering)
-
在 Prompt 中明确要求:“仅基于已知信息回答”、“若不确定请说明”。
-
24.3 LLM框架
24.2.1 通用开发框架(以LangChain为例)
什么是LangChain?它主要用来解决什么问题?
LangChain 是一个用于开发由语言模型(LLM, Large Language Model)驱动的应用程序的开源框架。它旨在简化构建复杂、多步骤的 LLM 应用的过程,尤其是在需要结合外部数据、工具、逻辑与多个 LLM 调用的场景下。
LangChain 主要解决的问题包括:
-
复杂流程编排:当一个应用需要多个 LLM 调用、有逻辑依赖或步骤顺序时,LangChain 提供了编排这些步骤的能力。
-
上下文管理:在长对话或多轮交互中,LangChain 支持管理上下文(如使用 Memory 模块),使得模型能够“记住”之前的交互。
-
外部数据连接:允许 LLM 与外部数据源(如数据库、API、文档等)交互,比如通过检索增强生成(RAG)来获取最新或私有信息。
-
工具调用与集成:让 LLM 可以调用外部工具(如搜索引擎、计算器、代码执行环境等),扩展其能力。
-
模块化与可复用性:提供标准化的组件(如 Prompt 模板、链式调用、Agent 等),方便开发者组合和复用。
简而言之,LangChain 不是 LLM 本身,而是一个“胶水层”框架,让开发者更高效地基于 LLM 构建功能丰富、结构复杂的智能应用。
LangChain的核心模块有哪些?分别有什么作用?
-
Models(模型接口)
-
作用:负责与各种大语言模型(如 OpenAI、Hunyuan、Claude、Mistral 等)进行交互的统一接口。
-
功能:支持文本生成、嵌入(Embedding)、聊天模型(ChatModel)等,提供统一的调用方式,便于替换底层模型。
-
-
Prompts(提示管理)
-
作用:管理和构造输入给 LLM 的提示(Prompt)。
-
关键组件:
-
PromptTemplate:用于定义带变量的模板化提示。 -
ChatPromptTemplate:用于构建对话型提示,常用于 Chat 模型。 -
支持从文件、变量动态加载提示内容。
-
-
-
Chains(链式调用)
-
作用:将多个组件(如模型调用、提示、数据处理等)组合成有序的“链”,实现多步逻辑处理。
-
常见链类型:
-
LLMChain:最基础的 LLM 调用链。 -
SequentialChain:按顺序执行多个链。 -
RouterChain/ConditionalChain:根据条件路由到不同的链。 -
更高级的如
RetrievalQA(检索问答链)、TransformChain(数据转换链)等。
-
-
-
Memory(记忆模块)
-
作用:为对话或应用提供状态保持能力,即“记忆”之前交互的内容。
-
应用场景:多轮对话、个性化交互等。
-
实现方式:如
ConversationBufferMemory(缓冲记忆)、ConversationSummaryMemory(摘要记忆)等。
-
-
Indexes & Retrievers(索引与检索,用于 RAG)
-
作用:将外部文档(如 PDF、txt 等)进行索引,构建向量库,并通过 Embedding 模型进行语义检索,常用于检索增强生成(RAG)。
-
关键组件:
-
VectorStore(如 FAISS、Chroma、Pinecone 等) -
Retriever:从索引中检索相关文档片段 -
常与
RetrievalQA链配合实现问答
-
-
-
Agents(智能代理)
-
作用:让 LLM 充当“智能决策者”,根据任务目标决定调用哪些工具、以什么顺序调用,并基于反馈迭代。
-
特点:
-
Agent 可以调用工具(如搜索引擎、API、代码执行器等)
-
支持 ReAct、Plan-and-execute 等推理策略
-
常用于开放域任务、自动化任务等
-
-
-
Tools(工具集成)
-
作用:让 LLM 能够使用外部工具,比如:
-
搜索引擎
-
计算器
-
API 接口
-
数据库查询
-
代码执行沙箱
-
-
LangChain 提供标准接口,开发者可以接入自定义工具。
-
-
Callbacks(回调系统)
-
作用:提供对 LLM 应用运行过程的监控和日志记录,用于调试、跟踪和集成监控系统。
-
LangChain支持哪些LLM模型?如何接入自定义模型?
LangChain 通过统一的接口支持 多种 LLM 模型服务提供商,包括但不限于:
-
主流商业模型 API:
-
OpenAI(GPT-3.5, GPT-4 等)
-
Anthropic(Claude)
-
Google(PaLM, Gemini)
-
Tencent(混元大模型,如通过 Hunyuan API)
-
Mistral、Cohere、HuggingFace Hub、Azure OpenAI 等
-
-
开源模型(通过本地部署或 API 代理):
-
LLaMA / LLaMA 2(通过 API 服务或本地部署如 llama.cpp)
-
Mistral、Falcon、GPT-J / GPT-NeoX
-
使用 FastChat、Text Generation Inference (TGI)、vLLM 等推理服务对外提供 API 后,LangChain 也可以接入
-
如何接入自定义模型?
-
方式一:通过 LangChain 的模型接口标准,封装自定义模型类
-
方式二:如果你的模型已经提供了类似 OpenAI 的 API(比如通过 FastChat、TGI、vLLM 等部署)
-
方式三:使用 Hugging Face Transformers 等本地模型
如何使用LangChain实现RAG?用哪些组件?什么流程?
-
Documents(文档)
-
你的原始数据,比如 PDF、txt、网页内容等。
-
通常使用
langchain.document_loaders加载,如PDFLoader、TextLoader。
-
-
Text Splitter(文本分割器)
-
将大文档切分成适当大小的 Chunk,便于后续索引。
-
组件:
RecursiveCharacterTextSplitter
-
-
Embedding 模型(文本向量化模型)
-
将文本块转换为向量表示,用于语义检索。
-
可使用 LangChain 支持的任意 Embedding 模型,如
HuggingFaceEmbeddings、OpenAIEmbeddings、或者腾讯混元 Embedding API。
-
-
Vector Store(向量存储 / 索引)
-
存储文本块及其嵌入向量,支持高效的相似度检索。
-
常见实现:
FAISS(内存)、Chroma、Pinecone、Weaviate、Qdrant等。 -
LangChain 提供统一接口:
VectorStore
-
-
Retriever(检索器)
-
根据用户问题,从 VectorStore 中检索出最相关的文档片段。
-
通常由 VectorStore 自带(如
faiss.as_retriever()),或可自定义。
-
-
Prompt Template(提示模板)
-
构造将检索到的上下文 + 用户问题一起传给 LLM 的提示。
-
-
LLM(大语言模型)
-
用于根据检索到的上下文和问题生成答案,如 GPT、Hunyuan、Claude 等。
-
-
RetrievalQA(可选,封装好的链)
-
LangChain 提供的一个开箱即用的链,组合了 Retriever + Prompt + LLM,简化 RAG 流程。
-
RAG 实现流程:
-
加载文档:从磁盘/网络加载原始数据(PDF、txt等)。
-
分割文档:将文档切分成小块(chunks)。
-
向量化:用 Embedding 模型将 chunks 转为向量。
-
构建索引:将向量存入 VectorStore(如 FAISS)。
-
检索:用户提问时,用 Retriever 找出最相关的文档片段。
-
构造 Prompt:将检索结果与用户问题组合成完整 Prompt。
-
调用 LLM:让 LLM 基于上下文回答问题。
-
(可选)使用 RetrievalQA 链:一步到位,简化上述流程。
如何使用LangChain实现workflow?用哪些组件?什么流程?
-
Chain(链)
-
基础组件,用于将多个操作(如 Prompt、LLM 调用、数据处理)组合成一个流程。
-
常见子类:
-
LLMChain:基础 LLM 调用链 -
SequentialChain:按顺序执行多个 Chain -
RouterChain/ConditionalChain:根据条件选择不同路径
-
-
-
SequentialChain(顺序链)
-
将多个 Chain 按顺序串联,前一个的输出作为下一个的输入。
-
适用于多步有依赖的任务,比如先提取信息,再总结,再翻译等。
-
-
RouterChain / ConditionalChain
-
根据输入内容,选择不同的处理路径,适合多分支逻辑。
-
-
自定义 Chain
-
继承
Chain基类,自定义你自己的多步逻辑。
-
Workflow 实现流程:
-
拆解任务步骤:将一个复杂任务拆解为多个子任务(如:信息抽取 → 信息加工 → 回答生成)。
-
构建单个 Chain:为每个子任务创建一个 Chain(如 Prompt + LLM)。
-
组合 Chain:使用
SequentialChain或自定义逻辑将多个 Chain 串联/并联。 -
执行 Workflow:输入初始数据,触发整个流程,得到最终结果。
如何使用LangChain实现Agent?用哪些组件?什么流程?
-
LLM(大模型)
-
用于决策:决定调用哪个工具、如何组织 prompt、反思等。
-
通常使用支持 ReAct 或 tool-use 的模型(如 GPT-3.5+/4、Hunyuan、Claude 等)。
-
-
Tools(工具集)
-
LLM 可调用的外部能力,比如:
-
搜索引擎
-
计算器
-
API 请求
-
代码执行器
-
数据库查询
-
-
工具需符合 LangChain Tool 接口,定义好名称、描述、调用函数。
-
-
ToolKit / 工具注册
-
将多个工具组合在一起,供 Agent 使用。
-
-
Agent 类型
-
LangChain 提供多种 Agent 实现,如:
-
ZeroShotAgent(基于 ReAct 模式,提示中定义可用工具) -
ReActAgent -
StructuredChatAgent -
SelfAskWithSearchAgent -
通过
agents模块灵活配置。
-
-
-
AgentExecutor
-
负责执行 Agent 的决策循环:思考 → 决定调用工具 → 调用 → 获取结果 → 反馈。
-
Agent 实现流程:
-
定义工具集:实现你希望 LLM 使用的各个工具(比如搜索、计算、API)。
-
加载 LLM:选择支持工具调用的模型。
-
构建 Agent:使用 Agent 类(如 ZeroShotAgent 或 ReAct 模式),告诉它可以用的工具。
-
执行 Agent:通过
AgentExecutor运行,用户提问后,Agent 自主决策调用工具并生成最终回复。
能介绍一下LangChain的ReAct和Tool使用方式吗?
LangChain 提供了内置的 ReAct Agent(如 ZERO_SHOT_REACT_DESCRIPTION),你只需要:
-
提供一组 Tools(工具)
-
使用 ReAct 模式的 Agent(如
ZeroShotAgent) -
LLM 就会根据问题,自动决定何时调用工具、调用哪个工具、以及如何组织推理过程。
Tool(工具)使用方式:
-
定义一个 Tool
-
让 LLM 使用这个 Tool(通过 Agent)
-
LLM 会先“思考”,然后决定调用
get_current_year,获取结果后生成回答
如何让LLM调用外部API?在LangChain中如何使用Tool实现?
让 LLM 调用外部 API,本质是:
-
定义一个 Tool,其内部封装了 API 请求逻辑(如 HTTP 请求)。
-
将该 Tool 提供给 Agent 或 Chain,让 LLM 在需要时调用它。
如何实现多轮对话的记忆功能(Memory)?用哪些组件?
Memory 的典型使用流程:
-
初始化一个 Memory 对象(如
ConversationBufferMemory)。 -
将 Memory 对象传入 Chain 或 Agent,比如
LLMChain(memory=memory)或initialize_agent(memory=memory)。 -
在多轮对话中反复调用,Memory 会自动累积用户与 AI 的对话历史,并在下一轮输入中注入到 Prompt。
-
(可选)自定义 Prompt 模板,将 memory 中的历史以合适格式拼接到用户问题之前。
在LangChain中如何管理上下文长度问题(比如Token超限)?
-
使用合适的 Memory 类型(减少历史输入)
-
如用 ConversationSummaryMemory 替代 ConversationBufferMemory,用摘要代替全部历史。
-
定期清理或截断 Memory 中的内容。
-
-
对话历史裁剪(Conversation Buffer Truncation)
-
LangChain 的
ConversationBufferMemory支持设置memory_key和return_messages,并可以控制保留多少轮对话。 -
你可以手动或使用
trim_memory()方法只保留最近 N 轮。
-
-
手动控制 Prompt 构造
-
在自定义 Prompt 时,只选择最重要的历史片段拼接,而不是全部历史。
-
比如只保留最近 3~5 轮对话,或者按时间/重要性筛选。
-
-
使用 Token 计算工具
-
LangChain 提供
get_token_ids或第三方工具(如 tiktoken)来计算输入内容的 Token 数,提前判断是否超限。
-
-
RAG 场景下的 Context 管理
-
检索出来的文档片段过多?用 Top-K / Top-N 过滤,只保留最相关的几条。
-
控制
Retriever返回的文档数量,比如只取 3~5 个最相关段落。
-
-
使用 Long-context 模型
-
如 GPT-4-32k、Claude 100k、Hunyuan长文模型、Mistral-long 等,它们支持更大的上下文窗口。
-
或者使用外部 分段处理 + 总结 策略,把长内容拆块处理。
-
你了解LangChain有哪些相关生态项目?比如LangChain.js、LangSmith、LangGraph?
-
LangChain.js
-
是什么:LangChain 的 JavaScript / TypeScript 版本,功能类似 Python 版,用于在 Node.js 或前端环境中开发 LLM 应用。
-
支持功能:
-
Models(调用 LLM API)
-
Prompts、Chains
-
Memory、Agents(部分支持)
-
适用于浏览器和服务器端 JS 环境
-
-
适用场景:
-
前端直接调用 LLM(如网页智能助手)
-
Node.js 后端服务构建
-
-
-
LangSmith
-
是什么:LangChain 官方推出的 调试、监控、测试与可视化平台,用于跟踪、评估和优化 LangChain 应用。
-
核心功能:
-
追踪 Chain / Agent 的调用链路,查看每一步输入/输出
-
支持 日志记录、错误排查、性能分析
-
提供 测试框架,支持单元测试和集成测试 LLM 应用
-
可视化 Prompt、工具调用、Retriever 结果等
-
-
适用场景:
-
生产环境调试复杂 Chain
-
LLM 应用质量保障与迭代
-
团队协作与版本管理
-
-
-
LangGraph
-
是什么:由 LangChain 团队推出的 用于构建有状态、循环、多路径决策流程的库,特别适合构建 Agent 助手、工作流、多轮推理等复杂拓扑结构。
-
与 Chain 的区别:
-
传统的 Chain 是线性或分支的,而 LangGraph 支持有环图、状态保存、循环执行。
-
-
适用场景:
-
构建 多轮交互式 Agent
-
实现 状态ful 工作流
-
复杂逻辑控制(如“先做 A,根据结果再决定 B 或 C,可能回到 A”)
-
-
24.2.2 LLMOps平台(以Dify为例)
Dify是什么?
Dify 是一个开源的 LLMOps 平台,用于快速构建、部署和管理大语言模型(LLM)应用,支持从原型设计到生产环境的全流程。它让开发者与产品经理可以无需深入掌握复杂的 LLM 编程细节,也能高效搭建 AI 应用。
简单来说:
Dify = 低代码/无代码 + LLM 应用开发平台 + LLMOps 工具链
它类似于 Streamlit + LangChain + Vercel + LangSmith 的集合体,但更聚焦于 LLM 应用层,目标是降低 LLM 应用开发与部署门槛,提升开发效率。
Dify的技术架构大致是什么?
虽然 Dify 提供的是 Web UI 和开箱即用的体验,但其背后是一套完整的架构,通常包括:
-
前端:React / Web UI,用于低代码应用编排与配置
-
后端:Python / FastAPI,负责业务逻辑、模型调度、API 封装
-
模型层:对接 OpenAI / Hunyuan / 自研模型等
-
向量存储:支持 Redis、Milvus、Qdrant 等,用于 RAG
-
数据库:PostgreSQL 等,用于存储用户数据、Prompt 模板、应用配置
-
部署支持:Docker / Kubernetes,支持云原生部署
Dify vs LangChain的关系与对比?
| 对比维度 | Dify | LangChain |
| 定位 | LLMOps 平台 / 应用开发平台,面向产品经理与开发者,主打低代码、快速交付 | LLM 应用开发框架,面向开发者,提供灵活的编程接口与模块 |
| 编程方式 | 可视化编排为主,也支持 YAML / API / SDK | 代码驱动(Python),高度灵活可定制 |
| 核心优势 | 快速搭建应用、内置 RAG / Agent / 工作流、支持部署与监控 | 模块化设计、生态丰富、适合复杂逻辑与定制化开发 |
| 适用人群 | 非技术背景 / 希望快速上线 AI 产品的人员、全栈开发者 | Python 开发者、希望深度控制模型与流程的工程师 |
| 部署方式 | 支持 SaaS(Dify Cloud)和私有化部署(Docker / K8s) | 纯代码部署,需自行封装服务与前端 |
| 是否开源 | ✅ 开源(AGPL / 商业版) | ✅ 开源(Apache 2.0) |
24.4 训练
24.4.1 AI算法
梯度消失是什么?为什么会梯度消失?
在深度神经网络训练过程中,反向传播算法通过链式法则计算每一层的梯度。如果这些梯度随着网络层数的增加变得越来越小,接近于零,导致浅层网络的权重几乎无法更新,这种现象称为梯度消失。
主要原因包括:
-
激活函数的饱和性:如 sigmoid 和 tanh 函数,在输入值很大或很小时,其导数接近于 0,导致反向传播时梯度逐层变小。
-
链式法则的连乘效应:在深层网络中,梯度是通过每一层的导数相乘得到的。如果每层的导数都小于1,多次连乘后梯度会指数级减小。
-
权重初始化不当:如果初始权重过大或过小,也可能导致梯度不稳定或趋向于0。
梯度消失解决方法?激活函数,参数初始化,正则化与归一化方法,残差连接分别是什么?
-
激活函数(Activation Function)
使用非饱和性、梯度友好的激活函数,例如:
-
ReLU (Rectified Linear Unit):当输入 > 0 时导数为 1,避免了梯度饱和。
-
Leaky ReLU / Parametric ReLU / ELU / Swish:对负值也有非零梯度,缓解死神经元问题。
-
-
参数初始化(Weight Initialization)
合理的初始化方法能让初始梯度保持在合理范围,例如:
-
Xavier / Glorot 初始化:适合 sigmoid/tanh,根据输入输出维度调整初始化范围。
-
He 初始化:适合 ReLU 系列激活函数,考虑了 ReLU 的零区域特性。
-
-
正则化与归一化方法(Regularization & Normalization)
-
Batch Normalization (BN):对每一层的输入做归一化,加速收敛,缓解梯度消失/爆炸。
-
Layer Normalization (LN):常用于 RNN 或 Transformer,对单个样本的不同特征归一化。
-
Weight Normalization / Group Normalization:其他归一化策略,有助于稳定训练。
-
-
残差连接(Residual Connections)
-
引入了跳跃连接(skip connection),如 ResNet 中的残差块,使得梯度可以直接回传,避免了梯度在多层中连乘衰减。
-
允许更深的网络训练,是解决梯度消失非常有效的方法。
-
梯度爆炸是什么?为什么会梯度爆炸?
与梯度消失相反,梯度爆炸指的是在反向传播过程中,梯度值变得非常大,导致权重更新幅度过大,模型参数发生剧烈震荡甚至溢出(NaN),网络无法收敛。
为什么会出现梯度爆炸?
-
同样源于链式法则中的连乘效应,但如果每一层的梯度都大于1,经过多层累积后梯度会指数级增长。
-
权重初始化过大、学习率过高、网络过深等也会诱发梯度爆炸。
梯度爆炸的解决方法?梯度裁剪,合适的权重初始化,归一化方法,优化器选择,残差连接,L2正则化分别是什么?
-
梯度裁剪(Gradient Clipping)
-
设定一个阈值,当梯度的范数超过该值时,按比例缩小梯度,防止更新步长过大。
-
常用于 RNN、Transformer 等模型,是处理梯度爆炸最直接有效的方法之一。
-
-
合适的权重初始化(Proper Weight Initialization)
-
使用 Xavier、He 等初始化方法,避免初始权重过大导致梯度不稳定。
-
-
归一化方法(Normalization)
-
如 BatchNorm、LayerNorm,有助于控制每层输入的分布,间接缓解梯度爆炸。
-
-
优化器选择(Optimizer Choice)
-
使用更先进的优化器如 Adam、RMSprop,它们对学习率有自适应调整能力,相比 SGD 更稳定,能缓解爆炸问题。
-
-
残差连接(Residual Connections)
-
通过跳跃连接让梯度可以直接回流,不仅缓解梯度消失,也对梯度爆炸有一定抑制作用。
-
-
L2 正则化(L2 Regularization)
-
通过对权重施加惩罚,限制权重的过大增长,间接控制梯度的大小。
-
过拟合是什么?为什么会过拟合?
模型在训练数据上表现很好,但在未见过的测试/验证数据上表现差,即模型过度记忆训练数据的噪声或细节,而失去了泛化能力。
为什么会出现过拟合?
-
模型过于复杂(参数量过多),容易记住而非学习规律。
-
训练数据量太少,模型容易拟合噪声。
-
训练时间过长,模型过度调参以适应训练集。
过拟合的解决方法?数据增强,降低模型复杂度,Dropout,Early Stopping分别是什么?
-
数据增强(Data Augmentation)
-
对训练数据进行变换(如旋转、翻转、加噪声、裁剪等),增加数据的多样性,提升模型的泛化能力,常用于图像、文本等领域。
-
-
降低模型复杂度(Reduce Model Complexity)
-
减少网络层数或神经元数量,使用更简单的模型结构,避免模型过于强大而记住噪声。
-
-
Dropout
-
在训练过程中随机“丢弃”一部分神经元(将其输出置零),防止某些神经元过度依赖,增强泛化能力,常用于全连接层。
-
相当于训练了很多子网络并集成,有正则化效果。
-
-
Early Stopping(早停法)
-
在验证集性能不再提升时提前终止训练,防止模型在训练集上过度拟合。
-
需要监控验证集损失或准确率,选择最佳 epoch。
-
24.4.2 Transformer
Transformer 整个架构是怎么样的?
Transformer 是由 "Attention is All You Need" (Vaswani et al., 2017) 提出的,最初用于机器翻译任务,目前是几乎所有大语言模型(如 GPT、BERT、T5、LLaMA 等)的基础架构。
Transformer 采用 完全基于 Attention 的架构,抛弃了传统的 RNN / CNN,核心由两大部分组成:
Transformer 包括:
-
Encoder(编码器):将源语言序列编码为一系列上下文表示。
-
Decoder(解码器):根据编码器的输出和已生成的部分目标序列,逐步生成目标语言序列。
注:像 GPT 这样的自回归语言模型只使用 Decoder 部分;像 BERT 这样的双向模型只使用 Encoder 部分。
每个 Encoder 和 Decoder 都是由 N 个相同的层(通常是 6~12 层)堆叠而成,每层包含:
-
Encoder 单层结构包括:
-
Multi-Head Self-Attention(多头自注意力机制)
-
Add & Norm(残差连接 + Layer Normalization)
-
Feed Forward Network(前馈全连接网络,FFN)
-
Add & Norm
-
-
Decoder 单层结构包括:
-
Masked Multi-Head Self-Attention(带掩码的自注意力,防止信息泄露)
-
Add & Norm
-
Encoder-Decoder Attention(交叉注意力,Q来自Decoder,K/V来自Encoder)
-
Add & Norm
-
Feed Forward Network
-
Add & Norm
-
其他重要组件:
-
Positional Encoding(位置编码):因为 Transformer 没有 RNN 的时序概念,需要显式加入位置信息。
-
Embedding 层:将词 token 转为向量表示。
-
输出部分(如语言模型头、线性层+Softmax):用于预测下一个 token。
说一下GPT模型与Transformer模型关系?
-
GPT(Generative Pre-trained Transformer) 是基于 Transformer 架构的 Decoder-only(仅解码器)模型。
-
具体来说:
-
原始 Transformer 是 Encoder-Decoder 结构,用于 seq2seq 任务(如机器翻译)。
-
BERT 使用 Transformer 的 Encoder 部分,是 双向模型,用于理解类任务(如 QA、文本分类)。
-
GPT 则使用 Transformer 的 Decoder 部分(且去掉 Cross-Attention),是 自回归、单向(只能看到前面 token) 的模型,用于 文本生成类任务。
-
说一下Transformer里self-attention的公式?
-
线性映射得到 Q, K, V:
-
$$Q=XW^Q,K=XW^K,V=XW^V$$
-
Q(Query)、K(Key)、V(Value)分别代表查询、键和值。
-
-
计算注意力分数(Attention Scores):
-
$$Attention(Q,K,V)=softmax(\frac{QK^T}{\sqrt{d_k}})V$$
-
QK^T:衡量每个 Query 和所有 Key 的相似度。
-
除以sqrt(d_k):缩放因子,防止点积过大导致 softmax 梯度消失。
-
softmax:归一化得到注意力权重。
-
最后乘以 V:加权求和得到每个位置的输出。
-
-
Multi-Head Attention(多头注意力):
-
将上述过程拆成多个头(head),每个头学习不同的注意力模式,最后拼接再投影。
-
Self-attention,q、k、v代表什么意思?
在 Self-Attention 机制中:
-
Q(Query):查询向量,代表当前正在处理的 token,用于“询问”其他 token 与我的相关性。
-
K(Key):键向量,代表其他 token 的“标识”,用于与 Query 做匹配,决定相关性。
-
V(Value):值向量,代表其他 token 的实际内容信息,最终根据注意力权重进行加权求和。
类比:
-
想象你在找某条信息(Query),有一堆文档(Key),你要先看每份文档标题(Key)跟你的问题有多相关,然后根据相关程度,去提取文档里的内容(Value)。
你觉得Transformer和RNN、LSTM相比,它的优势是什么?
-
并行计算能力强 → 训练速度更快。
-
通过 Self-Attention 可以捕捉全局依赖 → 长距离上下文理解更强。
-
模型表达能力更强,更适合大规模数据和预训练 → 成为如今大模型的基石。
训练时候模型的参数类型是什么?
可训练参数(Trainable Parameters / Model Parameters):
这些是模型通过反向传播和优化器自动学习、更新的参数,是训练的核心。
包括:
-
Embedding 层的权重矩阵:将 token id 映射为向量。
-
Q、K、V 的线性变换矩阵(WQ,WK,WV):用于计算 Self-Attention。
-
多头注意力中各个头的投影矩阵
-
Feed Forward Network(FFN)中的权重和偏置:通常是两层 MLP,如 FFN(x) = W₂(ReLU(W₁x + b₁)) + b₂
-
Layer Normalization 中的 γ(scale)和 β(shift)参数
-
输出层的参数(如语言模型头)
不可训练参数 / 超参数(Non-trainable / Hyperparameters):
这些不是由模型学习的,而是人为设定或固定的,包括:
-
学习率(learning rate)
-
batch size
-
模型层数、注意力头数、hidden size 等架构超参数
-
Dropout 比例
-
梯度裁剪阈值
-
Positional Encoding 的方式(固定 or 可学习)
Llama的位置编码是怎么样的?
这是 LLaMA(以及后续许多大模型如 GPT-NeoX、ChatGLM、Mistral 等)采用的一种相对位置编码方法,相比传统的绝对位置编码(如 Transformer 原始论文中的 Positional Encoding),RoPE 有更好的泛化性与长序列建模能力。
什么是 RoPE(Rotary Positional Encoding)?
-
核心思想:对 Query 和 Key 向量中的每个维度,根据其位置信息进行旋转(即在复数域做旋转变换)
-
相对于 token 的位置,为每个 token 的 Q 和 K 向量的不同维度引入不同的旋转角度,从而隐式编码位置信息
-
不增加额外的位置向量,而是直接对 Q 和 K 做变换,融入位置信息
RoPE 的优点:
-
相对位置信息建模更强:对 token 之间的相对位置关系更敏感,而不是单纯的绝对位置。
-
外推性好:对于比训练时更长的序列,也能较好泛化,不像传统位置编码那样受限于固定长度。
-
计算高效:与 Self-Attention 机制无缝集成,没有显著增加计算负担。
24.5 微调
什么是LLM微调?为什么要做微调?
大语言模型在大规模通用语料上预训练后,已经具备很强的语言理解与生成能力,但在面对特定行业、公司内部数据、专业术语、个性化风格时,可能存在以下问题:
-
生成内容不够专业或准确(比如医疗、法律、金融等领域)
-
语言风格不符合企业品牌或用户需求
-
对特定任务(如问答系统、表单填写、代码生成)效果不佳
-
缺乏对内部知识库、产品术语、私有数据的理解
👉 微调的目的就是:让通用的大模型,变成更懂你业务的“专属模型”。
LLM微调有哪些常见方法?(全量微调、LoRA、Adapter、SFT、RLHF)
(1)全量参数微调(Full Fine-tuning)
-
含义:对模型的所有参数进行更新训练。
-
优点:效果好,模型能最大程度适配目标任务。
-
缺点:计算资源消耗极大,需要大量数据和算力,容易过拟合,不适合频繁迭代。
-
适用场景:数据量大、算力充足、对性能要求极高的场景。
(2)部分参数微调 / 适配器微调(Partial Fine-tuning / Adapter Tuning)
-
含义:只训练模型的一部分参数(比如新增的“适配器层”),而保持原有主干参数不变。
-
常见技术:
-
Adapter Layers:在 Transformer 的每一层插入小型网络模块,只训练这些模块。
-
LoRA(Low-Rank Adaptation) ⭐热门技术⭐:通过引入低秩矩阵对模型权重做小范围调整,大幅减少可训练参数。
-
Prefix Tuning、Prompt Tuning:不直接改模型参数,而是优化输入前缀或提示词嵌入。
-
-
优点:节省显存和训练成本,易于部署和迭代。
-
缺点:效果可能略逊于全量微调,但对大多数任务已经足够。
-
适用场景:资源有限、需要快速实验和部署的场景。
让你做微调,流程是怎样的?
-
明确目标与场景
-
确定微调用途:问答、摘要、对话、专业领域助手等。
-
-
准备数据
-
收集 / 构造高质量、任务相关的指令-响应数据。
-
数据清洗、去重、格式标准化。
-
-
选择预训练模型
-
根据需求选择合适的大模型,如:
-
开源中文模型:ChatGLM、Baichuan、Qwen、InternLM
-
国际模型:LLaMA、Mistral、Falcon(需配合相应许可证与工具链)
-
-
-
选择微调方法
-
常用:SFT(全量或 LoRA 微调)
-
如果资源有限,优先选 LoRA / QLoRA / Adapter
-
-
配置训练环境
-
工具:Hugging Face Transformers + PEFT(LoRA)+ Datasets + Accelerate
-
硬件:至少 1~2 张 A10/A100 显卡,视模型大小而定
-
框架支持:LoRA、QLoRA、8bit/4bit 量化可选
-
-
训练 / 微调
-
设置好超参数(学习率、batch size、epoch、optimizer 等)
-
监控 loss 曲线,防止过拟合
-
可使用验证集评估中间效果
-
-
评估与部署
-
评估指标:自动指标(BLEU、F1等) + 人工评估(流畅性、准确性、专业性)
-
部署:将微调后的模型导出,可用 FastAPI、vLLM、Text Generation Inference 等做推理服务
-
什么是LoRA?LoRA的原理是什么?它为什么能高效微调大模型?
-
LoRA(Low-Rank Adaptation) 是一种参数高效的微调方法。
-
核心思想:冻结原模型权重,引入两个低秩矩阵(A 和 B)来模拟权重变化,只训练这两个小矩阵。
-
优点:大幅减少可训练参数量,降低显存占用与训练成本,效果好。
-
公式简述:
W′ = W + BA(W是原权重,B和A是小矩阵)
适配器(Adapter)微调是什么?和LoRA有什么区别?
-
在 Transformer 每一层插入小型网络模块(Adapter),只训练这些模块,冻结主干。
-
LoRA 是对权重矩阵做低秩分解,Adapter 是插入新结构。
-
两者都属“参数高效微调”。
SFT(Supervised Fine-Tuning,监督微调)是什么?
✅ 定义:
-
SFT 是指使用人工标注的“输入-输出”配对数据(如指令-回答),对预训练大模型进行有监督式的微调。
-
是 最基础的微调方式,让模型学会按照“指令”生成“期望回答”。
✅ 特点:
-
数据格式:{instruction, input(可选), output}
-
目标:让模型学会在给定任务下输出更符合人类期望的内容
-
不涉及奖励模型或强化学习
✅ 应用场景:
-
通用任务适配(问答、摘要、翻译等)
-
垂直领域初步微调(如客服、法律、医疗等)
强化学习微调(RLHF)在什么情况用?它有哪些特点?
✅ 定义:
-
基于人类反馈的强化学习微调(RLHF, Reinforcement Learning from Human Feedback)
-
核心流程:
-
SFT:先做有监督微调,让模型初步学会生成答案;
-
奖励模型(RM):收集人类对多个回答的偏好排序,训练一个奖励模型打分;
-
强化学习(如 PPO):用奖励信号指导模型优化生成策略,使其输出更符合人类偏好。
-
✅ 适用场景:
-
需要模型输出更符合人类价值观、偏好、安全性、体验感时
-
比如:对话友好性、回答真实性、避免有害内容、风格调优
✅ 特点:
-
数据要求高:需要人工对多个回答做排序/评分
-
流程复杂:SFT → RM → PPO,多阶段训练
-
优势:输出更对齐人类意图,更安全、可控、拟人化
-
劣势:成本高、难度大、容易不稳定
微调LLM时,常用的训练目标(Loss)是什么?
-
通常是 语言建模损失(Cross-Entropy Loss),即让模型预测下一个 token。
-
对于指令微调,也可能是多任务 loss 组合。
微调时通常使用哪些数据?如何准备?
-
数据应与目标任务强相关,如:
-
问答数据(Q&A pairs)
-
对话数据(user-assistant pairs)
-
指令数据(instruction-following)
-
-
数据要清洗、格式统一,最好带标签或明确目标。
你的微调的数据是怎么来的?
-
公开数据集
-
适用于通用任务,如问答、摘要、翻译等。
-
例子:OpenAssistant、Alpaca、ShareGPT、UltraChat、FLAN、Supervised Fine-Tuning (SFT) 数据集等。
-
优点:获取方便,覆盖面广。
-
缺点:可能与你的具体业务场景不完全匹配。
-
-
自建 / 私有业务数据
-
来自公司内部文档、产品手册、客服对话、工单记录、FAQ、会议纪要等。
-
适用于垂直领域(如金融、医疗、法律、电商等)。
-
需要经过清洗、去敏、格式化、人工标注/校验。
-
例子:将用户与客服的问答对整理为
{input: 用户问题, output: 标准回答}格式。
-
-
人工构造 / 伪标签
-
如果真实数据不足,可以通过规则、模板、GPT 辅助生成。
-
比如:用 GPT 生成一些可能的用户 query 和对应的理想回答,再经人工筛选。
-
适用于冷启动或数据极度稀缺场景。
-
-
合成数据 + 真实数据混合
-
一部分来自真实业务,一部分用 GPT 辅助生成,混合训练以提升泛化性。
-
Lora中一些调优参数怎么弄?超参怎么调的?学习率是怎么调的?
| 参数 | 说明 | 推荐范围/方法 |
| r(rank) | LoRA 低秩矩阵的秩,控制参数高效适配的“宽度” | 常用:4、8、16;越大模型越强,但参数量和计算量也增加 |
| alpha | 控制 LoRA 权重的缩放因子,通常设为 alpha = 2 * r或 4 * r | 与 r 搭配使用,如 r=8, alpha=16 |
| dropout | LoRA 层的 dropout 比例,防止过拟合 | 常用 0.1 左右,数据少时可适当提高 |
| 学习率(lr) | LoRA 参数的学习率,通常比全参数微调低很多 | 推荐:1e-4 ~ 5e-4,视任务和数据量而定 |
| batch size | 每次训练样本数,受显存限制 | 常见:4、8、16、32;可配合梯度累积 |
| 训练步数(steps / epochs) | 迭代次数,不宜过多以防过拟合 | 通常几十到几百步即可,数据少时更要控制 |
| weight decay / optimizer | 优化器常用 AdamW,weight decay 可防止过拟合 | AdamW(learning_rate=xx, weight_decay=0.01) |
学习率怎么调?——调参策略
-
LoRA 的学习率通常比全量微调低一个数量级,因为只训练一小部分参数。
-
常用范围:1e-4 ~ 5e-4(比如 3e-4、1e-4、5e-5)
-
调参建议:
-
从小学习率开始(如 1e-5),逐步上调
-
观察 loss 下降情况与验证集效果
-
使用学习率 warmup(前几步从小学习率逐步增加到目标 lr)
-
配合验证集指标(如 BLEU、准确率、人工评估)判断最佳 lr
-
你知道哪些支持LLM微调的工具或框架?
-
Hugging Face Transformers + PEFT(Parameter-Efficient Fine-Tuning)
-
支持 LoRA、Adapter、Prompt Tuning 等
-
-
LLaMA Factory、FastChat、Axolotl、Firefly
-
DeepSpeed、FSDP、Megatron-LM(大规模分布式微调)
-
vLLM、Text Generation Inference(推理部署)
评估LoRA finetune的模型有哪些方式?
常用指标:
-
自动指标:BLEU、ROUGE、Exact Match(EM)、Bertsocre
-
人工评估:流畅度、相关性、准确性、安全性
-
任务指标:如问答准确率、代码通过率、用户满意度
24.6 部署
24.7.1 部署
如何API服务化部署模型?
-
FastAPI(推荐,高性能异步框架)
-
Flask(轻量,适合简单场景)
-
gRPC
如何容器化部署模型?
将模型代码、依赖环境、模型文件等打包到一个标准的容器镜像(如 Docker 镜像)中,实现环境隔离、快速部署、跨平台迁移。
容器化是现代 AI 工程化部署的标准实践,尤其适用于团队协作、云端部署、微服务架构。
大模型有哪些常见格式?
| PyTorch 原生格式(.bin / .safetensors / .pt) | Hugging Face Transformers 默认保存格式,如 pytorch_model.bin或 model.safetensors | 原生 PyTorch 格式,适合继续训练或微调,但推理性能未必最优 |
| TensorFlow SavedModel / .ckpt | TensorFlow 框架的模型保存格式 | 适用于 TensorFlow 生态,适合 TF 推理引擎 |
| ONNX(Open Neural Network Exchange) | 跨框架的模型交换格式,可将 PyTorch / TF 模型导出为 ONNX 格式 | 支持跨平台、跨框架部署,常配合 ONNX Runtime 推理引擎使用,适合优化与加速 |
| TorchScript | PyTorch 提供的中间表示(IR),用于模型序列化与优化 | 适合 PyTorch 模型的部署,支持 C++ 推理,但灵活性受限 |
| TensorRT Plan | NVIDIA TensorRT 推理引擎编译后的优化模型格式 | 高性能推理,支持 FP16/INT8,适用于 NVIDIA GPU |
| HuggingFace 模型目录(HF Format) | 包含 config.json、tokenizer.json、pytorch_model.bin等文件的整个模型目录 | 社区标准,便于模型共享与加载,如 from_pretrained() |
| vLLM 格式 / 自定义格式 | 一些推理引擎(如 vLLM)可能使用自己的缓存与加载格式,优化大模型推理流程 | 针对大模型(如 LLaMA、GPT)的高性能推理优化 |
24.7.2 推理
模型推理是什么?模型推理 vs 训练有什么不同?
模型推理是指:使用已经训练好的模型,对新的输入数据进行处理,输出预测结果(如文本、类别、概率等)的过程。
-
比如:输入一段 prompt,大语言模型生成一段回答。
-
推理是模型应用的最终阶段,面向用户或业务系统。
| 维度 | 训练(Training) | 推理(Inference) |
| 目的 | 通过数据学习模型参数(优化 loss) | 使用已有模型对新数据做预测 |
| 计算过程 | 前向传播 + 反向传播 + 参数更新 | 只有 前向传播 |
| 数据 | 大量标注/无标注数据(训练集) | 单条或批量新数据(实时请求) |
| 速度要求 | 可以较慢(几小时~几天) | 要求快速响应(低延迟)或高并发(高吞吐) |
| 硬件资源 | 通常需要多卡 GPU,大量显存 | 可部署在 GPU / CPU / 边缘设备,追求资源效率 |
| 优化目标 | 最小化损失函数,提高泛化能力 | 最小化延迟、最大化吞吐、节省资源 |
| 框架侧重 | PyTorch / TensorFlow(动态图/静态图) | ONNX / TensorRT / vLLM / FastAPI(服务化) |
静态推理 vs 动态推理有什么不同?
-
静态推理(Static Inference):
-
输入大小、形状、batch 数量固定
-
模型推理图(computational graph)在部署前已经确定,可以进行更多优化(如算子融合、内存布局优化)
-
适合对性能要求极高、输入固定的场景
-
缺点:不够灵活,无法处理变长输入等
-
-
动态推理(Dynamic Inference):
-
输入大小、batch 数、序列长度可以变化
-
更加灵活,适合实际业务中用户输入长度不定的情况(如 LLM 的 prompt 长度不一)
-
但优化难度更大,可能牺牲一些性能
-
大模型(如 LLM)通常采用动态推理,支持可变长度序列
-
大模型推理流程简述下?
-
输入准备(Preprocessing)
-
用户输入文本(如 prompt)
-
Tokenization:将文本转为 token ID
-
可能的 padding / 截断 / 拼接(如 batching 场景)
-
-
模型加载(Model Loading)
-
加载 tokenizer 和模型权重(如从 HuggingFace、本地、ONNX 等)
-
模型可能位于 CPU / GPU / 多卡环境
-
-
推理执行(Inference)
-
将 token 输入模型,执行 前向传播(Forward Pass)
-
对于生成类任务(如 GPT 类模型),还会涉及 自回归生成(Autoregressive Decoding)
-
逐 token 生成,每一步都依赖之前生成的 token(KV Cache 优化很重要)
-
-
-
后处理(Postprocessing)
-
将模型输出的 token IDs 转回可读文本
-
可能的过滤、截断、格式化等
-
-
返回结果
-
将生成的文本或结构化结果返回给用户 / 客户端
-
单次推理 vs 批量推理有什么不同?
| 维度 | 单次推理(Single Inference) | 批量推理(Batch Inference) |
| 定义 | 一次只处理一个输入样本 | 一次处理多个输入样本(batch) |
| 效率 | 延迟低(适合实时),但吞吐量小 | 吞吐量高,但单样本延迟可能略增 |
| 显存利用 | 显存占用较少 | 批量大时显存占用更高,但可并行计算 |
| 适用场景 | 实时交互(如 chatbot 回答一条消息) | 高并发、离线任务(如批量生成摘要) |
| 优化目标 | 低延迟 | 高吞吐 |
大模型推理有哪些重要指标?
-
延迟(Latency):从输入请求到返回结果的时间(如生成一个回复的耗时)
-
吞吐量(Throughput):单位时间内能处理的请求数(QPS / RPS)
-
显存占用(GPU Memory Usage):模型加载与推理时占用的显存大小
-
首 Token 延迟(Time To First Token, TTFT):用户输入后,生成第一个 token 的时间
-
每 Token 延迟(Time Per Output Token, TPO):生成每个新 token 的平均时间
-
并发能力(Concurrency):系统同时处理的请求数量
大模型推理引擎你用过哪些?TensorRT、Triton、ONNX、vLLM分别是什么?
这些是当前主流的推理加速引擎、推理框架、模型格式和部署工具,常用于大模型的高性能推理部署。
| 工具/框架 | 是什么? | 主要用途 / 特点 |
| TensorRT | NVIDIA 推出的高性能推理引擎,用于深度学习模型在 NVIDIA GPU 上的推理加速 | 支持 FP16 / INT8 量化、层融合、内核优化,适合生产环境中的低延迟、高吞吐推理,常用于 CV/NLP 模型 |
| Triton Inference Server | NVIDIA 提供的通用模型推理服务框架,支持多种框架(TensorFlow / PyTorch / ONNX / TensorRT) | 提供多模型管理、动态批处理、并发推理、支持 GPU/CPU,适合大规模、多模型部署场景 |
| ONNX (Open Neural Network Exchange) | 开放的模型交换格式,可将不同框架(如 PyTorch / TensorFlow)的模型导出为统一格式 | 用于跨平台、跨框架部署,配合 ONNX Runtime 推理引擎可在 CPU / GPU 上高效执行 |
| vLLM | 专为大型语言模型(如 LLaMA、GPT)设计的高性能推理引擎,由 UC Berkeley 等推出 | 支持 连续批处理(Continuous Batching)、PagedAttention、高效 KV Cache 管理,显著提升 LLM 推理吞吐与速度,对大模型部署非常友好 |
大模型推理采样结果不一致的原因是什么(即使temp=0)?
-
Top-k / Top-p (Nucleus) 采样仍然在起作用:即使你把 temperature 设为 0,如果你还开启了 Top-k 或 Top-p(Nucleus)采样策略,那么模型就不是单纯选最高分的 token。
-
随机种子(Random Seed)未固定
-
模型推理中如果使用了任何随机操作(如 dropout【推理时一般关闭】、随机采样等),并且 没有设置固定的随机种子(random seed),那么结果可能因运行环境不同而不同。
-
特别是在 GPU 上,某些操作(如 cuDNN 卷积)可能有非确定性实现,导致浮点计算微小差异 → 影响 logits → 影响最终 token。
-
-
浮点计算的非确定性(Non-determinism)
-
特别是在 GPU 上,某些算子(如矩阵乘法、卷积)为了性能优化,可能使用 非确定性算法
-
导致同样的输入,两次前向计算的 logits 有微小差异 → softmax 后的分布略有不同 → 最终 token 可能不同
-
24.7.3 模型加速方法
模型剪枝(Pruning)是什么?
模型剪枝是一种通过移除神经网络中“不重要”的权重或神经元,来减小模型大小和计算量的技术。
-
“不重要”通常是指那些对最终输出贡献较小(如接近零)的参数。
-
剪枝后,模型结构变得更稀疏(Sparse),参数更少,计算更高效。
-
权重剪枝(Weight Pruning):剪掉模型中绝对值较小或重要性低的权重,使矩阵变稀疏
-
神经元剪枝(Neuron Pruning):剪掉整个神经元(即该神经元对应的所有输入/输出连接)
-
结构化剪枝(Structured Pruning):剪掉整个通道(Channel)、卷积核(Kernel)或层,更容易硬件加速
-
非结构化剪枝(Unstructured Pruning):剪掉单个权重,可能导致稀疏矩阵,需稀疏计算支持
模型量化(Quantization)是什么?
模型量化是指将模型中浮点数权重和激活值从高精度(如 FP32)转换为低精度(如 INT8 / FP16 / BF16)表示,从而减少模型存储、加快计算速度、降低内存与计算开销。
-
静态量化(Static Quantization):训练后对模型进行校准,确定激活值的量化参数,适合推理阶段
-
动态量化(Dynamic Quantization):在推理时动态计算激活值的量化参数,适合 RNN / Transformer 类模型
-
量化感知训练(QAT, Quantization-Aware Training):在训练过程中模拟量化效果,让模型“学会”在低精度下工作,精度更高
-
FP16 / BF16:使用半精度浮点数,无需转换整数,硬件支持良好(如 NVIDIA GPU)
模型蒸馏(Knowledge Distillation)是什么?
模型蒸馏是一种使用一个大的、复杂的教师模型(Teacher Model)来指导一个小的学生模型(Student Model)学习,从而在保持较高精度的同时大幅减小模型规模的技术。
-
不是直接让学生模型模仿真实数据标签,而是让它学习教师模型的输出(如 Soft Target / Attention Map / 中间特征)
-
常用损失函数包括:
-
KL 散度(软标签 vs 学生预测)
-
交叉熵(真实标签)
-
组合损失:真实目标 + 教师模型的软目标
-
-
Response-based(输出层蒸馏):学生学 teacher 的最终输出(最常见)
-
Feature-based(特征层蒸馏):学生学 teacher 的中间层特征表示
-
Relation-based(关系蒸馏):学习样本之间的关系信息
混合精度训练/推理(Mixed Precision)是什么?
-
FP32(单精度浮点):标准精度,精度最高,但计算慢、占用显存大
-
FP16(半精度浮点):速度快、显存省,但数值范围小,可能溢出/精度损失
-
BF16(Brain Float 16):类似 FP16,但数值范围更接近 FP32,适合训练,NVIDIA Ampere 后支持良好
-
INT8:用于推理量化,不在混合精度训练中常见
算子融合(Operator Fusion)是什么?
算子融合是指将多个连续的、简单的计算操作(如矩阵乘 + 激活函数 + Bias 加法)合并为一个复合的、整体的计算操作,以减少内存访问、提升计算效率、降低延迟。
常见融合组合:
-
Conv + BN + ReLU
-
Linear + Bias + Activation
-
MatMul + Add + Softmax
-
Attention 中的 QKV 计算与 Softmax 融合
谁来做算子融合?
-
推理引擎(如 TensorRT、ONNX Runtime、TVM、vLLM) 在模型部署优化阶段自动进行
-
也可以手动优化(如在自定义算子或 CUDA 层中融合)
LLM应用开发面试核心题解析
1836

被折叠的 条评论
为什么被折叠?



