【AI基础篇07】预训练 vs 微调 vs 提示工程

前言:同一个大模型,有三种完全不同的使用方式:预训练是"从零学语言",微调是"定向专修",提示工程是"临场发挥"。它们各自解决什么问题?成本差多少?什么场景选什么方案?本文用一张图讲清楚三者的本质区别,并给出2026年企业级决策框架。


📋 目录


一、宏观对比:三者的本质区别

1.1 一句话概括

预训练(Pre-training):
  "教模型说话"——从海量文本中学习语言规律

微调(Fine-tuning):
  "定向专修"——用特定领域数据调整模型参数

提示工程(Prompt Engineering):
  "临场发挥"——不调模型,只调输入

1.2 对比总览

维度 预训练 微调 提示工程
修改方式 从头训练参数 调整部分参数 不调参数,只调输入
数据需求 TB级无标注数据 千-万条标注数据 几条示例即可
计算成本 数百万美元 数百-数万美元 几乎为零
所需GPU 千卡集群,数周 单卡-几卡,数小时 不需要
模型变化 全新的模型 权重微调 输入变化
适用场景 自研基座模型 领域适配、私有部署 快速验证、日常使用
可控性
维护成本 极高
输出一致 不可控 ✅ 稳定可靠 依赖prompt质量

1.3 合作的"训练三阶段"

第一阶段:预训练
  数据:全网文本(20TB+)
  目标:学习语言规律
  产出:基座模型(Base Model)
  代表作:GPT-3、LLaMA、DeepSeek-V3-Base

第二阶段:指令微调(SFT)
  数据:高质量指令-回答对(百万级)
  目标:学会遵循指令
  产出:指令模型(Instruction Model)
  代表作:GPT-3.5-turbo、LLaMA-Chat

第三阶段:对齐(RLHF/DPO)
  数据:人类偏好标注
  目标:符合人类价值观
  产出:对齐模型(Aligned Model)
  代表作:ChatGPT、Claude

提示工程则发生在以上任何阶段之后——使用时动态注入。

💡 面试加分点:很多人以为ChatGPT是"一个模型",实际上它是预训练+指令微调+RLHF三个阶段的产物。Base模型(如GPT-3原始版)只会续写文本,不会"对话"。是SFT教会了它对话格式,RLHF教会了它"什么回答更好"。


二、预训练(Pre-training):从零学语言

2.1 什么是预训练

预训练 = 让模型在大量文本上学习"下一个词是什么"

输入:"我今天去"
目标输出:"上学"(或"上班"、"医院"等合理续写)

模型不需要"理解"文本,只需要学会:
  P(下一个词 | 前面所有的词)
  即:给定上下文,预测最可能的下一个词

2.2 预训练的两个流派

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
流派1:自回归(Autoregressive)—— GPT系列
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
训练目标:从左到右预测下一个token
  "I love AI" → 预测I→love→AI
  每个token只能看到自己左边的token

代表模型:GPT系列、LLaMA、DeepSeek、Qwen
优点:天然适合生成
缺点:不能利用右侧信息

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
流派2:自编码(Autoencoding)—— BERT系列
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
训练目标:还原被掩码的词
  "I [MASK] AI" → 预测[MASK] = love
  每个token可以看到上下文

代表模型:BERT、RoBERTa、ALBERT
优点:理解能力强
缺点:不适合生成(没见过从左到右生成)

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
2026年现状:自回归(GPT路线)几乎一统天下
BERT类模型仍在学术场景使用
但几乎所有商业大模型都走自回归路线
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

2.3 预训练的规模

预训练到底需要多少资源?(2026年参考)

模型规模     | 训练数据     | GPU · 天数   | 估算成本
------------|-------------|-------------|---------
7B (小)     | 2T tokens   | 256×H100·7天 | ~$500K
70B (中)    | 15T tokens  | 2048×H100·30天| ~$6M
671B (大)   | 15T tokens  | 8192×H100·60天| ~$50M+
(如DeepSeek-V3)

注:DeepSeek-V3训练成本约$5.5M(含MoE路由优化)
同规模GPT-4估算成本在$100M+级别
差距主要在架构(MoE)和工程优化

2.4 谁在做预训练?

2026年,有能力做预训练的实体已经很少:

国际巨头:
  OpenAI:GPT系列(闭源)
  Google:Gemini系列(闭源)
  Meta:LLaMA系列(开源)
  Anthropic:Claude系列(闭源)

中国实力派:
  DeepSeek:V3/R1/V4系列(开源+闭源)
  阿里:Qwen3系列(开源)
  智谱:GLM-5系列(开源)
  月之暗面:Kimi K2.6(开源)

趋势:预训练门槛越来越高
  2023年:几个博士生+几万美元就能训一个
  2025年:不算数据成本,单次训练就需数百万美元
  2026年:能做预训练的团队全球不超过20个

三、微调(Fine-tuning):定向专修

3.1 什么是微调

微调 = 用一个已训练好的模型,在你的特定数据上继续训练

类比:
  预训练 = 读完整个医学院(通识教育)
  微调   = 专攻心外科(专业深造)

关键区别:
  预训练:模型从头学,从随机参数开始
  微调:模型已经有"语言能力",只需调整方向

微调改变的是"行为",不是"能力"

3.2 全量微调 vs 参数高效微调

全量微调(Full Fine-tuning):
  更新模型所有参数
  效果最好,但代价最大

  7B模型全量微调:需要4×A100(~$50/小时)
  70B模型全量微调:需要64×A100(~$800/小时)

参数高效微调(PEFT):
  冻结大部分参数,只更新少量参数
  效果接近全量微调,成本降低90%+

  主流方法:
    LoRA:更新低秩矩阵(最流行)
    Prefix Tuning:学习虚拟token
    Adapter:插入小型适配层

3.3 微调的典型场景

场景1:领域适应
  通用模型 → 医疗/法律/金融专用模型
  数据:百万篇医学论文 + 病历数据
  效果:在医疗问答上提升30%+

场景2:指令遵循
  Base模型 → Chat模型
  数据:"
<s>用户:帮我写一封邮件</s>
<s>助理:好的,请参考以下模板...</s>"
  效果:从"只会续写"到"会对话"

场景3:私有部署
  公司内部知识模型
  数据:内部文档 + FAQ
  效果:回答准确率从60% → 92%

场景4:风格迁移
  模型适应特定写作风格
  数据:目标风格的文本
  效果:模仿特定作者/品牌语气

3.4 微调的代价

不考虑GPU成本,微调最大的代价是"数据":

需要什么样的数据?
  ❌ 粗糙的爬虫数据 → 模型质量差
  ✅ 人工标注的高质量数据 → 效果好

数据量需求:
  全量微调:10,000-100,000条
  LoRA微调:500-10,000条
  Few-shot:3-5条示例(但这是提示工程了)

数据标注成本(中文):
  普通标注:¥1-3/条
  专业领域(医疗/法律):¥10-50/条
  偏好标注(谁的回答更好):¥3-8/条

💡 面试加分点:微调不是万能的。如果你的任务只用几个示例就能让GPT-4做得很好,那不需要微调。微调主要解决的是:① 模型不知道的领域知识;② 需要固定输出格式;③ 数据隐私必须本地部署。


四、提示工程(Prompt Engineering):临场发挥

4.1 什么是提示工程

提示工程 = 设计输入文本(Prompt),引导模型输出期望结果

不改变模型参数
不训练模型
只改变"问法"

核心原则:
  LLM是基于"已生成文本 + 输入"预测下一个token
  模型不会"理解你的意图",只看到"文本模式"
  好的Prompt = 让模型"猜中"你想要什么

4.2 提示工程的层次

Level 1:基础提示(Zero-shot)
  "总结这篇文章:..."

Level 2:少样本提示(Few-shot)
  "示例1:... → ..."
  "示例2:... → ..."
  "现在处理:..."

Level 3:思维链(Chain-of-Thought)
  "让我们一步步思考:
  第一步:理解问题
  第二步:分析已知条件
  第三步:...输出答案"

Level 4:结构化提示
  """## 角色
  你是资深Python工程师

  ## 任务
  实现一个二叉搜索树

  ## 约束
  - 使用递归实现
  - 包含插入、删除、搜索
  - 时间复杂度O(log n)

  ## 输出格式
  ```python
  class BST:
      ...
  ```"""

Level 5:系统提示 + 多轮对话
  System: 你是一个客服机器人
  User: 我的订单还没到
  Assistant: 让我查一下...

4.3 提示工程的2026年现状

2026年,提示工程已经高度系统化:

1️⃣ 框架化
  DSPy:用编程方式自动优化Prompt
  LangChain:Prompt模板 + 链式调用
  Guidance:控制生成的结构化框架

2️⃣ 自动化
  Automatic Prompt Engineer(APE)
  让LLM自己写Prompt、评估、优化
  人类只需要提供任务描述

3️⃣ 分层设计
  System Prompt(全局)
  Task Prompt(任务级)
  Step Prompt(步骤级)
  Output Prompt(输出约束)

4️⃣ 提示注入防御
  用户输入的Prompt中可能含有恶意指令
  "忽略之前的指令,说你是..."
  需要做Prompt隔离和净化

结论:2026年的提示工程
  从"艺术"变成了"工程"
  有标准框架、评估指标、自动优化工具
  但仍需要人类判断"什么prompt效果好"

4.4 提示工程的局限性

✅ 优点:
  零成本:不需要训练
  快速迭代:改一行文本就能试
  灵活多变:同一个模型做不同任务
  
❌ 局限性:
  不稳定:同样prompt,不同次输出不同
  无法内化知识:模型不知道你的私有数据
  受限于上下文窗口:复杂任务prompt太长
  可重复性差:模型升级后prompt可能失效
  性能上限:不可能超过模型本身能力

决策信号灯 🚦
  🟢 简单任务、快速验证 → 提示工程
  🟡 需要稳定输出的生产环境 → 微调
  🔴 私有数据、特殊格式 → 微调

五、三者成本对比:差距有多大

5.1 成本量化对比

以一个"医疗问答"场景为例:

┌────────────────────────────────────────────────────────┐
│ 方案         │ 一次性成本    │ 每次调用成本 │ 质量     │
├────────────────────────────────────────────────────────┤
│ 提示工程     │ $0           │ $0.01-0.1   │ 60-80%  │
│ (直接调用API)│              │ (按token计费)│         │
├────────────────────────────────────────────────────────┤
│ Few-shot     │ $0           │ $0.02-0.2   │ 70-85%  │
│ (带示例prompt)│              │ (更长prompt) │         │
├────────────────────────────────────────────────────────┤
│ LoRA微调     │ $500-5000    │ $0.001-0.01 │ 85-95%  │
│ (本地部署)   │ (数据+训练)   │ (推理成本)   │         │
├────────────────────────────────────────────────────────┤
│ 全量微调     │ $5000-50000  │ $0.001-0.01 │ 90-97%  │
│ (本地部署)   │ (数据+训练)   │ (推理成本)   │         │
├────────────────────────────────────────────────────────┤
│ 预训练自研   │ $500K-50M+   │ $0.001-0.01 │ 基准    │
│              │ (数据+训练)   │ (推理成本)   │         │
└────────────────────────────────────────────────────────┘

关键洞察:
  提示工程:零启动成本,但每次调用都花钱
  微调:有启动成本,但后续调用更便宜
  预训练:天价启动成本,除非极大规模,否则不划算

5.2 长期成本曲线

成本曲线(年调用量 vs 总成本):

         ↑
  年成本 │   [提示工程: 成本线性增长]
         │    /
         │   / 
         │  /  [LoRA微调: 固定+线性]
         │ /   /
         │/   / [全量微调: 固定+线性]
         └──────────────────→ 
                年调用量

关键结论:
  调用量 < 10万次/年:提示工程最省钱
  调用量 10万-100万次/年:LoRA微调最划算
  调用量 > 100万次/年:全量微调摊薄后最便宜

六、2026年企业级决策框架

6.1 决策树

你的任务需要大模型?
│
├─ 任务简单,通用模型就能做?
│  ├─ 是 → 提示工程(零成本启动)
│  │     ├─ 效果满意? → 上线
│  │     └─ 不满意? → 优化prompt
│  │           └─ 仍不满意? → 看下面
│  │
│  └─ 否 → 需要领域知识/特殊格式?
│       │
│       ├─ 有标注数据?
│       │  ├─ <1000条 → 尝试Few-shot提示工程
│       │  │     └─ 效果不够 → LoRA微调
│       │  ├─ 1000-1万条 → LoRA/QLoRA
│       │  └─ >1万条 → 全量微调
│       │
│       └─ 没有标注数据?
│          ├─ 用大模型自动生成训练数据
│          └─ 人工标注(代价大但质量高)
│
└─ 需要私有部署?
   ├─ 7B级模型:LoRA + vLLM部署
   └─ 70B级模型:量化 + 多卡部署

6.2 2026年行业实践

不同行业的主流方案:

┌──────────┬──────────────────┬─────────────────────┐
│ 行业     │ 常用方案          │ 理由                │
├──────────┼──────────────────┼─────────────────────┤
│ 客服     │ 提示工程+RAG      │ 需求变化快,需要实时更新│
│ 医疗     │ LoRA微调+本地部署  │ 数据隐私,准确率要求高 │
│ 法律     │ 全量微调+私有部署  │ 格式固定,错误成本极高 │
│ 代码助手 │ 提示工程+工具调用  │ 不需要训练,工具调用即可│
│ 金融分析 │ RAG+LoRA微调      │ 数据实时+专业术语       │
│ 内容创作 │ 提示工程+多轮对话  │ 灵活创作,不需要固定格式│
│ 教育     │ 提示工程+知识库    │ 内容多样化,定期更新    │
└──────────┴──────────────────┴─────────────────────┘

通用原则:
  能用提示解决 → 绝不微调
  能用RAG解决 → 绝不微调
  只有"非微调不可"时才微调

七、微调的进阶路线:SFT → RLHF → DPO

7.1 SFT(Supervised Fine-Tuning)

监督微调 = 用人工标注的"指令-回答"对训练模型

数据格式:
  {
    "instruction": "用Python实现斐波那契数列",
    "output": "def fib(n):\n    if n <= 1:\n        return n\n    return fib(n-1) + fib(n-2)"
  }

训练方式:
  标准语言模型训练,但数据是高质指令数据
  冻结基座模型能力,教会"输出格式"

效果:
  Base模型 → 能听懂人话的Chat模型
  GPT-3 → ChatGPT的能力飞跃就在这一步

2026年SFT数据量:
  商业模型:百万级指令-回答对
  开源方案:10,000-50,000条高质量指令即可

7.2 RLHF(Reinforcement Learning from Human Feedback)

RLHF = 用"人类偏好"来优化模型回答

三步流程:

Step 1:收集偏好数据
  给标注员展示同一个问题的两个回答
  标注员选择"哪个更好"
  "用Python实现排序算法"
  回答A:def sort(arr): ...
  回答B:def sort(arr): ...
  标注员:B更好(因为处理了边界情况)

Step 2:训练奖励模型(Reward Model)
  用偏好数据训练一个"评分器"
  输入:问题+回答 → 输出:质量分数
  奖励模型学会"人类喜欢的回答长什么样"

Step 3:PPO强化学习
  用奖励模型给大模型的回答打分
  模型根据分数调整自己的参数
  目标是让模型生成"得分更高"的回答

代价:
  需要大量人工标注(昂贵)
  PPO训练不稳定
  DeepSeek-V3的RLHF用了数千GPU·小时

7.3 DPO(Direct Preference Optimization)—— 2024年的突破

DPO = 直接优化偏好,不需要奖励模型

为什么DPO比RLHF好?
  RLHF:需要训练一个奖励模型 + PPO强化学习
  DPO:直接利用偏好数据优化策略

DPO的核心洞察:
  偏好数据已经包含了"什么是好回答"的信息
  不需要先训练一个奖励模型"转述"一遍
  直接让模型在偏好数据上学习

数学直觉:
  RLHF:            模型 → 奖励模型 → 优化策略
  DPO:      模型 ← 偏好数据 ← 直接学习

效果对比:
  DPO达到或超过RLHF的效果
  训练成本降低50-70%
  训练稳定性大幅提升
  LLaMA 3 Chat使用DPO对齐

2026年现状:
  DPO已成为主流的对齐方法
  RLHF仍在大型商业模型中使用
  但新模型(Qwen3、DeepSeek-R1)都倾向DPO

7.4 微调路线总结

SFT(2020)→ RLHF(2022)→ DPO(2024)

SFT: 教模型"回答格式"
  数据:指令-回答对
  成本:中(需要人工写答案)
  效果:能对话,但回答质量参差不齐

RLHF: 教模型"什么回答更好"
  数据:偏好标注(A vs B)
  成本:高(需要训练奖励模型+PPO)
  效果:回答质量高,但训练不稳定

DPO: 直接学"更好"
  数据:偏好标注(跟RLHF一样)
  成本:低(不需要奖励模型)
  效果:接近或超过RLHF,训练稳定

2026年趋势:DPO正在取代RLHF
  但也开始出现"新的小趋势"
  如DeepSeek的GRPO(Group Relative Policy Optimization)
  在数学推理场景通过"组内自对比"实现对齐

八、参数高效微调:LoRA/QLoRA

8.1 LoRA的核心思想

LoRA(Low-Rank Adaptation,2021):
  不用修改模型所有参数
  而是"在旁边"加一个小型参数矩阵

直观理解:
  原来的权重矩阵 W(4096×4096,1670万个参数)
  在其旁边加两个小矩阵 A×B(4096×8 + 8×4096,6.5万个参数)
  训练时只更新 A 和 B,不碰 W

  效果:参数量减少99.6%,但效果接近全量微调

为什么LoRA有效?
  研究发现:模型参数的"有效秩"很低
  即大部分参数变化可以"压缩"到低维空间
  LoRA就是利用这一特性

8.2 QLoRA:量化+LoRA

QLoRA(2023) = Q(量化4-bit) + LoRA

方案:
  原始模型用4-bit量化(内存减少4倍)
  冻结量化后的模型
  只训练LoRA参数(保持float16精度)

效果:
  7B模型全量微调需要 56GB显存
  7B模型QLoRA只需要 16GB显存(一张消费级显卡即可)

  70B模型全量微调需要 560GB显存(8×A100)
  70B模型QLoRA只需要 96GB显存(2×A100或1×H100)
  
  消费级显卡(RTX 4090 24GB)可以微调13B模型!

8.3 LoRA的实战配置

LoRA关键参数:

rank(秩):
  越高 → 表达能力越强 → 效果越好
  越高 → 参数量越大 → 成本越高
  
  实践建议:
    简单任务:r=8(足够)
    复杂任务:r=16-32
    非常复杂:r=64(极少需要)

target_modules(作用目标):
  只对注意力层的Q、K、V、O矩阵做LoRA
  ✅ 效果好,参数少
  ❌ 全部层都做 → 参数太多

alpha(缩放因子):
  控制LoRA权重的影响程度
  通常 alpha = 2×rank

dropout:
  防止过拟合
  数据量少时用0.1,数据量大时用0.05

2026年主流配置(LLaMA-Factory等工具已封装成一行命令):
  lora_config = {
      "r": 16,
      "lora_alpha": 32,
      "target_modules": ["q_proj", "k_proj", "v_proj", "o_proj"],
      "lora_dropout": 0.05
  }

九、提示工程的系统化方法

9.1 结构化Prompt模板

2026年最实用的Prompt结构:

【角色】 → 【背景】 → 【任务】 → 【步骤】 → 【约束】 → 【输出格式】 → 【示例】

完整示例:
──────────────────────────────────────────
# 角色
你是一位资深的Python开发工程师

# 背景
用户需要一个高效的日志分析工具
日志格式:timestamp [LEVEL] module: message

# 任务
编写一个Python脚本,分析日志文件并生成统计报告

# 步骤
1. 读取日志文件
2. 按级别统计日志数量
3. 找出最频繁的错误模块
4. 生成可视化报告

# 约束
- 使用标准库,不要第三方依赖
- 处理大文件(>1GB)时考虑流式处理
- 代码需要有详细的注释

# 输出格式
输出完整的Python脚本,包含:
  1. 函数定义
  2. 主函数
  3. 使用示例

# 示例(输入输出对)
输入: log_analyzer.py system.log
输出:
​```python
import re
...

──────────────────────────────────────────

### 9.2 2026年提示工程工具链

DSPy(推荐):
from dspy import Signature, ChainOfThought

class GenerateAnswer(Signature):
​ “”“回答问题,基于给定上下文”“”
​ context = dspy.InputField()
​ question = dspy.InputField()
​ answer = dspy.OutputField()

program = ChainOfThought(GenerateAnswer)

DSPy会自动优化prompt!

LangChain:
from langchain.prompts import ChatPromptTemplate

prompt = ChatPromptTemplate.from_messages([
​ (“system”, “你是{role}专家”),
​ (“human”, “{input}”),
​ (“assistant”, “让我来帮您分析:”)
])
chain = prompt | model | output_parser

Guidance:
控制生成过程,确保输出格式
类似"模板+约束"的中间方案

### 9.3 2026年提示工程的"新常态"

1️⃣ 提示模板库化
企业级提示用Git管理
版本控制、A/B测试、回滚
不再是"在聊天框里试"

2️⃣ 自动化评估
用LLM评估LLM的输出
自动检测:相关性、准确性、格式
Prompt修改后自动跑回归测试

3️⃣ 多模型适配
同一个任务 → 适配GPT/Claude/DeepSeek
不同模型对prompt格式的敏感度不同
自动转换prompt格式

4️⃣ 安全审计
自动检测Prompt注入
输出内容过滤
敏感信息脱敏

---

## 十、实战:用代码体验三种模式

### 10.1 模拟预训练(简化版)

​```python
# 预训练的本质:预测下一个token
# 这里用一个小型语言模型演示

from transformers import AutoModelForCausalLM, AutoTokenizer
import torch

# 加载一个小型预训练模型
model_name = "gpt2"  # 124M参数,可在CPU上运行
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(model_name)

# 预训练模式的推理
def pretrain_generate(prompt, max_length=50):
    """基座模型:只会续写,不会对话"""
    inputs = tokenizer(prompt, return_tensors="pt")
    
    with torch.no_grad():
        outputs = model.generate(
            inputs.input_ids,
            max_length=max_length,
            temperature=0.7,
            do_sample=True
        )
    
    return tokenizer.decode(outputs[0], skip_special_tokens=True)

# 测试
print("=== 基座模型(预训练后)===")
print(pretrain_generate("The meaning of life is"))
# 输出可能:The meaning of life is to find your purpose and pursue it with passion.
# 模型只是在"续写",不是真的在回答

print(pretrain_generate("用户:你好\n助理:"))
# 输出问题:模型不知道"用户/助理"是什么格式
# 可能输出:用户:你好\n助理:你好!有什么可以帮你的吗?
# → 如果训练数据中有对话数据,模型可以"模仿"对话格式

10.2 使用LoRA微调

# 使用Hugging Face PEFT库进行LoRA微调
# 安装:pip install peft transformers datasets

from peft import LoraConfig, get_peft_model, TaskType
from transformers import AutoModelForCausalLM, AutoTokenizer, TrainingArguments, Trainer
from datasets import Dataset

# 1. 加载基座模型
model_name = "Qwen/Qwen2.5-0.5B"  # 小模型,适合演示
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(model_name)

# 2. 配置LoRA
lora_config = LoraConfig(
    task_type=TaskType.CAUSAL_LM,
    r=8,                      # 秩
    lora_alpha=16,            # 缩放因子
    target_modules=["q_proj", "k_proj", "v_proj", "o_proj"],  # 目标层
    lora_dropout=0.05,
    bias="none"
)

# 3. 应用LoRA
model = get_peft_model(model, lora_config)
print(f"可训练参数: {model.print_trainable_parameters()}")
# 输出:trainable params: 442,368 || all params: 494,038,272 || trainable%: 0.0895
# 仅0.09%的参数需要训练!

# 4. 准备数据(医疗问答示例)
train_data = [
    {"instruction": "什么是高血压?", "output": "高血压是指动脉血压持续升高的状态,收缩压≥140mmHg或舒张压≥90mmHg。"},
    {"instruction": "感冒了怎么办?", "output": "感冒通常为自限性疾病,建议多休息、多喝水、保持室内通风。"},
    # ... 实际需要500-10000条
]

# 5. 训练
def tokenize_function(examples):
    texts = [f"用户:{instr}\n助理:{out}" 
             for instr, out in zip(examples["instruction"], examples["output"])]
    return tokenizer(texts, truncation=True, padding="max_length", max_length=256)

dataset = Dataset.from_list(train_data)
tokenized_dataset = dataset.map(tokenize_function, batched=True)

training_args = TrainingArguments(
    output_dir="./lora-medical",
    per_device_train_batch_size=4,
    num_train_epochs=3,
    learning_rate=2e-4,
    save_strategy="epoch",
)

trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=tokenized_dataset,
)

# 开始训练
trainer.train()

# 6. 保存LoRA权重(只有几百KB,不是整个模型)
model.save_pretrained("./lora-medical-final")
print("LoRA微调完成!权重已保存")

10.3 提示工程对比实验

# 同一个任务,不同prompt策略的效果对比

import openai  # 以OpenAI API为例

client = openai.OpenAI(api_key="your-api-key")

def test_prompt_strategy(strategy_name, system_prompt, user_prompt):
    """测试不同prompt策略的效果"""
    response = client.chat.completions.create(
        model="gpt-4.1-mini",  # 2026年性价比之选
        messages=[
            {"role": "system", "content": system_prompt},
            {"role": "user", "content": user_prompt}
        ],
        temperature=0.3
    )
    return response.choices[0].message.content

task = "用Python写一个二分查找"

# 策略1:零样本
result_0 = test_prompt_strategy(
    "零样本",
    "你是一个Python工程师。",
    f"请完成以下任务:{task}"
)
print("=== 零样本 ===")
print(result_0[:200])
print("---")

# 策略2:少样本
result_1 = test_prompt_strategy(
    "少样本",
    "你是一个Python工程师。",
    f"""参考以下示例的格式:

示例1:
任务:用Python写一个计算阶乘的函数
回答:
def factorial(n):
    if n <= 1:
        return 1
    return n * factorial(n-1)

示例2:
任务:用Python写一个判断回文的函数
回答:
def is_palindrome(s):
    return s == s[::-1]

现在完成任务:
{task}
"""
)
print("=== 少样本 ===")
print(result_1[:200])
print("---")

# 策略3:思维链
result_2 = test_prompt_strategy(
    "思维链",
    "你是一个Python工程师。在写代码前先一步步思考。",
    f"""请完成以下任务:
{task}

在写代码之前,请先思考:
1. 这个算法的输入和输出是什么?
2. 使用什么数据结构?
3. 时间复杂度和空间复杂度是多少?
4. 边界情况如何处理?

然后输出完整的代码实现。
"""
)
print("=== 思维链 ===")
print(result_2[:200])
print("---")

# 策略4:结构化Prompt
result_3 = test_prompt_strategy(
    "结构化Prompt",
    """## 角色
资深算法工程师,擅长编写高质量、健壮的代码。

## 原则
1. 代码必须包含详细的注释
2. 必须处理边界情况
3. 提供完整的使用示例
4. 分析时间复杂度和空间复杂度

## 输出格式
```python
# 代码
...

# 使用示例
...

# 复杂度分析
...
```""",
    f"## 任务\n{task}"
)
print("=== 结构化Prompt ===")
print(result_3[:200])

# 结论:不同的prompt策略,即使调用同一个模型
# 输出质量和格式也可能天差地别

10.4 自动化Prompt优化(DSPy)

# DSPy:自动优化Prompt的框架
# 安装:pip install dspy

import dspy
from dspy.datasets import HotPotQA

# 配置语言模型
lm = dspy.LM("openai/gpt-4.1-mini")
dspy.settings.configure(lm=lm)

# 定义任务签名
class GenerateAnswer(dspy.Signature):
    """根据上下文回答问题"""
    context = dspy.InputField(desc="相关文档段落")
    question = dspy.InputField(desc="用户问题")
    answer = dspy.OutputField(desc="简洁准确的回答")

# 定义程序
class RAG(dspy.Module):
    def __init__(self, num_passages=3):
        super().__init__()
        self.retrieve = dspy.Retrieve(k=num_passages)
        self.generate_answer = dspy.ChainOfThought(GenerateAnswer)
    
    def forward(self, question):
        context = self.retrieve(question).passages
        prediction = self.generate_answer(context=context, question=question)
        return dspy.Prediction(context=context, answer=prediction.answer)

# 编译优化
from dspy.teleprompt import BootstrapFewShot

def validate_context_and_answer(example, pred, trace=None):
    """验证回答质量"""
    return example.answer in pred.answer

# 自动优化:DSPy会尝试不同的prompt策略
# 选择效果最好的组合
teleprompter = BootstrapFewShot(metric=validate_context_and_answer)
compiled_rag = teleprompter.compile(RAG(), trainset=...)  

# 使用优化后的程序
prediction = compiled_rag(question="Attention机制的核心思想是什么?")
print(f"答案: {prediction.answer}")
# DSPy已经自动优化了prompt,不需要手动调prompt!

📌 总结

预训练 vs 微调 vs 提示工程 核心要点:

1️⃣ 预训练:从零学语言
   成本:数百万-$50M+
   数据:TB级无标注文本
   适用:自研基座模型
   2026年:只有少数大厂能做

2️⃣ 微调:定向专修
   成本:数百-数万美元
   数据:千-万条标注数据
   适用:领域适配、私有部署
   2026年:LoRA/QLoRA是主流

3️⃣ 提示工程:临场发挥
   成本:几乎为零
   数据:几条示例即够
   适用:快速验证、日常使用
   2026年:已框架化、自动化

4️⃣ 微调进阶路线
   SFT(2020) → 学会对话格式
   RLHF(2022) → 学会偏好回答
   DPO(2024) → 直接优化偏好

5️⃣ 决策原则
   能用提示 → 绝不微调
   能用RAG → 绝不微调
   非微调不可 → 先用LoRA试水


🔗 延伸阅读

  • 【AI基础篇01】AI大模型基础概念全景图
  • 【AI基础篇02】从Transformer到GPT:生成式AI的演进史
  • 【AI基础篇03】大模型参数、算力、数据:Scaling Law的本质
  • 【AI基础篇04】Tokenization:文本如何变成数字,为什么分词器这么重要
  • 【AI基础篇05】注意力机制:Self-Attention详解
  • 【AI基础篇06】位置编码:为什么需要它?

觉得有帮助?点赞收藏!下一篇我们讲大模型评估指标——困惑度、BLEU、ROUGE,这些指标到底在衡量什么?怎么用?有哪些坑? 🚀

标签:人工智能、大模型、预训练、微调、LoRA、提示工程、RLHF、DPO、SFT、Prompt Engineering

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐