意图分类策略选择:小模型微调 vs 大模型 Prompt

发布于:2025-06-11 ⋅ 阅读:(57) ⋅ 点赞:(0)

在处理意图分类任务时,选择「大模型 Prompt」还是「小模型微调」确实取决于意图类别的数量和数据规模。我来详细解释这个决策逻辑,并提供具体实现方案。

一、决策逻辑与适用场景

场景 意图数量 单意图样本量 推荐方案 理由
少量意图(<20) 10-20 100+ 大模型 Few-Shot Prompt 大模型(如 GPT-4)已具备基础语义理解能力,Few-Shot 即可快速适配小类别
中等意图(20-100) 20-100 50+ 大模型 Zero-Shot + 后处理 将意图列表写入 Prompt,让模型直接分类,但需处理边界情况和误分类
大量意图(100+) 100-500 20+ BERT 类模型微调 大模型 Prompt 长度受限(如 GPT-4 约 8k tokens),且 Few-Shot 成本高
超大量意图(500+) 500+ 10+ 混合架构(检索 + 分类) 先通过检索筛选候选意图,再用模型分类,或使用分层分类器

二、具体实现方案

方案 1:大模型 Few-Shot Prompt(少量意图)

python

运行

import openai

def large_model_intent_classification(user_input, intent_list, few_shot_examples=None):
    # 构建Prompt
    prompt = f"""
    你是一个智能助手,擅长识别用户意图。请根据用户输入,从以下意图列表中选择最匹配的意图:
    意图列表:{', '.join(intent_list)}
    
    {'示例:' + few_shot_examples if few_shot_examples else ''}
    
    用户输入:{user_input}
    匹配意图:
    """
    
    # 调用大模型
    response = openai.ChatCompletion.create(
        model="gpt-4",
        messages=[{"role": "user", "content": prompt}]
    )
    
    return response.choices[0].message.content.strip()

# 使用示例
intent_list = ["旅游推荐", "景点查询", "预算询问", "天数询问", "再见"]
few_shot_examples = """
用户输入:推荐一些北京的景点
匹配意图:旅游推荐

用户输入:故宫门票多少钱?
匹配意图:景点查询
"""

user_input = "三天假期适合去哪里玩?"
predicted_intent = large_model_intent_classification(user_input, intent_list, few_shot_examples)
print(f"预测意图:{predicted_intent}")
方案 2:BERT 模型微调(大量意图)

python

运行

from transformers import BertTokenizer, BertForSequenceClassification, Trainer, TrainingArguments
from datasets import Dataset
import pandas as pd

# 加载数据(假设CSV文件包含text和label列)
df = pd.read_csv("intent_data.csv")
dataset = Dataset.from_pandas(df)

# 加载分词器和模型
tokenizer = BertTokenizer.from_pretrained("bert-base-chinese")
model = BertForSequenceClassification.from_pretrained(
    "bert-base-chinese", 
    num_labels=len(intent_list),  # 意图类别数量
    id2label={i: intent for i, intent in enumerate(intent_list)},
    label2id={intent: i for i, intent in enumerate(intent_list)}
)

# 预处理数据
def preprocess_function(examples):
    return tokenizer(examples["text"], truncation=True, padding="max_length", max_length=128)

tokenized_dataset = dataset.map(preprocess_function, batched=True)

# 定义训练参数
training_args = TrainingArguments(
    output_dir="./results",
    learning_rate=2e-5,
    per_device_train_batch_size=16,
    per_device_eval_batch_size=16,
    num_train_epochs=3,
    weight_decay=0.01,
)

# 创建训练器
trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=tokenized_dataset,
)

# 训练模型
trainer.train()

# 保存模型
model.save_pretrained("./intent_model")

# 预测函数
def bert_intent_classification(text, model, tokenizer, intent_list):
    inputs = tokenizer(text, return_tensors="pt")
    outputs = model(**inputs)
    logits = outputs.logits
    predicted_class_id = logits.argmax().item()
    return intent_list[predicted_class_id]

三、混合方案:大模型 + 小模型协同

当意图类别数量中等(50-200)且数据有限时,可以结合两种方案的优势:

python

运行

class HybridIntentClassifier:
    def __init__(self, large_model_threshold=0.8, bert_model_path=None):
        self.large_model_threshold = large_model_threshold
        self.intent_list = []
        
        # 初始化大模型
        self.large_model = None  # 如GPT-4
        
        # 初始化BERT模型
        if bert_model_path:
            self.bert_tokenizer = BertTokenizer.from_pretrained("bert-base-chinese")
            self.bert_model = BertForSequenceClassification.from_pretrained(bert_model_path)
        else:
            self.bert_model = None
    
    def add_intents(self, intents):
        self.intent_list = intents
    
    def classify(self, user_input):
        # 1. 优先使用大模型预测
        large_model_prediction = self._predict_with_large_model(user_input)
        
        # 2. 如果大模型置信度高,直接返回结果
        if large_model_prediction["confidence"] > self.large_model_threshold:
            return large_model_prediction
        
        # 3. 否则使用BERT模型预测
        if self.bert_model:
            bert_prediction = self._predict_with_bert(user_input)
            return bert_prediction
        
        # 4. 如果没有BERT模型,返回大模型结果(即使置信度低)
        return large_model_prediction
    
    def _predict_with_large_model(self, user_input):
        # 调用大模型并获取预测结果和置信度
        # (实际实现需根据大模型API调整)
        pass
    
    def _predict_with_bert(self, user_input):
        # 调用BERT模型进行预测
        pass

四、优化策略

  1. 意图聚类分层

    • 将 500 个意图分为 20 个大类,先通过大模型分类到大类,再用小模型细分到具体意图
  2. 动态 Prompt 优化

    • 对频繁出现的意图,在 Prompt 中增加示例
    • 使用 Embedding 相似度筛选最相关的 Few-Shot 示例
  3. 成本控制

    • 对简单意图(如问候)使用规则引擎
    • 仅对复杂或新用户请求调用大模型

五、决策流程图

plaintext

意图数量 < 20?
├─ 是 → 使用大模型Few-Shot
└─ 否 → 数据量充足(单意图>50)?
   ├─ 是 → 训练BERT类模型
   └─ 否 → 使用大模型Zero-Shot + 后处理

总结

  • 小批量意图(<20):大模型 Prompt 简单高效,无需训练
  • 中等批量意图(20-100):大模型 Zero-Shot + 人工修正边界情况
  • 大批量意图(100+):必须使用 BERT 等小模型微调,避免 Prompt 过长导致的成本和性能问题

实际应用中,建议先从大模型 Prompt 快速验证,随着意图数量和数据量增长,逐步过渡到混合架构或纯小模型方案。