24 LLM AI应用后端开发-面试题

LLM应用开发面试核心题解析

24.1 LLM基础

24.1.1 数据处理

你在构造数据集的时候,需要注意什么?

  1. 数据质量问题

  2. 数据格式

  3. 数据安全性

  4. 数据去噪与清洗

你在构造数据集的时候,数据集的采集一般怎么做的?

  1. 公开数据集

    1. 使用已有的高质量开源数据集,如:

      • The Pile

      • Common Crawl

      • OpenWebText

      • Wikipedia

      • BookCorpus

      • C4 (Colossal Clean Crawled Corpus)

      • 领域特定数据集:如医学(PubMed)、法律(CaseLaw)、代码(GitHub)、多语言(OPUS)等

  2. 网络爬虫 / 网页抓取

    1. 通过编写爬虫程序从互联网抓取相关网页内容,如新闻、博客、论坛、问答网站(如知乎、Stack Overflow)等

    2. 可使用工具:Scrapy、BeautifulSoup、Selenium 等

  3. 人工生成 / 众包平台

    1. 通过人工撰写、标注或审核来构造高质量数据,如:

      • 使用 Amazon Mechanical Turk、Appen、Label Studio 等众包平台

      • 内部团队或专家编写(适用于专业领域,如医疗、法律、金融)

  4. 合成数据(Synthetic Data)

    1. 利用已有模型(如 GPT、Hunyuan等)生成模拟数据,如对话、问答对、代码示例等

    2. 常用于冷启动、数据增强、特定场景构造

你在构造数据集的时候,数据集的采集如何保证质量?

  • 明确采集目标:采集前明确用途:是用于预训练、SFT(监督微调)、RLHF,还是特定任务(如问答、摘要、翻译)。不同任务对数据类型要求不同。

  • 选择可信来源:优先选择权威、高质量的公开数据源,如 Wikipedia、新闻站点、官方文档、开源代码库等。

  • 制定采集策略:包括主题分布、语言种类、领域覆盖、时间范围等,避免数据过于集中或缺失重要维度。

  • 初步筛选与过滤:在采集阶段就进行初步过滤,比如只抓取特定域名、文件类型、内容长度等,减少明显低质或无关内容。

你在构造数据集的时候,数据集的格式需要注意什么?

关键设计原则:

  • 结构清晰:每个字段含义明确,如 instruction(指令)、input(输入)、output(输出)、source(来源)等。

  • 字段一致:同一数据集内,所有样本应尽量保持相同字段结构。

  • 支持多任务:比如同时支持问答、摘要、翻译,可通过字段区分任务类型。

  • 可扩展性:可添加额外字段,如 iddomaindifficultylanguage等,便于后续筛选和分析。

你在构造数据集的时候,数据集的去噪和清洗需要注意什么?

常见的噪声与问题:

类型说明示例
​格式噪声​HTML标签、特殊符号、乱码、BOM头等<p>你好</p>、\xa0、
​内容噪声​广告、导航栏、版权声明、用户信息、脚本等“欢迎访问XXX网站”、“本站版权所有”
​低质内容​语句不通、语义模糊、拼写错误、语法错误“我明天去哪不知道去哪好”
​重复数据​完全重复或高度相似的样本抓取多次的同一篇文章
​有害/违规内容​暴力、色情、政治敏感、歧视性言论等不适宜公开传播的内容
​隐私信息​姓名、电话、地址、身份证、银行卡等“我的电话是138xxxx1234”

去噪与清洗的关键步骤:

  1. 初步过滤

    1. 按来源、文件类型、文本长度、语言等做初步筛选

    2. 去除明显非目标内容(如导航、广告、版权页)

  2. 格式清洗

    1. 去除 HTML/XML 标签、特殊字符、多余空格、BOM 头等

    2. 统一编码(如 UTF-8)、规范化文本(如全角/半角、大小写)

  3. 内容筛选

    1. 去除无意义、不通顺、语法错误严重的句子/段落

    2. 可使用语言模型、规则或分类器辅助判断内容质量

  4. 去重

    1. 基于文本相似度(如 TF-IDF、MinHash、SimHash、BERT Embedding + 余弦相似度)去除重复或高度相似样本

    2. 可设定阈值,如相似度 > 0.9 则认为是重复

  5. 有害/敏感内容过滤

    1. 使用关键词黑名单、分类模型、敏感内容检测 API 过滤不当内容

    2. 检查并去除隐私信息(可用脱敏工具或正则匹配)

  6. 语言/领域过滤

    1. 保留在目标语言(如中文、英文)范围内的数据

    2. 按领域关键词筛选,确保与任务相关

你做数据增强怎么做?

数据增强 是指在不改变数据语义或任务目标的前提下,通过一定方法生成新的、多样的、有效的训练样本,从而提升模型的学习能力与泛化性能。

在自然语言处理(NLP)和 LLM 场景中,数据增强主要针对 文本数据,目的是生成“看起来不一样,但语义或意图一致”的新样本。

下面按技术难度、可控性、适用任务等维度,介绍常用的数据增强方法:

  1. 基于文本变换的增强(Rule-based / Simple NLP)

      适用于大多数 NLP 任务,操作简单、可控性强。

    1. 同义替换(Synonym Replacement)

      1. 使用同义词库(如中文同义词词林、哈工大同义词词表、WordNet、中文近义词工具)将句子中的某些词语替换为其同义词。

      2. 例:

      3. 原句:这个产品质量很好 → 增强:这个商品品质不错

    2. 随机插入 / 删除 / 交换(EDA: Easy Data Augmentation)

      1. EDA 提出四种简单操作,适用于文本分类等任务:

        • 随机插入一个词的同义词

        • 随机删除一个非关键单词

        • 随机交换两个相邻词的位置

        • 随机替换一个词为其同义词

    3. 回译(Back Translation)

      1. 将原始文本翻译成另一种语言(如英文),再翻译回原语言,得到语义相近但表达不同的句子。

      2. 例:中文 → 英文 → 中文,常用于分类、生成类任务的增强。

      3. 工具:Google Translate API、百度翻译、DeepL、Hunyuan翻译等

  2. 基于模板 / 指令改写的增强(Instruction-based / Prompt-based)

适用于对话、问答、指令跟随类任务(如 InstructGPT、ChatGLM 的微调任务)。

  1. 指令改写(Instruction Paraphrasing)

    1. 对同一个任务目标,使用不同的语言表达方式重写 prompt / instruction。

    2. 例:

    3. 原始指令:总结这段文字 → 增强指令:请用一句话概括以下内容 / 这段话的核心意思是什么?

  2. 输入改写(Input Rephrasing)

    1. 对输入内容(如问题、描述)进行同义改写、句式变换,但保持原意。

    2. 例:

    3. 原问题:北京故宫什么时候建成的?→ 增强:故宫始建于哪一年?/ 明朝紫禁城建于何时?

  1. 基于生成模型的增强(LLM / Generator-based)

利用语言模型(如 GPT、Hunyuan、T5、BART)生成新的样本,适合数据稀缺或需要高质量多样化数据的场景。

  1. 生成式扩增(Generative Augmentation)

    1. 使用 LLM 生成:

      • 同任务的不同问法(如问答对的多种问法)

      • 同一语义的多种表达(如摘要的多种写法)

      • 对话中的不同用户 / 助手发言

      • 不同风格的文本(正式、口语、幽默等)

  1. 基于混合法 / 对抗增强的方法(Advanced)

    1. Mixup(较少用于文本,更多用于 CV,但有文本变种)

      1. 混合两个样本的部分信息生成新样本(如混合两段文本的摘要目标)

    2. 对抗样本增强(Adversarial Augmentation)

      1. 通过添加扰动(如同义词替换、字符级扰动)生成让模型容易出错的样本,再用于强化训练,提高鲁棒性

数据集一般怎么划分?训练集、验证集、测试集的比例是多少?

  • 经典 ML 场景(数据量适中): 70% 训练 / 15% 验证 / 15% 测试

  • 深度学习 / 大模型场景(数据量大): 90% 训练 / 5% 验证 / 5% 测试

  • 超大数据场景(如百亿 token 预训练): 几乎全部用于训练,验证/测试只占极小比例(如 0.1% ~ 1%)

划分原则:

  • 独立同分布(i.i.d.)假设: 训练/验证/测试集应来自同一分布,确保评估有效。

  • 测试集必须“不可见”: 只用于最终评估,不能参与任何调参或模型选择。

  • 验证集用于调优: 比如选择模型超参数、决定是否早停、模型 checkpoint 选择等。

  • 可复现性与随机性控制: 划分时使用固定随机种子(random seed),确保结果可复现。

如何保证划分后的数据分布一致(如领域、难度、语言)?

解决方法:分层采样 / 分布感知的划分(Stratified Sampling)

  1. 什么是分层采样?

  • 不是简单随机划分,而是按照某些关键属性(如类别、领域、语言等)先分组,然后在每个组内按比例划分,确保每个子集(训练/验证/测试)都包含相似的分布。

  1. 按什么维度做分层?

维度说明适用任务/场景
​类别(Class)​​每个类别的样本按比例划分,防止某些类只在训练或测试集中出现文本分类、情感分析、多标签任务
​领域(Domain)​​比如医疗、法律、新闻等,确保每个领域的数据都出现在各个集合中多领域对话、多文档摘要
​语言(Language)​​比如中、英、日等,确保每种语言都均匀分布多语言模型、翻译、跨语言检索
​难度 / 长度 / 来源​比如问题难度、文本长度区间、数据来源站点问答、推理、教育类任务
​用户 / 会话 ID​比如用户行为数据,同一用户的数据不要同时出现在训练和测试中推荐系统、搜索、个性化任务

实际操作方法:

  • 工具支持:

    • Python 中可使用 sklearn.model_selection.StratifiedShuffleSplit(适用于类别分布)

    • 自定义分层:按领域/语言等分组后,对各组分别做随机划分

    • 多维度分层:可做多级分组(如先按领域,再按类别)

  • 流程举例:

  • 假设你有一个多领域分类数据集,包括“医疗、法律、金融”三个领域,每个领域样本数不均。你可以:

    • 先按领域分组

    • 在每个领域内部,按比例(如 8:1:1)划分训练/验证/测试

    • 最后合并各领域的划分结果,形成整体数据集

  • 这样可以保证每个领域都在训练/验证/测试集中有代表,避免评估时出现“某个领域从未见过”的情况。

如果数据有类别不平衡问题,怎么处理?

  1. 重采样(Resampling)

    1. 过采样(Oversampling):增加少数类样本

      • 方法:随机复制、SMOTE(合成少数类样本,适用于数值型,文本类较少用)、数据增强(如改写少数类样本)

      • 适用:小样本类别,但要小心过拟合

    2. 欠采样(Undersampling):减少多数类样本

      • 方法:随机删除部分多数类样本

      • 适用:数据量很大时,但可能丢失重要信息

  2. 类别加权(Class Weighting)

    1. 在损失函数中为不同类别设置不同的权重,让模型更关注少数类

    2. 例如:loss = cross_entropy(..., weight=[w1, w2, ...])

    3. 适用于神经网络、分类模型(如 BERT、LLM 微调)

  3. 评估指标优化

    1. 不使用准确率(Accuracy),而是采用更合理的指标:

      • F1-score(尤其是宏平均 F1)

      • 精确率 / 召回率(Precision / Recall)

      • AUC / ROC(适用于二分类)

      • 混淆矩阵分析

  4. 分层评估(Stratified Evaluation)

    1. 在测试集划分时也按类别分层,确保每个类别都有样本参与评估,避免某些类“被忽略”

24.1.2 提示词工程

一个好的提示(Prompt)应该具备哪些特点?

  • 清晰明确:任务目标、输入输出要求清晰,不含糊。

  • 结构良好:比如使用指令(Instruction)、输入(Input)、输出格式(Output Format)等结构化元素。

  • 有上下文:必要时提供背景信息、示例或上下文,帮助模型更好理解。

  • 具有引导性:通过措辞引导模型生成你想要的风格、格式或内容。

  • 简洁有效:避免冗长、复杂的表述,防止模型抓不住重点。

提示词工程 vs 微调(Fine-tuning)有什么区别?

  • 提示词工程是通过优化输入提示来引导模型行为,无需修改模型参数,适用于快速迭代、灵活调整、多任务切换。

  • 微调(Fine-tuning)是通过用特定任务的数据训练模型,调整模型参数使其更适合某一任务,适合任务非常固定、数据量较大的情况。

  • 提示词工程更灵活、轻量,微调更定制化、成本更高。

常见的提示结构有哪些?

  1. 零样本提示(Zero-shot Prompt):直接提问或下达指令,不给示例。

    1. 例: “什么是机器学习?”

  2. 少样本提示(Few-shot Prompt):给出几个输入-输出示例,让模型模仿。

  3. 指令式提示(Instruction Prompt):明确告诉模型要做什么。

    1. 例: “请将以下句子翻译成英文:今天天气很好。”

  4. 角色扮演提示(Role-playing Prompt):让模型扮演某个角色,如医生、律师、客服。

    1. 例: “假设你是一名资深医生,请向患者解释高血压的危害。”

  5. 链式提示 / 思维链(Chain-of-Thought / CoT Prompt):引导模型逐步推理。

    1. 例: “让我们一步步思考:如果一个班级有 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怎么避免幻觉问题?

  1. 使用检索增强生成(RAG, Retrieval-Augmented Generation)

  • 原理: 先通过检索系统(如向量数据库 + embedding 模型)从可靠的知识库中检索相关信息,再将这些信息作为上下文输入给 LLM,让它基于真实内容作答,而非“编造”。

  • 优点: 显著提升回答的准确性和可追溯性,尤其适用于知识问答、文档助手、企业知识库等场景。

  1. 通过提示词工程约束模型

  • 在提示中明确要求模型“基于事实回答”、“不要编造信息”、“若不确定请说明”等。

  • 提供参考文档、上下文、来源信息,引导模型基于已知内容生成。

  1. 使用可信数据源进行微调或 SFT

  • 通过监督微调(SFT)让模型在高质量、可靠的数据上进行学习,减少“胡说”的倾向。

  • 适用于专业领域(如医疗、法律),用领域知识训练模型更“靠谱”。

你的产品的效率调优这块你们是怎么做的?

  1. 模型层面优化

    1. 选用合适的模型尺寸:比如用 7B、13B 参数模型 而非更大的 65B 或 175B,根据任务需求权衡效果与速度。

    2. 使用蒸馏模型(Distil-LLM)、量化模型(如 INT8 / GGUF / AWQ),减小模型体积,提升推理速度,适合部署在边缘设备或对延迟敏感的场景。

    3. 使用优化推理框架:如 vLLM、TensorRT-LLM、LLama.cpp、Text Generation Inference (TGI)、FastChat 等,支持高效批处理、KV Cache 优化、连续批处理等。

  2. 推理与部署优化

    1. 批处理(Batching):将多个请求合并为一个 batch 推理,提高 GPU 利用率和吞吐量。

    2. 流式输出(Streaming):支持逐字或逐句返回,提升用户交互体验,降低等待感。

    3. 缓存机制:对常见 Query 的结果或中间 Embedding 进行缓存,避免重复计算。

    4. 异步处理 & 队列系统:高并发场景下使用消息队列(如 Kafka、RabbitMQ)做请求调度,避免模型过载。

  3. 检索增强类任务优化(如 RAG)

    1. 优化向量检索速度:使用高效的 ANN 算法(如 HNSW、IVF),优化 embedding 模型(如 BGE-small、text2vec)。

    2. 限制检索返回的文档数量,只取 Top-k 最相关内容,减少输入 Token 数,加快生成速度。

    3. 对检索 + 生成 pipeline 做整体延迟优化,比如并行检索与模型预热。

  4. 成本控制

    1. 优先使用性价比高的模型(如开源模型本地部署 vs API 调用)。

    2. 对低价值或低频请求做降级处理,比如用规则引擎代替模型推理。

    3. 监控 GPU / TPU 使用率,动态扩缩容,避免资源浪费。

24.2 流程化

24.2.1 RAG

RAG是什么?

RAG 是 Retrieval-Augmented Generation 的缩写,中文通常翻译为 检索增强生成。它是近年来大语言模型(LLM, Large Language Model)应用中的一种重要技术架构,用于提升大模型在知识问答、信息检索等任务中的准确性和时效性。

大语言模型虽然具备强大的语言理解和生成能力,但其知识范围受限于训练数据的截止时间(例如,某个模型可能只训练到 2023 年底),并且它无法动态获取最新信息或访问特定领域的私有知识库。

RAG 的解决思路是:

不让大模型“凭空想象”答案,而是先从外部知识库中 检索出相关的文档或信息片段,再把这些信息作为上下文,提供给大模型,辅助它生成更准确、更有依据的回答。

简单来说就是:

  • 检索(Retrieval):从知识库中找出与用户问题最相关的资料。

  • 生成(Generation):将检索到的资料和用户问题一起输入大模型,让它基于这些信息生成回答。

【必问】说一下RAG的流程?

  1. 用户提问(User Query)

    1. 用户向系统提出一个问题,比如:“光合作用的具体过程是什么?”

  2. 检索模块(Retriever)

    1. 利用向量检索(如 Dense Retrieval)、关键词检索或混合检索方法,从知识库(通常是文档库、FAQ库、网页库等)中找出与用户问题最相关的几篇文档或文本片段。

    2. 常用的检索模型有:BM25(传统关键词匹配)、DPR(Dense Passage Retrieval,基于稠密向量)、FAISS、Milvus 等。

  3. 文档/片段准备

    1. 将检索到的相关文档进行整理,可能包括截断、拼接、格式化等处理,以便输入到 LLM 中。

  4. 生成模块(Generator,通常是大语言模型)

    1. 将 用户原始问题 + 检索到的相关文档内容 一同输入大语言模型(如 GPT、Hunyuan、LLaMA 等)。

    2. 大模型结合这些上下文信息,生成更加准确、有依据的回答。

MB25关键字检索的原理是什么?

BM25 是一种基于词频和逆文档频率的经典关键字检索算法,用于衡量一个文档与查询(Query)之间的相关性,它的核心思想是: 对查询中的每个关键词,计算其在当前文档中的重要性得分,然后将所有关键词的得分综合起来,得到文档与查询的整体相关性得分。

  1. 词频(TF, Term Frequency)部分:一个词在文档中出现的次数越多,通常说明它越相关 —— 但不是线性增长,而是有饱和效应。

  2. 逆文档频率(IDF, Inverse Document Frequency)部分:一个词如果在整个语料库中很少出现(比如专业词、关键词),那它对区分文档的相关性就更有价值。

你们用的是什么向量数据库?

在我们项目中,我们使用的是 Milvus 作为向量数据库,主要用于存储和高效检索高维向量数据,比如文本的嵌入向量。

  1. 高性能与高扩展性

  2. 支持多种索引类型,检索效率高

  3. 丰富的向量操作与灵活的元数据过滤

  4. 良好的生态与社区支持

  5. 生产就绪,支持云原生部署

【必问】RAG中retrieval你们是怎么实现的?你们在RAG中是怎么用Milvus的?

  1. 知识库预处理 & 文本切块(Chunking)

    1. 首先,我们将原始知识库(如文档、PDF、网页、FAQ、内部资料等)进行文本清洗、分段、切块,得到一系列较短的文本单元(通常 200~800 字符,视模型输入窗口而定)。

    2. 每个文本块会作为一个可检索的单元,后续会为它们生成 Embedding 向量并存储到向量数据库中。

  2. 文本向量化(Embedding)

    ✅ Embedding 模型是检索的基础,它决定了“语义相似度”的计算质量。

    1. 使用 Embedding 模型(我们用的是 BGE 系列模型,比如 BGE-base-zh),将每个文本块转化为高维向量(如 1024 维),用于后续的语义相似度计算。

    2. 同时,用户的问题(query)也会通过同一个 Embedding 模型转换成向量,确保与文档向量处于同一语义空间。

  3. 向量存储(Vector Storage)

    1. 将每个文本块的向量 + 元数据(如文档ID、标题、时间、来源等)存储进向量数据库(我们用的是 Milvus)。

    2. Milvus 支持高效的向量存储与检索,并能基于向量相似度快速召回最相关的文档。

  4. 向量检索(Dense Retrieval)

      🔍 这里我们用的索引通常是 HNSW 或 IVF 系列索引,以实现高效、快速的相似向量搜索。

    ✅ 这一步是典型的 Dense Retrieval(稠密检索 / 语义检索),它不依赖关键词,而是基于语义匹配,对表述多样、同义改写等情况更鲁棒。

    1. 当用户输入问题时,我们:

      • 先用 BGE 模型将用户 query 转为向量;

      • 然后通过 Milvus 向量数据库,基于向量相似度(如余弦相似度)检索出与 query 向量最相似的 Top-K 个文档片段(比如 Top 3~10)。

  5. 混合检索 / 关键词召回(增强召回)

    1. 除了向量检索,我们还可能结合 BM25 等关键词检索方法,召回一批基于关键词匹配的文档,再与向量检索结果做融合(如并集、加权排序),从而提高召回的全面性,避免漏召。

    2. 这属于 混合检索策略,我们根据实际效果选择是否启用。

  6. 检索结果返回

      这些文档会被输入到 生成模块(大语言模型),与大模型一起生成最终回答。

    1. 最终检索模块会返回:

      • Top-K 个最相关的文档片段

      • 通常还会附带一些元数据信息(如来源、时间等),用于后续展示或进一步过滤。

Milvus的原理你知道吗?

Milvus 采用分层架构设计,主要分为以下几个核心组件:

  1. Client(客户端)

  • 用户通过 SDK(如 Python、Java、Go 等)或 RESTful API 与 Milvus 交互,提交向量数据、创建索引、执行检索等操作。

  1. Query Node(查询节点)

  • 负责处理用户的向量相似性搜索请求,比如查找与某个 Query Vector 最相似的 Top-K 向量。

  • 它会基于索引结构快速筛选候选向量,并计算相似度(如欧氏距离、内积、余弦相似度)进行排序,返回最相关的结果。

  1. Data Node(数据节点)

  • 负责向量数据与元数据的存储与管理,包括原始向量、标量字段(如文档 ID、时间戳等)的写入、读取与持久化。

  1. Index Node(索引节点,部分版本中)

  • 负责构建向量索引,比如 HNSW、IVF 等。它会从 Data Node 获取原始向量数据,构建索引后供 Query Node 高效检索使用。

Milvus 的核心原理,可以拆解为以下几个关键技术点:

  1. 向量数据的存储

  • Milvus 存储的是高维向量(通常是 768 维、1024 维等 Embedding 向量),这些向量一般是由文本、图片、音频等数据通过 Embedding 模型(如 BERT、Hunyuan Embedding、SBERT 等)转化而来。

  • 每个向量通常还会附带一些标量字段(metadata),比如文档 ID、文本标题、时间等,用于辅助过滤和业务逻辑。

  1. 向量索引(Indexing)—— 核心原理之一

为了能在海量向量中快速找到与查询向量最相似的 Top-K 向量,Milvus 不为原始向量做线性扫描(那会非常慢),而是先为向量构建索引结构。

我们项目中通常使用的是 HNSW 或 IVF 系列索引,根据数据规模和查询延迟要求做选择。

  1. 相似性度量(Similarity Metric)

  • Milvus 支持多种向量相似度的计算方式,常见的有:

    • 欧氏距离(L2)

    • 内积(IP, Inner Product)

    • 余弦相似度(Cosine)

  • 在检索时,Milvus 会根据你选择的度量方式,对向量进行排序,返回最相似的 Top-K 条记录。

  1. 元数据过滤(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)最相关文档。

  1. 召回阶段(第一阶段检索)

    1. 使用 快速检索方法(如 BM25、Dense Retrieval)召回一批可能相关的文档,比如 Top 50~100 个候选。

    2. 这一步追求的是“召回尽可能多的潜在相关文档”,速度快但可能不够精准。

  2. 重排阶段(第二阶段精排)

    1. 将用户 Query 与每一个召回的 Document 配对,输入到 Cross-Encoder 模型中,计算它们之间的相关性得分。

    2. 根据得分对所有候选文档重新排序(Re-Rank),选出 Top-K 最相关的文档(如 Top 3~5)。

  3. 生成阶段

    1. 将用户 Query + 精排后的高质量文档,输入大语言模型(如 Hunyuan、GPT),生成最终回答。

为什么用Cross-Encoder重排?

  1. 语义理解能力强

    1. Cross-Encoder 能够理解 Query 和 Document 之间的复杂语义关系、上下文依赖、同义表达、逻辑关联,比单纯的向量相似度或关键词匹配更精准。

    2. 它考虑的是两者联合作用下的匹配信号,而不是独立的向量表示。

  2. 排序精度高

    1. 在召回后的小范围候选集上使用 Cross-Encoder 精排,可以大幅提升最终返回文档的相关性,从而提高 RAG 系统回答的准确性和可靠性。

    2. 实验证明,在很多检索评测任务中(如 MS MARCO、TREC),Cross-Encoder 重排能显著提高 NDCG@K、MAP、Recall@K 等指标。

  3. 灵活适配不同任务

    1. 可用于文档检索、问答匹配、语义相似度判断、多轮对话上下文选择等多种任务。

你做RAG的关键字检索和向量检索的比重是怎么调的?

在我们 RAG 系统中,关键字检索(如 BM25)和向量检索(如 Dense Retrieval)的比重调整,本质上是在 召回阶段如何平衡‘字面匹配’与‘语义匹配’,最终目标是召回既精准又全面的相关文档。 我们通常不会简单设定一个固定比例,而是通过实验、召回效果评估、线上 AB 测试等方式,动态调整两者的权重或组合策略。

方法 1:结果融合(Post-Merging)—— 最常用工程实践

🔹 不直接设定“比例”,而是:

  • 分别用 BM25(关键字) 和 Dense(向量,如 BGE + Milvus) 召回 Top-K 候选文档(比如各召回 Top 30~50),

  • 然后对两组结果进行 去重、合并、综合排序,最终选出 Top-N(如 Top 5~10)送入生成模块。

🔧 常见融合策略包括:

  1. 并集合并(Union Merge):简单合并两路召回结果,去重后统一排序(比如按时间、来源、或简单规则)。

  2. 加权打分(Score Fusion):为每路召回结果设定一个权重,比如:

    1. BM25 得分 × α

    2. 向量相似度得分 × β

    3. 然后计算综合得分:Score = α × BM25 + β × DenseScore,按总分排序

    4. 我们通过实验调整 α 和 β 的值(比如 α=0.4,β=0.6 或反之),找到最优组合

  3. 重排序(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 = 多模态知识理解 + 多模态信息检索 + 多模态内容生成。

  1. 多模态信息的输入与预处理

  • 用户可能输入:

    • 纯文本问题

    • 图片(如 JPG、PNG,含文字/图表)

    • PDF / 扫描件(含文字和布局)

    • PPT / Word / 截图等

🔹 预处理包括:

  • OCR(光学字符识别):提取图片、PDF、扫描件中的文字内容(常用模型如 PaddleOCR、Tesseract、TrOCR、Donut 等)

  • Layout Analysis(版面分析):识别文档中的文字区域、表格、标题、图表位置等(用于结构化信息提取)

  • 多模态文档解析:将 PDF、PPT、图片等转换为文本 + 结构化信息,甚至保留图文对应关系

✅ 目标:把多模态内容转化为可检索、可理解、可嵌入的文本或结构化信息。

  1. 多模态 Embedding(嵌入)与向量化

  • 为了让多模态内容(如图文混合、图表+说明文字)能被检索,我们需要将其转化为向量表示(Embedding),和传统文本一样存入向量数据库。

🔹 关键技术:

  • 对于 纯文本部分,仍然使用文本 Embedding 模型(如 BGE、SBERT)

  • 对于 图像/图表/多模态内容,使用 多模态 Embedding 模型,比如:

    • BLIP-2、BLIP、Flamingo、LLaVA、Otter、ImageBind、Multimodal-BERT

    • CLIP(用于图像+文本联合嵌入)

    • 多模态文档模型(如 Donut、UniDoc、mPLUG-DocOwl、Minigpt4、Qwen-VL 等)

👉 这些模型能将 图像+文本、图文混排内容 映射到一个统一的 Embedding 空间,从而支持多模态语义检索。

  1. 多模态检索(Multimodal Retrieval)

  • 用户的问题可能是纯文本(如“这个图里的趋势是什么?”),也可能是图文混合。

  • 我们需要从多模态知识库中,检索出与该问题最相关的多模态内容(如图表页、图片、PDF 页面等)。

🔹 检索方式包括:

  • 图文联合检索:将用户问题 + 图像内容同时 Embedding,进行相似度匹配

  • 文本描述检索:如果多模态内容已被 OCR 或解析为文本,可走传统文本检索(Dense / BM25)

  • 多模态向量数据库:使用支持多模态向量的数据库(如 Milvus、Weaviate、Pinecone、Qdrant(逐步支持)),存储多模态 Embedding,实现高效检索

✅ 核心:把多模态内容向量化后,通过相似度检索召回最相关的那部分信息,用于后续生成。

  1. 多模态生成(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 等)按照一定顺序组织与协调,所形成的处理流程。

一个典型的大模型工作流可能包括如下环节:

  1. 任务理解与输入处理

    1. 用户输入解析、意图识别、参数提取等。

  2. 上下文管理(Memory)

    1. 对于多轮对话或任务,需要维护上下文,比如对话历史、用户偏好等。

  3. 知识检索(可选,如 RAG 场景)

    1. 从向量数据库或文档中检索相关信息,与用户问题组合输入给 LLM。

  4. Prompt 构造

    1. 动态或静态地构造输入给大模型的提示词,可能包括指令、上下文、示例等。

  5. 模型调用(LLM Inference)

    1. 将构造好的 Prompt 发送给大语言模型,获取生成结果。

  6. 后处理

    1. 对模型输出进行格式化、提取结构化信息、过滤噪音等。

  7. 工具/动作执行(可选,如 Agent 场景)

    1. 如果涉及到工具调用(如搜索、计算、API),则执行相应动作并可能反馈给模型二次处理。

  8. 结果返回与展示

    1. 最终结果返回给用户,可能伴随 UI 展示、导出等。

你是如何编排大模型工作流的?

编排大模型工作流,本质上是将多个步骤模块化,并按逻辑顺序组织起来,确保信息正确流转、模块间高效协作,最终完成目标任务。

在实际项目中,编排工作流通常会借助一些框架(如 LangChain、LlamaIndex、AutoGen、Semantic Kernel 等),但也可以手动设计和编排。

工作流编排的关键点:

  • 模块化设计:每个步骤职责清晰,便于维护和替换;

  • 数据流转:确保每一步的输出能正确作为下一步的输入;

  • 可扩展性:方便插入新的模块(如新增一个检索源、工具等);

  • 容错与日志:对关键步骤加入异常处理和调用监控;

  • 灵活配置:支持不同任务使用不同的子工作流。

chain式的工作流有哪些优缺点?

优点:

  1. 模块化 & 可复用

    1. 每个 Chain 封装一段逻辑(如检索+Prompt+LLM),可以在多个地方复用。

  2. 逻辑清晰

    1. 通过链式调用(如 chain1 >> chain2SequentialChain),流程顺序一目了然,便于理解和维护。

  3. 易于编排与组合

    1. LangChain 提供多种 Chain 类型(如 SimpleChainSequentialChainRouterChainTransformChain),支持灵活组合。

  4. 抽象层次高

    1. 开发者无需关心底层的 Prompt 如何传参、LLM 如何调用,Chain 已帮你封装好。

  5. 便于调试与监控

    1. 可以为每个 Chain 加入回调(Callback)机制,记录输入输出,方便排查问题。

缺点:

  1. 灵活性受限

    1. Chain 通常是线性(顺序)执行,如果任务需要条件分支、循环、动态决策,纯 Chain 模型可能不够灵活(此时需要 Agent 或 Graph)。

  2. 错误处理较弱

    1. 如果中间某一步出错(如检索失败、Embedding 错误),可能缺乏细粒度的错误捕获与恢复机制,需要额外编码处理。

  3. 复杂流程编排较难

    1. 对于有多个输入来源、多工具协同、状态依赖等复杂场景,仅靠 Chain 很难清晰表达逻辑,可能需要引入 Agent、LangGraph 等更高级编排方式。

  4. 性能瓶颈

    1. 多个 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、SimpleChainLangChain 的 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框架?

  1. LangChain(Python)

    1. 提供多种 Agent 类型:ReActAgentZeroShotAgentPlanAndSolveAgentSelfAskWithSearchAgent等。

    2. 支持 Tool 调用、Prompt 策略、多工具协同。

  2. AutoGen(Microsoft,Python & TS)

    1. 支持多 Agent 协作、人机混合、复杂任务分解,非常适合构建多角色智能体系统。

  3. Dify.AI / OpenAGI / Agent助手平台(国内/商业化)

    1. 提供低代码/无代码方式构建 Agent 应用,有些支持自定义 Agent Workflow。

Agent的ReAct模式是什么?

ReAct(Reason + Act,推理 + 行动)是一种提示策略,让 LLM 模拟人类的“思考 → 行动 → 观察”过程,从而在复杂任务中做出更好的决策,尤其适用于工具调用与推理任务。

典型流程:

  1. 思考(Thought):分析问题,决定接下来需要什么信息或动作。

  2. 行动(Action):执行一个工具调用或者逻辑步骤(如搜索、计算)。

  3. 观察(Observation):得到行动的结果,继续推理。

Agent的Plan-and-Solve模式是什么?

Plan-and-Solve(计划与解决)是另一种常见的 Agent 提示策略,它要求 LLM 先制定一个清晰的计划(Plan),然后一步步按照计划去执行(Solve),从而完成任务。

典型流程:

  1. 计划(Plan):先想清楚要分几步,每一步做什么。

  2. 执行(Solve / Act):按计划逐步执行,可能包括工具调用、逻辑推理等。

Multi-Agent如何做?

Multi-Agent 系统是由多个 Agent 协作或竞争,共同完成一个复杂任务。

常见方式:

  1. 角色分工:每个 Agent 扮演不同角色(如 Manager、Coder、Tester、Searcher)。

  2. 通信机制:Agent 之间通过消息、共享内存、对话等方式交互。

  3. 任务分配与调度:由主 Agent 协调,或基于规则/市场机制分配任务。

  4. 协作与冲突解决:多个 Agent 可能需协商、投票、合并结果。

框架支持:

  • AutoGen:原生支持多 Agent 对话与协作,非常适合构建客服、开发团队模拟等。

  • MetaGPT:模拟软件公司多个角色(产品经理、程序员、测试)协作开发软件。

  • LangChain + 自定义通信层:也可以自己实现 Agent 间消息传递。

Agent里幻觉怎么解决呢?

解决方法包括:

  1. 使用外部工具验证

    1. 不轻信 LLM“口说无凭”,而是让它调用搜索、数据库、API 获取真实信息。

    2. 例如:问“北京人口是多少?”→ 不直接回答,而是调用搜索工具查最新数据。

  2. 引入检索增强生成(RAG)

    1. 让 Agent 基于可靠的知识库/文档回答问题,而非自由发挥。

  3. 采用 ReAct / Plan-and-Solve 等结构化策略

    1. 引导模型先思考、再行动、再验证,减少胡编乱造。

  4. 提示工程(Prompt Engineering)

    1. 在 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的核心模块有哪些?分别有什么作用?

  1. Models(模型接口)

    1. 作用:负责与各种大语言模型(如 OpenAI、Hunyuan、Claude、Mistral 等)进行交互的统一接口。

    2. 功能:支持文本生成、嵌入(Embedding)、聊天模型(ChatModel)等,提供统一的调用方式,便于替换底层模型。

  2. Prompts(提示管理)

    1. 作用:管理和构造输入给 LLM 的提示(Prompt)。

    2. 关键组件:

      • PromptTemplate:用于定义带变量的模板化提示。

      • ChatPromptTemplate:用于构建对话型提示,常用于 Chat 模型。

      • 支持从文件、变量动态加载提示内容。

  3. Chains(链式调用)

    1. 作用:将多个组件(如模型调用、提示、数据处理等)组合成有序的“链”,实现多步逻辑处理。

    2. 常见链类型:

      • LLMChain:最基础的 LLM 调用链。

      • SequentialChain:按顺序执行多个链。

      • RouterChain/ ConditionalChain:根据条件路由到不同的链。

      • 更高级的如 RetrievalQA(检索问答链)、TransformChain(数据转换链)等。

  4. Memory(记忆模块)

    1. 作用:为对话或应用提供状态保持能力,即“记忆”之前交互的内容。

    2. 应用场景:多轮对话、个性化交互等。

    3. 实现方式:如 ConversationBufferMemory(缓冲记忆)、ConversationSummaryMemory(摘要记忆)等。

  5. Indexes & Retrievers(索引与检索,用于 RAG)

    1. 作用:将外部文档(如 PDF、txt 等)进行索引,构建向量库,并通过 Embedding 模型进行语义检索,常用于检索增强生成(RAG)。

    2. 关键组件:

      • VectorStore(如 FAISS、Chroma、Pinecone 等)

      • Retriever:从索引中检索相关文档片段

      • 常与 RetrievalQA链配合实现问答

  6. Agents(智能代理)

    1. 作用:让 LLM 充当“智能决策者”,根据任务目标决定调用哪些工具、以什么顺序调用,并基于反馈迭代。

    2. 特点:

      • Agent 可以调用工具(如搜索引擎、API、代码执行器等)

      • 支持 ReAct、Plan-and-execute 等推理策略

      • 常用于开放域任务、自动化任务等

  7. Tools(工具集成)

    1. 作用:让 LLM 能够使用外部工具,比如:

      • 搜索引擎

      • 计算器

      • API 接口

      • 数据库查询

      • 代码执行沙箱

    2. LangChain 提供标准接口,开发者可以接入自定义工具。

  8. Callbacks(回调系统)

    1. 作用:提供对 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 也可以接入

如何接入自定义模型?

  1. 方式一:通过 LangChain 的模型接口标准,封装自定义模型类

  2. 方式二:如果你的模型已经提供了类似 OpenAI 的 API(比如通过 FastChat、TGI、vLLM 等部署)

  3. 方式三:使用 Hugging Face Transformers 等本地模型

如何使用LangChain实现RAG?用哪些组件?什么流程?

  1. Documents(文档)

    1. 你的原始数据,比如 PDF、txt、网页内容等。

    2. 通常使用 langchain.document_loaders加载,如 PDFLoaderTextLoader

  2. Text Splitter(文本分割器)

    1. 将大文档切分成适当大小的 Chunk,便于后续索引。

    2. 组件:RecursiveCharacterTextSplitter

  3. Embedding 模型(文本向量化模型)

    1. 将文本块转换为向量表示,用于语义检索。

    2. 可使用 LangChain 支持的任意 Embedding 模型,如 HuggingFaceEmbeddings、OpenAIEmbeddings、或者腾讯混元 Embedding API。

  4. Vector Store(向量存储 / 索引)

    1. 存储文本块及其嵌入向量,支持高效的相似度检索。

    2. 常见实现:FAISS(内存)、ChromaPineconeWeaviateQdrant等。

    3. LangChain 提供统一接口:VectorStore

  5. Retriever(检索器)

    1. 根据用户问题,从 VectorStore 中检索出最相关的文档片段。

    2. 通常由 VectorStore 自带(如 faiss.as_retriever()),或可自定义。

  6. Prompt Template(提示模板)

    1. 构造将检索到的上下文 + 用户问题一起传给 LLM 的提示。

  7. LLM(大语言模型)

    1. 用于根据检索到的上下文和问题生成答案,如 GPT、Hunyuan、Claude 等。

  8. RetrievalQA(可选,封装好的链)

    1. LangChain 提供的一个开箱即用的链,组合了 Retriever + Prompt + LLM,简化 RAG 流程。

RAG 实现流程:

  1. 加载文档:从磁盘/网络加载原始数据(PDF、txt等)。

  2. 分割文档:将文档切分成小块(chunks)。

  3. 向量化:用 Embedding 模型将 chunks 转为向量。

  4. 构建索引:将向量存入 VectorStore(如 FAISS)。

  5. 检索:用户提问时,用 Retriever 找出最相关的文档片段。

  6. 构造 Prompt:将检索结果与用户问题组合成完整 Prompt。

  7. 调用 LLM:让 LLM 基于上下文回答问题。

  8. (可选)使用 RetrievalQA 链:一步到位,简化上述流程。

如何使用LangChain实现workflow?用哪些组件?什么流程?

  1. Chain(链)

    1. 基础组件,用于将多个操作(如 Prompt、LLM 调用、数据处理)组合成一个流程。

    2. 常见子类:

      • LLMChain:基础 LLM 调用链

      • SequentialChain:按顺序执行多个 Chain

      • RouterChain/ ConditionalChain:根据条件选择不同路径

  2. SequentialChain(顺序链)

    1. 将多个 Chain 按顺序串联,前一个的输出作为下一个的输入。

    2. 适用于多步有依赖的任务,比如先提取信息,再总结,再翻译等。

  3. RouterChain / ConditionalChain

    1. 根据输入内容,选择不同的处理路径,适合多分支逻辑。

  4. 自定义 Chain

    1. 继承 Chain基类,自定义你自己的多步逻辑。

Workflow 实现流程:

  1. 拆解任务步骤:将一个复杂任务拆解为多个子任务(如:信息抽取 → 信息加工 → 回答生成)。

  2. 构建单个 Chain:为每个子任务创建一个 Chain(如 Prompt + LLM)。

  3. 组合 Chain:使用 SequentialChain或自定义逻辑将多个 Chain 串联/并联。

  4. 执行 Workflow:输入初始数据,触发整个流程,得到最终结果。

如何使用LangChain实现Agent?用哪些组件?什么流程?

  1. LLM(大模型)

    1. 用于决策:决定调用哪个工具、如何组织 prompt、反思等。

    2. 通常使用支持 ReAct 或 tool-use 的模型(如 GPT-3.5+/4、Hunyuan、Claude 等)。

  2. Tools(工具集)

    1. LLM 可调用的外部能力,比如:

      • 搜索引擎

      • 计算器

      • API 请求

      • 代码执行器

      • 数据库查询

    2. 工具需符合 LangChain Tool 接口,定义好名称、描述、调用函数。

  3. ToolKit / 工具注册

    1. 将多个工具组合在一起,供 Agent 使用。

  4. Agent 类型

    1. LangChain 提供多种 Agent 实现,如:

      • ZeroShotAgent(基于 ReAct 模式,提示中定义可用工具)

      • ReActAgent

      • StructuredChatAgent

      • SelfAskWithSearchAgent

      • 通过 agents模块灵活配置。

  5. AgentExecutor

    1. 负责执行 Agent 的决策循环:思考 → 决定调用工具 → 调用 → 获取结果 → 反馈。

Agent 实现流程:

  1. 定义工具集:实现你希望 LLM 使用的各个工具(比如搜索、计算、API)。

  2. 加载 LLM:选择支持工具调用的模型。

  3. 构建 Agent:使用 Agent 类(如 ZeroShotAgent 或 ReAct 模式),告诉它可以用的工具。

  4. 执行 Agent:通过 AgentExecutor运行,用户提问后,Agent 自主决策调用工具并生成最终回复。

能介绍一下LangChain的ReAct和Tool使用方式吗?

LangChain 提供了内置的 ReAct Agent(如 ZERO_SHOT_REACT_DESCRIPTION),你只需要:

  • 提供一组 Tools(工具)

  • 使用 ReAct 模式的 Agent(如 ZeroShotAgent

  • LLM 就会根据问题,自动决定何时调用工具、调用哪个工具、以及如何组织推理过程。

Tool(工具)使用方式:

  1. 定义一个 Tool

  2. 让 LLM 使用这个 Tool(通过 Agent)

  3. LLM 会先“思考”,然后决定调用 get_current_year,获取结果后生成回答

如何让LLM调用外部API?在LangChain中如何使用Tool实现?

让 LLM 调用外部 API,本质是:

  1. 定义一个 Tool,其内部封装了 API 请求逻辑(如 HTTP 请求)。

  2. 将该 Tool 提供给 Agent 或 Chain,让 LLM 在需要时调用它。

如何实现多轮对话的记忆功能(Memory)?用哪些组件?

Memory 的典型使用流程:

  1. 初始化一个 Memory 对象(如 ConversationBufferMemory)。

  2. 将 Memory 对象传入 Chain 或 Agent,比如 LLMChain(memory=memory)initialize_agent(memory=memory)

  3. 在多轮对话中反复调用,Memory 会自动累积用户与 AI 的对话历史,并在下一轮输入中注入到 Prompt。

  4. (可选)自定义 Prompt 模板,将 memory 中的历史以合适格式拼接到用户问题之前。

在LangChain中如何管理上下文长度问题(比如Token超限)?

  1. 使用合适的 Memory 类型(减少历史输入)

    1. 如用 ConversationSummaryMemory 替代 ConversationBufferMemory,用摘要代替全部历史。

    2. 定期清理或截断 Memory 中的内容。

  2. 对话历史裁剪(Conversation Buffer Truncation)

    1. LangChain 的 ConversationBufferMemory支持设置 memory_keyreturn_messages,并可以控制保留多少轮对话。

    2. 你可以手动或使用 trim_memory()方法只保留最近 N 轮。

  3. 手动控制 Prompt 构造

    1. 在自定义 Prompt 时,只选择最重要的历史片段拼接,而不是全部历史。

    2. 比如只保留最近 3~5 轮对话,或者按时间/重要性筛选。

  4. 使用 Token 计算工具

    1. LangChain 提供 get_token_ids或第三方工具(如 tiktoken)来计算输入内容的 Token 数,提前判断是否超限。

  5. RAG 场景下的 Context 管理

    1. 检索出来的文档片段过多?用 Top-K / Top-N 过滤,只保留最相关的几条。

    2. 控制 Retriever返回的文档数量,比如只取 3~5 个最相关段落。

  6. 使用 Long-context 模型

    1. 如 GPT-4-32k、Claude 100k、Hunyuan长文模型、Mistral-long 等,它们支持更大的上下文窗口。

    2. 或者使用外部 分段处理 + 总结 策略,把长内容拆块处理。

你了解LangChain有哪些相关生态项目?比如LangChain.js、LangSmith、LangGraph?

  1. LangChain.js

    1. 是什么:LangChain 的 JavaScript / TypeScript 版本,功能类似 Python 版,用于在 Node.js 或前端环境中开发 LLM 应用。

    2. 支持功能:

      • Models(调用 LLM API)

      • Prompts、Chains

      • Memory、Agents(部分支持)

      • 适用于浏览器和服务器端 JS 环境

    3. 适用场景:

      • 前端直接调用 LLM(如网页智能助手)

      • Node.js 后端服务构建

  2. LangSmith

    1. 是什么:LangChain 官方推出的 调试、监控、测试与可视化平台,用于跟踪、评估和优化 LangChain 应用。

    2. 核心功能:

      • 追踪 Chain / Agent 的调用链路,查看每一步输入/输出

      • 支持 日志记录、错误排查、性能分析

      • 提供 测试框架,支持单元测试和集成测试 LLM 应用

      • 可视化 Prompt、工具调用、Retriever 结果等

    3. 适用场景:

      • 生产环境调试复杂 Chain

      • LLM 应用质量保障与迭代

      • 团队协作与版本管理

  3. LangGraph

    1. 是什么:由 LangChain 团队推出的 用于构建有状态、循环、多路径决策流程的库,特别适合构建 Agent 助手、工作流、多轮推理等复杂拓扑结构。

    2. 与 Chain 的区别:

      • 传统的 Chain 是线性或分支的,而 LangGraph 支持有环图、状态保存、循环执行。

    3. 适用场景:

      • 构建 多轮交互式 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。

梯度消失解决方法?激活函数,参数初始化,正则化与归一化方法,残差连接分别是什么?

  1. 激活函数(Activation Function)

      使用非饱和性、梯度友好的激活函数,例如:

    1. ReLU (Rectified Linear Unit):当输入 > 0 时导数为 1,避免了梯度饱和。

    2. Leaky ReLU / Parametric ReLU / ELU / Swish:对负值也有非零梯度,缓解死神经元问题。

  2. 参数初始化(Weight Initialization)

      合理的初始化方法能让初始梯度保持在合理范围,例如:

    1. Xavier / Glorot 初始化:适合 sigmoid/tanh,根据输入输出维度调整初始化范围。

    2. He 初始化:适合 ReLU 系列激活函数,考虑了 ReLU 的零区域特性。

  3. 正则化与归一化方法(Regularization & Normalization)

    1. Batch Normalization (BN):对每一层的输入做归一化,加速收敛,缓解梯度消失/爆炸。

    2. Layer Normalization (LN):常用于 RNN 或 Transformer,对单个样本的不同特征归一化。

    3. Weight Normalization / Group Normalization:其他归一化策略,有助于稳定训练。

  4. 残差连接(Residual Connections)

    1. 引入了跳跃连接(skip connection),如 ResNet 中的残差块,使得梯度可以直接回传,避免了梯度在多层中连乘衰减。

    2. 允许更深的网络训练,是解决梯度消失非常有效的方法。

梯度爆炸是什么?为什么会梯度爆炸?

与梯度消失相反,梯度爆炸指的是在反向传播过程中,梯度值变得非常大,导致权重更新幅度过大,模型参数发生剧烈震荡甚至溢出(NaN),网络无法收敛。

为什么会出现梯度爆炸?

  • 同样源于链式法则中的连乘效应,但如果每一层的梯度都大于1,经过多层累积后梯度会指数级增长。

  • 权重初始化过大、学习率过高、网络过深等也会诱发梯度爆炸。

梯度爆炸的解决方法?梯度裁剪,合适的权重初始化,归一化方法,优化器选择,残差连接,L2正则化分别是什么?

  1. 梯度裁剪(Gradient Clipping)

    1. 设定一个阈值,当梯度的范数超过该值时,按比例缩小梯度,防止更新步长过大。

    2. 常用于 RNN、Transformer 等模型,是处理梯度爆炸最直接有效的方法之一。

  2. 合适的权重初始化(Proper Weight Initialization)

    1. 使用 Xavier、He 等初始化方法,避免初始权重过大导致梯度不稳定。

  3. 归一化方法(Normalization)

    1. 如 BatchNorm、LayerNorm,有助于控制每层输入的分布,间接缓解梯度爆炸。

  4. 优化器选择(Optimizer Choice)

    1. 使用更先进的优化器如 Adam、RMSprop,它们对学习率有自适应调整能力,相比 SGD 更稳定,能缓解爆炸问题。

  5. 残差连接(Residual Connections)

    1. 通过跳跃连接让梯度可以直接回流,不仅缓解梯度消失,也对梯度爆炸有一定抑制作用。

  6. L2 正则化(L2 Regularization)

    1. 通过对权重施加惩罚,限制权重的过大增长,间接控制梯度的大小。

过拟合是什么?为什么会过拟合?

模型在训练数据上表现很好,但在未见过的测试/验证数据上表现差,即模型过度记忆训练数据的噪声或细节,而失去了泛化能力。

为什么会出现过拟合?

  • 模型过于复杂(参数量过多),容易记住而非学习规律。

  • 训练数据量太少,模型容易拟合噪声。

  • 训练时间过长,模型过度调参以适应训练集。

过拟合的解决方法?数据增强,降低模型复杂度,Dropout,Early Stopping分别是什么?

  1. 数据增强(Data Augmentation)

    1. 对训练数据进行变换(如旋转、翻转、加噪声、裁剪等),增加数据的多样性,提升模型的泛化能力,常用于图像、文本等领域。

  2. 降低模型复杂度(Reduce Model Complexity)

    1. 减少网络层数或神经元数量,使用更简单的模型结构,避免模型过于强大而记住噪声。

  3. Dropout

    1. 在训练过程中随机“丢弃”一部分神经元(将其输出置零),防止某些神经元过度依赖,增强泛化能力,常用于全连接层。

    2. 相当于训练了很多子网络并集成,有正则化效果。

  4. Early Stopping(早停法)

    1. 在验证集性能不再提升时提前终止训练,防止模型在训练集上过度拟合。

    2. 需要监控验证集损失或准确率,选择最佳 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的公式?

  1. 线性映射得到 Q, K, V:

    1. $$Q=XW^Q,K=XW^K,V=XW^V$$

    2. Q(Query)、K(Key)、V(Value)分别代表查询、键和值。

  2. 计算注意力分数(Attention Scores):

    1. $$Attention(Q,K,V)=softmax(\frac{QK^T}{\sqrt{d_k}})V$$

    2. QK^T:衡量每个 Query 和所有 Key 的相似度。

    3. 除以sqrt(d_k):缩放因子,防止点积过大导致 softmax 梯度消失。

    4. softmax:归一化得到注意力权重。

    5. 最后乘以 V:加权求和得到每个位置的输出。

  3. Multi-Head Attention(多头注意力):

    1. 将上述过程拆成多个头(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相比,它的优势是什么?

  1. 并行计算能力强 → 训练速度更快。

  2. 通过 Self-Attention 可以捕捉全局依赖 → 长距离上下文理解更强。

  3. 模型表达能力更强,更适合大规模数据和预训练 → 成为如今大模型的基石。

训练时候模型的参数类型是什么?

可训练参数(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 的优点:

  1. 相对位置信息建模更强:对 token 之间的相对位置关系更敏感,而不是单纯的绝对位置。

  2. 外推性好:对于比训练时更长的序列,也能较好泛化,不像传统位置编码那样受限于固定长度。

  3. 计算高效:与 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:不直接改模型参数,而是优化输入前缀或提示词嵌入。

  • 优点:节省显存和训练成本,易于部署和迭代。

  • 缺点:效果可能略逊于全量微调,但对大多数任务已经足够。

  • 适用场景:资源有限、需要快速实验和部署的场景。

让你做微调,流程是怎样的?

  1. 明确目标与场景

    1. 确定微调用途:问答、摘要、对话、专业领域助手等。

  2. 准备数据

    1. 收集 / 构造高质量、任务相关的指令-响应数据。

    2. 数据清洗、去重、格式标准化。

  3. 选择预训练模型

    1. 根据需求选择合适的大模型,如:

      • 开源中文模型:ChatGLM、Baichuan、Qwen、InternLM

      • 国际模型:LLaMA、Mistral、Falcon(需配合相应许可证与工具链)

  4. 选择微调方法

    1. 常用:SFT(全量或 LoRA 微调)

    2. 如果资源有限,优先选 LoRA / QLoRA / Adapter

  5. 配置训练环境

    1. 工具:Hugging Face Transformers + PEFT(LoRA)+ Datasets + Accelerate

    2. 硬件:至少 1~2 张 A10/A100 显卡,视模型大小而定

    3. 框架支持:LoRA、QLoRA、8bit/4bit 量化可选

  6. 训练 / 微调

    1. 设置好超参数(学习率、batch size、epoch、optimizer 等)

    2. 监控 loss 曲线,防止过拟合

    3. 可使用验证集评估中间效果

  7. 评估与部署

    1. 评估指标:自动指标(BLEU、F1等) + 人工评估(流畅性、准确性、专业性)

    2. 部署:将微调后的模型导出,可用 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)

  • 数据要清洗、格式统一,最好带标签或明确目标。

你的微调的数据是怎么来的?

  1. 公开数据集

    1. 适用于通用任务,如问答、摘要、翻译等。

    2. 例子:OpenAssistant、Alpaca、ShareGPT、UltraChat、FLAN、Supervised Fine-Tuning (SFT) 数据集等。

    3. 优点:获取方便,覆盖面广。

    4. 缺点:可能与你的具体业务场景不完全匹配。

  2. 自建 / 私有业务数据

    1. 来自公司内部文档、产品手册、客服对话、工单记录、FAQ、会议纪要等。

    2. 适用于垂直领域(如金融、医疗、法律、电商等)。

    3. 需要经过清洗、去敏、格式化、人工标注/校验。

    4. 例子:将用户与客服的问答对整理为 {input: 用户问题, output: 标准回答}格式。

  3. 人工构造 / 伪标签

    1. 如果真实数据不足,可以通过规则、模板、GPT 辅助生成。

    2. 比如:用 GPT 生成一些可能的用户 query 和对应的理想回答,再经人工筛选。

    3. 适用于冷启动或数据极度稀缺场景。

  4. 合成数据 + 真实数据混合

    1. 一部分来自真实业务,一部分用 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)通常采用动态推理,支持可变长度序列

大模型推理流程简述下?

  1. 输入准备(Preprocessing)

    1. 用户输入文本(如 prompt)

    2. Tokenization:将文本转为 token ID

    3. 可能的 padding / 截断 / 拼接(如 batching 场景)

  2. 模型加载(Model Loading)

    1. 加载 tokenizer 和模型权重(如从 HuggingFace、本地、ONNX 等)

    2. 模型可能位于 CPU / GPU / 多卡环境

  3. 推理执行(Inference)

    1. 将 token 输入模型,执行 前向传播(Forward Pass)

    2. 对于生成类任务(如 GPT 类模型),还会涉及 自回归生成(Autoregressive Decoding)

      • 逐 token 生成,每一步都依赖之前生成的 token(KV Cache 优化很重要)

  4. 后处理(Postprocessing)

    1. 将模型输出的 token IDs 转回可读文本

    2. 可能的过滤、截断、格式化等

  5. 返回结果

    1. 将生成的文本或结构化结果返回给用户 / 客户端

单次推理 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)?

  1. Top-k / Top-p (Nucleus) 采样仍然在起作用:即使你把 temperature 设为 0,如果你还开启了 Top-k 或 Top-p(Nucleus)采样策略,那么模型就不是单纯选最高分的 token。

  2. 随机种子(Random Seed)未固定

    1. 模型推理中如果使用了任何随机操作(如 dropout【推理时一般关闭】、随机采样等),并且 没有设置固定的随机种子(random seed),那么结果可能因运行环境不同而不同。

    2. 特别是在 GPU 上,某些操作(如 cuDNN 卷积)可能有非确定性实现,导致浮点计算微小差异 → 影响 logits → 影响最终 token。

  3. 浮点计算的非确定性(Non-determinism)

    1. 特别是在 GPU 上,某些算子(如矩阵乘法、卷积)为了性能优化,可能使用 非确定性算法

    2. 导致同样的输入,两次前向计算的 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 层中融合)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值