继续肝AI产品实战落地系列。
上一篇写完了RAG在实战中的落地方案,其中我提到了为了更好的让RAG筛选出我们想要的内容,需要解决用户上下文连贯性提问的问题。
RAG系统是把用户的query向量化后与库里的向量进行匹配,这个过程是没有上下文的,所以如果用户进行了一次追问操作,RAG就失效了。
例如:Q1:山东大学在哪? Q2:北京大学呢?
这时需要进入RAG系统参与匹配的应该是北京大学在哪?而不是北京大学呢?
所以这时候就需要上下文分析的能力来分析上下文得到用户的真实问题北京大学在哪?
我们当时使用了一套上下文分析的提示词来完成这个任务,随着上线后用户的提问越来越多,我们日志分析人员提出了许多的badcase,例如:

我们提示词中的上下文,是用户的两次疑问,我们做了节约tokens和响应时间的优化,把第一次提问的A省略掉了,让大模型仅通过两次Q来分辨第二次Q的真实意图。
用户第一次问:学校宿舍离教学楼远吗
用户第二次问:宿舍可以用大功率电器吗??
我需要大模型返回的是第二次问题的真正意图。即宿舍可以用大功率电器吗??
而deepseek V3 给的输出是:宿舍离教学楼的具体距离是多少?宿舍使用大功率电器的具体限制是什么?
为了解决这一类的问题,我们尝试了许多提示词上的改动之后发现,依然还是有一些case没办法兼顾到(文末贴有微调、RAG、prompt的应用场景)。
最终,我们选择了微调模型,先上结果:

同样的提示词,我们微调的模型可以很好的识别用户的真实意图:宿舍可以用大功率电器吗?
相同的提示词 deepseekV3没处理好,但是我们微调的千问7B可以,而他们的参数量级差了接近100倍!
下文我们将会从数据准备开始,完整的复现这个微调的方案。
开始之前,我们要先选择一个合适的微调平台和模型。
平台名称 | 价格 | 是否可下载 | 支持模型 | 支持训练方式 | 地址 | 备注 |
---|---|---|---|---|---|---|
讯飞星辰Maas | token单价 | 是 | 千问系列、星火系列、deepseek系列 | LoRA | 链接 | 实测并未出现扣费 |
火山方舟 | (训练集tokens) × epoch × token单价 | 否 | 豆包系列 | LoRA | 链接 | - |
百度千帆 | (训练集tokens) × epoch × token单价 | 否 | ERNIE系列及开源模型 | LoRA | 链接 | 限时训练费用五折 |
阿里百炼 | (训练数据Token总数 + 混合训练数据Token总数) × 循环次数 × 训练单价 | 否 | 千问系列 | 全参训练、高效训练 | 链接 | - |
表格中tokens单价部分不同的模型有不同的费用,目前最贵的模型是阿里的千问72B系列0.15/千tokens。其他模型通常都是0.05/千tokens左右。
本次微调是在讯飞开放平台上进行的,目前讯飞是免费支持微调的,并且开源模型还支持下载到本地。

准备数据
在进行微调之前,我们需要准备三份数据:训练数据集、验证数据集、测试数据集
●训练数据集是用来做微调的数据
●验证数据集是用来在微调过程中验证的数据
●测试数据集是用来评估效果使用
数据集的数量占比,通常按照 8:1:1或者 6:2:2的比例配置。
总的数据量,目前看在上下文分析这种场景,需要两千条左右的数据。不过在一些简单场景,例如:指定类型的标题生成
。一千条作用的数据也可以起到一定的效果。
通常我们按照以下三个原则来判断数据集的大小:
●要确保数据多样性,能够覆盖场景中的多数任务,重点覆盖bad case
●任务难度越低需要的数据量越小
●数据集越小,对数据的质量要求越高
bad case 分析
数据集中的数据内容,并不是我们当前任务的全量数据,而是我们想要的任务在当前大模型中执行的不好的case。
例如:
我们要用 Qwen_7B 进行微调,那么我们第一步就是把我们场景中的任务在7B中进行测试,找到执行的不好的任务,针对这类任务进行数据集的准备
对于上下文分析的场景来说,我们发现的问题有:
●用户在一次query中询问了多个问题。Q1:北京大学的计算机专业好么? Q2:好考么?学费是多少?招多少人? 此时,AI可能会回复我们的问题不全。
●用户第二个问题是独立问题。 Q1:北京大学的计算机专业好么? Q2:宿舍能用大功率电器么? 此时,AI可能会回复我们第一个+第二个两个问题。
●用户第二个问题是第一个问题的补充、追问。Q1:北京大学的计算机专业好么? Q2:介绍一下 此时,AI可能会丢失第一个问题中提到的主体。
●用户的问题是二义性问题。Q1:北京大学的计算机专业好么? Q2:土木工程怎么样? 此时,AI可能会按照独立问题的方式处理。
优化数据
针对这些问题场景我们需要准备上述所说的三套数据集。
推荐人工 + AI整理,由人工整理一些基本的问题, 搭配「问题抽取」和「数据增强」的工具进行。
就像我们这个场景,动用一个数据人员对4类问题进行集中处理,每个问题准备50个数据集,再加上场景中其他问题的覆盖,大约三百条人工数据。
准备问题的过程中数据人员可以使用我们的问题抽取功能,对我们的文档资料进行问题提取后作为Q1,然后人工仅编造Q2即可。
随后使用「数据增强」对数据1:10的比例进行扩充,再由人工从中筛选出可用的数据。
这样很快我们就完成了两千+训练数据集的准备。
发起微调
在讯飞平台使用微调非常简单,在模型管理界面,点击创建模型,

输入一个模型名字,然后选择一个微调的基座模型。基座模型如果是开源的,则微调完整后是支持下载的。

然后选择自己的训练集,对于讯飞来说,这个训练集等于我们的训练数据集 + 验证数据集。
对于新手来说,下面的参数需要注意的是学习率和训练次数。其他参数基本都不需要调整。
学习率决定了模型权重更新的速度。太高的学习率可能导致训练不稳定,太低的学习率则可能导致训练过程缓慢。默认值可以不改,最终可以根据收敛效果来决定调整。
几个训练次数就代表训练数据集被模型完整训练几遍。增加训练次数可以提高模型的性能,但也可能导致过拟合。(我通常会选择3-5)

训练完成之后,看一下过程指标的图。随着模型的训练loss不再持续下降,就说明模型已经在收敛了。

但是这并不一定就代表着,模型会有好的效果,所以我们还需要用我们的测试数据集进行一遍测试。
在进行测试之前,我们需要先把模型部署一下。
部署到应用
未发布过的模型,在模型下载上方,有一个发布按钮,点击发布,选择一个应用,就可以完成发布了。发布后会赠送500万tokens。

应用是来自于讯飞开放平台,创建一个自己的应用即可。
目前,讯飞并没有对微调和部署有额外的费用,目前收费的环节都是调用时的tokens需要付费。
微调(Fine-tuning) vs RAG vs Prompt工程 对比表
核心特性对比
维度 | 微调(Fine-tuning) | RAG | Prompt工程 |
---|---|---|---|
技术本质 | 调整模型参数 | 检索+生成混合系统 | 上下文指令设计 |
知识存储位置 | 模型参数内化 | 外部向量数据库 | 无持久存储 |
计算阶段 | 训练阶段 | 检索阶段+生成阶段 | 纯推理阶段 |
成本对比
资源类型 | 微调成本 | RAG成本 | Prompt成本 |
---|---|---|---|
GPU消耗 | 极高(训练需求) | 中(检索GPU+生成GPU) | 极低 |
维护成本 | 需版本管理 | 需维护知识库 | 无需维护 |
人力投入 | 需要ML工程师 | 需要搜索工程师 | 只需业务专家 |
适用场景对比
场景 | 推荐方案 | 原因说明 |
---|---|---|
金融风控 | 微调 | 需要高精度模型 |
智能客服 | RAG+微调混合 | 兼顾准确性与知识更新 |
内容生成 | Prompt工程 | 快速迭代需求 |
医疗问答 | RAG | 需要引用权威文献 |
结语
再来总结一下RAG和微调的场景:
选择RAG场景:是因为我们的模型能力没问题,是数据出问题了,所以我们使用RAG进行筛选内容。
选择微调场景:是模型能力出问题了,即使给到数据,也不一定会回答的理想。所以我们要按照我们的需求,对大模型进行训练。
所以,我们评估一下自己的任务,是能力问题还是数据问题,就可以很轻易的知道选择哪个方案了。
本篇结合前面两篇文章,基本上大家都可以撸出来一套相对完善的agent了,加油!
若有收获,就点个赞吧,有问题欢迎留言,看到就会回复。
☺️你好,我是华洛,如果你对程序员转型AI产品负责人感兴趣,请给我点个赞。
已入驻公众号【华洛AI转型纪实】,欢迎大家围观,后续会分享大量最近三年来的经验和踩过的坑。