过去的AI世界强调“数据驱动一切”:大模型靠海量数据训练才能“变聪明”,而微调也总被认为需要成千上万条样本。可现实是,大多数企业、开发者根本没有这些“量级”的资源。
但如今,有种趋势在悄悄逆袭:
用极少样本,微调出强专家。
这不是口号,而是已经被验证过的工程范式:
Few-shot Prompt + LoRA 微调的组合打法,已经在多个领域(财税、政务、法律、教育)中获得惊人的效果。
数据合规压力更大了
业务定制化需求上升
大模型原生能力强,少样本足够激发潜力
模型定制方式 | 数据需求 | 计算资源 | 特点 | 适用场景 |
---|---|---|---|---|
全参数微调 | 上万到百万 | 非常高 | 最彻底的改写方式 | 模型预训练阶段、自研大厂 |
LoRA 微调 | 几百~几千 | 中等 | 插入可学习层、成本低 | 企业级小定制 |
Prompt Fine-tuning | 5条起步 | 极低 | 不改模型、不需训练 | 快速测试、低门槛接入 |
联合策略(推荐) | 5~500条 | 低-中 | Prompt + LoRA 效果叠加 | 多轮交互、RAG接入 |
核心观点:你不需要几十万数据,只要几十条设计良好的“黄金样本”,就能训练出行业专家模型。
本系列文章将围绕一个目标展开:
用尽可能少的样本(5~100条),训练出能够在特定领域回答问题、辅助决策、甚至写文档的专家模型。
涉及三种核心策略:
“Few-shot Prompt”说白了就是这样一个策略:
我不给你训练,只给你几个例子,看你能不能举一反三。
这正是大模型与传统机器学习最大的差异:它们具备了强大的**“上下文学习”能力(In-context Learning)**,你只要“喂得巧”,它就能“学得好”。
类型 | 描述 | 示例数 | 是否训练模型 |
---|---|---|---|
Zero-shot | 不提供示例,直接提问 | 0 | 否 |
Few-shot | 提供2~5个类似问题的问答示例 | 2~5 | 否 |
CoT Prompt | 加入“推理链”或步骤展示 | 2~10 | 否 |
Fine-tune | 用大量数据训练模型参数 | 上千 | 是 |
我们关注的核心是:Few-shot Prompt + 自定义结构设计 + 模型能力激活
一个高质量 Few-shot Prompt 通常具备以下结构:
【系统提示】你是一位领域专家,请准确回答用户提出的相关问题。
问:公司发年终奖需要缴哪些税?
答:需要代扣代缴个人所得税,按“全年一次性奖金”计税方式处理。
问:购买二手房要交哪些税?
答:通常包括契税、增值税和个税,具体情况视房产年限与类型而定。
问:{{用户实际问题}}
答:
我们要特别注意三个重点:
技巧类型 | 操作建议 |
---|---|
示例选择 | 优先选高频问题、用户常错问题、易混淆问题 |
顺序优化 | 将最重要的问题排前、弱问题排后,提升模型激活路径 |
多样化改写 | 同一问题用不同语气说法构建 Prompt,避免模型“记死答案” |
标签型提示设计 | 明确指定“角色”/“知识类型”/“输出结构”,如“你是财税专家” |
样本标签隐式化 | 将问题难度/分类标签加入提示中,如“复杂问题:…” |
你可以通过简单的 Python 模板系统来生成高质量 Prompt,以下是一个最简实战版:
def build_prompt(role: str, examples: list, user_question: str):
prompt = f"你是{role},请准确回答以下问题。\n\n"
for ex in examples:
prompt += f"问:{ex['q']}\n答:{ex['a']}\n\n"
prompt += f"问:{user_question}\n答:"
return prompt
Few-shot Prompt 好不好,不在于你写了多少,而在于你写得是否有代表性。
构建 Few-shot 数据的核心目标是:
用极少数样本,覆盖最大范围的用户真实提问场景,并引导模型输出“符合你期待”的答案风格。
本章我们就来拆解这件事,提供可操作的方案、样本结构与构建流程。
我们不求量,而求“质”:
比如对于“财税领域”,你要挑选:
字段 | 说明 | 示例 |
---|---|---|
instruction |
问题描述/任务指令 | “请告诉我该场景应缴哪些税?” |
input |
问题上下文(可选) | “我在北京卖掉了一套自住房。” |
output |
答案/行为期望 | “需要缴纳契税,符合减免条件可申请免税。” |
推荐标准化格式如下(JSONL 每行为一组样本):
{"instruction": "公司年终奖需交哪些税?", "input": "", "output": "需缴纳个税,按照全年一次性奖金计税方式处理。"}
采集历史问答
分类聚合
语义去重 + 多样改写
格式规范 + 样式控制
[
{
"instruction": "公司发年终奖要交哪些税?",
"output": "需要代扣代缴个人所得税,按“全年一次性奖金”计税方法处理。"
},
{
"instruction": "卖二手房需要缴哪些税?",
"output": "通常包括契税、增值税和个税,视房屋年限和是否唯一住房决定。"
},
{
"instruction": "离职补偿金要交税吗?",
"output": "在合理补偿范围内免税,超额部分需缴纳个人所得税。"
}
]
误区 | 正确做法 |
---|---|
示例太泛 | 选“业务高频+易混”才有价值 |
示例太长或过短 | 控制在 100~300 字为佳 |
回答风格前后不一致 | 统一回答口吻(如是否列举) |
输入输出内容结构混乱 | 保持 instruction / output 区分 |
如果你现在有了 3~5 组高质量的领域问题示例,恭喜你,你就能立即构建一个“行业模型的原型版本”,完全不需要微调。
这就是 Prompt 的力量。
你是一位{{领域}}专家,请根据已有示例回答用户提问:
问:{{示例问题1}}
答:{{示例答案1}}
问:{{示例问题2}}
答:{{示例答案2}}
问:{{用户实际问题}}
答:
每组 Prompt 控制在 800~1200 tokens 内,避免截断。建议使用 2~4 个示例问题最佳。
你可以很快搭出一个 Prompt 构造引擎:
def build_fewshot_prompt(role, examples, user_input):
prompt = f"你是一位{role},请根据示例回答用户提问:\n\n"
for ex in examples:
prompt += f"问:{ex['instruction']}\n答:{ex['output']}\n\n"
prompt += f"问:{user_input}\n答:"
return prompt
你可以把它接到任何大模型 API 上,比如:
from openai import OpenAI
prompt = build_fewshot_prompt("财税专家", fewshot_examples, "个人卖房需要交什么税?")
response = OpenAI().chat(prompt=prompt)
维度 | 说明 |
---|---|
相关性 | 回答是否与问题紧密相关 |
正确性 | 回答是否包含真实可靠的信息 |
一致性 | 回答风格是否统一、语气是否稳定 |
灵活性 | 是否支持用户输入不同问法仍能答对 |
实操建议:
阶段 | 操作 |
---|---|
本地评估 | 多组 Prompt + 多组输入交叉对比输出效果 |
实验环境 | 用 Prompt API 接入业务系统灰度流量 |
动态切换 | 支持 A/B Prompt 切换、更新 Prompt 版本 |
长期演进 | 用户反馈回收 → 更新示例 → Prompt 自学习 |
Prompt 很强,但有两个“隐形问题”:
而轻量级的 LoRA 微调,刚好可以把 Prompt 中的知识固化进模型本体,从“临时激发”进化成“永久记忆”。
全量微调(Fine-tune)会动模型上百亿个参数,成本高、过拟合风险大。而 LoRA(Low-Rank Adaptation)策略的核心是:
只训练少数插入层参数,把新知识“外挂”到已有大模型上。
优点很明确:
优势 | 说明 |
---|---|
速度快 | 通常几十分钟内完成微调 |
不改模型结构 | 插入权重不影响原模型参数 |
存储省 | LoRA 文件通常 < 300MB |
可热插拔 | Prompt 不变时直接加载 LoRA 权重动态生效 |
项目 | 推荐值 | 说明 |
---|---|---|
LoRA R 值 | 8 | 控制微调参数量,4~16之间常用 |
LoRA α 值 | 16 | 缩放比例 |
Dropout | 0.05 | 防止过拟合 |
Epoch | 3~5 | 小样本情况下不要过多 |
Batch size | 2~4 | 显存决定上限 |
学习率 | 2e-4 ~ 5e-5 | 建议线性 warmup,配合 scheduler |
使用 HuggingFace / Swift 微调框架时,需将 Few-shot Prompt 转为统一格式,如:
{
"instruction": "公司发年终奖要交哪些税?",
"input": "",
"output": "需要代扣代缴个人所得税,按“全年一次性奖金”计税方法处理。"
}
转换为训练语料(推荐模板):
用户:公司发年终奖要交哪些税?
助手:需要代扣代缴个人所得税,按“全年一次性奖金”计税方法处理。
from datasets import load_dataset
from swift.tuners import SwiftModel
model = SwiftModel.from_pretrained("deepseek-ai/deepseek-7b")
dataset = load_dataset("json", data_files="fewshot_data.json")
model.finetune(
train_dataset=dataset,
lora_r=8,
lora_alpha=16,
lora_dropout=0.05,
epochs=3,
batch_size=2,
lr=5e-5
)
输出模型保存位置下,会生成:
adapter_model.bin
:LoRA 权重config.json
:LoRA 结构定义tokenizer_config.json
:兼容原模型 tokenizer问题症状 | 可能原因 |
---|---|
输出格式错乱 | 训练样本格式不统一 / 不清楚回答边界 |
输出“记不住” | 示例量太少 or Prompt 输入不清晰 |
微调后表现变差 | LoRA 学习率过高 / Epoch 过多导致过拟合 |
微调文件太大 / 无法部署 | 没有使用正确的 adapter-only 保存方式 |
你写的代码训练完了,模型也跑通了。那效果到底怎么样?本章我们来实测三种方式输出的实际效果差异,从多个维度给出对比分析。
以“财税领域”示例测试输入:
用户提问:个人转让公司股权需要缴纳哪些税?
我们将通过以下三种方式输出:
模型类型 | 输出 | 评价 |
---|---|---|
原始模型 | “根据中国相关规定,可能需要缴纳相关税费。” | ❌ 模糊、无实际信息 |
Prompt | “个人转让公司股权需缴纳个人所得税,若涉及不动产还需缴契税。” | ✅ 基本准确 |
LoRA | “需缴纳个人所得税,依据<个人所得税法>;若为大额转让,涉资公司股权还涉及印花税。” | ✅✅ 准确、引用法规、表达自然 |
维度 | A 原始 | B Prompt | C LoRA |
---|---|---|---|
相关性 | 2 | 4 | 5 |
正确性 | 2 | 4 | 5 |
表达逻辑 | 3 | 4 | 5 |
知识引用深度 | 1 | 3 | 5 |
语气/风格一致性 | 3 | 4 | 5 |
结论:Few-shot Prompt 可快速提升模型表现,但在“细节补充、格式控制、知识稳定性”方面,LoRA 微调更胜一筹。
你可以使用 matplotlib
或 plotly
绘制对比雷达图,帮助产品/业务方直观理解差异:
import matplotlib.pyplot as plt
import numpy as np
labels = ['相关性', '正确性', '表达逻辑', '引用深度', '语气一致性']
scores = {
"原始模型": [2, 2, 3, 1, 3],
"Prompt": [4, 4, 4, 3, 4],
"LoRA微调": [5, 5, 5, 5, 5]
}
angles = np.linspace(0, 2 * np.pi, len(labels), endpoint=False).tolist()
angles += angles[:1]
plt.figure(figsize=(6,6))
ax = plt.subplot(111, polar=True)
for label, data in scores.items():
data += data[:1]
ax.plot(angles, data, label=label)
ax.fill(angles, data, alpha=0.1)
ax.set_thetagrids(np.degrees(angles), labels)
plt.legend(loc='upper right')
plt.show()
你已经构建了一个“小而强”的定制化模型,无论是通过 Few-shot Prompt,还是 LoRA 微调。
这最后一步,咱们要把它 “部署出去 → 接入业务 → 持续演进”,真正实现从实验室到线上产品的闭环。
Prompt 方法无需训练,只需构建一个“模板引擎”+“请求合成器”,即可在任意模型 API 层做动态注入。
from langchain.prompts import PromptTemplate
from langchain.llms import HuggingFaceHub
prompt = PromptTemplate(
input_variables=["question"],
template="""
你是一位财税专家,请回答以下问题:
问:公司发年终奖需要交哪些税?
答:需要代扣代缴个人所得税,按“全年一次性奖金”计税方式处理。
问:{question}
答:
"""
)
llm = HuggingFaceHub(repo_id="Qwen/Qwen1.5-7B-Chat")
output = llm(prompt.format(question="买房交什么税"))
@app.post("/qa")
def ask_question(data: Dict):
prompt = render_prompt_template(fewshot_examples, data["question"])
result = model.generate(prompt)
return {"answer": result}
优势:上线快、便于 A/B 测试、多 Prompt 实验可配置
注意:上下文 Token 长度别超限,注意编码规范和缓存策略
LoRA 微调后的模型只增加一个 adapter 权重,可以在原模型基础上轻松加载:
from peft import PeftModel
from transformers import AutoModelForCausalLM
base = AutoModelForCausalLM.from_pretrained("deepseek-ai/deepseek-7b")
lora_model = PeftModel.from_pretrained(base, "your_lora_path/")
场景 | 推荐部署策略 |
---|---|
内网服务调用 | FastAPI + Uvicorn |
多业务并发调用 | Triton Server + 多 LoRA Adapter 动态切换 |
云端部署 | 模型仓库 + GPU/CPU 多实例编排(K8s) |
每个微调后的模型本质上是“角色专家”,适合做多专家架构 / 多业务模型集群
为了形成闭环,每次调用之后建议保留以下内容:
可以用以下结构组织:
{
"user_question": "离职补偿金要交税吗?",
"model_answer": "...",
"prompt_version": "v1.2",
"lora_model": "finetuned_tax_expert_v0.3",
"user_feedback": "thumbs_up"
}
所有这些数据可以形成下一轮 Prompt 优化 / 微调数据来源。
你也可以搭配一个“标注系统 + 自动评分脚本”,形成训练闭环。
上线前,推荐用 A/B 实验平台部署多个版本并行运行,观察:
例如:
版本 | 命中率 | 用户评分 | 平均响应时长 |
---|---|---|---|
Prompt v1 | 68% | 3.7 | 2.3s |
Prompt v2 | 84% | 4.4 | 2.5s |
LoRA v1 | 91% | 4.7 | 2.8s |
为了持续运营,你可以构建一个简单的可视化控制台,用于:
工具选型推荐:
如果你觉得这篇文章对你有启发,或者你也在构建少样本的大模型系统,欢迎:
点个赞支持一下我继续写
留言告诉我你用的是什么模型(DeepSeek?Qwen?ChatGLM?)
我将持续更新这类“实操派、可落地”的国产模型部署与优化指南,感谢你的关注!