【自然语言处理】“bert-base-chinese”的基本用法及实战案例
目录
一、引言
二、基础用法:模型加载与分词
(一)核心库与工具
(二)代码分步解析
1. 下载模型到本地
2. 加载分词器(文本→模型输入格式转换)
3. 加载 BERT 基础模型(特征提取核心)
4. 示例文本处理与特征提取
5. 模型推理与特征获取
(三)整体作用与应用场景
(四)Python代码完整实现
三、文本情感的二分类(积极/消极)
1. 结果目录管理
2. BERT 模型与分词器加载
3. 本地数据集加载
4. 数据预处理
5. 训练参数配置(适配 CPU 环境)
6. 模型训练
7. 情感分类推理验证
8.整体作用
9.Python代码完整展示
四、总结
一、引言
BERT-base-chinese是由Google和HuggingFace团队开发的中文预训练模型,基于BERT架构在大规模中文语料上训练而成。该模型包含12层Transformer编码器,768维隐藏层,12个注意力头,总参数约110M。适用于各类中文自然语言处理任务,如文本分类、命名实体识别、问答系统等。本文讲述的“bert-base-chinese”是从 ModelScope 平台下载中文 BERT 模型,并用它提取文本的上下文特征,是基于 BERT 进行自然语言处理(NLP)任务的基础流程。下面讲解“bert-base-chinese”的基本用法与情感分类,以及Python代码完整实现。
二、基础用法:模型加载与分词
(一)核心库与工具
transformers
库:Hugging Face 开发的 NLP 工具库,提供了 BERT 等预训练模型的分词器(BertTokenizer
)和基础模型(BertModel
),简化模型加载和文本处理流程。modelscope
库:阿里达摩院推出的模型平台,snapshot_download
函数用于从 ModelScope 下载模型到本地(类似 Hugging Face 的from_pretrained
,但针对 ModelScope 平台的模型)。
(二)代码分步解析
1. 下载模型到本地
model_dir = snapshot_download('tiansz/bert-base-chinese')
- 功能:从 ModelScope 平台下载第三方维护的中文 BERT 模型(
tiansz/bert-base-chinese
),并返回模型在本地的存储路径(如~/.cache/modelscope/hub/tiansz/bert-base-chinese
)。 - 说明:
tiansz/bert-base-chinese
是基于原版 BERT 的中文预训练模型,适用于通用中文 NLP 任务(如文本分类、特征提取等)。
2. 加载分词器(文本→模型输入格式转换)
tokenizer = BertTokenizer.from_pretrained(model_dir)
- 功能:加载 BERT 专用分词器,负责将原始文本转换为模型可接受的输入格式。
- 核心作用:
- 分词:将中文文本拆分为 BERT 能理解的 “子词(subword)”(如 “自然语言” 可能拆分为 “自”“然”“语”“言”);
- 编码:将每个子词映射为对应的数字 ID(如 “我”→100);
- 添加特殊符号:自动添加
[CLS]
(句首标记,用于整体文本特征)和[SEP]
(句尾标记); - 生成辅助信息:如注意力掩码(
attention_mask
,标记有效 token)。
3. 加载 BERT 基础模型(特征提取核心)
model = BertModel.from_pretrained(model_dir)
- 功能:加载 BERT 的基础预训练模型(仅用于特征提取,不含下游任务头)。
- 说明:BERT 模型的核心是 “双向 Transformer”,能通过预训练学习到文本的上下文语义特征。
BertModel
输出的是文本中每个 token 的上下文表示(隐藏状态),可用于后续 NLP 任务(如分类、命名实体识别等)。
4. 示例文本处理与特征提取
text = '我爱自然语言处理'
inputs = tokenizer(text, return_tensors='pt', padding=True, truncation=True)
- 功能:用分词器处理示例文本,生成模型输入。
- 参数说明:
return_tensors='pt'
:返回 PyTorch 张量(若需 TensorFlow 张量用'tf'
);padding=True
:当输入文本长度不足时,用[PAD]
填充至批次最长文本长度(此处单句文本,无实际填充);truncation=True
:当文本长度超过模型最大限制(BERT 默认 512token)时,截断多余部分。
- 输出
inputs
包含:input_ids
:token 的数字编码;attention_mask
:1 表示有效 token,0 表示[PAD]
(此处全为 1);token_type_ids
:单句文本全为 0(句对任务用于区分第一 / 二句)。
5. 模型推理与特征获取
outputs = model(**inputs)
last_hidden_state = outputs.last_hidden_state
print(f'输出形状:{last_hidden_state}')
- 功能:将处理后的输入传入 BERT 模型,获取输出特征。
- 输出解析:
outputs
是模型输出的封装对象,包含多层隐藏状态,核心是last_hidden_state
(最后一层 Transformer 的输出);last_hidden_state
的形状为[batch_size, sequence_length, hidden_size]
:batch_size
:样本数量(此处为 1);sequence_length
:文本转换后的 token 数量(含[CLS]
和[SEP]
,如 “我爱自然语言处理” 可能对应 8 个 token);hidden_size
:每个 token 的特征维度(BERT-base 为 768);
- 含义:每个位置的向量是对应 token 的 “上下文语义特征”(如
last_hidden_state[0, 1]
是 “我” 的上下文表示,融合了前后文信息)。
(三)整体作用与应用场景
这段代码实现了 文本→BERT 上下文特征” 的转换 ,是 NLP 任务的基础模块。获取的last_hidden_state
可用于:
- 文本分类(取
[CLS]
位置的特征作为文本整体表示); - 命名实体识别(用每个 token 的特征预测实体标签);
- 语义相似度计算(用文本特征向量计算余弦相似度)等。
(四)Python代码完整实现
from transformers import BertTokenizer, BertModel
from modelscope.hub.snapshot_download import snapshot_download# 下载模型,返回本地存储路径
model_dir = snapshot_download('tiansz/bert-base-chinese')# 加载分词器
tokenizer = BertTokenizer.from_pretrained(model_dir)# 加载基础模型(用于特征提取)
model = BertModel.from_pretrained(model_dir)# 示例文本处理
text = '我爱自然语言处理'
inputs = tokenizer(text, return_tensors='pt', padding=True, truncation=True)
outputs = model(**inputs)# 获取最后一层隐藏状态
last_hidden_state = outputs.last_hidden_state
print(f'输出形状:{last_hidden_state}')
程序运行结果如下:
输出形状:tensor([[[-3.1871e-01, -1.4261e-01, -2.1352e-01, ..., 2.9723e-01,
2.2834e-01, -2.9380e-01],
[ 6.7322e-01, 1.2139e-01, 3.0185e-01, ..., -1.1036e+00,
-4.9975e-02, 8.7921e-02],
[ 3.6870e-01, -5.3108e-01, -6.8611e-01, ..., 1.9168e-01,
-1.7675e-02, -2.7852e-01],
...,
[-4.4902e-04, -1.3693e-01, 1.2886e+00, ..., -6.4702e-02,
-3.4146e-01, -1.6366e-01],
[ 6.7370e-01, 7.9813e-01, 6.0917e-02, ..., -3.2120e-01,
2.8577e-01, -1.1626e-01],
[ 3.5677e-01, -3.3870e-01, 1.3571e+00, ..., 4.6651e-01,
-7.7460e-03, 1.9304e-01]]], grad_fn=<NativeLayerNormBackward0>)
三、文本情感的二分类(积极/消极)
1. 结果目录管理
- 功能:在桌面创建
sentiment_results
目录,用于存储训练产生的模型、日志等结果。 - 细节:若目录 / 文件已存在,会先强制删除 / 清空旧内容,避免新旧结果冲突,确保训练环境 “干净”。
2. BERT 模型与分词器加载
- 模型下载:通过
modelscope
的snapshot_download
从 ModelScope 平台下载中文 BERT 预训练模型(tiansz/bert-base-chinese
),获取模型在本地的存储路径。 - 分词器加载:用
BertTokenizer.from_pretrained
加载与模型配套的分词器,负责将中文文本拆分为 BERT 能识别的 “子词(subword)”,并编码为数字 ID。 - 分类模型加载:用
BertForSequenceClassification.from_pretrained
加载 “带序列分类头” 的 BERT 模型,指定num_labels=2
(对应 “积极 / 消极” 二分类);ignore_mismatched_sizes=True
用于兼容模型参数可能的微小不匹配。
3. 本地数据集加载
- 功能:通过
datasets.load_dataset
加载本地 CSV 格式的数据集,包含train
(训练集)、test
(测试集)、validation
(验证集)三个子集。 - 细节:指定编码为
utf-8
确保中文正常读取;加载后打印各子集样本数与训练集示例,验证数据完整性。
4. 数据预处理
- 功能:将原始文本转换为 BERT 模型可直接输入的格式。
- 过程:定义
preprocess_function
函数,对文本执行:- 截断 / 填充:将文本统一处理为长度 128 的序列(文本过长则截断,过短则用
[PAD]
填充); - 标签转换:将文本标签转为整数类型(模型需要数值型标签);
- 批量处理:通过
dataset.map
对整个数据集批量执行预处理,提升效率。
- 截断 / 填充:将文本统一处理为长度 128 的序列(文本过长则截断,过短则用
5. 训练参数配置(适配 CPU 环境)
- 功能:通过
TrainingArguments
配置训练参数,让训练在 CPU 上稳定运行:output_dir
:指定模型、日志的保存路径(即桌面的sentiment_results
);num_train_epochs=3
:训练 3 轮,平衡效果与时间成本;per_device_train_batch_size=4
/per_device_eval_batch_size=4
:因 CPU 内存有限,设置小批量避免内存溢出;eval_strategy="epoch"
/save_strategy="epoch"
:每轮训练结束后做验证、保存模型,方便追踪训练过程;logging_strategy="no"
/report_to=[]
:禁用日志和可视化报告(如 TensorBoard),减少 CPU 资源消耗;load_best_model_at_end=True
:训练结束后,自动加载 “验证集表现最优” 的模型,提升最终效果。
6. 模型训练
- 功能:通过
Trainer
启动训练流程。 - 细节:传入模型、训练参数、训练集和测试集后,调用
trainer.train()
开始训练。因使用 CPU,训练速度较慢(约 5 - 10 分钟),但可在无 GPU 环境下完成。
7. 情感分类推理验证
- 功能:用训练好的模型对示例文本做情感预测,验证模型效果。
- 过程:对 3 条示例文本(正面、负面、中性偏负面):
- 用分词器处理文本,生成模型输入张量;
- 模型前向传播得到
logits
(类别得分); - 取
logits
最大值的索引,映射为 “积极” 或 “消极” 标签并输出。
8.整体作用
这套代码无需 GPU,纯 CPU 即可完成中文文本情感二分类任务的全流程(数据准备→模型训练→效果验证),适合 NLP 入门或在无 GPU 环境下快速验证 BERT 模型的情感分析能力。
9.Python代码完整展示
import os
import torch
import shutil
from transformers import (BertForSequenceClassification,Trainer,TrainingArguments,BertTokenizer # 删掉重复的 TrainingArguments 导入
)
from modelscope.hub.snapshot_download import snapshot_download
from datasets import load_dataset# -------------------------- 1. 桌面路径创建(权限无问题)+ 清理冲突 --------------------------
output_dir = os.path.join(os.path.expanduser("~"), "Desktop", "sentiment_results")
# 强制删除同名文件/清空旧目录
if os.path.exists(output_dir):if os.path.isfile(output_dir):os.remove(output_dir)print(f"删除同名文件:{output_dir}")else:shutil.rmtree(output_dir, ignore_errors=True)print(f"清空旧目录:{output_dir}")
# 重新创建目录
os.makedirs(output_dir, exist_ok=True)
print(f"✅ 模型保存目录:{output_dir}")# -------------------------- 2. 下载BERT模型(国内源稳定) --------------------------
model_dir = snapshot_download('tiansz/bert-base-chinese')# -------------------------- 3. 加载分词器和模型 --------------------------
tokenizer = BertTokenizer.from_pretrained(model_dir)
model = BertForSequenceClassification.from_pretrained(model_dir,num_labels=2,ignore_mismatched_sizes=True
)# -------------------------- 4. 加载本地数据集 --------------------------
dataset = load_dataset("csv",data_files={"train": "./train.csv","test": "./test.csv","validation": "./valid.csv"},encoding="utf-8"
)
print("\n📊 数据集加载成功:")
print(f"训练集条数:{len(dataset['train'])}")
print(f"测试集条数:{len(dataset['test'])}")
print("训练集示例:", dataset["train"][0]["text"], "→ 标签:", dataset["train"][0]["label"])# -------------------------- 5. 数据预处理 --------------------------
def preprocess_function(examples):tokenized = tokenizer(examples["text"],truncation=True,max_length=128,padding="max_length")tokenized["label"] = [int(lab) for lab in examples["label"]]return tokenizedtokenized_dataset = dataset.map(preprocess_function, batched=True)
print("\n🔧 数据预处理完成(已分词+统一长度)")# -------------------------- 6. 训练参数(旧版本100%兼容) --------------------------
training_args = TrainingArguments(output_dir=output_dir,num_train_epochs=3,per_device_train_batch_size=4, # CPU专用,避免内存溢出per_device_eval_batch_size=4,eval_strategy="epoch", # 旧版本兼容的验证策略save_strategy="epoch", # 与验证策略统一,支持加载最优模型logging_strategy="no", # 彻底禁用日志report_to=[], # 禁用所有报告工具(包括TensorBoard)load_best_model_at_end=True,disable_tqdm=False, # 显示进度条do_eval=True
)# -------------------------- 7. 启动训练(去掉不兼容的回调逻辑) --------------------------
# 旧版本Trainer无需手动过滤回调,默认回调已被logging_strategy和report_to禁用
trainer = Trainer(model=model,args=training_args,train_dataset=tokenized_dataset["train"],eval_dataset=tokenized_dataset["test"]
)print("\n🚀 开始训练(CPU训练约5-10分钟,耐心等待)...")
trainer.train()# -------------------------- 8. 推理验证 --------------------------
print("\n🎉 训练完成!情感分类测试:")
texts = ["这部电影非常精彩,推荐大家观看!","剧情拖沓,演员演技差,不推荐。","这家餐厅的菜味道一般,价格还贵。"
]
for text in texts:inputs = tokenizer(text, return_tensors="pt")with torch.no_grad():logits = model(**inputs).logitspred = torch.argmax(logits, dim=1).item()print(f"文本:{text} → 情感:{'积极' if pred == 1 else '消极'}")
程序运行结果如下:
📊 数据集加载成功:
训练集条数:1000
测试集条数:200
训练集示例: 这款耳机味道很难吃,体验极差~ → 标签: 0
🔧 数据预处理完成(已分词+统一长度)
🚀 开始训练(CPU训练约5-10分钟,耐心等待)...
{'eval_loss': 2.4222437787102535e-05, 'eval_runtime': 12.7974, 'eval_samples_per_second': 15.628, 'eval_steps_per_second': 3.907, 'epoch': 1.0}
{'eval_loss': 1.1633565918600652e-05, 'eval_runtime': 12.8015, 'eval_samples_per_second': 15.623, 'eval_steps_per_second': 3.906, 'epoch': 2.0}
{'eval_loss': 9.382321877637878e-06, 'eval_runtime': 11.6915, 'eval_samples_per_second': 17.106, 'eval_steps_per_second': 4.277, 'epoch': 3.0}
{'train_runtime': 1791.0048, 'train_samples_per_second': 1.675, 'train_steps_per_second': 0.419, 'train_loss': 0.012714094797770182, 'epoch': 3.0}
🎉 训练完成!情感分类测试:
文本:这部电影非常精彩,推荐大家观看! → 情感:积极
文本:剧情拖沓,演员演技差,不推荐。 → 情感:消极
文本:这家餐厅的菜味道一般,价格还贵。 → 情感:消极
四、总结
本文介绍了中文预训练模型BERT-base-chinese的基本用法及其在情感分析中的应用。主要内容包括:
(1)通过ModelScope平台下载模型并加载分词器和基础BERT模型;
(2)文本预处理和特征提取流程;
(3)利用BERT模型实现中文文本情感二分类任务。
文章详细展示了从模型加载、数据处理到训练验证的完整Python代码实现,特别针对CPU环境优化了训练参数配置。该方案适用于通用中文NLP任务,为自然语言处理初学者提供了可复现的实践案例。