Transformers框架进行意图分类和实体抽取的处理流程
一.首先需要的标准训练数据结构
{
"意图名称": [{
"text": "训练语句(其中包含需要抽取的实体)",
"entities": [{
"value": "训练语句中的实体值",
"entity": "实体名称",
"start": "实体在训练语句中的开始坐标",
"end": "实体在训练语句中的结束坐标"
}]
}]
}
例如:
{
"product_search": [{
"text": "蓝医保百万医疗可以保100万保额吗",
"entities": [{
"value": "蓝医保",
"entity": "product",
"start": 0,
"end": 3
},
{
"value": "100万",
"entity": "coverage",
"start": 10,
"end": 14
}
]
}]
}
二.准备模型意图识别数据
需要给模型的数据结构:
DataFrame形式的数据:
| text | label | label_id |
|------------|----------------|----------|
| 我要订机票 | book_flight | 0 |
| 帮我查天气 | check_weather | 1 |
-
DataFrame 是 Python Pandas 库里的二维表格数据结构
-
本质是 带行列索引的表格
-
支持:
-
列名(column names)
-
行索引(row index)
-
对行/列切片、过滤、统计等操作
-
标签映射: 分别是文本对应的数字ID和数字ID对应的文本
在训练时,模型用 数字 id 来计算 loss
用于预测结果,模型输出的是数字id,需要转换回文本
def prepare_intent_data(examples):
"""准备意图识别数据"""
intent_data = []
for example in examples:
intent_data.append({
'text': example['text'],
'label': example['intent']
})
df = pd.DataFrame(intent_data)
# 构建标签映射
labels = sorted(df['label'].unique())
label2id = {label: idx for idx, label in enumerate(labels)}
id2label = {idx: label for label, idx in label2id.items()}
df['label_id'] = df['label'].map(label2id)
return df, label2id, id2label
三.使用 Hugging Face datasets 库将 DataFrame 转换为 Dataset 对象
dataset = Dataset.from_pandas(intent_df[['text', 'label_id']])
只保留 text 和 label_id 两列,用于训练
Dataset 优势:高效处理大规模数据,并可直接与 Trainer 结合
四.初始化tokenizer进行数据分词
tokenizer = AutoTokenizer.from_pretrained('hfl/chinese-roberta-wwm-ext')
使用 AutoTokenizer 加载指定模型的分词器(tokenizer)
处理流程:
①文本标准化: 去掉空格符号
②分词:根据模型分词算法,切分语句变成单个字
③每个 token 在模型词表里有一个 唯一 ID,类似数据库主键。
④生成输入张量:
input_ids(数字 ID 序列):就是对应的唯一数字ID序列
attention_mask:标记哪些是真实 token,哪些是补齐 [PAD]
token_type_ids:区分句子 A / 句子 B(句对任务)
为什么这么处理:
神经网络只能处理数字
压缩词表
覆盖率(即使出现新词,也能拆成已知子词)
Tokenizer = 分词算法 + 词表查找
文本被拆成最小可表示的 token,然后在词表里找到对应的 ID,拼成模型能理解的数字序列。
五.预处理数据变成dataset
# 预处理数据
def preprocess_intent(examples):
return tokenizer(
examples['text'],
truncation=True,
padding='max_length',
max_length=args.max_length
)
encoded_dataset = dataset.map(preprocess_intent, batched=True)
encoded_dataset = encoded_dataset.rename_column('label_id', 'labels')
-
preprocess_intent函数: 因为模型输入的张量需要具有同一的矩形形状,所以需要处理过长和过短的语句,把过长的语句拆分成短语句,过短的语句填充数字0
-
dataset.map()将分词函数应用到 Dataset -
batched=True表示一次处理一批数据,效率更高 -
rename_column将label_id改名为labels,因为 Hugging Face 模型训练时默认标签列名是labels
此时数据集可以直接用于模型训练
六.初始化模型
# 初始化模型
model = AutoModelForSequenceClassification.from_pretrained(
'hfl/chinese-roberta-wwm-ext',
num_labels=len(intent_label2id),
id2label=intent_id2label,
label2id=intent_label2id
)
AutoModelForSequenceClassification 自动加载对应 Transformer 模型并加分类头
参数分别是: 模型名称,分类数量,id对应文本的映射,文本对应id的映射
1.AutoModelForSequenceClassification作用是: 文本分类
2.AutoModelForTokenClassification作用是: 关键词抽取
3.其他常见的处理头任务模型类
| 模型类 | 主要用途 | 说明 |
|---|---|---|
| AutoModelForMaskedLM | 掩码语言建模 (MLM) | 预训练/微调 BERT 类模型 |
| AutoModelForCausalLM | 自回归语言建模 | GPT 系列,文本生成 |
| AutoModelForQuestionAnswering | 抽取式问答 | 预测答案在文本中的起止位置 |
| AutoModelForSeq2SeqLM | 序列到序列任务 | 翻译、摘要(BART、T5) |
| AutoModelForMultipleChoice | 多选题任务 | 例如 RACE 数据集,给多个选项,选择最佳答案 |
七.训练参数设置
# 训练参数 - 🚀 优化为更好的置信度
training_args = TrainingArguments(
output_dir=args.intent_output,
num_train_epochs=10, # 🔧 增加训练轮数:5 → 10
per_device_train_batch_size=4, # 🔧 减小批次让学习更精细:8 → 4
per_device_eval_batch_size=4,
learning_rate=2e-5, # 🔧 降低学习率:默认5e-5 → 2e-5
warmup_steps=50, # 🔧 调整预热步数
weight_decay=0.01,
logging_dir=f"{args.intent_output}/logs",
logging_steps=10,
save_steps=500,
save_total_limit=2,
load_best_model_at_end=False,
)
TrainingArguments 用于定义训练细节:
-
output_dir:保存模型路径 -
num_train_epochs:训练轮数 -
per_device_train_batch_size/eval_batch_size:训练和评估批量大小 -
learning_rate:学习率 -
warmup_steps:预热步数(学习率从小到大) -
weight_decay:权重衰减(防止过拟合) -
logging_dir、logging_steps:日志记录 -
save_steps、save_total_limit:保存模型策略
八.自定义评估函数
# 评估函数
def compute_intent_metrics(eval_pred):
predictions, labels = eval_pred
predictions = torch.argmax(torch.tensor(predictions), dim=-1)
precision, recall, f1, _ = precision_recall_fscore_support(labels, predictions, average='weighted')
accuracy = accuracy_score(labels, predictions)
return {
'accuracy': accuracy,
'f1': f1,
'precision': precision,
'recall': recall
}
自定义评估函数:
-
将模型输出 logits 转换为预测类别
torch.argmax -
使用 sklearn 计算准确率、精确率、召回率、F1
-
返回字典,Trainer 在训练/验证时会打印这些指标
九.创建训练器并且开始训练
# 创建训练器
trainer = Trainer(
model=model,
args=training_args,
train_dataset=encoded_dataset,
tokenizer=tokenizer,
compute_metrics=compute_intent_metrics,
)
# 开始训练
trainer.train()
-
使用 Hugging Face Trainer API 创建训练器
-
参数说明:
-
model:训练的模型,第6步处理化好的模型 -
args:第7步函数定义的训练参数 -
train_dataset:训练数据(第5步预处理成dataset) -
tokenizer:用于数据预处理(第4步处理的tokenizer) -
compute_metrics:自定义评估函数(第8步定义的评估函数)
-
-
如果是实体抽取还需要DataCollator
-
意图分类 → 分类的label 是一个整数,不需要 collator。
-
序列标注(NER、关键字抽取) → 实体的label 是一个序列,要和输入一起 pad,对齐逻辑复杂 → 必须用
DataCollatorForTokenClassification。
十.保存训练好的模型到指定目录
# 保存模型
model.save_pretrained(args.intent_output)
tokenizer.save_pretrained(args.intent_output)
-
将训练好的模型和 tokenizer 保存到指定目录
-
后续可以直接
from_pretrained加载
十一.训练总结
1.准备好训练数据: 意图,对应意图的多组训练数据,包括训练数据上的实体标注
2.处理训练数据:
①将训练数据转为DataFrame形式数据,表格形式为: 意图id,意图名称,意图对应的训练数据,
然后下一步利用transformers的函数将DataFrame数据转为dataset形式数据
②把所有的意图标签,转为两种数据结构,一种是数字id一定的标签名称,一种是标签名称对应的数字id
3.初始化模型: 将要预训练的模型和上一步处理的训练数据, 意图标签于id的映射关系初始化
4.初始化预训练模型的tokenizer和准备模型的训练参数,包括评估函数
5.初始化训练器,参数需要初始化的模型,训练参数,训练数据dataset,预训练模型的tokenizer,评估函数
6.直接运行train函数开始训练完成后,保存训练好的模型
十二.使用训练好的模型进行意图分类和实体抽取
1.初始化意图识别和实体抽取模型
##意图识别
self.intent_pipe = pipeline("text-classification", model=intent_model_path)
##实体抽取
self.ner_pipe = pipeline("ner", model=ner_model_path, grouped_entities=True)
使用Hugging Face Transformers 提供的 pipeline 高层 API
text-classification: 是pipeline 任务类型做文本分类的
ner: 是命名实体识别、关键词抽取、序列标注
model: 指定你加载的 NER 模型路径(可以是本地文件夹,也可以是 Hugging Face Hub 上的模型名称)
grouped_entities=True,就会把相邻的同一类标签合并
2.识别用户输出的语句
##意图识别
result = self.intent_pipe(text)
##实体抽取
results = self.ner_pipe(text)
1882

被折叠的 条评论
为什么被折叠?



