新增内容AI 共创
AI播客:大语言模型凭什么强大?Zero-shot与Few-shot揭秘

什么是 Few-shot 和 Zero-shot Learning

---|---------|------|------|---------| | 传统训练 | 成千上万 | 准确 | 贵、慢、需要大量数据 | 专业任务 | | Few-shot | 3-10 个 | 快、灵活 | 不如专门训练准确 | 快速适配新任务 | | Zero-shot | 0 个 | 超快、超灵活 | 准确性最低 | 探索性任务 |


实际应用:

Zero-shot 场景:

  1. 翻译新语言

    • 问:"把'Hello'翻译成冰岛语"
    • AI 可能没见过这个翻译对,但能猜:"Halló"
  2. 新话题分类

    • 问:"这篇文章是关于'量子计算'还是'区块链'?"
    • AI 从没训练过这两个类别,但能通过关键词判断
  3. 通用问答

    • 问:"秦始皇哪年统一六国?"
    • AI 从没见过这个问题,但从训练数据里"知道"答案

Few-shot 场景:

  1. 客服对话

    例子1:客户说"退款" → 转接退款部门 例子2:客户说"发货慢" → 转接物流部门 例子3:客户说"质量问题" → 转接售后部门 新对话:"我的订单还没到" AI:转接物流部门
  2. 代码风格模仿

    例子1: 输入:add two numbers 输出:def add(a, b): return a + b 例子2: 输入:multiply two numbers 输出:def multiply(a, b): return a * b 新任务:subtract two numbers AI:def subtract(a, b): return a - b
  3. 写作风格模仿

    例子:鲁迅风格 "我向来是不惮以最坏的恶意来推测中国人的..." 新任务:用鲁迅风格写"现代人玩手机" AI:我向来不惮以最深的沉沦来揣度玩手机的人...

为什么大语言模型这么厉害?

传统 AI(如 2015 年前):

  • 每个任务都要专门训练(成千上万数据)
  • 换个任务 = 重新训练
  • 贵、慢、不灵活

大语言模型(GPT-3 之后):

  • 预训练阶段:读遍全网,啥都知道一点
  • Zero-shot:新任务直接上,凭"常识"猜
  • Few-shot:给几个例子,立刻学会
  • 不用重新训练!

核心原因: 大模型通过预训练学会了"学习的能力"(元学习)


提示词技巧(Prompt Engineering):

Zero-shot 写法:

直接告诉 AI 任务: "把下面这段话翻译成英文:今天天气很好"

Few-shot 写法:

先给例子,再提问: 例子1:苹果 → Apple 例子2:香蕉 → Banana 例子3:橙子 → Orange 现在翻译:葡萄

最佳实践:

  1. Zero-shot 先试 - 如果效果好,就不用给例子
  2. 不行就 Few-shot - 给 3-5 个例子
  3. 还不行就微调 - 用成千上万数据专门训练

常见误区:

误区 1:"Few-shot 比 Zero-shot 一定更准"

  • 不一定!有时候例子反而误导 AI
  • 例子质量 > 例子数量

误区 2:"给越多例子越好"

  • 不是!例子太多会"占用上下文"
  • 一般 3-5 个例子就够了
  • 超过 10 个,不如直接微调

误区 3:"Zero-shot 就是瞎猜"

  • 不是!AI 是基于预训练知识"推理"
  • 类似你从没见过"火龙果",但听名字能猜出"可能是红色的、和火有关的水果"

打个比方:

想象你是新来的服务员:

  • 传统训练:师傅带你 3 个月,教你所有菜名、价格、做法(成千上万次重复)
  • Few-shot:师傅只告诉你 3 个菜怎么点,剩下的你自己类推
  • Zero-shot:师傅啥都不教,但你见过其他餐厅,大概能猜出怎么做

说白了,Few-shot/Zero-shot 就是大语言模型的"举一反三"能力——不用专门训练,看几个例子(或不看)就能干活。这也是为什么 GPT-3/ChatGPT 这么火:终于不用每个任务都费劲巴拉训练模型了!

预计阅读时间: 10 分钟

few-shot-zero-shot

Few-shot Learning(少样本学习)和 Zero-shot Learning(零样本学习)是大型语言模型(LLM)的核心能力之一,代表了 AI 从"需要大量训练数据"到"看几个例子就能学会"的范式转变。

核心概念

传统监督学习 vs Few-shot vs Zero-shot

学习方式训练样本数训练成本泛化能力适用场景
传统监督学习数千到数百万高(需专门训练)特定任务强专业领域(医疗、金融)
Few-shot Learning1-100 个低(无需训练)快速适配新任务、小数据场景
Zero-shot Learning0 个极低广泛但浅层探索性任务、通用场景

学习范式演变

传统 AI(2010-2018): 任务 A → 收集 10,000 样本 → 训练模型 A 任务 B → 收集 10,000 样本 → 训练模型 B (每个任务都需要独立训练) 大语言模型时代(2020+): 预训练一个大模型(读遍全网) ↓ 任务 A → Zero-shot 直接做 任务 B → Few-shot(给 5 个例子) 任务 C → 微调(给 1000 个例子) (一个模型搞定所有任务!)

Zero-shot Learning(零样本学习)

定义

没有任何任务示例的情况下,仅通过任务描述(自然语言指令)完成任务。

工作原理

用户输入(Prompt): "将下面的句子翻译成法语:I love you." 模型内部推理: 1. 识别任务:翻译(英语 → 法语) 2. 调用预训练知识:法语中"爱"的表达是"aime" 3. 生成输出:Je t'aime.

关键: 模型从未见过这个具体翻译任务,但通过预训练学到了:

  • 什么是翻译
  • 英语和法语的词汇、语法
  • 如何理解"将...翻译成..."的指令

实际案例

案例 1:情感分析

Prompt: 判断下面句子的情感(正面/负面): "This movie is terrible!" 模型输出: 负面

解析:

  • 模型从未见过这个具体句子
  • 但知道"terrible"是负面词汇
  • 因此推断出情感

案例 2:文本分类

Prompt: 将下面的新闻分类(体育/科技/娱乐): "苹果公司发布新款 iPhone" 模型输出: 科技

案例 3:问答

Prompt: 问:秦始皇哪年统一六国? 答: 模型输出: 公元前 221 年

解析:

  • 这个具体问题可能没在训练数据中出现
  • 但模型在预训练时"读到"过相关历史知识
  • 通过推理给出答案

Zero-shot 的局限性

问题 1:准确性有限

Prompt: 判断下面句子是否有语法错误: "She don't like apples." 模型输出: 有错误(don't 应改为 doesn't)

✅ 简单任务表现好

Prompt: 判断下面医学报告是否提示癌症风险: [复杂的医学术语...] 模型输出: (可能出错,因为缺乏专业训练)

❌ 专业任务容易出错

问题 2:格式不稳定

Prompt: 提取文本中的人名: "张三和李四去了北京。" 可能输出: - "张三, 李四"(理想) - "张三和李四"(多了"和") - "文本中的人名有张三和李四"(格式不对)

Few-shot Learning(少样本学习)

定义

通过在提示词中提供少量示例(通常 1-10 个),让模型快速学会任务模式。

工作原理

提示词结构: [示例1] 输入 → 输出 [示例2] 输入 → 输出 [示例3] 输入 → 输出 ... [新任务] 输入 → ? 模型推理: 观察示例的模式 ↓ 应用到新任务 ↓ 生成输出

实际案例

案例 1:情感分析(3-shot)

Prompt: 判断句子情感: 例子1: 句子:I love this product! 情感:正面 例子2: 句子:Worst purchase ever. 情感:负面 例子3: 句子:It's okay, nothing special. 情感:中性 现在判断: 句子:Amazing quality and fast shipping! 情感: 模型输出: 正面

案例 2:代码生成(2-shot)

Prompt: 根据描述生成 Python 函数: 示例1: 描述:计算两个数的和 代码: def add(a, b): return a + b 示例2: 描述:计算两个数的乘积 代码: def multiply(a, b): return a * b 现在生成: 描述:计算两个数的差 代码: 模型输出: def subtract(a, b): return a - b

案例 3:格式转换(1-shot)

Prompt: 将 JSON 转为 YAML: 示例: JSON: {"name": "Alice", "age": 30} YAML: name: Alice age: 30 现在转换: JSON: {"city": "Beijing", "country": "China"} YAML: 模型输出: city: Beijing country: China

Few-shot vs Zero-shot 对比实验

任务: 提取句子中的地名

Zero-shot:

Prompt: 提取句子中的地名: "我昨天去了北京和上海。" 输出(不稳定): - 可能:北京, 上海 - 可能:北京和上海 - 可能:句子中提到了北京和上海两个城市

Few-shot(3-shot):

Prompt: 提取句子中的地名: 例子1: 句子:我去了杭州。 地名:杭州 例子2: 句子:他住在纽约和洛杉矶。 地名:纽约, 洛杉矶 例子3: 句子:这里是中国的首都。 地名:(无) 现在提取: 句子:我昨天去了北京和上海。 地名: 输出(稳定): 北京, 上海

结论: Few-shot 的格式一致性准确性显著提升。

One-shot Learning(单样本学习)

Few-shot 的特殊情况:只给一个示例

案例:风格模仿

Prompt: 模仿下面的写作风格: 示例: 原文:今天天气很好。 改写:今日阳光明媚,天气甚佳。 现在改写: 原文:我很开心。 改写: 模型输出: 吾心甚悦。

提示词工程(Prompt Engineering)

基本格式

Zero-shot 格式:

[任务指令] [输入内容]

Few-shot 格式:

[任务指令] [示例1] [示例2] [示例3] ... [新任务输入]

最佳实践

1. 示例质量 > 数量

❌ 差示例(质量低):

例子1:好 → Good 例子2:坏 → Bad 例子3:高兴 → Happy 例子4:伤心 → Sad 例子5:美丽 → Beautiful (5 个例子,但都太简单) 任务:翻译"锲而不舍" 输出:(可能翻译不准,因为例子太简单)

✅ 好示例(质量高):

例子1:锲而不舍 → Perseverance 例子2:一丝不苟 → Meticulous 例子3:鞠躬尽瘁 → Dedicated 任务:翻译"胸有成竹" 输出:Confident(更准确)

2. 示例多样性

❌ 单一类型:

例子1:我爱你 → I love you 例子2:他爱她 → He loves her 例子3:我们爱祖国 → We love our country (都是"爱"的句型)

✅ 多样化:

例子1:我爱你 → I love you(情感) 例子2:今天下雨 → It's raining today(天气) 例子3:他在工作 → He is working(状态) (覆盖不同句型)

3. 分隔符清晰

❌ 格式混乱:

翻译:苹果 Apple 香蕉 Banana 橙子 Orange 现在翻译葡萄 (模型可能看不懂哪里是示例、哪里是任务)

✅ 格式清晰:

任务:中英翻译 示例1: 中文:苹果 英文:Apple 示例2: 中文:香蕉 英文:Banana 现在翻译: 中文:葡萄 英文:

4. 控制示例数量

示例数效果成本适用场景
0(Zero-shot)不稳定最低简单任务、探索
1-3(Few-shot)较好常规任务
5-10很好中等复杂任务
>10提升有限高(占用上下文)不推荐,改用微调

原因: 超过 10 个示例后,性能提升边际递减,且浪费上下文窗口。

In-Context Learning(上下文学习)

Few-shot/Zero-shot 的底层机制。

定义

模型通过"上下文"(提示词中的示例)学习任务,而无需更新参数

与传统学习的对比

传统微调(Fine-tuning):

收集 1000 个训练样本 ↓ 训练模型(更新参数) ↓ 模型学会新任务

In-Context Learning:

在提示词中放 3 个示例 ↓ 模型读取示例(不更新参数) ↓ 模型"理解"任务并执行

为什么有效?

理论解释:

  1. 元学习(Meta-Learning): 模型在预训练时学会了"如何学习"
  2. 模式匹配: 模型识别示例中的模式并应用到新输入
  3. 隐式微调: 模型在前向传播中"临时适配"任务

实验证据(GPT-3 论文):

  • 模型规模越大,In-Context Learning 能力越强
  • GPT-3(175B)的 Few-shot 性能接近甚至超过某些专门微调的小模型

Few-shot vs 微调(Fine-tuning)

维度Few-shot微调
训练样本1-1001,000-1,000,000
是否更新参数
成本极低(几次 API 调用)高(GPU + 时间)
性能中等高(专业任务)
灵活性高(随时换任务)低(每次换任务要重新训练)
适用场景快速原型、探索生产环境、专业领域

决策树

需要新任务? ↓ 数据 < 100 条? ↓ 是 先试 Zero-shot ↓ 效果不好? ↓ 是 试 Few-shot(3-10 个示例) ↓ 还不够好? ↓ 是 收集更多数据(1000+ 条)→ 微调 数据 > 1000 条? ↓ 是 直接微调

实际应用案例

案例 1:客服自动分类(Few-shot)

prompt = """
将客户问题分类(退款/物流/产品/其他):

示例1:
问题:我要退款
分类:退款

示例2:
问题:订单什么时候发货?
分类:物流

示例3:
问题:这个产品是什么材质?
分类:产品

现在分类:
问题:我的订单还没到
分类:
"""

# 调用模型
response = model.generate(prompt)
# 输出:物流

案例 2:数据格式转换(One-shot)

prompt = """
将用户信息转为 JSON 格式:

示例:
输入:姓名张三,年龄25,城市北京
输出:{"name": "张三", "age": 25, "city": "北京"}

现在转换:
输入:姓名李四,年龄30,城市上海
输出:
"""

# 输出:{"name": "李四", "age": 30, "city": "上海"}

案例 3:代码注释生成(Zero-shot)

prompt = """
为下面的代码添加注释:

def fibonacci(n):
    if n <= 1:
        return n
    return fibonacci(n-1) + fibonacci(n-2)
"""

# 输出:
# 计算斐波那契数列的第 n 项
# 参数 n: 项数
# 返回值: 第 n 项的值
# 使用递归实现

常见问题

Q: Few-shot 能完全替代微调吗?

A: 不能。对于专业领域(医疗、法律)或需要极高准确性的任务,微调仍然必要。

Q: 为什么有时候 Zero-shot 比 Few-shot 效果还好?

A: 可能原因:

  1. 示例质量差,误导了模型
  2. 任务太简单,Zero-shot 已经足够
  3. 示例与测试数据分布不一致

Q: 如何选择示例?

A: 最佳实践:

  1. 覆盖不同情况(多样性)
  2. 难度适中(不要太简单或太复杂)
  3. 格式清晰(明确输入-输出对应关系)

Q: 中文和英文的 Few-shot 效果有差异吗?

A: 有一定差异:

  • 英文:大多数模型训练数据以英文为主,英文效果通常更好
  • 中文:需要更多示例或更明确的指令
  • 建议:中文任务给 5 个示例,英文任务 3 个可能就够

参考资料