自然语言处理容易混淆知识点(七)模型架构 vs 使用方式

模型架构 vs 使用方式

一个模型基座可能有多种用法
embedding_model = SentenceTransformer('/workspace/huggingface_cache/models/bert-base-uncased')
cross_encoder = CrossEncoder('/workspace/huggingface_cache/models/bert-base-uncased', num_labels=2)

一、核心区别:模型架构 vs 使用方式

关键点:

同一个预训练权重(bert-base-uncased)可以被实例化为不同的下游模型架构。

比喻:

  • 预训练权重 就像是一个刚毕业的医学生(有医学基础知识)
  • SentenceTransformer 就像让这个学生成为全科医生(快速诊断多个病人)
  • CrossEncoder 就像让这个学生成为专科会诊医生(两个病人一起看,详细分析)

二、详细解释

1. 相同的起点:BERT预训练权重

python 复制代码
# 这两个都从同一个文件加载权重
model_path = "/workspace/huggingface_cache/models/bert-base-uncased"

# 加载的是相同的预训练参数
# 这些参数包括:
# - 12层Transformer权重
# - 768维隐藏层
# - 12个注意力头
# - 等等...

2. 不同的实例化:架构适配

A. SentenceTransformer(Bi-Encoder)
python 复制代码
from sentence_transformers import SentenceTransformer

# 加载为SentenceTransformer时:
# 1. 使用BERT作为基础编码器
# 2. 添加池化层(mean pooling, CLS等)
# 3. 输出:单个句子的固定维度向量
embedding_model = SentenceTransformer(model_path)

# 使用方式:
vector1 = embedding_model.encode("Hello world")      # 形状: [768]
vector2 = embedding_model.encode("How are you?")     # 形状: [768]
similarity = cosine_similarity(vector1, vector2)    # 计算相似度

关键特征

  • 每个句子独立编码
  • 输出:向量表示
  • 相似度计算:向量运算(余弦相似度等)
  • 适合:检索、聚类、语义搜索
B. CrossEncoder
python 复制代码
from sentence_transformers import CrossEncoder

# 加载为CrossEncoder时:
# 1. 同样使用BERT作为基础
# 2. 但添加分类头(classification head)
# 3. 设计为处理句子对
cross_encoder = CrossEncoder(model_path, num_labels=2)

# 使用方式:
# 两个句子一起输入
score = cross_encoder.predict([("Hello world", "How are you?")])
# 输出直接是相似度分数或分类概率

关键特征

  • 两个句子一起编码
  • 输出:相似度分数/分类概率
  • 相似度计算:模型内部计算
  • 适合:重排序、文本蕴含、精细相似度

三、架构对比图

复制代码
# Bi-Encoder (SentenceTransformer) 架构:
句子A → BERT编码器 → 池化层 → 向量A (768维)
                                          ↘
                                            余弦相似度 → 分数
                                          ↗
句子B → BERT编码器 → 池化层 → 向量B (768维)

# CrossEncoder 架构:
句子A + 句子B → 拼接 → [CLS] A [SEP] B [SEP]
                             ↓
                         BERT编码器(完整交互)
                             ↓
                         分类头/回归头
                             ↓
                          分数 (0-1)

四、技术实现的区别

1. 输入处理不同

python 复制代码
# Bi-Encoder的处理
input1 = tokenizer("Hello world", padding=True, truncation=True)
input2 = tokenizer("How are you?", padding=True, truncation=True)
# 分别通过BERT模型

# CrossEncoder的处理
input_pair = tokenizer(
    "Hello world", 
    "How are you?", 
    padding=True, 
    truncation=True, 
    return_tensors="pt"
)
# [CLS] Hello world [SEP] How are you? [SEP]

2. 注意力模式不同

python 复制代码
# Bi-Encoder中的注意力
# 句子A内部的自注意力:只能看到句子A的token
# 句子B内部的自注意力:只能看到句子B的token

# CrossEncoder中的注意力
# 拼接序列的自注意力:每个token可以看到两个句子的所有token
# 例如:"Hello"可以关注到"world"、"How"、"are"、"you"

3. 输出头不同

python 复制代码
# SentenceTransformer的输出
output = model(input_ids, attention_mask)  # 形状: [batch_size, seq_len, hidden_dim]
pooled = mean_pooling(output, attention_mask)  # 形状: [batch_size, hidden_dim]
# 这就是句子向量

# CrossEncoder的输出
output = model(input_ids, attention_mask)  # 同上
cls_output = output[:, 0, :]  # 取[CLS] token
logits = classifier_head(cls_output)  # 通过分类头
# 输出相似度分数

五、为什么这样设计?

1. 效率 vs 精度权衡

  • Bi-Encoder(SentenceTransformer)

    • 推理快 :句子向量可以预计算并缓存
    • 适合大规模检索:比较向量很快(余弦相似度)
    • 精度稍低:缺少句子间交互
  • CrossEncoder

    • 精度高:有完整的句子间注意力
    • 推理慢:每次比较都需要重新计算
    • 不适合大规模:O(n²)的复杂度

2. 实际应用场景

python 复制代码
# 场景:100万个文档的语义搜索

# 第一步:用Bi-Encoder快速筛选(召回阶段)
query_vector = bi_encoder.encode("机器学习是什么")
# 预计算所有文档向量(离线)
doc_vectors = precomputed_document_vectors  # 形状: [1_000_000, 768]
# 快速相似度计算(毫秒级)
top_100_indices = find_top_k(query_vector, doc_vectors, k=100)

# 第二步:用CrossEncoder精细排序(排序阶段)
candidate_docs = get_docs(top_100_indices)
scores = []
for doc in candidate_docs:
    score = cross_encoder.predict([(query, doc)])
    scores.append(score)
# 重新排序这100个候选

六、在增强SBERT中的作用

知识蒸馏流程:

python 复制代码
# 1. CrossEncoder作为教师(精度高)
teacher = CrossEncoder("bert-base-uncased")

# 2. 用CrossEncoder标注大量未标注数据
#    生成"软标签"(相似度分数)
pseudo_labels = teacher.predict(unlabeled_pairs)

# 3. Bi-Encoder作为学生(效率高)
student = SentenceTransformer("bert-base-uncased")

# 4. 学生向教师学习
#    目标:让Bi-Encoder的向量相似度接近CrossEncoder的分数
train_student_with_distillation(student, teacher, pseudo_labels)

# 结果:学生获得了接近教师的精度,但保持了高效率

七、总结:同一个预训练模型的不同"人格"

方面 SentenceTransformer (Bi-Encoder) CrossEncoder
角色 快速筛选者 精细裁判员
输入 单句独立 句子对一起
输出 句子向量 相似度分数
速度 ⚡⚡⚡ 非常快 ⚡ 较慢
精度 良好 优秀
缓存 可以预计算向量 不能预计算
适用场景 召回、检索、聚类 重排序、精细匹配

简单说

  • 两者都是"BERT医生",但:
    • SentenceTransformer分诊台护士,快速判断该去哪个科室
    • CrossEncoder专家会诊,详细分析病情

在增强SBERT中,就是让护士(Bi-Encoder) 学习专家(CrossEncoder) 的判断经验,从而让护士在保持高效率的同时,做出更接近专家水平的判断。

相关推荐
傻啦嘿哟2 小时前
隧道代理在数据挖掘中的实战应用:从原理到落地的全流程解析
人工智能·数据挖掘
会飞的小新2 小时前
从 LLM 到 ReACT Agent:推理与行动协同的智能体框架深度解析
人工智能·语言模型
无心水2 小时前
【神经风格迁移:多风格】17、AIGC+风格迁移:用Stable Diffusion生成自定义风格
人工智能·机器学习·语言模型·stable diffusion·aigc·机器翻译·vgg
摸鱼仙人~2 小时前
Bert系列之为什么选择chinese_roberta_wwm_ext
人工智能·深度学习·bert
Roxanne0072 小时前
吴教授《AI for everyone》笔记梳理(DAY1)
人工智能·笔记
倔强的石头1062 小时前
昇腾大模型量化实战:ModelSlim 工具上手与 W8A8 精度优化全流程解析
人工智能·机器学习
TMT星球2 小时前
“智汇众力 共擎新元”,机器人租赁平台“擎天租”发布
大数据·人工智能·机器人
HUT_Tyne2652 小时前
第2章 语言模型基础
人工智能·语言模型·自然语言处理
熬夜敲代码的小N2 小时前
自然语言处理与Transformer模型
人工智能·自然语言处理·transformer