You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用GPT-2计算词嵌入与句嵌入?代码正确性求验证

你的GPT-2词嵌入与句嵌入计算逻辑分析

词嵌入部分:逻辑正确

你提取outputs[0]作为词嵌入的做法没问题。GPT2Model的outputs[0]就是模型最后一层的隐藏状态,形状为(batch_size, seq_len, hidden_size),每个位置对应输入序列中对应token的上下文嵌入,完全符合词嵌入的需求。

句嵌入部分:存在两处关键问题

直接取word_embedding[:, -1, :]作为句嵌入的逻辑有漏洞,同时你的padding方式也不符合GPT-2的tokenizer规范,具体问题如下:

1. 手动padding的错误

GPT2Tokenizer默认没有专门的pad token,你直接用[0]填充的话,0对应的是GPT-2的<|endoftext|>(结束符),模型会把这些填充的0当成真实的输入token处理,导致隐藏状态计算失真。正确的做法是先给tokenizer指定pad token,再用tokenizer自带的批量编码方法处理,自动完成padding。

2. 句嵌入提取的错误

如果序列被padding,[:, -1, :]取到的是填充位置的隐藏状态,而不是原句子最后一个有效token的状态。必须借助attention_mask来定位每个序列的真实末尾位置,提取对应嵌入。

修正后的代码

from transformers import GPT2Tokenizer, GPT2Model
import torch

tokenizer = GPT2Tokenizer.from_pretrained('gpt2')
# 给GPT2Tokenizer指定pad token(复用eos token)
tokenizer.pad_token = tokenizer.eos_token
model = GPT2Model.from_pretrained('gpt2')
captions = ["example caption", "example bird", "the bird is yellow has red wings", "hi", "very good"]

# 用tokenizer批量编码,自动生成input_ids和attention_mask
encoded_input = tokenizer(
    captions,
    padding=True,
    truncation=True,
    return_tensors='pt'
)

outputs = model(**encoded_input)
word_embedding = outputs[0].contiguous()

# 利用attention_mask找到每个序列的真实最后一个token位置
# attention_mask中1表示有效token,0表示padding
# 计算每个序列的有效长度,再减1得到最后一个有效token的索引
seq_lengths = torch.sum(encoded_input['attention_mask'], dim=1) - 1
# 提取每个序列对应位置的隐藏状态作为句嵌入
sentence_embedding = word_embedding[torch.arange(word_embedding.size(0)), seq_lengths, :].contiguous()

额外说明

  • 如果你的场景允许忽略padding的影响(比如所有句子长度一致),句嵌入取最后一个位置也能勉强用,但实际应用中几乎都会遇到长度不一致的情况,必须用attention_mask处理。
  • GPT-2的隐藏状态本身是上下文相关的,所以提取的词嵌入和句嵌入都带有上下文信息,符合大部分NLP任务的需求。

内容的提问来源于stack exchange,提问作者user23180808

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 20:27:40